湘潭大学软件工程算法设计与分析实验-模拟退火算法
文章目录
- 写在前面
- 代码
- 分析
写在前面
总共是要四份代码,好像都是实现背包问题,前面三个都比较简单直观,朋友上周在机房给我讲解了一下之后,我大概弄清楚了,这周好像是最后一次算法课了,所以明天我得把剩下的那个实验代码讲一下。还要写之前小组作业的文档,还有这个实验的文档。
害其实文档不需要有太大压力吧。改一改就好了。
代码
//模拟退火
//
#include <bits/stdc++.h>
using namespace std;
void knapsackSa(int w[], int v[], int n, int M) { //n件物品,其重量和价值分别为w[i]和c[i],寻找将其装入容量为M的背包中物品的最大价值int i, j, dv, dw;int ans[n]; //定义解空间for (i = 0; i < n; i++) { //初始化解为0ans[i] = 0;}int val = 0, wei = 0; //初始化总价值和总重量float t0 = 500; //初始温度,控制参数t的初值float t = t0; //当前温度float a = 0.95f; //衰减因子float e = 0.00001f; //终止条件int L = 100 * n; //等温迭代次数,即每个温度都要迭代的次数,即生成新解的个数while (t > e) { //停止退火for (int k = 0; k < L; k++) {i = rand() % n; //随机选取第i件物品->生成新解if (ans[i] == 0) { //若i不在背包中 (则考虑将i放入背包)if (wei + w[i] <= M) { //且加入总重量后不超过容量M,则直接放入背包中ans[i] = 1;val = val + v[i];wei = wei + w[i];} else{ j = rand() % n; //随机拿出物品jwhile (ans[j] == 0) { //一直找,直到找到一个在背包的物体j = rand() % n; }dv = v[i] - v[j];dw = w[i] - w[j];if (wei + dw <= M) //(拿出j放入i后)总重量后不超过容量Mif (dv > 0 || (exp(dv / t) > (double)(rand() / (double)RAND_MAX))) { //价值差大于0或以exp(dv/T)的接受概率接受新解ans[i] = 1;ans[j] = 0;val = val + dv;wei = wei + dw;}}} else { //若i在包中,则考虑将i拿出j = rand() % n; //随机选一个不在包里的物品while (ans[j] == 1) {j = rand() % n;}dv = v[j] - v[i];dw = w[j] - w[i];if(wei + dw <= M)if (dv > 0 || (exp(dv / t) > (double)(rand() / (double)RAND_MAX))) { //价值差大于0或以exp(df/T)的接受概率接受新解ans[i] = 0;ans[j] = 1;val = val + dv;wei = wei + dw;}}}t = t * a; //降温}cout << "该0/1背包问题的最优解为: ";for (i = 0; i <= n - 1; i++) cout << ans[i] << " ";cout << endl << "最大总价值为:" << val << endl;
}
int main() {int n, M;//n件物品,其重量和价值分别为w[i]和c[i],寻找将其装入容量为M的背包中物品的最大价值cout << "请输入物品件数n和背包容量M:" << endl;cin >> n >> M;int w[n],v[n];cout << "请依次输入物品重量和价值:" << endl;for (int i = 0; i < n; i++) {cin >> w[i] >> v[i];}srand((unsigned)time(NULL)); //初始化随机函数种子(播种),srand((unsigned)time(NULL));是拿系统时间作为种子,由于时间是变化的,种子变化,可以产生不相同的随机数。knapsackSa(w, v, n, M);return 0;
}
分析
这只有几页介绍,应该大概理解一下就好了吧。模拟退火算法表示的是,最开始把系统加热,然后让其冷却,最后得到的就是一个比较稳定的状态。我还是不懂。
模拟退火算法视频
模拟退火算法博客教程
看完了上面两个教程,感觉大概懂了一些了。现在去看一下代码。感觉就是贪心,然后有一定的概率不贪心,设计了一个函数,这个函数的取值是一个概率函数,依照这个概率不贪心。
又加了一些注释,明天对着这个注释给助教讲了。还有就是自己就是太担心了,有些事情可以大胆一点,比如说去给助教讲这个算法,害主要还是自己不是很熟练。反正明天一过去就讲,早点讲不用排队。
//模拟退火
//
#include <bits/stdc++.h>
using namespace std;
void knapsackSa(int w[], int v[], int n, int M) { //n件物品,其重量和价值分别为w[i]和c[i],寻找将其装入容量为M的背包中物品的最大价值int i, j, dv, dw;int ans[n]; //定义解空间for (i = 0; i < n; i++) { //初始化解为0ans[i] = 0;}int val = 0, wei = 0; //初始化总价值和总重量float t0 = 500; //初始温度,控制参数t的初值float t = t0; //当前温度float a = 0.95f; //衰减因子,这里加个 f 表示这个数字是单精度浮点数float e = 0.00001f; //终止条件int L = 100 * n; //等温迭代次数,即每个温度都要迭代的次数,即生成新解的个数while (t > e) { //停止退火for (int k = 0; k < L; k++) {i = rand() % n; //随机选取第i件物品->生成新解if (ans[i] == 0) { //若i不在背包中 (则考虑将i放入背包)if (wei + w[i] <= M) { //且加入总重量后不超过容量M,则直接放入背包中ans[i] = 1;val = val + v[i];//表示的是当前的背包里面放的总的价值wei = wei + w[i];//表示当前背包里面放的总的重量} else{ //这里表示的意思是 i 放不下,但是抽到了 i 这个物品,那么下面我们要重新找一个物品j = rand() % n; //随机拿出物品jwhile (ans[j] == 0) { //一直找,直到找到一个在背包的物体j = rand() % n; }//找到之后把 j 拿出来,把 i 放进去,对 j 多少有点不厚道了哈哈哈dv = v[i] - v[j];//这个表示的是差值,或者直接直观理解就好,这样写可能还有点绕dw = w[i] - w[j];if (wei + dw <= M) //(拿出j放入i后)总重量后不超过容量Mif (dv > 0 || (exp(dv / t) > (double)(rand() / (double)RAND_MAX))) { //价值差大于0或以exp(dv/T)的接受概率接受新解ans[i] = 1;//把 i 放进去ans[j] = 0;//把 j 拿出来val = val + dv;wei = wei + dw;}}} else { //若i在包中,则考虑将i拿出j = rand() % n; //随机选一个不在包里的物品while (ans[j] == 1) {j = rand() % n;}dv = v[j] - v[i];//表示的是把这件物品拿出来之后的情况dw = w[j] - w[i];if(wei + dw <= M)//wei 表示的是总重量if (dv > 0 || (exp(dv / t) > (double)(rand() / (double)RAND_MAX))) { //价值差大于0或以exp(df/T)的接受概率接受新解ans[i] = 0;ans[j] = 1;val = val + dv;wei = wei + dw;}}}t = t * a; //降温}cout << "该0/1背包问题的最优解为: ";for (i = 0; i <= n - 1; i++) cout << ans[i] << " ";cout << endl << "最大总价值为:" << val << endl;
}
int main() {int n, M;//n件物品,其重量和价值分别为w[i]和c[i],寻找将其装入容量为M的背包中物品的最大价值cout << "请输入物品件数n和背包容量M:" << endl;cin >> n >> M;int w[n],v[n];cout << "请依次输入物品重量和价值:" << endl;for (int i = 0; i < n; i++) {cin >> w[i] >> v[i];}//拿系统时间作为种子产生随机数srand((unsigned)time(NULL)); //初始化随机函数种子(播种),srand((unsigned)time(NULL));是拿系统时间作为种子,由于时间是变化的,种子变化,可以产生不相同的随机数。//重量和价值的数组,物品件数,总的能承受的重量knapsackSa(w, v, n, M);return 0;
}
相关文章:
湘潭大学软件工程算法设计与分析实验-模拟退火算法
文章目录 写在前面代码分析 写在前面 总共是要四份代码,好像都是实现背包问题,前面三个都比较简单直观,朋友上周在机房给我讲解了一下之后,我大概弄清楚了,这周好像是最后一次算法课了,所以明天我得把剩下…...
Three.js 零基础+概念理解
文章目录 一、Three.js基础概念(一)什么是Three.js(二)核心对象(三)几何体(Geometries)和材质(Materials) 二、基础实例应用(一)创建一…...

c#使用COM接口设置excel单元格宽高匹配图片,如何计算?
c#使用COM接口设置excel单元格宽高如何换算 在实际工作中,经常需要在excel中插入图片。并设置单元格与图片对齐。但是excel单元格的宽度和高度使用不同的单位。单元格的宽度以字符宽度为单位,而高度以点为单位。如果按照实际值来设置,例如设…...
Excel模板下载\数据导出
pom <dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>4.1.2</version> </dependency><build><resources><resource><!--将xlsx打包到jar--><director…...

Vite初始化Vue3+Typescrpt项目
初始化项目 安装 Vite 首先,确保你的 Node.js 版本 > 12.0.0。然后在命令行中运行以下命令来创建一个 Vite Vue 3 TypeScript 的项目模板: npm init vitelatest进入项目目录 创建完成后,进入项目目录: cd vue3-demo启动…...

深入剖析【C++继承】:单一继承与多重继承的策略与实践,解锁代码复用和多态的编程精髓,迈向高级C++编程之旅
🌟个人主页:落叶 🌟当前专栏: C专栏 目录 继承的概念及定义 继承的概念 继承定义 定义格式 继承基类成员访问⽅式的变化 继承类模板 基类和派⽣类间的转换 继承中的作⽤域 隐藏规则 成员函数的隐藏 考察继承【作⽤…...
地级市能源消耗数据(2006至2021)含原始数据、计算过程、计算结果-最新出炉
能源消耗数据分析-2006-2021年地级市能源消耗数据(原始数据计算过程结果) 下载链接-点它👉👉👉:https://download.csdn.net/download/qq_67479387/89911272 全国能源消耗概况 2021年,我国单位…...

MySQL技巧之跨服务器数据查询:基础篇-A数据库与B数据库查询合并
MySQL技巧之跨服务器数据查询:基础篇-A数据库与B数据库查询合并 上一篇已经描述:借用微软的SQL Server ODBC 即可实现MySQL跨服务器间的数据查询。 而且还介绍了如何获得一个在MS SQL Server 可以连接指定实例的MySQL数据库的链接名: MY_ODBC_MYSQL 以…...

AutoSAR CP DoIP规范导读
主要功能和用途 诊断通信协议实现 遵循标准:遵循ISO 13400 - 2标准,实现了诊断通信在IP网络上的传输协议和网络层服务,包括数据封装、传输、路由等功能。 多种消息支持 车辆识别与公告:能够进行车辆识别请求和响应,…...

Window下PHP安装最新sg11(php5.3-php8.3)
链接: https://pan.baidu.com/s/10yyqTJdwH_oQJnQtWcwIeA 提取码: qz8y 复制这段内容后打开百度网盘手机App,操作更方便哦 (链接失效联系L88467872) 1.下载后解压文件,将对应版本的ixed.xx.win文件放进php对应的ext目录下,如图所示 2.修改ph…...
2024华为OD机试真题---中文分词模拟器
华为OD机试中的中文分词模拟器题目,通常要求考生对给定的不包含空格的字符串进行精确分词。这个字符串仅包含英文小写字母及英文标点符号(如逗号、分号、句号等),同时会提供一个词库作为分词依据。以下是对这类题目的详细解析 一…...

Kubernetes网络揭秘:从DNS到核心概念,一站式综述
文章目录 一.overlay vs underlayL2 underlayL3 underlay 二、calico vs flannel2.1 calico架构2.2 flannel架构 三、iptables四、Vxlan五、kubernetes网络架构综述六、DNS七、Kubernetes域名解析策略 一.overlay vs underlay overlay网络是在传统网络上虚拟出一个虚拟网络&am…...

C#封装EPPlus库为Excel导出工具
1,添加NUGet包 2,封装工具类 using OfficeOpenXml; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection;namespace GMWPF.utils {public class ExcelUtil<T>{/// <summary>///…...
【LeetCode】【算法】461. 汉明距离
LeetCode 461. 汉明距离 题目描述 两个整数之间的 汉明距离 指的是这两个数字对应二进制位不同的位置的数目。 给你两个整数 x 和 y,计算并返回它们之间的汉明距离。 思路 思路:将两个数转成二进制后求异或结果,就是它们之间的汉明距离。…...
Docker Compose部署Rabbitmq(延迟插件已下载)
整个工具的代码都在Gitee或者Github地址内 gitee:solomon-parent: 这个项目主要是总结了工作上遇到的问题以及学习一些框架用于整合例如:rabbitMq、reids、Mqtt、S3协议的文件服务器、mongodb github:GitHub - ZeroNing/solomon-parent: 这个项目主要是…...
生信技能62 - 常用机器学习算法的R语言实现
1. 加载R包和数据 # 安装R包, 是否update统一选择不更新n BiocManager::install("caret") BiocManager::install("randomForest") BiocManager::install("gbm") BiocManager::install("kernlab") BiocManager::install("glmnet…...

【3D Slicer】的小白入门使用指南二
3D Slicer中DICOM数据加载和三维可视化 任务 数据集下载和解压缩 加载和查看DICOM数据 1)将第一个数据集文件夹,整个往3Dslicer左侧拖动即可 得到 2)选中右侧patient 1就可显示出该患者的基本信息 (第二行蓝色是研究信息;第三行蓝色是序列信息)...

部署搭建AI相关项目时,不用魔法也能轻松自动下载所需大模型
背景 最近搭建了许多AI相关的自动化服务,有些时候因为国内服务器墙了 huggingface.co 访问,导致一些依赖文件和模型下载不下来,手动去下载又特别麻烦,今天教你一个小招,轻松解决这个问题 开搞 1:首先确定…...
zookeeper之节点基本操作
ZooKeeper是一个分布式协调服务,它的节点操作包括创建、查询、更新、删除等,以下是ZooKeeper节点的基本操作介绍: 1. 创建节点 持久节点(Persistent Node) 含义:持久节点是ZooKeeper中最基本的节点类型。创建后,除非显式删除,否则它将一直存在于ZooKeeper树中,即使创…...

技术最好 ≠ 最适合:数字化转型切忌盲目追求最先进的技术
企业引入新兴技术时面临的挑战 企业在引入新兴技术时会面临一定挑战,根据调查结果显示,企业在引入新兴技术时做出决策的三个最重要考量因素分别是: 价格与投资回报 新兴技术成熟度 新兴技术与业务的适配性 不要盲目追求最先进的技术 企业…...

数字IC后端教程之Innovus hold violation几大典型问题
今天小编给大家分享下数字IC后端实现Physical Implementation过程中经常遇到的几个hold violation问题。每个问题都是小编自己在公司实际项目中遇到的。 数字后端实现静态时序分析STA Timing Signoff之min period violation Q1: 在Innouvs postCTS时序优化的log中我们经常会看…...
rust并发
文章目录 Rust对多线程的支持std::thread::spawn创建线程线程与 move 闭包 使用消息传递在线程间传送数据std::sync::mpsc::channel()for received in rx接收两个producer 共享状态并发std::sync::Mutex在多个线程间共享Mutex,使用std::sync::Arc 参考 Rust对多线程…...

力扣 最小路径和
又是一道动态规划基础例题。 题目 这道题可以类似不同路径。先把左上角格子进行填充,然后用一个数组去更新每走到一个格的数字总和,首先处理边界问题,把最左边的列只能由上方的行与原来的格子数值的和,同理,最上方的行…...
Scala中的可变Map操作:简单易懂指南 #Scala Map #Scala
引言 在编程中,Map是一种常见的数据结构,用于存储键值对。Scala提供了不可变Map和可变Map两种类型,它们在处理数据时有不同的特性和用途。本文将通过一个简单的示例,带你了解Scala中可变Map的基本操作,包括添加元素、…...

【go从零单排】XML序列化和反序列化
🌈Don’t worry , just coding! 内耗与overthinking只会削弱你的精力,虚度你的光阴,每天迈出一小步,回头时发现已经走了很远。 📗概念 在 Go 语言中,处理 XML 数据主要使用 encoding/xml 包。这个包提供了…...

在 Oracle Linux 8.9 上安装Oracle Database 23ai 23.5
在 Oracle Linux 8.9 上安装Oracle Database 23ai 23.5 1. 安装 Oracle Database 23ai2. 连接 Oracle Database 23c3. 重启启动后,手动启动数据库4. 重启启动后,手动启动 Listener5. 手动启动 Pluggable Database6. 自动启动 Pluggable Database7. 设置开…...
在 Ubuntu 上安装 `.deb` 软件包有几种方法
在 Ubuntu 上安装 .deb 软件包有几种方法,可以使用命令行工具,也可以通过图形界面进行安装。以下是几种常见的安装方法: 方法 1:使用 dpkg 命令安装 .deb 包 打开终端。 使用 dpkg 命令安装 .deb 包: sudo dpkg -i /…...

一文了解Android本地广播
在 Android 开发中,本地广播(Local Broadcast)是一种轻量级的通信机制,主要用于在同一应用进程内的不同组件之间传递消息,而无需通过系统的全局广播机制。这种方法既可以提高安全性(因为广播仅在应用内传播…...

Ingress nginx 公开TCP服务
文章目录 背景搞起拓展( PROXY Protocol )参考 背景 公司业务繁多, HTTP、GRPC、TCP多种协议服务并存,Kubernetes流量入口复杂,所以萌生了通过LoadBalancer Ingress-nginx 的方式完全的结果入口流量,当然在高并发的场景下可以对…...

谷歌浏览器支持的开发者工具详解
谷歌浏览器(Google Chrome)是全球最受欢迎的网页浏览器之一,它不仅提供了快速、安全的浏览体验,还为开发者提供了强大的开发者工具。本文将详细介绍如何使用谷歌浏览器的开发者工具,并解答一些常见问题。(本…...