遗传算法和动态规划哪个是解决经典0-1背包问题的最佳方法? [关闭]

2023-12-27

假设我有这样的问题:

  • 背包容量=2000万
  • 商品数量 = 500
  • 每件物品的重量是100到2000万之间的随机数
  • 每个项目的利润是1到10之间的随机数

那么哪种方法是解决我的问题的最佳方法呢?遗传算法还是动态规划?

请给我一个简单的解释,因为我是这方面的新手..


动态规划(DP):

  • 精确算法 - 寻找全局最优解
  • 运行时间长
  • 占用大量内存
  • 实施起来非常简单

遗传算法(GA):

  • 估计——不一定能找到全局最优解
  • 运行时间短
  • 内存使用量取决于个体数量,但通常是可以管理的
  • 解决方案的质量取决于选择有效的表示+让它运行足够长的时间
  • 实施起来相当简单,但设计决策可能会稍微复杂一些,特别是如果您没有丰富的 GA 经验的话

爬山:

  • 估计 - 不一定能找到全局最优解。更多可能会停在局部最优 http://en.wikipedia.org/wiki/Local_optimum与 GA 相比,尽管有一些方法可以减少这种情况发生的可能性
  • 运行时间短
  • 内存使用率非常低
  • 实施起来非常简单

DP(或 NP 完全问题的任何精确算法)通常仅对于相当小的问题或者寻找全局最优是最重要的事情时才是一个好主意。

有 2 种 DP 方法:(有一种相当简单的优化,您只存储 2 行,我的内存使用分析是基于使用这种优化的假设)

  • 有一个由项目 x 重量组成的矩阵,单元格值为最大值

    矩阵大小 = 500 x 20 000 000

    运行时间 = O(500 * 20 000 000) = O(10 000 000 000)

    内存 = 最大 10 * 500 -> 5 000 -> 短 = 2 字节 -> 2 * 20 000 000 * 2 = 80 000 000

    解释:下面的 A[i,j] 表示从具有权重的元素 1 到 i 的任意子集中可获得的最佳(最高)值小于或等于j。下面的更新规则意味着 - 找到不包含当前元素(因此权重和值保持不变)或包含它之间的最佳值(因此查找(当前权重减去当前项目的权重)的最佳值并添加当前项目的值)。然后只需返回 A[500, 20000000],它表示从具有背包大小最大重量的所有元素的任何子集中可获得的最高值。

    算法:

    A[0, 0..20000000] = 0
    for i = 1:500
    for x = 0:20000000
      A[i, x] = max(A[i-1, x], value(i) + A[i-1, x-weight(i)])
    // ignore value(i) + A[i-1, x-weight(i)] when weight(i) > x
    return A[500, 20000000]
    
  • 有一个由项目 x 值组成的矩阵,单元格值为最小权重

    矩阵大小 = 500 x 10*500

    运行时间 = O(500 * 10*500) = O(2 500 000)

    内存 = 最大 20 000 000 -> int = 4 字节 -> 2 * 500 * 4 = 4 000

    解释:下面的 A[i,j] 表示从具有 value 的元素 1 到 i 的任意子集中可获得的最低权重equal toj。下面的更新规则意味着 - 找到不包含当前元素(因此权重和值保持不变)或包含它之间的最佳值(因此查找(当前值减去当前项目的值)的最佳值并添加当前项目的重量)。任意单元格的值为exact子集的权重来产生该值,因此我们需要查看所有单元格 A[500, x],它表示任何值 x 的元素的最小权重子集。

    算法:

    A[0, 0] = 0
    A[0, 1..5000] = ∞
    for i = 1:500
    for x = 0:5000
      A[i, x] = min(A[i-1, x], weight(i) + A[i-1, x-value(i)])
    // interpret A[i-1, x-value(i)] as 0 when value(i) > x
    return largest x that A[500, x] <= 20000000
    

所以,是的,复杂性几乎是不言而喻的,第一种方式你将等待几个小时,但第二种方式只需几秒钟,并且内存使用量也有类似的差异(尽管 80 MB 仍然几乎可以忽略不计)(注意这是FAR根据规则,每个案例都需要单独分析)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

遗传算法和动态规划哪个是解决经典0-1背包问题的最佳方法? [关闭] 的相关文章

  • 贪心技术与穷举搜索有何不同?

    我正在为一些示例问题编写伪代码 并且我注意到贪婪技术和详尽搜索之间存在令人担忧的模式 Job 1 Job 2 Job 3 Job 4 Job 5 Person 1 9 2 7 8 Person 2 6 4 3 7 Person 3 5 8
  • 优化两个三位数乘积的最大回文数?

    我正在研究一个面试问题 我被问到这个问题 我应该编写一个程序 从两个三位数的乘积中找到最大的回文数 这里是question https projecteuler net problem 4 我想出了这种从底部开始的蛮力方法 public c
  • 查找一个二维矩阵是否是另一个二维矩阵的子集

    最近我参加了一个黑客马拉松 我了解到一个问题 试图在 2d 矩阵中找到网格形式的模式 模式可以是 U H 和 T 并由 3 3 矩阵表示 假设我想展示 H 和 U 1 0 1 1 0 1 1 1 1 gt H 1 0 1 gt U 1 0
  • C 中是否可以动态定义结构体

    我很确定这最终将成为一个非常明显的问题 这就是为什么我没有找到太多关于它的信息 不过 我认为还是值得问一下 基本上 使用结构访问数据非常快 如果数据以一种可以立即作为结构进行处理的形式从网络中出来 那么从性能的角度来看 这是非常好的 但是
  • 测量数组的“无序”程度

    给定一个值数组 我想找到总 分数 其中每个元素的分数是数组中出现在其之前的具有较小值的元素的数量 e g values 4 1 3 2 5 scores 0 0 1 1 4 total score 6 O n 2 算法很简单 但我怀疑可以通
  • 机器人探索算法

    我正在尝试为机器人设计一种算法 试图找到位于未知位置的旗帜 该旗帜位于一个包含障碍物的世界中 机器人的任务是夺取旗帜并将其带到他的基地 代表他的起始位置 机器人在每一步只能看到有限的邻域 他事先不知道世界是什么样子 但他有无限的内存来存储已
  • 寻找簇的中心

    我有以下问题 进行抽象以找出关键问题 我有 10 个点 每个点与其他点有一定距离 我想要 能够找到簇的中心 即与其他点的成对距离最小的点 令 p j p k 表示点 j 和 k 之间的成对距离p i 是簇的中心点 iff p i s t m
  • 最接近 x,y 的线上的点[重复]

    这个问题在这里已经有答案了 可能的重复 如何判断一个点是否在某条线附近 https stackoverflow com questions 910882 how can i tell if a point is nearby a certa
  • 生成 2D 中的非简并点集 - C++

    我想在 2D 平面中创建一大组非退化的随机点云 整个集合中没有 3 个点在一条直线上 我有一个简单的解决方案 它生成一个随机浮点对 P new x y 并检查到目前为止生成的每对点 P1 P2 是否位于同一行 这需要 O n 2 检查添加到
  • Diamond-Square 算法的平滑问题

    我正在使用菱形方形算法来生成随机地形 它工作得很好 除了我让这些大圆锥形状要么伸出或伸入地形 问题似乎在于 时不时会有一个点被设置得太高或太低 Here is a picture of the problem And it can be b
  • 为什么Python中pop()的大O与pop(0)不同[重复]

    这个问题在这里已经有答案了 他们不应该都是O 1 因为从 Python 列表中的任何位置弹出一个元素涉及销毁该列表并在新的内存位置创建一个元素 蟒蛇的list实现使用动态调整大小的 Carray在引擎盖下 删除元素usually要求您移动后
  • 查找重叠事件/时间的算法

    在处理自定义日历时 我不知道如何找到与任何其他时间段重叠的时间段 时段从 0 点至 720 点 上午 9 点至晚上 9 点 每个像素代表一分钟 var events id 1 start 0 end 40 an event from 9 0
  • 使用 stl sort 对表进行排序

    我有一个巨大的表 约 50Gb 格式为 i j k 来自稀疏矩阵 存储为 uint32 t idx1 idx2 float vals uint32 t tablesize 我想使用给定的比较函数 即 idx1 和 idx2 的函数 对其进行
  • 在大文件中查找重复项

    我有一个非常大的文件 大约有 1500 万个条目 文件中的每一行都包含一个字符串 称为键 我需要使用 java 查找文件中的重复条目 我尝试使用哈希图并检测重复的条目 显然 这种方法向我抛出了 java lang OutOfMemoryEr
  • n的渐近增长选择下限(n/2)

    如何找到 n select Floor n 2 的渐近增长 我试过 使用扩展并得到它等于 n n 1 floor n 2 1 n floor n 2 知道我该如何从那里去吗 感谢任何帮助 更喜欢提示而不是答案 我同意上面的答案 但想提供更多
  • 在VB.net中动态添加用户控件

    我在 Vb net Windows 应用程序 中制作了自定义 UserControl 如何将其动态添加到表单中 UserControl 本质上只是另一个类 它继承自 Control 因此您可以使用控件执行各种操作 但除此之外它只是一个类 因
  • 递归:n项级数之和

    需要递归函数 系列是 1 2 3 3 4 5 4 5 6 7 递归求 n 的级数之和 我无法想到应该在函数中传递哪些参数 我的方法 我认为我应该传递 n 要相乘的项数 但我无法想到的是我应该如何在同一个函数中 和 以及我的 return 语
  • 将数组复制到动态分配的内存

    我的代码可以正常工作 但我觉得好像有一种更快的方法可以做到这一点 特别是在我的函数副本中 这是我的代码 这能再快一点吗 顺便说一句 这是 C 语言 另外 当我从函数返回 cpy 时 它是否会删除动态内存 因为它超出了范围 我不想发生内存泄漏
  • 广度优先搜索:检查访问状态的时机

    在有向图的广度优先搜索中 可能循环 当一个节点出队时 其所有尚未访问的子节点都会入队 并且该过程将继续 直到队列为空 有一次 我以相反的方式实现它 将节点的所有子节点排队 并在节点出队时检查访问状态 如果正在出队的节点之前已被访问过 则该节
  • 插入排序 - 如何接受输入并打印排序后的数组

    我试图做一个插入排序程序 它接受任何数据类型 Int Double String 然后打印排序后的数组 我知道我的代码可以工作 但我无法找出真正的问题 import java util public class MyInsertionSor

随机推荐