我知道這已被問過,但我沒有在任何帖子中找到答案。有人可以建議我一個枚舉圖中所有哈密頓路徑的算法嗎?枚舉*所有*哈密爾頓路徑
有點背景:我正在研究一個問題,我必須列舉每個哈密爾頓路徑,做一些分析並返回結果。爲此,我需要列舉所有可能的哈密爾頓路徑。
謝謝。
我知道這已被問過,但我沒有在任何帖子中找到答案。有人可以建議我一個枚舉圖中所有哈密頓路徑的算法嗎?枚舉*所有*哈密爾頓路徑
有點背景:我正在研究一個問題,我必須列舉每個哈密爾頓路徑,做一些分析並返回結果。爲此,我需要列舉所有可能的哈密爾頓路徑。
謝謝。
按照建議使用BFS/DFS,但不要停在第一個解決方案。 BFS/DFS的主要用途(在這種情況下)將是找到所有的解決方案,你需要給它一個條件停止在第一個。
謝謝。你能否詳細說明你的意思是「解決方案」。據我所知,在圖上運行DFS將簡單地給出訪問節點序列(例如,對於具有頂點A,B,C,D的圖的A→B→C→D)。但它永遠不會「探索」所有可能的路徑。你能否詳細說明一下? – 2011-04-23 23:56:31
DFS和BFS都會爲您提供從特定節點開始的所有可能路徑。從這些哈密爾頓路徑中,那些長度與圖形大小完全相同的節點,每個節點只存在一次。所以如果你有一個有5個節點的圖,並且有一個p1-> p2-> p3-> p4-> p5的路徑,它就是一個哈密爾頓路徑。另外請注意,您將不得不從每個節點開始搜索。 – SinistraD 2011-04-24 00:46:39
謝謝SinistraD,這非常有幫助! – 2011-04-24 20:52:31
我的Java代碼:(絕對基於遞歸方法)
算法:
+開始在1點連接到另一點它可以看到(以形成路徑)。
+刪除路徑並遞歸查找最新點的新路徑,直到連接圖的所有點。
+除去路徑和回溯到初始圖表如果斜面形成從最新點
public class HamiltonPath {
public static void main(String[] args){
HamiltonPath obj = new HamiltonPath();
int[][]x = {{0,1,0,1,0}, //Represent the graphs in the adjacent matrix forms
{1,0,0,0,1},
{0,0,0,1,0},
{1,0,1,0,1},
{0,1,0,1,0}};
int[][]y = {{0,1,0,0,0,1},
{1,0,1,0,0,1},
{0,1,0,1,1,0},
{0,0,1,0,0,0},
{0,0,1,0,0,1},
{1,1,0,0,1,0}};
int[][]z = {{0,1,1,0,0,1},
{1,0,1,0,0,0},
{1,1,0,1,0,1},
{0,0,1,0,1,0},
{0,0,0,1,0,1},
{1,0,1,0,1,0}};
obj.allHamiltonPath(y); //list all Hamiltonian paths of graph
//obj.HamiltonPath(z,1); //list all Hamiltonian paths start at point 1
}
static int len;
static int[]path;
static int count = 0;
public void allHamiltonPath(int[][]x){ //List all possible Hamilton path in the graph
len = x.length;
path = new int[len];
int i;
for(i = 0;i<len;i++){ //Go through column(of matrix)
path[0]=i+1;
findHamiltonpath(x,0,i,0);
}
}
public void HamiltonPath(int[][]x, int start){ //List all possible Hamilton path with fixed starting point
len = x.length;
path = new int[len];
int i;
for(i = start-1;i<start;i++){ //Go through row(with given column)
path[0]=i+1;
findHamiltonpath(x,0,i,0);
}
}
private void findHamiltonpath(int[][]M,int x,int y,int l){
int i;
for(i=x;i<len;i++){ //Go through row
if(M[i][y]!=0){ //2 point connect
if(detect(path,i+1))// if detect a point that already in the path => duplicate
continue;
l++; //Increase path length due to 1 new point is connected
path[l]=i+1; //correspond to the array that start at 0, graph that start at point 1
if(l==len-1){//Except initial point already count =>success connect all point
count++;
if (count ==1)
System.out.println("Hamilton path of graph: ");
display(path);
l--;
continue;
}
M[i][y]=M[y][i]=0; //remove the path that has been get and
findHamiltonpath(M,0,i,l); //recursively start to find new path at new end point
l--; // reduce path length due to the failure to find new path
M[i][y] = M[y][i]=1; //and tranform back to the inital form of adjacent matrix(graph)
}
}path[l+1]=0; //disconnect two point correspond the failure to find the..
} //possible hamilton path at new point(ignore newest point try another one)
public void display(int[]x){
System.out.print(count+" : ");
for(int i:x){
System.out.print(i+" ");
}
System.out.println();
}
private boolean detect(int[]x,int target){ //Detect duplicate point in Halmilton path
boolean t=false;
for(int i:x){
if(i==target){
t = true;
break;
}
}
return t;
}
}
深度優先窮舉搜索給你的答案漢密爾頓路徑。我剛剛完成了一個Java實現了這個問題(包括代碼)寫了起來:
http://puzzledraccoon.wordpress.com/2012/06/07/how-to-cool-a-data-center/
解決方案在Python3:
def hamiltonians(G, vis = []):
if not vis:
for n in G:
for p in hamiltonians(G, [n]):
yield p
else:
dests = set(G[vis[-1]]) - set(vis)
if not dests and len(vis) == len(G):
yield vis
for n in dests:
for p in hamiltonians(G, vis + [n]):
yield p
G = {'a' : 'bc', 'b' : 'ad', 'c' : 'b', 'd' : 'ac'}
print(list(hamiltonians(G)))
你嘗試普通的搜索? BFS/DFS?你的圖表有多大? – slezica 2011-04-23 18:47:23
聖地亞哥,謝謝你的回覆。我的圖很小(6-7節點)。我曾考慮過BFS和DFS,但我認爲BFS/DFS用於搜索特定的密鑰,而不是列舉所有可能的路徑。我如何讓BFS/DFS生成*所有*可能的週期.. – 2011-04-23 20:11:14
定期BFS/DFS找到匹配的第一個鍵後停止。你只需要改變它,讓它遍歷整個圖(如果可能的話),並將其記錄爲解決方案。 – slezica 2011-04-23 23:28:39