哈密尔顿回路(旅行售货员问题)
哈密尔顿回路(旅行售货员问题)
哈密顿图(哈密尔顿图)(英语:Hamiltonian path,或Traceable path)是一个无向图,由天文学家哈密顿提出,由指定的起点前往指定的终点,途中经过所有其他节点且只经过一次。在图论中是指含有哈密顿回路的图,闭合的哈密顿路径称作哈密顿回路(Hamiltonian cycle),含有图中所有顶点的路径称作哈密顿路径。
由来
天文学家哈密顿(William Rowan Hamilton) 提出,在一个有多个城市的地图网络中,寻找一条从给定的起点到给定的终点沿 途恰好经过所有其他城市一次的路径。
这个问题和著名的七桥问题的不同之处在于,过桥只需要确定起点,而不用确定终点。哈密顿问题寻找一条从给定的起点到给定的终点沿 途恰好经过所有其他城市一次的路径
算法
哈密顿路径问题在上世纪七十年代初,终于被证明是“NP完备”的。据说具有这样性质的问题,难于找到一个有效的算法。实际上对于某些顶点数不到100的网络,利用现有最好的算法和计算机也需要比较荒唐的时间(比如几百年)才能确定其是否存在一条这样的路径。
从图中的任意一点出发,路途中经过图中每一个结点当且仅当一次,则成为哈密顿回路。
要满足两个条件:
⒈封闭的环
⒉是一个连通图,且图中任意两点可达
经过图(有向图或无向图)中所有顶点一次且仅一次的通路称为哈密顿通路。
经过图中所有顶点一次且仅一次的回路称为哈密顿回路。
具有哈密顿回路的图称为哈密顿图,具有哈密顿通路但不具有哈密顿回路的图称为半哈密顿图。
问题
旅行售货员问题又称TSP问题,问题如下:某售货员要到若干个城市推销商品,已知各城市之间的路程(或旅费),他要选定一条从驻地出发,经过每个城市一遍最后回到驻地的路线,使总的路线(或总的旅费)最小。数学模型为给定一个无向图,求遍历每一个顶点一次且仅一次的一条回路,最后回到起点的最小花费。
输入要求:
输入的第一行为测试样例的个数T( T < 120 ),接下来有T个测试样例。每个测试样例的第一行是无向图的顶点数n、边数m( n < 12,m < 100 ),接下来m行,每行三个整数u、v和w,表示顶点u和v之间有一条权值为w的边相连。( 1 <= u < v <= n,w <= 1000 )。假设起点(驻地)为1号顶点。
输出要求:
对应每个测试样例输出一行,格式为"Case #: W",其中’#'表示第几个测试样例(从1开始计),W为TSP问题的最优解,如果找不到可行方案则输出-1。
样例输入:
2
5 8
1 2 5
1 4 7
1 5 9
2 3 10
2 4 3
2 5 6
3 4 8
4 5 4
3 1
1 2 10
样例输出:
Case 1: 36
Case 2: -1
代码
#include<iostream>
#define N 100
using namespace std;
int n,m,w, //图的顶点数和边数 graph[N][N], //图的加权邻接矩阵 c=0, //当前费用 bestc=-1, //当前最优值 x[N], //当前解 bestx[N]; //当前最优解
void backtrack(int k);
void swap(int &a,int &b);
void swap(int &a,int &b)
{ int temp=a; a=b; b=temp;
}
void backtrack(int k)
{ if(k==n) { if( (c+graph[x[n-1]][x[n]]+graph[x[n]][1]<bestc||bestc==-1) && graph[x[n-1]][x[n]]!=-1 && graph[x[n]][1]!=-1 ) { bestc=c+graph[x[n-1]][x[n]]+graph[x[n]][1]; for(int i=1;i<=n;i++) { bestx[i]=x[i]; } } return ; } else { for(int i=k;i<=n;i++) { if( graph[x[k-1]][x[i]]!=-1 && (c+graph[x[k-1]][x[i]]<bestc || bestc==-1)) { swap(x[i],x[k]); c+=graph[x[k-1]][x[k]]; backtrack(k+1); c-=graph[x[k-1]][x[k]]; swap(x[i],x[k]); } } }
}
int main(void)
{ int i,j,tmp=1,testNum; cin>>testNum; while(tmp<=testNum) { cin>>n>>m; for(i=1;i<=n;i++) for(j=1;j<=n;j++) graph[i][j]=-1; for(int k=1;k<=m;k++) { cin>>i>>j>>w; graph[i][j]=w; graph[j][i]=w; } for(i=1;i<=n;i++) { x[i]=i; bestx[i]=i; } backtrack(2); cout<<"Case "<<tmp<<": "<<bestc<<endl; bestc=-1; c=0; tmp++; } return 0;
}
哈密尔顿回路(旅行售货员问题)相关推荐
- 最短汉密尔顿回路算法c语言,【算法】浅谈最短哈密尔顿回路类问题的两种近似算法...
// 标题是糊弄人的 1. 问题引入 给出一张图,求其最短哈密尔顿回路,也就是 "旅行商问题"(Traveling Saleman Problem,TSP) 假设有一个旅行商人要拜 ...
- 欧拉回路和哈密尔顿回路
"哈密尔顿回路问题"与"欧拉回路问题"看上去十分相似,然而却是完全不同的两个问题."哈密尔顿回路问题"是访问除原出发结点以外的每个结点一次且 ...
- 哈密尔顿回路 - 杂录
哈密尔顿回路 1859年,爱尔兰数学家哈密尔顿(Hamilton) 提出了一个周游世界的游戏 在正十二面体上依次标记伦敦.巴黎.莫斯科等世界著名大城市, 正十二面体的棱表示连接这些城市的路线. 试问能 ...
- java哈密尔顿回路算法,用回溯方法求哈密尔顿回路——java求解
// 哈密尔顿回路问题 public class Hamilton { // 图中顶点个数为n,图的邻接矩阵为c[][],存放回路的顶点序号x[],在这里,n个顶点的标号是:0,1,2,...,n-1 ...
- 哈密尔顿道路与哈密尔顿回路
简介 1857年爱尔兰数学家哈密尔顿发明了"周游世界"玩具,用一个正十二面体的20个顶点表示世界上20个大城市,30条棱代表这些城市之间的道路.要求游戏者从任意一个城市(即顶点)出 ...
- “欧拉回路”与“哈密尔顿回路”
1.欧拉回路 17世纪的东普鲁士有一座哥尼斯堡(Konigsberg)城(现为俄国的加里宁格勒(Kaliningrad)城),城中有一座奈佛夫(Kneiphof)岛,普雷格尔(Pregol)河的两条支 ...
- 什么是哈密尔顿回路/路径?
一:哈密尔顿回路与哈密尔顿路径 1859 年,爱尔兰数学家哈密尔顿(Hamilton)提出了一个"周游世界"的游戏: 在一个正十二面体的二十个顶点上,标注了伦敦,巴黎,莫斯科等世界 ...
- 用mips汇编实现哈密尔顿回路
用mips汇编实现哈密尔顿回路. 哈密顿回路是一个非常经典的问题 题目难度不大,虽然是np的但是只需要你写一个非多项式的实现算法. 我们先回顾一下怎么用c++实现 #include <bits/ ...
- 蓝桥杯 哈密尔顿回路 Java
问题描述 给出一个有向图,输出这个图的一个哈密尔顿回路. 输入格式 输入的第一行包含两个整数n, m,分别表示图的点数和边数. 接下来m行,每行包含两个整数,表示一条边的起点和终点. 输出格式 输出一 ...
最新文章
- Services(服务)
- numpy 矩阵乘法_一起学习Python常用模块——numpy
- mysql进度查看_MySQL长查询进度监控
- What means the error-message 'java.lang.OutOfMemoryError: GC overhead limit exceeded' in Java?
- MySQL InnoDB的缓冲池之预读失效和缓存池污染
- Java基础知识盘点(二)- 集合篇
- C# 循环语句 for
- iOS项目中常见定时器
- Babylon-AST初探-代码生成(Create)
- android 结束if循环_简单探究Android平台下' if ' 语句条件判断耗时情况
- 【OpenCV】简单高效地访问图像像素
- CImagelist 基本用法
- linux 中more、less 和 most 的区别
- PS:高清晰度的源文件保存成图片如何使图片大小最小
- Word文档排版——自动编号
- 2018年小米校招笔试题
- 摄影测量与遥感专业英语词汇
- Ava 自动化测试----对函数的简单测试和对Http接口的测试
- 如何利用互联网了解你的客户
- [渝粤教育] 广东-国家-开放大学 21秋期末考试建设工程法规10221k2