这是问题所在:
我有n个点(p1,p2,p3,.. pn),每个点都可以以确定的成本x连接到任何其他点。
每个点都属于一组点类型之一(例如“A”“B”“C”“D”......)。
方法的输入是我想要遵循的路径,例如“A-B-C-A-D-B”。
输出是连接输入类型I的点的最短路径,例如“p1-p4-p32-p83-p43-p12”,其中p1是A型,p4是B型,p32 C型,p83型,A型,p43型,D型,p12型,B型。
“简单”解决方案包括计算所有可能的路径,但计算成本非常高!
有人能找到更好的算法吗?
正如我在标题中所说,我不知道它是否存在!
更新
阻止我使用Dijkstra和其他类似算法的关键点是我必须根据类型链接点。
作为输入我有一系列类型,我必须按顺序链接。
这是Kent Fredric的图片(非常感谢),描述了最初的情况(红色允许的链接)!
一个现实生活中的例子:
一个男人想早上去教堂,去餐馆,下午去博物馆。
地图上有6个教堂,30个餐厅和4个博物馆。
他希望教堂休息博物馆的距离是最小的。
答案 0 :(得分:7)
您可以使用Floyd-Warshall算法。这是WikiPedia给出的伪代码:
/* Assume a function edgeCost(i,j) which returns the cost of the edge from i to
(infinity if there is none).
Also assume that n is the number of vertices and edgeCost(i,i)=0
*/
int path[][];
/* A 2-dimensional matrix. At each step in the algorithm, path[i][j] is the shortest path
from i to j using intermediate vertices (1..k-1). Each path[i][j] is initialized to
edgeCost(i,j) or infinity if there is no edge between i and j.
*/
procedure FloydWarshall ()
for k: = 1 to n
for each (i,j) in {1,..,n}2
path[i][j] = min ( path[i][j], path[i][k]+path[k][j] );
我必须编写关于同一问题的算法课程的程序。这个算法就像一个魅力!古德勒克。
答案 1 :(得分:4)
有许多算法比计算所有可能的路径都要好。 Breadth-first search是我想到的算法族的基本起点,Best-first search是合适的,因为您定义了顶点成本,如果您可以获得有关您的问题空间的更多信息,您可能能够使用A*或Dijkstra's algorithm。 (在每种情况下,从允许的起始节点集中查找路径。)
重新编辑:您的路径约束(您需要满足的节点类型数组)不会阻止您使用这些算法;恰恰相反,它可以帮助他们更好地工作。您只需要以允许合并路径约束的方式实现它们,将搜索中每个步骤可用的顶点限制为在给定约束条件下有效的顶点。
答案 2 :(得分:4)
正如Jan所提到的,你只需要一个普通的无聊最短路径算法(如Dijkstra或Floyd's算法);但是,您需要转换输入图形,以便输出路径将遵循路径约束。
给出路径约束:A - B - A
创建一个新图G
,并将A
中的所有顶点插入到G
中,并使用新标签(如a_01)。然后将B
中的所有顶点插入G
并将A
顶点与B
顶点连接(边缘应指向新插入的节点)复制成本原始图。然后,使用A
(和任何其他路径组件)将新插入的顶点连接到B
中的顶点,重复此步骤。因此,您创建一个图形,其中只有存在的路径满足路径约束。然后,您可以使用常规的最短路径算法。
关键的见解是,当您重新访问一个类时,您实际上正在访问一组不同的节点,并且您只需要连接相邻节点类的边。
答案 3 :(得分:2)
在您的问题的修订版中,您似乎要求每个字母一个节点 - 在这种情况下,它是一个简单的动态编程解决方案:计算长度为1的所有最短路径,这些路径满足序列的开始,每对之间节点然后为所有节点对提供k所有这些路径,为k + 1构造是微不足道的。
答案 4 :(得分:2)
这是带有动态编程解决方案的伪代码:
n - length of desired path
m - number of vertices
types[n] // desired type of ith node
vertice_types[m]
d[n][m] // our DP tab initially filled with infinities
d[0][0..m] = 0
for length from 1 to n
for b from 0 to m
if types[length] == vertice_types[b]
for a from 0 to m
if types[length-1] == vertice_types[a]
d[length][b] = min(d[length][b], d[length-1][a] + cost(a,b))
您的最低成本路径是min(d [n] [0..m])
你可以将d表的大小减少到2行,但它会使解决方案混淆
答案 5 :(得分:1)
据我了解你的问题,你需要有向图中的最短路径。 http://en.wikipedia.org/wiki/Dijkstra%27s_algorithm应该给你一个想法。
问候,Jan
答案 6 :(得分:1)
希望这很清楚。
这种解决方案不是特别有效,但显然是多项式的。