哈密顿圈问题相关
1.文章缘由
毕业论文与这个相关,于是搜索了一些资料,看到有位前辈做过研究,感觉挺有意思。
2.哈密顿圈问题简介
参考自百度百科:哈密顿圈问题(Hamilton circuit problem)是图论中著名的难题之一。巡回售货员问题有一个基于图的天然类似问题,它是图论中的一个基本问题,给定一个有向图G(V,E),如果G中的圈C恰好经过每一个顶点一次,则称圈C是一个哈密顿圈。换句话说,它构成一条经过所有顶点的、没有重复的“路线”。哈密顿圈问题如下:给定一个有向图G,问它有一条哈密顿圈吗?
3.研究的问题图

4.解决问题代码
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);
}
}
5.运行结果

6.总结如上过程
前辈代码段的注释很详细,这里就不给与解释,用到的方法总结来说就是:以邻接矩阵为基础,采用深度优先遍历来进行对哈密顿圈问题的处理,在进行到仅有一个连接点时,采用回溯算法,回到上一个结点继续进行(这也是深度优先遍历的内涵)