给定一个连通图和一个N个指定顶点的列表,我想找到一种有效的方法来创建N个子图,每个子图包含一个指定顶点。为了实现这一点,我们可以修剪边。但是,我们应该修剪尽可能少的边权重。
例如,让我们从下面的图开始,我们想要得到三个包含三个红色顶点
之一的子图
结果应如下所示:
现在,我使用的是启发式算法,但它在某些边的情况下效果不好,并且在顶点数量上有n^2的复杂度。其思想是计算两个顶点之间的最短路径,并删除最亮的边,重复直到顶点断开连接。以下是我的代码:
import pandas as pd
import igraph as ig
from collections import Counter
ucg_df = pd.DataFrame(
[
[0, 1, 100],
[0, 2, 110],
[2, 3, 70],
[3, 4, 100],
[3, 1, 90],
[0, 3, 85],
[5, 7, 90],
[0, 8, 100],
[3, 6, 10],
[2, 5, 60],
],
columns=["nodeA", "nodeB", "weight"],
)
ucg_graph = ig.Graph.DataFrame(ucg_df, directed=False)
ig.plot(
ucg_graph,
target='stack1.pdf',
edge_label=ucg_graph.es["weight"],
vertex_color=['red']*3 + ['green']*(len(ucg_df)-3),
vertex_label = ucg_graph.vs.indices
)
def generate_subgraphs_from_vertexes(g, vertex_list):
for i, vertex in enumerate(vertex_list):
for j in range(i + 1, len(vertex_list)):
while True:
path = g.get_shortest_paths(vertex_list[i], vertex_list[j], mode='ALL', output='epath',
weights='weight')[0]
if len(path) == 0:
break
edge_2_drop = min(g.es[path], key=lambda x: x['weight'])
edge_2_drop.delete()
return g
graph = generate_subgraphs_from_vertexes(ucg_graph, ucg_graph.vs[0,1,2])
ig.plot(
graph,
target='stack2.pdf',
edge_label=graph.es["weight"],
vertex_color=['red']*3 + ['green']*(len(ucg_df)-3),
vertex_label = graph.vs.indices
)
我可以用什么样的算法来更好地解决这个问题?
2条答案
按热度按时间im9ewurl1#
我对Python中的
igraph
不太熟悉,但下面是我对R
的尝试,希望你能从中得到一些提示。我认为您的问题可以重新表述为assignment problem,因为关键部分是将"红色"分配给关联的"绿色"顶点以使成本最大化
运行
plot(out, layout = layout_nicely(g))
时,您将看到数据
kzipqqlq2#
受Find rows of matrix which contain rows of another matrix的启发,假设图是无向的,我发现: