import networkx as nx
import matplotlib.pyplot as plt
import csv

# タスクとそのdurationをCSVファイルから読み込む
tasks = {}
with open('float.csv', newline='', encoding='utf-8') as csvfile:
    reader = csv.DictReader(csvfile)
    for row in reader:
        tasks[row['CODE']] = int(row['DAYS'])

# タスク間の依存関係をCSVファイルから読み込む
dependencies = []
with open('float.csv', newline='', encoding='utf-8') as csvfile:
    reader = csv.DictReader(csvfile)
    for row in reader:
        dependencies.append((row['CODE'], row['PREDECESSORS']))

# グラフを作成
G = nx.DiGraph()

# タスクをノードとして追加し、durationを属性として設定
for CODE, DAYS in tasks.items():
    G.add_node(CODE, duration=DAYS)

# タスク間の依存関係をエッジとして追加
G.add_edges_from(dependencies)



cycles = list(nx.simple_cycles(G))

# 検出されたサイクルの表示
print("検出されたサイクル:", cycles)

# トポロジカルソートして最早開始時刻（ES）を計算
es = {node: 0 for node in G.nodes()}
for node in nx.topological_sort(G):
    es[node] = max([es[p] + G.nodes[p]["duration"] for p in G.predecessors(node)], default=0)

# 逆向きのグラフを用いて最遅開始時刻（LS）を計算
ls = {node: es[node] for node in G.nodes()}
for node in list(reversed(list(nx.topological_sort(G)))):
    ls[node] = min([ls[s] - G.nodes[node]["duration"] for s in G.successors(node)], default=max(ls.values()))



# クリティカルパスを計算
float_time = {node: ls[node] - es[node] for node in G.nodes()}
critical_path = [node for node, float_time in float_time.items() if float_time == 0]



# トポロジカルソートしてグラフを一列に並べて表示
topological_order = list(nx.topological_sort(G))
print("トポロジカルソート順序:", topological_order)

# レイアウト調整
pos = {node: (i, 0) for i, node in enumerate(topological_order)}

# グラフを描画
nx.draw(G, pos, with_labels=True, node_size=500, node_color="lightblue", font_size=10, font_weight="bold", node_shape="o", arrowsize=20, connectionstyle="arc3,rad=0.1")
plt.show()
