实验九 TSP问题

news/2024/5/16 15:23:59/文章来源:https://blog.csdn.net/m0_57322261/article/details/129770606

《算法设计与分析》实验报告

       

所在院系

计算机与信息工程学院

学生学号

学生姓名

年级专业

2020级计算机科学与技术

授课教师

彭绪富

学         期

2022-2023学年第一学期

提交时间

2022年10月26日

  

实验九-1:TSP问题

一、实验目的与要求

二、实验环境

三、实验步骤与分析

四、实验小结

实验九-2 最大子段和

一、实验目的与要求

二、实验环境

三、实验步骤与分析

四、实验小结

实验九-1:TSP问题 

一、实验目的与要求 

TSP问题是指旅行家要旅行n个城市,要求各个城市经历且经历一次,然后回到出发城市,并要求所走的路程最短。

二、实验环境

Devc++

三、实验步骤与分析

假设从顶点s出发,令d(i, V’)表示从顶点i出发经过V’(是一个点的集合)中各个顶点一次且仅一次,最后回到出发点s的最短路径长度。

推导:(分情况来讨论)

  • 当V’为空集,那么d(i, V’),表示从i不经过任何点就回到s了,如上图的 城市3->城市0(0为起点城市)。此时d(i, V’)=Cis(就是 城市i 到 城市s 的距离)   

②如果V’不为空,那么就是对子问题的最优求解。你必须在V’这个城市集合中,尝试每一个,并求出最优解。d(i, V’)=min{Cik +  d(k, V’-{k})}注:Cik表示你选择的城市和城市i的距离,d(k, V’-{k})是一个子问题。

综上所述,TSP问题的动态规划方程就出来了:

图3-1

现在对问题定义中的例子来说明TSP的求解过程。(假设出发城市是 0城市)

图3-2

①我们要求的最终结果是d(0,{1,2,3}),它表示,从城市0开始,经过{1,2,3}之中的城市并且只有一次,求出最短路径.

②d(0,{1,2,3})是不能一下子求出来的,那么他的值是怎么得出的呢?看上图的第二层,第二层表明了d(0,{1,2,3})所需依赖的值。那么得出:

d(0,{1,2,3})=min  {

                                    C01+d(1,{2,3})

                                    C02+d{2,{1,3}}

                                    C03+d{3,{1,2}}

                     }

③d(1,{2,3}),d(2,{1,3}),d(3,{1,2})同样也不是一步就能求出来的,它们的解一样需要有依赖,就比如说d(1,{2,3})

       d(1,{2,3})=min{

                              C12+d(2,{3})                             

                              C13+d(3,{2})

                              }

       d(2,{1,3}),d(3,{1,2})同样需要这么求。

④按照上面的思路,只有最后一层的,当当V’为空集时,Cis的值才可以求,它的值是直接从图3-3里求出的。

图3-3

将d(i, V’)转换成二维表,d[i][j]如图3-4

3-4

伪代码及代码测试:

四、实验小结

算法需要对顶点集合{1, 2, .,.n-1)的每一个子集都进行操作,因此时复杂度为0(2^n)。和蛮力法相比,动态规划法求解TSP问题,把原来的时间复杂度是(n!)的排列问题转化为组合问题,从而降低了算法的时间复杂度,但仍需要指数时间。

实验九-2 最大子段和

一、实验目的与要求

给定由n个整数(可能有负整数)组成的序列(a1, a2, .. an),求该序列形如子段和的最大值

分别用蛮力法、分治法和动态规划法设计最大子段和问题的算法,并设测试数据,比较不同算法的时间性能。

二、实验环境

DEVC++

三、实验步骤与分析

源代码:

#include<iostream>
#include<ctime>
using namespace std;
const int length = 1000;//用于求三个数中最大值的辅助函数,由于内容少,定义为内联函数以提高效率
inline int max(const int& x1, const int& x2, const int& x3)
{if (x1 >= x2 && x1 >= x3){return x1;}else if (x2 >= x1 && x2 >= x3){return x2;}else return x3;
}//蛮力法求解,即求出数组的所有子段并分别计算子段和,从子段和中选择最大值
int BruteForce(const int* a, const int& n)
{int max = 0;for (int length = 1; length <= n; length++)//对于每一种可能长度都需要求出子段和{for (int i = 0; i <= n - length; i++)//对于子段长度相同的不同子段也需要分别求出子段和{int sum = 0;for (int j = i; j < i + length; j++){sum += a[j];}if (sum > max)//每求出一个子段和就与当前最大子段和进行比较,如果新求出的子段和更大则更新当前最大子段和{max = sum;}}}return max;//返回求出的所有子段和中的最大值
}//分治法求解,对于任意一个数组,其子段和无非可以分为三种情况:最大和对应子段在数组的左半段、最大和对应的子段在数组的右半段、最大和对应的子段跨越了数组的中点
int DivideConquer(const int* a, const int& left, const int& right)//区间的形式采用左闭右开
{//首先处理递归基,也就是数组中只包含一个元素的情况,这时根据最大子段和的定义,如果该元素是正数则结果为其自身,否则结果为0if (right - left <= 1){if (a[left] > 0){return a[left];}else return 0;}int middle = (left + right) >> 1;//首先找到数组的中点,方便后续处理int leftMax = 0, rightMax = 0;int leftSum = 0, rightSum = 0;//分别以数组的中点为基准,分别找出其向左和向右方向的最大子段长度for (int i = middle - 1; i >= left; i--){leftSum += a[i];if (leftSum >= leftMax)leftMax = leftSum;}for (int i = middle; i < right; i++){rightSum += a[i];if (rightSum >= rightMax)rightMax = rightSum;}//从三种情况中选择最大的一种,三种情况分别是最大和子段在数组左半段,最大和子段在数组右半段,最大和数组跨越了数组中点(此处使用了辅助函数max用于求出三个数中的最大值)return max(DivideConquer(a, left, middle), DivideConquer(a, middle, right), leftMax + rightMax);
}//动态规划法求解,使用一个数组temp,temp[i]可以理解为到第i号元素为止最大子段和的长度
int DynamicProgram(int* a,const int& n)
{int* temp = new int[n];temp[0] = a[0] > 0 ? a[0] : 0;for (int i = 1; i < n; i++){temp[i] = temp[i - 1] > 0 ? (temp[i - 1] + a[i]) : a[i];}int max = 0;for (int i = 0; i < n; i++){if (temp[i] > max)max = temp[i];}return max;
}int main(void)
{//首先创建一个指定长度的整数数组int* array = new int[length];int result;clock_t start, end;double TimeGap;srand(1);//固定随机数种子,方便后续多次调试for (int i = 0; i < length; i++){array[i] = rand() % 21 - 10;//采用随机数的方法给数组元素赋值(正数与负数出现的概率均等)}//首先采用蛮力法求解该问题并计算运行时间start = clock();result = BruteForce(array, length);end = clock();TimeGap = double((end - start) / CLK_TCK);cout << "蛮力算法的运行结果为:" << result << ",求解时间为:" << TimeGap << "ms" << endl;//接着采用分治法求解该问题并计算运行时间start = clock();result = DivideConquer(array, 0, length);end = clock();TimeGap = double((end - start) / CLK_TCK);cout << "分治算法的运行结果为:" << result << ",求解时间为:" << TimeGap << "ms" << endl;//最后采用动态规划求解该问题并计算运行时间start = clock();result = DynamicProgram(array, length);end = clock();TimeGap = double((end - start) / CLK_TCK);cout << "动态规划算法的运行结果为:" << result << ",求解时间为:" << TimeGap << "ms" << endl;delete[]array;return 0;
}

  1. 数组长度为1000时:
  2. 数组长度为5000时:

  1. 数组长度为20000000(两千万)时:

四、实验小结

综上所属,时间性能比较:动态规划算法>分治算法>蛮力算法

原因分析:动态规划算法的时间复杂度为O(n),分治算法的时间复杂度为O(nlogn),而蛮力算法的时间复杂度为O(2n),因此随着问题规模的增加,最终的运行时间总会呈现:动态规划时间最短,分治算法的时间次之,蛮力算法的时间最长。

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

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

相关文章

【图解http】

目录了解web及网络基础TCP/IP协议族与HTTP关系密切的协议&#xff1a;IP、TCP和DNS各种协议与HTTP协议的关系URI和URLhttp协议HTTP是不保存状态的协议请求URI定位资源告知服务器意图的HTTP方法持久连接节省通信量HTTP报文编码提升传输速率压缩传输的内容编码分割发送的分块传输…

关于参加新星计划的收获

目录 作者简介 前言 一、新星计划介绍 二、新星计划创作目标 &#xff08;一&#xff09;创作打卡阶段第1周&#xff08;3/13-3/19&#xff09; &#xff08;二&#xff09;创作打卡阶段第2周&#xff08;3/20-3/26&#xff09; 三、参赛文章的构思与创作 &#xff08…

Go map 内存泄露

前言 在Go中, map这个结构使用的频率还是比较高的. 其实在所有的语言中, map使用的频率都是很高的. 之前在使用中, 一直都知道map的内存在元素删除的时候不会回收, 但一直没有仔细的研究为什么. 今天就来好好揣摩揣摩. func main() {m : make(map[int][128]byte)for i : 0; …

2023热门抖音权重查询小程序源码

2023热门抖音权重查询小程序源码 跟抖音上很火的一模一样&#xff0c;小程序适配优化。接口免费。小程序不是网页 修改教程: 1&#xff0c;如果想修改或者去除水印&#xff0c;直接删除或修改“index.html”12&#xff5e;22行 2&#xff0c;如果想修改logo&#xff0c;直接…

“全球首款旗舰”填补行业空白,两轮电动车技术创新为何只看绿源?

作者 | 曾响铃 文 | 响铃说 乒乓作为我们的“国球”&#xff0c;在数不清的体育赛事里书写辉煌战绩&#xff0c;也进一步被国人熟知、热爱。更难能可贵的是“国球”精神&#xff1a;“别人可能练了一千次&#xff0c;而我们却练了一万次”&#xff0c;冠军品质&#xff0c;奋…

MYSQL【基础篇】MYSQL 主要函数

MySQL中的函数主要分为以下四类&#xff1a; 字符串函数、数值函数、日期函数、流程函数 ​MySQL函数是MySQL数据库提供的内部函数。这些内部函数可以帮助用户更加方便的处理表中的数据 MySQL函数可以对表中数据进行相应的处理&#xff0c;以便得到用户希望得到的数据。这些函…

JAVA Session会话 Thymeleaf - 视图模板技术配置步骤

JAVAWebSession会话会话跟踪技术session保存作用域Thymeleaf - 视图模板技术配置过程Session会话 HTTP是无状态的&#xff1a;服务器无法区分这两个请求是同一个客户端发过来的&#xff0c;还是不同的客户端发过来的 现实问题&#xff1a;第一次请求是添加商品到购物车&#x…

C++中的string类【详细分析及模拟实现】

string类 目录string类一、stirng的介绍及使用1.为什么学习string类&#xff1f;2.标准库中的string类2.1 引入&#xff1a;编码2.2 basic_string3.string类的使用3.1 构造函数3.2 遍历string方式1&#xff1a;for循环方式2&#xff1a;范围for4.迭代器4.1 正向迭代器4.2反向迭…

Golang流媒体实战之二:回源

欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码)&#xff1a;https://github.com/zq2599/blog_demos 本篇概览 今天的实战是流传输过程中的常见功能&#xff1a;回源如下图&#xff0c;lal(源站)和lal(拉流节点)代表两台电脑&#xff0c;上面都部署了lalVLC在…

【蓝桥杯】巧克力

问题描述&#xff1a; 题解分析&#xff1a; 错误思想&#xff1a;本来的想法是先使用低价格的巧克力&#xff0c;并且判断需要吃几块【其中内容比较细】&#xff0c;直接计算即可&#xff0c;但是本题好像不可以用简单的最小价格的贪心来做 正确思路&#xff1a;创建一个结…

【内网安全】 横向移动IPCATSC命令Impacket套件CS插件全自动

文章目录域信息收集-目标&用户&凭据&网络域横向移动-IPC-命令版-AT&schtasks上线配置at < Windows2012 (该版本之前的操作系统使用at命令)补充反向连接上线效果图schtasks >Windows2012(适用于windows2012后的操作系统版本)建立IPC常见的错误代码域横向移…

【MySQL】JDBC---数据库编程

目录JDBC介绍准备工作操作数据库本文介绍 java 如何使用 jdbc 连接数据库以及连接数据库后的基本操作。JDBC介绍 首先来了解 JDBC(Java Database Connectivity)&#xff0c;java数据库连接。是 Java 提供一套用于操作数据库的接口 API&#xff0c;是 Java 中的数据库连接规范&…

Chapter8.2:PID控制器设计及MATLAB_SIMULINK应用

该系列博客主要讲述Matlab软件在自动控制方面的应用&#xff0c;如无自动控制理论基础&#xff0c;请先学习自动控制系列博文&#xff0c;该系列博客不再详细讲解自动控制理论知识。 自动控制理论基础相关链接&#xff1a;https://blog.csdn.net/qq_39032096/category_10287468…

Flink-FinkSQL进阶操作(系统函数,UDF,表聚合函数等,输入kafka,elasticsearch等外部系统)

11.7 函数 11.7.1 系统函数 标量函数 只有数值大小&#xff0c;没有方向的量&#xff0c;行变行 比较函数 逻辑函数 算数函数 字符串函数 时间函数 聚合函数 多行变一行 count(),sum(),rank(),row_number() 11.7.2 自定义函数(UDF) 分类 标量函数&#xff0c;聚合函…

【数据结构】二叉树及相关习题详解

新年新气象! 祝大家兔年 财源滚滚! 万事胜意! 文章目录前言1. 树的一些基础概念1.1 树的一些基本概念1.2 树的一些重要概念2. 二叉树的一些基本概念2.1 二叉树的结构2.2 两种特殊的二叉树3. 二叉树的性质4. 二叉树的存储5. 二叉树的基本操作5.1 构造一棵二叉树5.2 二叉树的遍历…

华为OD机试题【剩余可用字符集】用 Java 解 | 含解题说明

华为Od必看系列 华为OD机试 全流程解析+经验分享,题型分享,防作弊指南华为od机试,独家整理 已参加机试人员的实战技巧华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典本篇题目:剩余可用字符集 题目 给定两个…

杨辉三角形 (蓝桥杯) JAVA

目录题目描述&#xff1a;暴力破解&#xff08;四成&#xff09;&#xff1a;二分法破解&#xff08;满分&#xff09;&#xff1a;题目描述&#xff1a; 下面的图形是著名的杨辉三角形&#xff1a; 如果我们按从上到下、从左到右的顺序把所有数排成一列&#xff0c;可以得到如…

SpringMVC 源码解析 - 请求执行的过程

一、SpringMVC 请求执行的过程 SpringMVC 是一个基于 Spring 框架的 MVC 框架&#xff0c;它简化了 Web 应用程序的开发。采用了前端控制器模式&#xff0c;请求会首先被一个中央控制器 DispatcherServlet 处理&#xff0c;再由其分发到具体的 Controller 进行处理。其中 Spri…

【Spring Cloud Alibaba】6.添加熔断机制(Sentinel)

文章目录简介什么是 Sentinel开始搭建引入依赖和启用Sentinel创建熔断器类并实现对应的 Feign 接口Service指定熔断器实现类# 启动项目测试未启动服务提供者启动服务提供者简介 接下来为我们的服务消费者提供熔断机制&#xff0c;通过Sentinel来实现熔断&#xff0c;本操作先要…

CTFHUB-web-SSRF

内网访问 flag&#xff1a; ctfhub{efd010883e087c1346bbc0ba} 伪协议读取文件 file:// — 访问本地文件系统 http:// — 访问 HTTP(s) 网址 ftp:// — 访问 FTP(s) URLs php:// — 访问各个输入/输出流&#xff08;I/O streams&#xff09; zlib:// — 压缩流 data:// — 数据…