如何解决如何从python
我正在使用networkx手动将(u,v,权重)输入到图形中。但是,当输入变得更大时,手动插入节点和边将变得非常繁琐且容易出错。我正在尝试,但还没有弄清楚如何在没有人工的情况下执行此任务。
示例输入:
my_list = [“ s1 [0]”,“ d1 [0,2]”,“ s2 [0]”,“ d2 [1,3]”,“ d3 [0,2]”,“ d4 [ 1,4]“,” d5 [2, 3]“,” d6 [1,4]“]
手动插入:
在将节点插入图中之前,我需要给它们编号,因此可以将“ s”或“ d”的首次出现与以后的类似字符区分开,例如s1,s2,s3,...和d1,d2,d3,... 我知道这与SSA表单(编译器)相似,但是找不到对我的案子有用的东西。
手动将(u,v,权重)插入DiGraph()
my_graph.add_weighted_edges_from([("s1","d1",0),("d1","s2","d3",2),("s2",(
"d2","d4",1),("d2","d5",3),("d3",("d4","d6",4)])
问题:
如何将输入列表(my_list)自动转换为DAG(my_graph),避免手动插入?
完整代码: 这是我到目前为止所写的。
import networkx as nx
from networkx.drawing.nx_agraph import write_dot,graphviz_layout
from matplotlib import pyplot as plt
my_graph = nx.DiGraph()
my_graph.add_weighted_edges_from([("s1",4)])
write_dot(my_graph,"graph.dot")
plt.title("draw graph")
pos = graphviz_layout(my_graph,prog='dot')
nx.draw(my_graph,pos,with_labels=True,arrows=True)
plt.show()
plt.clf()
说明:
-
的'和'd'是一些指令,分别需要1个或2个寄存器来执行操作。
-
在上面的示例中,我们有2个's'操作和6个'd'操作,并且有五个寄存器[0,1,2,3,4]。
-
每个操作都会执行一些计算,并将结果存储在相关的寄存器中。
-
从输入中我们可以看到d1使用寄存器0和2,因此直到两个寄存器都释放后它才能工作。因此,d1依赖于s1,因为s1在d1之前并且正在使用寄存器0。一旦s1完成,d1就可以操作,因为寄存器2已经是空闲的。
-
例如我们用1初始化所有寄存器。s1将其输入加倍,而d1将两个输入求和,并将结果存储在第二个寄存器中:
因此s1 [0] reg-0 * 2-> 1 * 2 => reg-0 = 2
并且在d1 [0,2] reg-0 + reg-2-> 2 +1 => reg-0 = 2和reg-2 = 3
之后
更新1:该图将是基于某些资源[0 ... 4]的依赖关系图,每个节点将需要1(对于's')或2(对于'd' ')的这些资源。
更新2:两个问题引起了混乱,因此我将它们分开。现在,我已经更改了输入列表,只有一个任务就是将该列表转换为DAG。我还包括一个说明部分。
PS:如果尚未安装graphviz,则可能需要点安装它。
解决方法
好了,现在我对映射的工作方式有了一个更好的了解,它可以归结为用代码描述过程,保留对哪个op正在使用哪个资源的映射,并在操作使用资源时进行迭代。通过前面的操作,我们生成了一条边。我认为这符合您的需求:
import ast
class UniqueIdGenerator:
def __init__(self,initial=1):
self.auto_indexing = {}
self.initial = initial
def get_unique_name(self,name):
"adds number after given string to ensure uniqueness."
if name not in self.auto_indexing:
self.auto_indexing[name] = self.initial
unique_idx = self.auto_indexing[name]
self.auto_indexing[name] += 1
return f"{name}{unique_idx}"
def generate_DAG(source):
"""
takes iterable of tuples in format (name,list_of_resources) where
- name doesn't have to be unique
- list_of_resources is a list of resources in any hashable format (list of numbers or strings is typical)
generates edges in the format (name1,name2,resource),- name1 and name2 are unique-ified versions of names in input
- resource is the value in the list of resources
each "edge" represents a handoff of resource,so name1 and name2 use the same resource sequentially.
"""
# format {resource: name} for each resource in use.
resources = {}
g = UniqueIdGenerator()
for (op,deps) in source:
op = g.get_unique_name(op)
for resource in deps:
# for each resource this operation requires,if a previous operation used it
if resource in resources:
# yield the new edge
yield (resources[resource],op,resource)
# either first or yielded an edge,this op is now using the resource.
resources[resource] = op
my_list = ["s[0]","d[0,2]","s[0]","d[1,3]",4]","d[2,4]"]
data = generate_DAG((a[0],ast.literal_eval(a[1:])) for a in my_list)
print(*data,sep="\n")
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。