java 汉米尔顿回路_哈密顿回路分支限界遍历法

package com.jiang.hamilton2;

public class Calculate {

// public LinkedList elem = new LinkedList();//

// 存放结点(结点均为int型从0开始)

public int[] elem;

// 经测试,当节点数小于19时,数组的效率要快于链表

public int depth = Matrix.data.length;// 数组(放图的邻接矩阵)的长度即将要遍历的总深度

public int currentDepth = 0;// 放当前正在遍历的深度(层次)

public int count = 0;// 记录总共计算过的 从根到叶子的 所有路径数

// public LinkedList best = null;// 存放当前最优路径

public int[] best;

public int leastLength = 0x7fffffff;// 存放当前最优路径(回路)的长度 缺省为一个最大的int型

private int currentLength = 0;// 用于存放从根节点到当前结点的长度,用于同leastLength比较以实现分支限界法

/**

* 构造函数 根据节点个数,建立一条链表,按照用自然数标记每个节点的序号,依次增1 在把所有节点放入链表后,最终要添加一个 0

* 节点,此处假设哈密顿回路从 0开始,这样便于计算最后一个节点到出发节点的长度

*/

public Calculate() {

elem = new int[Matrix.data.length + 1];

best = new int[Matrix.data.length + 1];

for (int i = 0; i < Matrix.data.length; i++) {

elem[i] = i;

}

elem[elem.length - 1] = 0;

replace();

}

/**

* 核心递归方法 没有形参,但是通过各个实例变量 控制递归的层次以及判断结束的条件

*

* 主要思路: 成员变量thisLength暂存父节点到自身节点的距离,加到currentLength上, 如果currentLength已经

* 大于最优路径长度,返回; 如果小于则判断是否是最深层,即是否将所有点都遍历了一遍,如果是,则把最后一个

* 节点到出发节点的长度finalLength加到currentLength,之后判断currentLength和 leastLength的关系.

* 如果不属于以上两种情况,那就是普通的节点,记录好各个变量,进行循环

*/

public void show() {

currentDepth++;// 进入方法,首先标记层次加1

int thisLength = 0;

if (currentLength >= leastLength) {// 分支限界,如果当前

} else if (currentDepth == depth) {// 如果已经遍历过所有节点,并且当前路径还没有超过最优,则进行最后的计算

count++;

int finalLength = lengthOf(elem, currentDepth - 1, currentDepth);

currentLength += finalLength;

if (currentLength < leastLength) {// 替换掉当前最优路径

leastLength = currentLength;

replace();

//displayArray(elem);

//System.out.print('\t' + currentLength + "\n");

}

currentLength -= finalLength;

}

for (int i = currentDepth; i < depth; i++) {

// elem.add(depth - 1, elem.remove(currentDepth));

curl(elem, currentDepth);

thisLength = lengthOf(elem, currentDepth - 1, currentDepth);

currentLength += thisLength;// 同currentDepth的+-

show();

currentLength -= thisLength;

}

currentDepth--;// 退出方法,要标记层次减1

}

/**

* 计算链表中 第offset到第end之间,节点的距离

*

* @param ll

* 要计算的链表对象

* @param offset

* 进行计算的起始位置

* @param end

* 进行计算的结束位置

* @return 查Matrix.data 返回结果

*/

public int lengthOf(int[] array, int offset, int end) {

int length = 0;

for (int i = offset; i < end; i++) {

length += Matrix.data[array[i]][array[i + 1]];

}

return length;

}

public void replace() {

for (int i = 0; i < elem.length; i++) {

best[i] = elem[i];

}

}

void curl(int[] array, int index) {

int a = array[index];

for (int i = index + 1; i < array.length - 1; i++) {

array[i - 1] = array[i];

}

array[array.length - 2] = a;

}

void displayArray(int[] array) {

System.out.print('[');

for (int i = 0; i < array.length; i++) {

System.out.print(array[i] + ((i == array.length - 1) ? "" : ","));

}

System.out.print(']');

}

}// /:~

另外,为了方便测试,并使测试更贴近实际节点间的距离,采用如下方式生成节点

package com.jiang.hamilton2;

import java.util.Random;

import javax.swing.JOptionPane;

public class Matrix {

private static Random random = new Random();

public static int data[][] = { { 0x7fffffff, 15, 30, 20, 25, 60 },

{ 15, 0x7fffffff, 10, 35, 45, 60 },

{ 30, 10, 0x7fffffff, 40, 55, 60 },

{ 20, 35, 40, 0x7fffffff, 50, 60 },

{ 25, 45, 55, 50, 0x7fffffff, 60 },

{ 60, 60, 60, 60, 60, 0x7fffffff } };

static class Point {

public int x;

public int y;

Point() {

x = (random.nextInt(19) + 1) * 5;

y = (random.nextInt(19) + 1) * 5;

}

}

private static int distanceBetween(Point a, Point b) {

return (int) Math.sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y)

* (a.y - b.y));

}

public static void generate(int size) {

data = new int[size][size];

Point points[] = new Point[size];

for (int i = 0; i < size; i++) {

points[i] = new Point();

}

for (int i = 0; i < size; i++) {

for (int j = 0; j < size; j++) {

if (j == i) {

data[i][j] = 0x7fffffff;

} else if (j > i) {

data[i][j] = distanceBetween(points[i], points[j]);

} else if (j < i) {

data[i][j] = data[j][i];

}

}

}

//for (int i = 0; i < size; i++) {

//for (int j = 0; j < size; j++) {

//

//System.out.print(data[i][j] == 0x7fffffff ? "MAX\t" : data[i][j]

//+ "\t");

//}

//System.out.println();

//}

}

public static void generate() {

int size = Integer.parseInt(JOptionPane.showInputDialog("输入数组大小"));

generate(size);

}

}// /:~

经测试,采用linkedlist,

节点数:时间(s)

5:0.015

6:0.016

7:0.015

8:0.047

9:0.031

10:0.156

11:1.453

12:15

13:185

14:2446

而采用数组

节点数:时间(s)

12:4.6

13:54.6

14:739

15:9895

总结:

java中数组要比c++复杂,会判断下标越界异常,如果换成C++来实现,可能性能会更好一些.

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【优质项目推荐】 1、项目代码均经过严格本地测试,运行OK,确保功能稳定后才上传平台。可放心下载并立即投入使用,若遇到任何使用问题,随时欢迎私信反馈与沟通,博主会第一时间回复。 2、项目适用于计算机相关专业(如计科、信息安全、数据科学、人工智能、通信、物联网、自动化、电子信息等)的在校学生、专业教师,或企业员工,小白入门等都适用。 3、该项目不仅具有很高的学习借鉴价值,对于初学者来说,也是入门进阶的绝佳选择;当然也可以直接用于 毕设、课设、期末大作业或项目初期立项演示等。 3、开放创新:如果您有一定基础,且热爱探索钻研,可以在此代码基础上二次开发,进行修改、扩展,创造出属于自己的独特应用。 欢迎下载使用优质资源!欢迎借鉴使用,并欢迎学习交流,共同探索编程的无穷魅力! 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip
哈密回路算法(Hamiltonian cycle algorithm)是解决哈密回路问题的一种算法。该问题是指在给定的无向图中是否存在一条简单回路,经过每个顶点恰好一次。以下是一个简单的Java实现: ```java public class HamiltonianCycle { private int numOfVertexes; private int[] hamiltonianPath; private int[][] adjacencyMatrix; public HamiltonianCycle(int[][] adjacencyMatrix) { this.adjacencyMatrix = adjacencyMatrix; this.numOfVertexes = adjacencyMatrix.length; this.hamiltonianPath = new int[numOfVertexes]; this.hamiltonianPath[0] = 0; } public void solve() { if (findFeasibleSolution(1)) { printHamiltonianPath(); } else { System.out.println("No feasible solution found"); } } private boolean findFeasibleSolution(int position) { if (position == numOfVertexes) { if (adjacencyMatrix[hamiltonianPath[position - 1]][hamiltonianPath[0]] == 1) { return true; } else { return false; } } for (int vertexIndex = 1; vertexIndex < numOfVertexes; ++vertexIndex) { if (isFeasible(vertexIndex, position)) { hamiltonianPath[position] = vertexIndex; if (findFeasibleSolution(position + 1)) { return true; } //backtrack } } return false; } private boolean isFeasible(int vertexIndex, int actualPosition) { // first criterion: whether the two nodes are connected? if (adjacencyMatrix[hamiltonianPath[actualPosition - 1]][vertexIndex] == 0) { return false; } // second criterion: whether we have already added this given node? for (int i = 0; i < actualPosition; ++i) { if (hamiltonianPath[i] == vertexIndex) { return false; } } return true; } private void printHamiltonianPath() { System.out.print("Hamiltonian cycle: "); for (int i = 0; i < numOfVertexes; ++i) { System.out.print(hamiltonianPath[i] + " "); } System.out.println(hamiltonianPath[0]); } } ``` 这个实现中,我们使用邻接矩阵来表示图,并且在每一步中使用回溯算法来寻找哈密回路

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值