我尝试创建一个路径,给定一个起始节点和终端节点,它将传递到图中的每个节点,并最大限度地降低这样做的成本。
图表是无向的,并且每个节点都直接相互连接。每条边的重量都是正的。我认为因为每个节点都相互连接,所以有很多"循环"在我的图表中,但我不想生成一个带有循环的路线。
因此,对于具有N个节点的图,我有(N * N-1)个有向边。具有节点A,B,C,D的图形将具有边缘:
当我从维基百科实施Floyd Warshall算法时,我只得到一个包含2个节点的数组。本文中的一个函数为您提供从节点U到节点V的最短路径,并且该函数仅返回[U,V](包含U和V的数组)
我必须误解Floyd Warshall究竟要解决的问题。我将附上我的代码,以显示我是如何在javascript中实现它的。
function colorsToEdgeMatrix(colors){
var dist = [];
for(var i = 0; i < colors.length;i++){
dist[i] = [];
var c1 = colors[i];
for(var j = 0; j < colors.length;j++){
if(i == j){continue;}
var c2 = colors[j];
dist[i][j] = colorDistance(c1,c2);
}
}
return dist;
}
function colorsToNextMatrix(colors){
var next = [];
for(var i = 0; i < colors.length;i++){
next[i] = [];
for(var j = 0; j < colors.length;j++){
if(i == j){continue;}
next[i][j] = j;
}
}
return next;
}
//lab colors
function FloydWarshallWithPathReconstruction (colors){
var next = [];
var dist = colorsToEdgeMatrix(colors);
var next = colorsToNextMatrix(colors);
var N = colors.length;
for(var k = 0; k < N; k++){ // standard Floyd-Warshall implementation
for(var i = 0; i < N; i++){
for(var j = 0; j < N; j++){
if(dist[i][k] + dist[k][j] < dist[i][j]){
dist[i][j] = dist[i][k] + dist[k][j]
next[i][j] = next[i][k]
}
}
}
}
return next;
}
function Path(next,u, v) {
var path = [];
if(next[u][v] == null){
return []
}
path = [u]
while(u != v){
u = next[u][v]
path.push(u)
}
return path;
}
var lab = randomLABArray(100); //make an array of LAB color space colors. a LAB element has an array structure [L,a,b]
lab = sortLuminosityLAB(lab); //sorts the LAB colors from light to dark
var next = FloydWarshallWithPathReconstruction(lab); //gets all paths using floyd warshall
var path = Path(next, 0, lab.length-1); //gets the path calculated from lightest to darkest
console.log( path );
此算法是否不一定会返回通过每个节点的路径?我猜它的作用是为每个开始和结束节点吐出最佳路径,并且不保证任何路径都通过每个节点...
我使用最近邻算法得到了不错的结果,并且在10个元素之后不可能使用Brute Force。我希望Floyd Warshall会给出更好的结果
嗯......所以这实际上可能是汉密尔顿路径问题,并不像我想的那么简单......答案 0 :(得分:0)
这可以简化为旅行商问题,如下所示。选择一个大数M
,它大于图表中所有权重的总和。将此数字添加到图形中所有边的权重,但连接起始节点和结束节点的边缘除外。该边缘的成本应设为零。解决由此产生的旅行商问题。很容易看出TSP的最佳解决方案将包括连接起始节点和结束节点的边缘。将该边缘从最佳解决方案中移开并将权重调整回其原始值 - 您已找到解决问题的最佳方案。
相反,常规TSP可以更简单的方式减少您的问题。随机选择一个节点并复制它。让其中一个新复制的节点成为起始节点,另一个节点作为终端节点。解决此实例的最佳路径问题。然后 - 将这两个节点重新合并到原始节点中,原始节点将两端拼接在一起形成一个电路,这很容易被看作是最佳的。这证实了你的直觉,即问题至少与汉密尔顿电路问题一样困难。