最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

找到最短路径小于或等于Python中非循环有向图的给定值

SEO心得admin159浏览0评论
本文介绍了找到最短路径小于或等于Python中非循环有向图的给定值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

所以我们假设我有一个非循环的有向图 G ,节点 a0,a1,a2,b0,b1,b2,c0,c1 ,c2 ,我知道每个节点到任何邻居的传出距离。可以使用什么算法来找到小于给定长度的任何两个节点之间的最长路径?

编辑:我查看了维基百科页面最长路径问题,但我不知道是否使用非循环图和关键路径中概述的算法'部分或参数化复杂度部分中的一个。我有两个问题。在前者中,该算法要求您具有传入距离(我有传出距离),并且说实话,后面的描述可以贯穿我的头。

$ b $编辑2:我完成的图如下

graph = {a0:set([ a1,b0)a1:set([a2,b1])a2:set([b2])b0 :set([b1,c0])b1:set([b2,c1])b2:set([c2]) c0:set([c1])c1:set([c2])c2:set([])}

我还在单独的字典中有出站距离,例如

edge_distance = {a0:0 a1:4 a2:12 b0 :2 b1:1 b2:4 c0:7 c1:2 c2:1 }

只有我有进入距离的节点是c2

我想要找到的路径是a0到c2

EDIT3:我的图,toposorted:

c2 b2 c1 a2 b1 c0 a1 b0 a0

解决方案

'''

给出的问题规格,除了它显示两点之间的所有距离。选择最大的一个低于某个阈值是微不足道的。

它根本没有被优化,并不普遍,因为给出的问题规范有离开任何特定节点的每个边的单个距离。不过,应该很容易修改以使其更为一般。

此外,主要变量是全局变量,但这也很容易补救。

$ b注意:我不确定问题规格是否正确,因为距离a0的距离为0,但距离c2(不连接任何地方)的距离为在任何情况下,场景(和示例代码)都是非常有创造力的,因为离现有节点的所有边都不太可能在现实生活中具有相同的长度。

'''

如果1:

import集合 #问题描述中给出的数据 #键是起始节点,值是目标节点。 graph = {a0:set([a1,b0]),a1:set([a2,b1 ]),a2:set([b2]),b0:set([b1,c0]),b1 ([b2,c1]),b2:set([c2]),c0:set([c1]), c1:set([c2]),c2:set([]),} #从节点的每个出站边的长度 edge_distance = {a0:0,a1:4,a2:12,b0 b1:1,b2:4,c0:7,c1:2,c2 } def sort_graph():'''使用Kahn算法开发排序列表'''#每个传入顶点的数量节点 incoming = collections.defaultdict(int) #所有节点与ve退出他们的帐户 startnodes = set() #所有节点的顶点输入 endnodes = set() 在图中开始:$ startnodes.add(start) endnodes.add(end) incoming [end] + = 1 订单= [] startnodes - = endnodes ,而startnodes: start = startnodes.pop() ordered.append(start) for图形结束[start ]: incoming [end] - = 1 如果没有传入[end]: startnodes.add(end)如果sum(incoming.values()): raise ValueError(Graph has至少一个循环) 返回排序 ordered = sort_graph() def calc_dists(start) :'''返回包含从给定的起始节点到彼此节点的所有可能的距离的字典,表示为一组可能的dis每个目标节点都有。如果目标节点从开始节点不可访问,则该集合将为空。 ''' dist_to_node = collections.defaultdict(set) dist_to_node [start] .add(0)用于开始排序: cumulative = dist_to_node [start ] dist = edge_distance [start] 为图结尾[开始]: dist_to_node [end] .update(dist + prev为累积值)返回dist_to_node #显示a0和c2之间的所有距离 print(calc_dists('a0')['c2'])

So let's say I have an acyclic, directed graph G with nodes a0, a1, a2, b0, b1, b2, c0, c1, c2 and I know both the outgoing distance for each node to any of it's neighbors. What algorithm can I use to find the longest path between any two nodes that is less than a given length?

EDIT: I have looked at the Wikipedia page for the Longest path problem but I don't know whether to use the algorithm outlined in the 'Acyclic graphs and critical paths' section or the one in the 'Parameterized complexity' section. I'd have problems with either case. In the former, the algorithm requires you to have the incoming distance (I have the outgoing distance) and to be honest, the description in the latter goes over my head as far as implementation.

EDIT2: My completed graph is as follows

graph = { "a0": set(["a1", "b0]) "a1": set(["a2", "b1"]) "a2": set(["b2"]) "b0": set(["b1", "c0"]) "b1": set(["b2", "c1"]) "b2": set(["c2"]) "c0": set(["c1"]) "c1": set(["c2"]) "c2": set([]) }

I also have the outgoing distance in a separate dictionary e.g.

edge_distance = { "a0": 0 "a1": 4 "a2": 12 "b0": 2 "b1": 1 "b2": 4 "c0": 7 "c1": 2 "c2": 1 }

Technically the only node for which I have the incoming distance is c2

The path I want to find is a0 to c2

EDIT3: My graph, toposorted:

c2 b2 c1 a2 b1 c0 a1 b0 a0

解决方案

'''

This meets the problem spec as given, except that it shows all distances between two points. It is trivial to choose the largest one that is below some threshold.

It is not at all optimized, and is not general, in that the problem spec as given has a single distance for every edge leaving any particular node. Nonetheless, it should be easy to modify to make more general.

Also, the major variables are global, but this is easily remedied as well.

NOTE: I am not sure the problem spec is quite correct, because the distance out of a0 is given as 0, but the distance out of c2 (which doesn't go connect anywhere) is given as 1. In any case the scenario (and the example code) is quite contrived, because it is highly unlikely that all edges leaving a given node would have the same length in real life.

'''

if 1:

import collections # Data given in problem description # Keys are starting nodes, values are destination nodes. graph = { "a0": set(["a1", "b0"]), "a1": set(["a2", "b1"]), "a2": set(["b2"]), "b0": set(["b1", "c0"]), "b1": set(["b2", "c1"]), "b2": set(["c2"]), "c0": set(["c1"]), "c1": set(["c2"]), "c2": set([]), } # Length of every outbound edge from the node edge_distance = { "a0": 0, "a1": 4, "a2": 12, "b0": 2, "b1": 1, "b2": 4, "c0": 7, "c1": 2, "c2": 1, } def sort_graph(): ''' Develop a sorted list using Kahn's algorithm ''' # Number of incoming vertices to each node incoming = collections.defaultdict(int) #All nodes with vertices exiting them startnodes = set() # All nodes with vertices entering them endnodes = set() for start in graph: for end in graph[start]: startnodes.add(start) endnodes.add(end) incoming[end] += 1 ordered = [] startnodes -= endnodes while startnodes: start = startnodes.pop() ordered.append(start) for end in graph[start]: incoming[end] -= 1 if not incoming[end]: startnodes.add(end) if sum(incoming.values()): raise ValueError("Graph has at least one cycle") return ordered ordered = sort_graph() def calc_dists(start): ''' Returns a dictionary containing all possible distances from a given start node to each other node, expressed as a set of possible distances for each target node. The set will be empty if the target node is not reachable from the start node. ''' dist_to_node = collections.defaultdict(set) dist_to_node[start].add(0) for start in ordered: cumulative = dist_to_node[start] dist = edge_distance[start] for end in graph[start]: dist_to_node[end].update(dist + prev for prev in cumulative) return dist_to_node # Show all possible distances between a0 and c2 print(calc_dists('a0')['c2'])

发布评论

评论列表(0)

  1. 暂无评论