zoukankan      html  css  js  c++  java
  • 基于回溯法寻找哈密顿回路

    回溯法是一种选优搜索法,又称为试探法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。

    在包含问题的所有解的解空间树中,按照深度优先搜索的策略,从根结点出发深度探索解空间树。当探索到某一结点时,要先判断该结点是否包含问题的解,如果包含,就从该结点出发继续探索下去,如果该结点不包含问题的解,则逐层向其祖先结点回溯(其实回溯法就是对隐式图的深度优先搜索算法)。 若用回溯法求问题的所有解时,要回溯到根,且根结点的所有可行的子树都要已被搜索遍才结束。 而若使用回溯法求任一个解时,只要搜索到问题的一个解就可以结束。

    哈密顿图是一个无向图,由天文学家哈密顿提出,由指定的起点前往指定的终点,途中经过所有其他节点且只经过一次。在图论中是指含有哈密顿回路的图,闭合的哈密顿路径称作哈密顿回路,含有图中所有顶点的路径称作哈密顿路径。

    利用回溯法判断哈密顿回路是一种简单粗暴的试探,也因而容易理解,其方法如下代码,因注释详细,不再详述。

    #include <iostream>
    using namespace std;
    const int MAX_V = 50;
    void print(int path[], int V)
    {
        cout << "存在哈密顿回路" << endl;
        for (int i = 0; i < V; i++) cout << path[i] << " ";
        cout << path[0] << endl;
    }
    //path记录路径,visited记录顶点是否访问过,len记录当前路径的长度
    bool hamCycle(int graph[][MAX_V], int V, int path[], bool visited[], int current) {
        if (current == V) { //访问到最后一个顶点
            if (graph[path[current - 1]][0] == 1)  return true;//有到0点的边
            else return false;
        }
        //遍历起点外其它顶点
        for (int v = 1; v < V; v++) {
            //如果没访问过,并且有边相连
            if (!visited[v] && graph[path[current - 1]][v] == 1) {
                visited[v] = true;
                path[current] = v;
                //当本次递归的child也为true时返回true
                if (hamCycle(graph, V, path, visited, current + 1)) return true;
                //当本条递归线路失败时恢复原图
                path[current] = -1;
                visited[v] = false;
            }
        }
        return false;
    }
    //从起点开始引导
    bool hamCycleStart(int graph[][MAX_V], int V) {
        int path[MAX_V];
        memset(path, -1, sizeof(path));
        bool visited[MAX_V] = { 0 };
        path[0] = 0;
        visited[V] = true; //把起点标记为访问过
        //起点已确定,current从1开始
        if (hamCycle(graph, V, path, visited, 1) == false) {
            cout << "哈密顿回路不存在" << endl;
            return false;
        }
        print(path, V);
        return true;
    }
    int main() {
        int graph[MAX_V][MAX_V];
        int V;
        cout << "请输入点的个数:" << endl;
        cin >> V;
        for (int i = 0;i < V;++i)
        {
            cout << "请输入图的第" << i << "" << endl;
            for (int j = 0;j < V;++j)
            {
                cin >> graph[i][j];
            }
        }
        hamCycleStart(graph, V);
        return 0;
    }
     
  • 相关阅读:
    uniDAC 8.4.1一个严重的bug
    Delphi Event Bus进阶(三)如何使用通道?
    从delphi 10.3到delphi 10.4的改变实务
    uniDAC 8.4.1 database is locked
    调整Delphi IDE代码的行间距
    Deployment Manager now Open Source
    Delphi 10.4.2 Android 64位发布格式之App Bundle格式aab
    每日日报79
    每日日报78
    团队冲刺博客(四)
  • 原文地址:https://www.cnblogs.com/cielosun/p/5654577.html
Copyright © 2011-2022 走看看