File tree Expand file tree Collapse file tree 5 files changed +281
-31
lines changed
Expand file tree Collapse file tree 5 files changed +281
-31
lines changed Original file line number Diff line number Diff line change 1+ """
2+ 背景,假如你在用python开发游戏的任务系统
3+ 这个任务系统必须是无环的,否则就出bug了。
4+ """
5+
6+ # 拓扑图
7+ # 任务id:任务信息
8+ num2Task = {
9+ 1 : {
10+ "name" : "开始冒险" ,
11+ "details" : "前往风起之地" ,
12+ },
13+ 2 : {
14+ "name" : "解救云隐村" ,
15+ "details" : "帮助云隐村解决危机" ,
16+ },
17+ 3 : {
18+ "name" : "破晓之星" ,
19+ "details" : "追踪星银之路" ,
20+ },
21+ 4 : {
22+ "name" : "征服风神" ,
23+ "details" : "挑战风神巅峰" ,
24+ },
25+ 5 : {
26+ "name" : "龙之末裔" ,
27+ "details" : "揭开龙的秘密" ,
28+ },
29+ }
30+
31+ graph = {
32+ 1 : {2 , 3 },
33+ 2 : {4 },
34+ 3 : {4 },
35+ 4 : {5 },
36+ 5 : {},
37+ }
Original file line number Diff line number Diff line change 1+ from graphlib import TopologicalSorter , CycleError
2+
3+
4+ def main ():
5+ # test0()
6+ # test1()
7+ test3 ()
8+ ...
9+
10+
11+ def test0 ():
12+ # 返回前驱为0的节点
13+ ts = TopologicalSorter ({
14+ "D" : {"B" , "C" },
15+ "C" : {"A" },
16+ "B" : {"A" }
17+ })
18+ ts .prepare () # 先让它准备一下,看看有没有环
19+ print (ts .get_ready ()) # 找到没有前驱的节点
20+
21+
22+ def test1 ():
23+ graph = {"D" : {"B" , "C" }, "C" : {"A" }, "B" : {"A" }}
24+ ts = TopologicalSorter (graph )
25+ c = ts .static_order ()
26+ print (list (c )[::- 1 ])
27+
28+
29+ def test2 ():
30+ try :
31+ ts2 = TopologicalSorter ({
32+ 'a' : {'b' },
33+ 'b' : {'c' },
34+ 'c' : {'d' },
35+ 'd' : {'a' },
36+ })
37+ print (list (ts2 .static_order ()))
38+ except CycleError :
39+ ...
40+
41+
42+ def test3 ():
43+ # 同样的图,换一个图的生成方式,用边生成
44+ ts = TopologicalSorter ()
45+ ts .add ('d' , 'b' )
46+ ts .add ('d' , 'c' )
47+ ts .add ('b' , 'a' )
48+ ts .add ('c' , 'a' )
49+ print (list (ts .static_order ()))
50+ ...
51+
52+
53+ if __name__ == "__main__" :
54+ """
55+ 自创编译系统检测引入是否合理
56+ 工作流程管理
57+
58+ 在游戏项目中:
59+ 任务系统 关卡设计 任务进度解锁 效果触发
60+
61+ """
62+ main ()
Original file line number Diff line number Diff line change 1+ from typing import *
2+
3+
4+ def main ():
5+ num2Task = {
6+ 1 : {
7+ "name" : "构思" ,
8+ "details" : ...,
9+ },
10+ 2 : {
11+ "name" : "拍视频" ,
12+ "details" : ...,
13+ },
14+ 3 : {
15+ "name" : "找素材" ,
16+ "details" : ...,
17+ },
18+ 4 : {
19+ "name" : "剪辑" ,
20+ "details" : ...,
21+ },
22+ 5 : {
23+ "name" : "发b站" ,
24+ "details" : ...,
25+ },
26+ }
27+ graph = {
28+ 1 : {2 , 3 },
29+ 2 : {4 },
30+ 3 : {4 },
31+ 4 : {5 },
32+ 5 : {},
33+ }
34+ graph = {
35+ 1 : {2 },
36+ 2 : {3 },
37+ 3 : {1 },
38+ }
39+ arr = f (graph )
40+ if len (arr ) < len (graph ):
41+ print ("cycle" )
42+ print ()
43+
44+
45+ def f (graph : Dict [int , Set [int ]]) -> List [int ]:
46+ from collections import deque
47+
48+ count_dict = {n : 0 for n in graph }
49+ for node , child_set in graph .items ():
50+ for child in child_set :
51+ count_dict [child ] += 1
52+
53+ q = deque ()
54+ for node , count in count_dict .items ():
55+ if count == 0 :
56+ q .append (node )
57+
58+ res = []
59+ while q :
60+ n = q .popleft ()
61+ res .append (n )
62+ child_set = graph [n ]
63+ for child in child_set :
64+ count_dict [child ] -= 1
65+ if count_dict [child ] == 0 :
66+ q .append (child )
67+ return res
68+
69+
70+ if __name__ == '__main__' :
71+ main ()
Original file line number Diff line number Diff line change 1+ """
2+ 拓扑排序的传统实现
3+
4+ """
5+
6+
7+ def topological_sort (graph ):
8+ def dfs (node ):
9+ visited [node ] = True
10+ for child in graph [node ]:
11+ if not visited [child ]:
12+ dfs (child )
13+ result .append (node )
14+
15+ # 初始化
16+ visited = {node : False for node in graph }
17+ result = []
18+
19+ # 遍历图中的每个节点
20+ for node in graph :
21+ if not visited [node ]:
22+ dfs (node )
23+
24+ # 结果是逆序的,反转得到拓扑排序
25+ return result [::- 1 ]
26+
27+
28+ def f (graph ):
29+ # 记录所有的入度量
30+ from collections import deque
31+ count_graph = {n : 0 for n in graph }
32+ for k , child_set in graph .items ():
33+ for child in child_set :
34+ count_graph [child ] += 1
35+ # 所有入度为0的节点入队列
36+ q = deque ()
37+ for node , count in count_graph .items ():
38+ if count == 0 :
39+ q .append (node )
40+ res = []
41+ # 准备好开始队列了
42+ while q :
43+ n = q .popleft ()
44+ res .append (n )
45+ child_set = graph [n ]
46+ for child in child_set :
47+ count_graph [child ] -= 1
48+ if count_graph [child ] == 0 :
49+ q .append (child )
50+ return res
51+
52+
53+ def topological_sort_no_cycle (graph ):
54+ # 能检测出是否有环的情况
55+ def dfs (node ):
56+ visited [node ] = True
57+ currently_visiting .add (node )
58+
59+ for child in graph [node ]:
60+ if not visited [child ]:
61+ if dfs (child ):
62+ return True
63+ elif child in currently_visiting :
64+ # 如果在当前DFS路径上发现已经访问过的节点,说明存在环
65+ return True
66+
67+ currently_visiting .remove (node )
68+ result .append (node )
69+ return False
70+
71+ # 初始化
72+ visited = {node : False for node in graph }
73+ result = []
74+ currently_visiting = set ()
75+
76+ # 遍历图中的每个节点
77+ for node in graph :
78+ if not visited [node ]:
79+ if dfs (node ):
80+ # 如果在DFS中发现环,返回空列表表示拓扑排序不可行
81+ return []
82+
83+ # 结果是逆序的,反转得到拓扑排序
84+ return result [::- 1 ]
85+
86+
87+ def main ():
88+ # 示例用法
89+ graph = {
90+ 1 : {2 , 3 },
91+ 2 : {4 },
92+ 3 : {4 , 5 },
93+ 4 : {5 },
94+ 5 : {},
95+ }
96+ g = {
97+ 1 : {2 },
98+ 2 : {3 },
99+ 3 : {4 },
100+ 4 : {5 },
101+ 5 : {1 },
102+ }
103+
104+ # result = topological_sort_no_cycle(graph)
105+ # result = topological_sort(g)
106+ result = f (graph )
107+ print ("Topological Sort:" , result )
108+
109+
110+ if __name__ == '__main__' :
111+ main ()
Load Diff This file was deleted.
You can’t perform that action at this time.
0 commit comments