电路的python networkx循环

电路的python networkx循环,python,python-3.x,graph,networkx,scientific-computing,Python,Python 3.x,Graph,Networkx,Scientific Computing,我试图通过大小为LXL的networkx中的每条边(分支)查找电流。为此,我使用基尔霍夫电压定律,该定律规定: 为了建立联立线性方程组,我需要在图中找到圈,因为我有一个无向图,所以我应用了nx.simple_cycles(G),其中G是我的图 但这会返回一些正确的周期和一些错误的周期。我不知道还有什么好尝试的。为了弄清楚这一点,我几个星期来一直把头撞在墙上。如果这失败了,我将求助于将网络导出到SPICE包中,并使用它解决分支电流。或者有没有其他方法来获取电流 import numpy as n

我试图通过大小为LXL的networkx中的每条边(分支)查找电流。为此,我使用基尔霍夫电压定律,该定律规定:

为了建立联立线性方程组,我需要在图中找到圈,因为我有一个无向图,所以我应用了
nx.simple_cycles(G)
,其中G是我的图

但这会返回一些正确的周期和一些错误的周期。我不知道还有什么好尝试的。为了弄清楚这一点,我几个星期来一直把头撞在墙上。如果这失败了,我将求助于将网络导出到SPICE包中,并使用它解决分支电流。或者有没有其他方法来获取电流

import numpy as np
import networkx as nx
import matplotlib.pyplot as plt



def gen_random_num():
    return np.random.weibull(a=1.0)

G = nx.Graph()
rows = range(3)
columns = range(3)


#grid algorithm https://networkx.github.io/documentation/networkx-1.10/_modules/networkx/generators/classic.html#grid_graph
G.add_nodes_from( ((i,j) for i in rows for j in columns))

G.add_edges_from( ((i,j),(i-1,j)) for i in rows for j in columns if i>0)
G.add_edges_from( ((i,j),(i,j-1)) for i in rows for j in columns if j>0)   

for n in G.nodes:
    G.node[n]['current'] = int(gen_random_num())

pos = dict((n, n) for n in G.nodes())

node_labels = nx.get_node_attributes(G,'current')

nx.draw(G, pos, with_labels=True, node_size=500)
plt.show()
plt.savefig('fig')

cycles = nx.cycle_basis(G)


numedges = G.number_of_edges()
numnodes = G.number_of_nodes()
num_cycles = len(cycles)

for cycle in cycles:
    print(cycle)
这将返回:

[(1, 1), (1, 2), (0, 2), (0, 1)]
[(1, 1), (2, 1), (2, 2), (1, 2)]
[(0, 0), (1, 0), (2, 0), (2, 1), (2, 2), (1, 2), (0, 2), (0, 1)]
[(1, 1), (1, 0), (2, 0), (2, 1)]
这是错误的,因为在左下角的网格中应该有另一个循环


有人能帮忙吗?

cycle\u basis
返回一组基本周期,而不是图表中的所有周期。通过迭代所有对并计算对称差,将循环基础扩展到所有循环的集合

import itertools
import numpy as np
import networkx as nx
import matplotlib.pyplot as plt

def symmetric_difference(graph, cycle_a, cycle_b):
    # get edges
    edges_a = list(graph.subgraph(cycle_a).edges())
    edges_b = list(graph.subgraph(cycle_b).edges())

    # also get reverse edges as graph undirected
    edges_a += [e[::-1] for e in edges_a]
    edges_b += [e[::-1] for e in edges_b]

    # find edges that are in either but not in both
    edges_c = set(edges_a) ^ set(edges_b)

    cycle_c = frozenset(nx.Graph(list(edges_c)).nodes())
    return cycle_c

def gen_random_num():
    return np.random.weibull(a=1.0)

G = nx.Graph()
rows = range(3)
columns = range(3)

#grid algorithm https://networkx.github.io/documentation/networkx-1.10/_modules/networkx/generators/classic.html#grid_graph
G.add_nodes_from( ((i,j) for i in rows for j in columns))
G.add_edges_from( ((i,j),(i-1,j)) for i in rows for j in columns if i>0)
G.add_edges_from( ((i,j),(i,j-1)) for i in rows for j in columns if j>0)

for n in G.nodes:
    G.node[n]['current'] = int(gen_random_num())

pos = dict((n, n) for n in G.nodes())
node_labels = nx.get_node_attributes(G,'current')
nx.draw(G, pos, with_labels=True, node_size=500)
plt.show()
plt.savefig('fig')

cycle_basis = nx.cycle_basis(G)
cycles = []
for c1, c2 in itertools.combinations(cycle_basis, 2):
    cycles.append(list(symmetric_difference(G, c1, c2)))
cycles += cycle_basis

for cycle in cycles:
    print(cycle)

# [(1, 2), (0, 1), (2, 1), (0, 2), (2, 2), (1, 1)]
# [(0, 1), (1, 2), (0, 0), (2, 1), (2, 0), (2, 2), (1, 0), (1, 1)]
# [(0, 1), (1, 2), (2, 1), (1, 1), (2, 0), (1, 0), (0, 2)]
# [(1, 2), (0, 1), (0, 0), (2, 1), (0, 2), (2, 0), (1, 0), (1, 1)]
# [(1, 2), (2, 1), (2, 0), (2, 2), (1, 0), (1, 1)]
# [(1, 2), (0, 1), (0, 0), (2, 1), (0, 2), (2, 2), (1, 0), (1, 1)]
# [(1, 1), (1, 2), (0, 2), (0, 1)]
# [(1, 1), (2, 1), (2, 2), (1, 2)]
# [(0, 0), (1, 0), (2, 0), (2, 1), (2, 2), (1, 2), (0, 2), (0, 1)]
# [(1, 1), (1, 0), (2, 0), (2, 1)]

cycle\u basis
返回一组基本周期,而不是图形中的所有周期。通过迭代所有对并计算对称差,将循环基础扩展到所有循环的集合

import itertools
import numpy as np
import networkx as nx
import matplotlib.pyplot as plt

def symmetric_difference(graph, cycle_a, cycle_b):
    # get edges
    edges_a = list(graph.subgraph(cycle_a).edges())
    edges_b = list(graph.subgraph(cycle_b).edges())

    # also get reverse edges as graph undirected
    edges_a += [e[::-1] for e in edges_a]
    edges_b += [e[::-1] for e in edges_b]

    # find edges that are in either but not in both
    edges_c = set(edges_a) ^ set(edges_b)

    cycle_c = frozenset(nx.Graph(list(edges_c)).nodes())
    return cycle_c

def gen_random_num():
    return np.random.weibull(a=1.0)

G = nx.Graph()
rows = range(3)
columns = range(3)

#grid algorithm https://networkx.github.io/documentation/networkx-1.10/_modules/networkx/generators/classic.html#grid_graph
G.add_nodes_from( ((i,j) for i in rows for j in columns))
G.add_edges_from( ((i,j),(i-1,j)) for i in rows for j in columns if i>0)
G.add_edges_from( ((i,j),(i,j-1)) for i in rows for j in columns if j>0)

for n in G.nodes:
    G.node[n]['current'] = int(gen_random_num())

pos = dict((n, n) for n in G.nodes())
node_labels = nx.get_node_attributes(G,'current')
nx.draw(G, pos, with_labels=True, node_size=500)
plt.show()
plt.savefig('fig')

cycle_basis = nx.cycle_basis(G)
cycles = []
for c1, c2 in itertools.combinations(cycle_basis, 2):
    cycles.append(list(symmetric_difference(G, c1, c2)))
cycles += cycle_basis

for cycle in cycles:
    print(cycle)

# [(1, 2), (0, 1), (2, 1), (0, 2), (2, 2), (1, 1)]
# [(0, 1), (1, 2), (0, 0), (2, 1), (2, 0), (2, 2), (1, 0), (1, 1)]
# [(0, 1), (1, 2), (2, 1), (1, 1), (2, 0), (1, 0), (0, 2)]
# [(1, 2), (0, 1), (0, 0), (2, 1), (0, 2), (2, 0), (1, 0), (1, 1)]
# [(1, 2), (2, 1), (2, 0), (2, 2), (1, 0), (1, 1)]
# [(1, 2), (0, 1), (0, 0), (2, 1), (0, 2), (2, 2), (1, 0), (1, 1)]
# [(1, 1), (1, 2), (0, 2), (0, 1)]
# [(1, 1), (2, 1), (2, 2), (1, 2)]
# [(0, 0), (1, 0), (2, 0), (2, 1), (2, 2), (1, 2), (0, 2), (0, 1)]
# [(1, 1), (1, 0), (2, 0), (2, 1)]

cycle\u basis
为您提供了一组循环的基础,所有其他循环都可以通过集合并集和交集进行构造。它不会返回图中的所有循环。@Paul-有没有办法只返回唯一的循环?有
simple_cycles()
,但它需要一个有向图。我在考虑通过设置电流的方向(可能是顺时针方向)来创建一个有向图。你知道我能实现什么算法来找到循环吗?或者一种更简单的方法来计算电流?你只需要取基集中每对周期之间的对称差,iirc。请参阅下面的答案(不能将代码作为注释)。这并不能回答您的实际问题,但我相当确定,可以始终从基本循环生成完整的KCL方程组。它们可能不是最简单/最短的方程,但如果您以编程方式求解方程,这可能无关紧要。@mbrig是的,我知道您可以使用所谓的“超级网格”来求解它们。我想我可以试一下,看看以后是否可以证明。
cycle\u basis
提供了一组循环的基集,所有其他循环都可以通过集合并集和交集来构造。它不会返回图中的所有循环。@Paul-有没有办法只返回唯一的循环?有
simple_cycles()
,但它需要一个有向图。我在考虑通过设置电流的方向(可能是顺时针方向)来创建一个有向图。你知道我能实现什么算法来找到循环吗?或者一种更简单的方法来计算电流?你只需要取基集中每对周期之间的对称差,iirc。请参阅下面的答案(不能将代码作为注释)。这并不能回答您的实际问题,但我相当确定,可以始终从基本循环生成完整的KCL方程组。它们可能不是最简单/最短的方程,但如果您以编程方式求解方程,这可能无关紧要。@mbrig是的,我知道您可以使用所谓的“超级网格”来求解它们。我想我可以试一下,看看以后是否能证明。谢谢,让我在笔记本上试一下。它仍然返回我不想要的循环(比如超级循环)。也许我需要做更多的过滤?可能是你不想要所有的周期,但是这个集合的有效值是:[(1,1),(1,2),(0,2),(0,1)],[(1,1),(2,1),(2,2),(1,2)],[(1,1),(1,0),(2,0),(2,1)],和[(0,0),(0,1),(1,1),(1,0)]?如果是这样的话,你也许应该看看我的答案:谢谢,让我在笔记本上试试。它仍然返回我不想要的循环(比如超级循环)。也许我需要做更多的过滤?可能是你不想要所有的周期,但是这个集合的有效值是:[(1,1),(1,2),(0,2),(0,1)],[(1,1),(2,1),(2,2),(1,2)],[(1,1),(1,0),(2,0),(2,1)],和[(0,0),(0,1),(1,1),(1,0)]?如果是这样的话,你应该看看我的答案: