贪心算法求解TSP问题的C语言实现
创作时间:
作者:
@小白创作中心
贪心算法求解TSP问题的C语言实现
引用
CSDN
1.
https://blog.csdn.net/mahoon411/article/details/105940729
旅行商问题(TSP)是一个经典的组合优化问题,在物流、网络路由等领域有广泛的应用。本文将介绍如何使用贪心算法来求解TSP问题,并通过C语言实现具体的算法。
1 TSP问题简介
旅行商问题,即TSP问题(Traveling Salesman Problem)又译为旅行推销员问题、货郎担问题,是数学领域中著名问题之一。假设有一个旅行商人要拜访n个城市,他必须选择所要走的路径,路径的限制是每个城市只能拜访一次,而且最后要回到原来出发的城市。路径的选择目标是要求得的路径路程为所有路径之中的最小值。
TSP的数学模型为:
2 贪心算法简介
贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的是在某种意义上的局部最优解。
贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的选择,选择的贪心策略必须具备无后效性,即某个状态以前的过程不会影响以后的状态,只与当前状态有关。
3 贪心算法应用于TSP问题
贪心算法是一种算法策略,或者说问题求解的策略。基本思想是“今朝有酒今朝醉”。即一定要做当前情况下的最好选择,否则将来可能后悔,故名“贪心”。
将贪心算法应用于TSP问题中的求解思想:从某一个城市开始,每次选择一个城市,知道所有城市都被走完。注:每次在选择下一个城市的时候,只考虑当前情况,保证迄今为止经过的路径的总距离最短。
4 C程序流程图(参考战德臣老师)
5 C程序代码实现贪心算法求解TSP问题
#include <stdio.h>
#define n 4
int main(void) {
int Dis[n][n], City[n], Sum, i, j, k, l, Dtmp, Found;
City[0] = 0;
Sum = 0;
Dis[0][1] = 2; Dis[0][2] = 1; Dis[0][3] = 5; Dis[1][0] = 2; Dis[1][2] = 4;
Dis[1][3] = 4; Dis[2][0] = 1; Dis[2][1] = 4; Dis[2][3] = 6; Dis[3][0] = 5;
Dis[3][1] = 4; Dis[3][2] = 6;
for (i = 1; i < n; i++) {
Dtmp = 10000;
for (k = 1; k < n; k++) {
Found = 0;
for (l = 0; l < i; l++) {
if (City[l] == k) {
Found = 1;
break;
}
}
if (Found == 0 && Dis[City[i - 1]][k] < Dtmp) {
j = k;
Dtmp = Dis[City[i - 1]][k];
}
}
City[i] = j;
Sum = Sum + Dtmp;
}
Sum = Sum + Dis[j][0];
for (i = 0; i < n; i++) {
printf("%d\t", City[i]);
}
printf("\n");
printf("Sum = %d", Sum);
getchar();
}
5.1 变量说明:
- 城市映射为编号:A-0, B-1, C-2, D-3。
- 数组Dis[n][n]用于存储城市之间的距离关系。
- 数组City[n]用来存储实现距离最短的依次访问的城市代号顺序。
- Sum用来存储最终的最短距离。
- Dtmp用于存储临时的一个最短距离。
- Found用来判定第k个城市是否是已经访问过的城市。
- i表示第i次将要访问的城市。City[i]即第i次要访问的城市的代号。
- j用来存储已确定的第i次要访问的城市代号j。
- k用来存储第i次可能要访问的城市的代号。
- l表示前几次已经访问过的城市。City[l]即第l次访问过的城市的代号。
5.2 程序流程说明
- 声明变量
- 设定起点城市,即第0次访问的城市代号为0。
- 初始化Sum的值为0。
- 导入城市距离矩阵。
- 进入循环:
- 外层循环:从i=1开始循环,i小于n, 初始化最短距离为10000(取一个大值,使其至少大于城市距离矩阵中的最大值)。即首先求出第1次将要访问的城市代号(利用中层循环及内层循环求解),然后将求出的第1次将要访问的城市代号j赋值给City[1],并将当前城市(代号0)至代号为j的城市的距离Dtmp累加至Sum。直至求出第n-1次要访问的城市代号。
- 中层循环:从k=1开始循环,k小于n,初始化Found的值为0。即先假设第i次要访问的城市代号为1,并判断代号为1的城市有没有出现在前几次访问过的城市中(利用内层循环判断),如果代号为1的城市没有出现在已经访问过的城市中并且当前城市(代号i-1)至代号为1的城市的距离小于Dtmp,那就把k=1的值赋值给j,再把当前城市(代号i-1)至代号为1的城市的距离赋值给Dtmp。直至循环到代号为n-1的城市,这样就能根据局部最短距离求出下一个城市的代号i与距离Dtmp。
- 内层循环:从l=0开始循环,l小于i,判断第l次访问过的城市代号是否与k的值相等,如果相等,代表第l次已经访问过代号为k的城市了,那么就将Found值置1,跳出循环。直至判断完第i-1次访问过的城市。
- 循环结束。
- 将第n-1次要访问的代号为j的城市到起点城市的距离累加至Sum。
- 输出访问城市的代号次序。
- 输出最短距离。
热门推荐
肺癌的各種治療方式
两次世界大战为什么都是德国发动的?
理解BMI体重指数:计算方法、分类及健康管理的重要性
治疗打喷嚏流鼻涕的西药
如何在萤石云视频APP转移设备
新中国机器人史上的"哈工大时刻",这些成就载入史册
抽烟为什么会头晕?这些原因你可能不知道
从盖棺定论到歌功颂德:中国古代谥议制度的发展史
3-12岁托管行业调查报告及市场分析
如何查询学区房名额?这些途径有哪些限制和注意事项?
百家姓之5——周姓,起源·迁徙·家训·名人故事
新手设计师如何建立自己的作品集
牙膏成分疑云:碳酸钙、三氯生、二氧化钛真的有害吗?
张雪峰谈北京师范大学强基计划:招生专业、就业前景、分数线
预防压疮,告别烦恼!
什么是服务期
次口径弹药:从“穿甲钻头”到“闪击利器”
相刑的意思是什么 八字相刑的影响与判断
CMD|揭开阻塞性睡眠呼吸暂停、肥胖与代谢综合征的相互关系及治疗进展
腿跑步拉伤了怎么办
《王者荣耀》赛季结束机制解析:时间、奖励与玩家体验的全方位探讨
颈椎病导致的臂丛神经疼痛怎么办?三种治疗方式全解析
2024年中国集成电路产业链上中下游市场分析(附产业链图谱)
在上海找专家看病的误区,你中了几条?(不同医院特色不同,该如何选择)
两千年数学经典《几何原本》:23个定义奠定几何根基,你了解多少
睡前吃东西的危害都有哪些
i5十代最高支持多少内存,内存频率看主板还是cpu
长春净月高新区国家城乡融合发展试验区:科技+文旅+智能 为新型农业发展之路赋能
路由器屏蔽网站方法详解:从网址过滤到防火墙规则
Docker Namespace & Cgroups