| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192 |
- '''calc flow direction.
- step1. division block.
- step2. appoint source.
- setp3. calc flow direction.
- '''
- from relations.src.system_relation import systemdatautils
- import networkx as nx
- def calc(block_datas,source_datas):
- '''
- calc block flow direction.
- :param project_id:
- :param block_id:
- :return:
- '''
- # get roots
- roots=list(i.source_id for i in source_datas)
- g = nx.Graph()
- for item in block_datas:
- item.direction=None
- g.add_edge(item.id1,item.id2)
- G = g.to_directed()
- # get leaves
- leaves=list(v for v,d in G.out_degree() if d==1)
- G_new=nx.DiGraph()
- try:
- for i in range(len(roots)):
- root=roots[i]
- sign=1 if source_datas[i].is_source else -1
- for leaf in leaves:
- paths = nx.all_simple_paths(G, root, leaf)
- for path in paths:
- # remove contain source path
- if is_path_contain_root(path, roots, root):
- continue
- # set path direction
- for j in range(len(path) - 1):
- G_new.add_edge(path[j], path[j + 1],weight=(j*sign))
- # add source direct to source path.
- for j in range(i + 1, len(roots)):
- next_root=roots[j]
- paths = list(nx.all_simple_paths(G, root, next_root))
- for path in paths:
- if len(path) == 2:
- G_new.add_edge(root, next_root,weight=0)
- G_new.add_edge(next_root, root,weight=0)
- except Exception as ex:
- print(ex)
- for edge in G_new.edges:
- edge_data=G_new.get_edge_data(edge[0],edge[1])
- weight=edge_data["weight"]
- set_edge_direction(block_datas,edge,weight)
- return block_datas
- def is_path_contain_root(path, roots, cur_root):
- '''
- judge whether path contain root node except cur_root.
- :param path:
- :param roots:
- :param cur_root:
- :return:
- '''
- result = False
- for root in roots:
- if root == cur_root:
- continue
- result = (root in path)
- if result:
- break
- return result
- def set_edge_direction(block_datas,edge,weight):
- '''
- set connected_block direction.
- connector1 to connector2.sign:1
- connector2 to connector1.sign:-1
- both way.sign:0
- un calc.sign:None
- :param block_datas:
- :param edge:
- :return:
- '''
- for block_data in block_datas:
- # connector1 to connector2.sign:1
- if block_data.id1 == edge[0] and block_data.id2 == edge[1]:
- j=1
- block_data.direction=(block_data.direction+j if block_data.direction else j)
- block_data.depth=(weight)
- # connector2 to connector1.sing:-1
- if block_data.id1 == edge[1] and block_data.id2 == edge[0]:
- j = -1
- block_data.direction=(block_data.direction+j if block_data.direction else j)
- block_data.depth = (weight)
|