C++遗传算法 解决01背包问题(背包容量165 每个物体总量:23 31 29 44 53 38 63 85 89 82 每个物体价值92 57 49 6 60 4367 84 87 72)

C++遗传算法解决背包问题


题目:
  1. 背包容量:165
  2. 每个物品总量:23,31,29,44,53,38,63,85,89,82
  3. 每个物品价值:92,57,49,6,60,43,67,84,87,72
解决思路:
  1. 利用遗传算法,基因数组的长度就是物体数目。其0,1表示放与不放。
  2. 每个个体都有自己的基因数组,实际上每个个体就是一个解决方案,基因数组的序列就分别对应第几个物体放与不放。
  3. 杂交采用0,2,4。。与1,3,5交换基因序列,用随机数判断是否杂交。
  4. 变异利用随机数在某基因点位让其取反。
实现效果:

在这里插入图片描述
若同时求解多个背包,只需在代码基础上稍作修改。可以从个体(内含基因数组)初始化下手,也可以简单的写多个个体类。

具体实现细节可见代码及其注释

代码下载链接

https://download.csdn.net/download/weixin_41747528/11036971

参考

https://blog.csdn.net/mrzzzzk/article/details/78408247

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是用 C++ 实现的模拟退火算法解决 01 背包问题的示例代码: ```c++ #include <iostream> #include <cmath> #include <ctime> #include <cstdlib> using namespace std; const int maxn = 1005; int v[maxn], w[maxn]; // v[i] 表示第 i 个物品的价值,w[i] 表示第 i 个物品的重量 int n, c; // n 表示物品数量,c 表示背包容量 double ans; // 最大价值 int ansx[maxn]; // 最优解 int x[maxn]; // 当前解 double t = 100; // 初始温度 const double delta = 0.98; // 降温系数 const double eps = 1e-8; // 终止温度 double rand01() { // 生成 0 到 1 之间的随机数 return rand() / (double)RAND_MAX; } void init() { // 初始化 srand(time(NULL)); ans = 0; for (int i = 1; i <= n; i++) { x[i] = rand01() > 0.5 ? 1 : 0; // 随机初始化解 ansx[i] = x[i]; ans += x[i] * v[i]; } } double evaluate(int x[]) { // 计算当前解的价值 double value = 0; int weight = 0; for (int i = 1; i <= n; i++) { value += x[i] * v[i]; weight += x[i] * w[i]; } if (weight > c) { // 如果超过背包容量,则价值为负无穷大 value = -1e9; } return value; } void SA() { // 模拟退火算法 while (t > eps) { // 终止温度 int i = rand() % n + 1; // 随机选择一个位置 int j = rand() % n + 1; int delta = evaluate(x); // 计算当前解的价值 swap(x[i], x[j]); // 交换两个位置的值 delta = evaluate(x) - delta; // 计算新解的价值与旧解的价值之差 if (exp(-delta / t) < rand01()) { // 根据概率接受新解 swap(x[i], x[j]); // 恢复旧解 } else { // 更新最优解 if (evaluate(x) > ans) { ans = evaluate(x); for (int k = 1; k <= n; k++) { ansx[k] = x[k]; } } } t *= delta; // 降温 } } int main() { cin >> n >> c; for (int i = 1; i <= n; i++) { cin >> v[i] >> w[i]; } init(); // 初始化 SA(); // 模拟退火算法 cout << ans << endl; for (int i = 1; i <= n; i++) { cout << ansx[i] << " "; } cout << endl; return 0; } ``` 这段代码首先通过 `rand01()` 函数生成随机解,然后使用模拟退火算法不断更新解,直到达到终止温度 `eps`。在每次更新解时,随机选择两个位置交换值,计算新解的价值与旧解的价值之差,根据概率接受新解或恢复旧解,并更新最优解。在降温时,使用降温系数 `delta` 乘以当前温度。最后输出最大价值和最优解。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值