基于回溯法寻找哈密顿回路

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

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

 

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

 

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

#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;
}
 

 

    原文作者:分支限界法
    原文地址: https://blog.csdn.net/u011579908/article/details/68943534
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞