简体   繁体   English

创建一个networkx加权图并找到权重最小的2个节点之间的路径

[英]Create a networkx weighted graph and find the path between 2 nodes with the smallest weight

I have a problem involving graph theory. 我有一个涉及图论的问题。 To solve it, I would like to create a weighted graph using networkx. 为了解决这个问题,我想使用networkx创建一个加权图。 At the moment, I have a dictionnary where each key is a node, and each value is the associated weight (between 10 and 200 000 or so). 目前,我有一个字典,其中每个键是一个节点,每个值是关联的权重(介于10到200 000之间)。

weights = {node: weight}

I believe I do not need to normalize the weights with networks. 我相信我不需要通过网络标准化权重。 At the moment, I create a non-weighted graph by adding the edges: 此刻,我通过添加边来创建非加权图:

def create_graph(data):
    edges = create_edges(data)

    # Create the graph
    G = nx.Graph()

    # Add edges
    G.add_edges_from(edges)

    return G

From what I read, I can add a weight to the edge. 通过阅读,我可以为边缘添加权重。 However, I would prefer the weight to be applied to a specific node instead of an edge. 但是,我希望将权重应用于特定节点而不是边缘。 How can I do that? 我怎样才能做到这一点?

Idea: I create the graph by adding the nodes weighted, and then I add the edges between the nodes. 想法:我通过添加加权的节点来创建图形,然后在节点之间添加边。

def create_graph(data, weights):
    nodes = create_nodes(data)
    edges = create_edges(data) # list of tuples

    # Create the graph
    G = nx.Graph()

    # Add edges
    for node in nodes:
        G.add_node(node, weight=weights[node])

    # Add edges
    G.add_edges_from(edges)

    return G

Is this approach correct? 这种方法正确吗?

Next step is to find the path between 2 nodes with the smallest weight. 下一步是找到权重最小的2个节点之间的路径。 I found this function: networkx.algorithms.shortest_paths.generic.shortest_path which I think is doing the right thing. 我发现了这个功能: networkx.algorithms.shortest_paths.generic.shortest_path ,我认为这样做是正确的。 However, it uses weights on the edge instead of weights on the nodes. 但是,它在边缘使用权重而不是在节点上使用权重。 Could someone explain me what this function does, what the difference between wieghts on the nodes and weights on the edges is for networkx, and how I could achieve what I am looking for? 有人可以解释一下此功能的作用,对节点的权重与对边缘的权重之间的区别是什么,以及如何实现所需的功能? Thanks :) 谢谢 :)

This generally looks right. 这通常看起来是正确的。

You might use bidirectional_dijkstra . 您可以使用bidirectional_dijkstra It can be significantly faster if you know the source and target nodes of your path (see my comments at the bottom). 如果您知道路径的源节点和目标节点,则速度会大大提高(请参阅底部的评论)。

To handle the edge vs node weight issue, there are two options. 要解决边缘与节点权重问题,有两种选择。 First note that you are after the sum of the nodes along the path. 首先请注意,您位于路径上节点的总和之后。 If I give each edge a weight w(u,v) = w(u) + w(v) then the sum of weights along this is w(source) + w(target) + 2 sum(w(v)) where the nodes v are all nodes found along the way. 如果我给每条边一个权重w(u,v) = w(u) + w(v)那么沿这条权重的总和就是w(source) + w(target) + 2 sum(w(v))其中节点v是沿途发现的所有节点。 Whatever has the minimum weight with these edge weights will have the minimum weight with the node weights. 具有这些边缘权重的最小权重将具有带有节点权重的最小权重。

So you could go and assign each edge the weight to be the sum of the two nodes. 因此,您可以将每个边的权重分配为两个节点的总和。

for edge in G.edges():
    G.edges[edge]['weight'] = G.nodes[edge[0]]['weight'] + G.nodes[edge[1]]['weight']

But an alternative is to note that the weight input into bidirectional_dijkstra can be a function that takes the edge as input. 但另一种方法是注意,输入bidirectional_dijkstra的权重可以是将边作为输入的函数。 Define your own function to give the sum of the two node weights: 定义您自己的函数以给出两个节点权重之和:

def f(edge):
    u,v = edge
    return G.nodes[u]['weight'] + G.nodes[v]['weight']

and then in your call do bidirectional_dijkstra(G, source, target, weight=f) 然后在通话中执行bidirectional_dijkstra(G, source, target, weight=f)

So the choices I'm suggesting are to either assign each edge a weight equal to the sum of the node weights or define a function that will give those weights just for the edges the algorithm encounters. 因此,我建议的选择是为每个边缘分配的权重等于节点权重之和,或者定义一个函数,以仅针对算法遇到的边缘给出权重。 Efficiency-wise I expect it will take more time to figure out which is better than it takes to code either algorithm. 在效率方面,我希望找出哪种方法比编写任何一种算法要花更多的时间。 The only performance issue is that assigning all the weights will use more memory. 唯一的性能问题是分配所有权重将使用更多的内存。 Assuming memory isn't an issue, use whichever one you think is easiest to implement and maintain. 假设内存不是问题,请使用您认为最容易实现和维护的内存。


Some comments on bidirectional dijkstra: Imagine you have two points in space a distance R apart and you want to find the shortest distance between them. 关于双向dijkstra的一些评论:假设您在空间中有两个点,它们之间的距离为R,并且您想找到它们之间的最短距离。 The dijkstra algorithm (which is the default of shortest_path) will explore every point within distance D of the source point. dijkstra算法(默认为shortest_path)将探索源点距离D内的每个点。 Basically it's like expanding a balloon centered at the first point until it reaches the other. 基本上,这就像在第一个点居中展开一个气球,直到到达另一个。 This has a volume (4/3) pi R^3. 它的体积为(4/3)pi R ^ 3。 With bidirectional_dijkstra we inflate balloons centered at each until they touch. 使用bidirectional_dijkstra我们使每个气球居中膨胀,直到它们接触为止。 They will each have radius R/2. 它们各自的半径为R / 2。 So the volume is (4/3)pi (R/2)^3 + (4/3) pi (R/2)^3, which is a quarter the volume of the original balloon, so the algorithm has explored a quarter of the space. 因此,体积为(4/3)pi(R / 2)^ 3 +(4/3)pi(R / 2)^ 3,是原始气球体积的四分之一,因此该算法已探索了四分之一空间。 Since networks can have very high effective dimension, the savings is often much bigger. 由于网络可以具有非常高的有效维度,因此节省的费用通常更大。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在 NetworkX 中找到加权图的最短路径长度 - Find the shortest path length of a weighted graph in NetworkX 加权有向图中总重量最小 - Smallest total weight in weighted directed graph 如何在加权networkx图中找到具有最高总和的路径? - How to find path with highest sum in a weighted networkx graph? 如何使用networkx在加权图中找到最短路径? - How to find shortest path in a weighted graph using networkx? 如何获得两个节点之间最小路径的权重? - How to get the weight of the smallest path between two nodes? 如何使用networkx图根据中间节点的属性值找到2个节点之间的路径? - How to find a path between 2 nodes based on in-between node's attribute's value using networkx graph? Python networkx加权图在最短路径计算中没有考虑节点的权重? - Python networkx weighted graph not taking into account weight of node in shortest path calculation? 在有向加权图中,有效地找到两个节点 A 和 B 之间穿过节点 X 的最短路径的成本 - In a directed, weighted graph, efficiently find the cost of the shortest path between two nodes A and B that traverses through a node X Python - Networkx:具有一定权重的邻居节点图 - Python - Networkx: Graph of Neighbor Nodes with certain weight 如何使用 NetworkX 在加权图中获得最短路径? - How to get the shortest path in a weighted graph with NetworkX?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM