算法筆記_073:哈密頓回路問題(Java)


目錄

1 問題描述

2 解決方案

 


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

 

 

 

參考資料:

1.基於回溯法尋找哈密頓回路

2.《算法設計與分析基礎》第3版   Anany Levitin 著  潘彥 譯

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM