目錄
1 問題描述
什么是哈密頓回路?
引用自百度百科:
哈密頓圖(哈密爾頓圖)(英語:Hamiltonian path,或Traceable path)是一個無向圖,由天文學家哈密頓提出,由指定的起點前往指定的終點,途中經過所有其他節點且只經過一次。在圖論中是指含有哈密頓回路的圖,閉合的哈密頓路徑稱作哈密頓回路(Hamiltonian cycle),含有圖中所有頂點的路徑稱作哈密頓路徑。
現在本文要解決的問題:給定一個圖,判斷這個圖是否包含哈密頓回路?如果包含,輸出其中一條哈密頓回路,如果不包含,則無任何輸出。
2 解決方案
本文尋找哈密頓回路,運用了深度優先搜索方法,即遞歸和回溯法思想。
下面代碼所用圖數據如下:
具體代碼如下:
package com.liuzhen.chapter12; public class HamiltonCircuit { /* * 參數adjMatrix:給定圖的鄰接矩陣,其中值為1表示兩個頂點可以相通,值為-1表示兩個頂點不能相通 */ public void getHamiltonCircuit(int[][] adjMatrix) { boolean[] used = new boolean[adjMatrix.length]; //用於標記圖中頂點是否被訪問 int[] path = new int[adjMatrix.length]; //記錄哈密頓回路路徑 for(int i = 0;i < adjMatrix.length;i++) { used[i] = false; //初始化,所有頂點均未被遍歷 path[i] = -1; //初始化,未選中起點及到達任何頂點 } used[0] = true; //表示從第1個頂點開始遍歷 path[0] = 0; //表示哈密頓回路起點為第0個頂點 dfs(adjMatrix, path, used, 1); //從第0個頂點開始進行深度優先遍歷,如果存在哈密頓回路,輸出一條回路,否則無輸出 } /* * 參數step:當前行走的步數,即已經遍歷頂點的個數 */ public boolean dfs(int[][] adjMatrix, int[] path, boolean[] used, int step) { if(step == adjMatrix.length) { //當已經遍歷完圖中所有頂點 if(adjMatrix[path[step - 1]][0] == 1) { //最后一步到達的頂點能夠回到起點 for(int i = 0;i < path.length;i++) System.out.print(((char)(path[i] + 'a'))+"——>"); System.out.print(((char)(path[0] + 'a'))); System.out.println(); return true; } return false; } else { for(int i = 0;i < adjMatrix.length;i++) { if(!used[i] && adjMatrix[path[step - 1]][i] == 1) { used[i] = true; path[step] = i; if(dfs(adjMatrix, path, used, step + 1)) return true; else { used[i] = false; //進行回溯處理 path[step] = -1; } } } } return false; } public static void main(String[] args) { HamiltonCircuit test = new HamiltonCircuit(); int[][] adjMatrix = {{-1,1,1,1,-1,-1}, {1,-1,1,-1,-1,1}, {1,1,-1,1,1,-1}, {1,-1,1,-1,1,-1}, {-1,-1,1,1,-1,1}, {-1,1,-1,-1,1,-1}}; test.getHamiltonCircuit(adjMatrix); } }
運行結果:
a——>b——>f——>e——>c——>d——>a
參考資料:
2.《算法設計與分析基礎》第3版 Anany Levitin 著 潘彥 譯