【旅行商问题的优化】

#include<bits/stdc++.h> // 包含标准库的头文件using namespace std; // 使用标准命名空间template <class Type> // 模板声明,Type为类型参数
class Traveling{ // 定义Traveling类friend Type Tsp(int **, int[],int, Type); // 声明友元函数Tsp
public:int predict(int j);void Backtrack(int i); // 声明Backtrack函数int n, *x, *bestx; // 声明成员变量n顶点数目, x存放当前解的结点编号, bestx存放最优解的结点编号Type **a, cc, bestc; // 声明成员变量a邻接矩阵, cc当前已经求得的费用, bestc最佳费用
};template <class Type> // 模板声明,Type为类型参数
Type Tsp(Type **a, int v[], int n); // 声明Tsp函数int min_edge = INT_MAX;int main() // 主函数入口
{clock_t start = clock();int **a,*v, n,bestc; // 声明指针变量和整型变量cin>>n; // 输入n的值v= new int[n+1]; // 动态分配数组v的内存空间a=new int* [n+1]; // 动态分配数组a的内存空间for(int i=0;i<=n;i++) // 循环,初始化数组a的每一行a[i]=new int [n+1]; // 动态分配数组a的每一行的内存空间for(int i=1;i<=n;i++) // 循环,输入每一行的数据for(int j=i+1;j<=n;j++){ // 循环,输入每一行的数据cin>>a[i][j]; // 输入数据到数组aa[j][i]=a[i][j]; // 将对称位置的数据设为相同的值if(i == 1 && a[i][j] < min_edge) min_edge = a[i][j]; }bestc=Tsp(a,v,n); // 调用Tsp函数计算最短路径长度cout << bestc << endl; // 输出最短路径长度clock_t end = clock();float duration = (float)(end - start) / CLOCKS_PER_SEC;cout << duration;return 0; // 返回0,表示程序正常结束
}template <class Type>
int Traveling <Type>::predict(int j)
{int sum = 0;int *sign = new int[n+1];memset(sign, 0, sizeof(sign));for(int i = 1; i <= j; i++) sign[x[i]] = 1;for(int i = j; i <= n; i++){int smallest = INT_MAX, small = INT_MAX;int vertex = x[i];for(int to = 1; to <= n; to++){if(sign[to] || to == vertex) continue;if(a[vertex][to] < smallest) {small = smallest; // 将原来的最小值赋给次小值smallest = a[vertex][to]; // 更新最小值}else if(a[vertex][to] < small) {small = a[vertex][to]; // 更新次小值}}if(small != INT_MAX) sum += small, sum += smallest;else if(smallest != INT_MAX) sum += smallest*2;}return sum/2 + min_edge;
}template <class Type> // 模板声明,Type为类型参数
void Traveling <Type>::Backtrack(int i) // 类Traveling成员函数Backtrack的实现
{cout << bestc;puts("");int temp; // 声明临时变量tempif(i==n){ // 如果i等于nif(a[x[n-1]][x[n]]!=0 && a[x[n]][x[1]]!=0 && // 如果路径形成一个环(cc+a[x[n-1]][x[n]]+a[x[n]][x[1]]<bestc || bestc ==0)){ // 并且路径长度小于最优长度或者最优长度为0for(int j=1;j<=n;j++) // 循环,复制当前路径到最优路径bestx[j]=x[j]; // 复制当前路径到最优路径bestc=cc+a[x[n-1]][x[n]]+a[x[n]][x[1]]; // 更新最优路径长度}}else{ // 否则for(int j=i;j<=n;j++) // 循环,尝试不同的下一个城市if(a[x[i-1]][x[j]]!=0 && // 如果下一个城市可达(cc+a[x[i-1]][x[j]]+predict(j)<bestc || bestc==0)){ // 并且路径长度小于最优长度或者最优长度为0temp=x[i]; // 交换城市顺序x[i]=x[j]; // 交换城市顺序x[j]=temp; // 交换城市顺序cc+=a[x[i-1]][x[i]]; // 更新路径长度Backtrack(i+1); // 递归调用Backtrack函数cc-=a[x[i-1]][x[i]]; // 恢复路径长度temp=x[i]; // 交换城市顺序x[i]=x[j]; // 交换城市顺序x[j]=temp; // 交换城市顺序}}
}template <class Type> // 模板声明,Type为类型参数
Type Tsp(Type **a, int v[], int n) // 函数Tsp的实现
{Traveling <Type> Y; // 声明Traveling类的实例YY.x=new int[n+1]; // 动态分配数组Y.x的内存空间for(int i=1;i<=n;i++) // 循环,初始化Y.x数组Y.x[i]=i; // 初始化Y.x数组Y.a=a; // 将参数a赋值给Y.aY.n=n; // 将参数n赋值给Y.nY.bestc=0; // 将Y.bestc初始化为0Y.bestx=v; // 将参数v赋值给Y.bestxY.cc=0; // 将Y.cc初始化为0Y.Backtrack(2); // 调用Backtrack函数计算最短路径delete [] Y.x; // 释放Y.x的内存空间return Y.bestc; // 返回最短路径长度
}

predict函数采用贪心策略,搜索剩余结点之间(可从x[j]开始,但不到x[j],因为判断中已经把x[i-1]到x[j]的长度考虑了,不属于未知部分,所以这是约束不是预测)的最短和次短邻接边,然后取平均再分别求和,作为对到剩余结点的预测。也就是说原本的代码不存在限界函数,只有约束函数,我们加入了限界函数,进一步完成了剪枝。(注意加上返回1的最短边)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/18660.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

WPF hc:PropertyGrid 嵌套显示

重点&#xff1a; 编写Edit特性即可&#xff1a; public class ParameterEditor : PropertyEditorBase{public override FrameworkElement CreateElement(PropertyItem propertyItem){var pg new PropertyGrid();return pg;}public override DependencyProperty GetDependen…

2024/5/22 ARMday7

按键控制LED灯亮和灭 do_irq.c #include "key_it.h" //#include "led.h" extern void printf(const char *fmt, ...); unsigned int i 0; void do_irq(void) {//获取中断号unsigned int irqno(GICC->IAR & (0x3FF));switch (irqno){case 99://处…

Playwright 元素定位

一、get_by_XXXXX 1. get_by_role&#xff1a;根据元素角色进行定位, 常用的参数有两个&#xff0c;第一个是角色名称 role&#xff0c;第二个是元素的文本 name。其他参数的解释大家可以参考源码注释。 # 获取页面名称为确定的按钮 page.get_bt_role(button, name确定) pl…

cfa三级大神复习经验分享系列(一)

教材还是Notes? 对于愚钝如我之流&#xff0c;建议大家三级一定要看教材。Note很精华很浓缩&#xff0c;我觉得看过教材再看note感觉总结的很精辟&#xff0c;但是Note是以考点列的&#xff0c;而教材像小说一样娓娓道来&#xff0c;有逻辑有情节&#xff0c;如果不follow很难…

Android MIPI屏配置

参考资料&#xff1a;RockChip发布的DRM Display Driver Development Guide手册&#xff0c;以及网上大量相关博客资料 首先要拿到《屏幕硬件规格书》和《DataSheet》&#xff0c;软件配置主要依靠DataSheet提供数据支持。 查阅DataSheet里面on sequence和off sequence说明&a…

机器学习之爬山算法(Hill Climbing Algorithm)

爬山算法(Hill Climbing Algorithm)是一种简单而常见的启发式搜索算法,通常用于解决优化问题。它的基本思想类似于登山过程中爬升到山顶的过程,即从一个起始点开始,不断尝试向邻近的点移动,直到找到一个局部最优解。 下面是爬山算法的基本工作流程: 初始化:选择一个初…

关于同一个地址用作两个不同页面时,列表操作栏按钮混淆状态

同一个地址用作两个不同页面时&#xff0c;列表页的操作栏中有好多个按钮&#xff0c;如果用了v-if&#xff0c;可能会导致按钮混淆状态如disabled等属性混乱 解决方法1&#xff1a; 将v-if换成v-show&#xff0c;用了v-show之后意味着所有按钮都在只是在页面上隐藏了 解决方…

【python深度学习】——torch.min()

【python深度学习】——torch.min 1. torch.min()1.1 计算整个张量的最小值1.2 沿特定维度计算最小值1.3 比较两个张量 1. torch.min() torch.min()接受的参数如下: input: 输入的张量。dim: 沿指定维度寻找最小值。如果指定了该参数&#xff0c;返回一个元组&#xff0c;其中…

基于Vue+SpirngBoot的博客管理平台的设计与实现(论文+源码)_kaic

摘 要 随着当下社会的发展&#xff0c;互联网已经成为时代的主流&#xff0c;从此进入了互联网时代&#xff0c;对大部分人来说&#xff0c;互联网在日常生活中的应用是越来越频繁&#xff0c;大家都在互联网当中互相交流、学习、娱乐。博客正是扮演这样一个角色。博客已成为当…

[Nodejs]使用adm-zip和fs-extra压缩打包后的文件

在此之前&#xff0c;操作目录、压缩文件是通过scripts来实现的&#xff0c;在windows机器上多有不便&#xff0c;需要通过linux命令行来实现cp、rm命令&#xff1a; "cpdist": "cp -r ./dist/* ../../qw-portal/assetAllocation/", "rmdist": …

实验八 单区域OSPF路由协议配置

一、实验目的 掌握 OSPF 动态路由协议的配置、诊断方法。 二、实验步骤 1、 运行Cisco Packet Tracer软件&#xff0c;在逻辑工作区放入三台路由器、两台工作站PC及一台笔记本&#xff0c;分别点击各路由器&#xff0c;打开其配置窗口&#xff0c;关闭电源&#xff0c;分别加…

如何选择云服务器

云服务器选择概述 在选择合适的云服务器时&#xff0c;需要综合考虑多个方面的因素&#xff0c;包括但不限于云服务器的类型、配置、价格、性能、安全性、可靠性、扩展性以及服务商的品牌信誉等。以下是根据搜索结果得出的详细分析和建议。 云服务器选择详解 云服务器类型选…

Python装饰器的应用

Python 中的装饰器是一种语法糖&#xff0c;可以在运行时&#xff0c;动态的给函数或类添加功能。装饰器本质上是一个函数&#xff0c;使用 函数名就是可实现绑定给函数的第二个功能 。它的作用就是在不修改被装饰对象源代码和调用方式的前提下为被装饰对象添加额外的功能。 …

策略模式代码

import java.util.*; enum TYPE { NORMAL,CASH_DISCOUNT,CASH_RETURN}; interface Cashsuper { public double acceptCash(double money); } class CashNormal implements CashSuper{// 正常收费子类 public double accptCash(double money){ return money; …

微信小程序如何在公共组件中改变某一个页面的属性值

需求 公共组件A改变页面B的属性isShow的值。 思路 首先目前我不了解可以直接在组件中改变页面的值的方法&#xff0c;所以我通过监听的方式在B页面监听app.js的某一属性值的改变从而改变B页面的值&#xff0c;众所周知app.js的某一属性值是很容易就能更改的。 app.js globa…

Ownips+Coze海外社媒数据分析实战指南

目录 一、引言二、ISP代理简介三、应用实践——基于Ownips和coze的社媒智能分析助手3.1、Twitter趋势数据采集3.1.1、Twitter趋势数据接口分析3.1.2、Ownips原生住宅ISP选取与配置3.1.3、数据采集 3.2、基于Ownips和Coze的社媒智能助手3.2.1、Ownips数据采集插件集成3.2.2、创建…

解锁未标记图像的力量:深入探索计算机视觉中无监督卷积神经网络

引言 近年来&#xff0c;计算机视觉领域取得了显著进步&#xff0c;这在很大程度上得益于深度学习&#xff0c;尤其是卷积神经网络&#xff08;CNN&#xff09;的发展。这些强大的模型在图像分类、目标检测和分割等任务上表现出色&#xff0c;主要依靠大规模标记数据集进行监督…

Flutter 中的 FadeTransition 小部件:全面指南

Flutter 中的 FadeTransition 小部件&#xff1a;全面指南 在 Flutter 中&#xff0c;动画是一种吸引用户注意力并提供流畅用户体验的强大工具。FadeTransition 是 Flutter 提供的一个动画小部件&#xff0c;它允许子组件在不透明度上进行渐变&#xff0c;从而实现淡入和淡出效…

git基础 -- 判断 Git 输入名称是分支名还是标签名

判断 Git 输入名称是分支名还是标签名 背景 在使用 Git 进行版本控制时&#xff0c;有时需要判断一个给定的名称是分支名还是标签名。分支和标签在 Git 中是两种不同的引用类型&#xff0c;但它们的名称空间是独立的&#xff0c;因此同一个名称可以同时存在于分支和标签中。为…

Linux备份脚本

作用 Linux文件备份的作用较多&#xff0c;推荐以下几种&#xff1a; 保护文件&#xff1a;备份可以帮助用户保护文件&#xff0c;防止文件被意外删除或损坏。保证系统安全和应用安全&#xff1a;Linux系统管理人员对系统和业务应用要有一个合理的备份恢复策略&#xff0c;完…