我想用爬山算法解决零子集和问题,但我不确定我是否找到了一个好的状态空间。
这就是问题所在:考虑我们有一组数字,我们想要找到这个集合的一个子集,使得这个子集中的元素之和为零。
我自己通过爬山来解决这个问题的想法是,在第一步中,我们可以选择集合的一个随机子集(例如,主集合是我们选择了随机),那么这个状态的孩子可以通过添加一个元素来构建到或从中删除一个元素本身。这意味着每个州都有孩子们。目标函数可以是元素的总和我们想要最小化的。
这是一个很好的建模吗?是否有更好的建模或目标函数可以更智能地工作?
我想用爬山算法解决零子集和问题,但我不确定我是否找到了一个好的状态空间。
这就是问题所在:考虑我们有一组数字,我们想要找到这个集合的一个子集,使得这个子集中的元素之和为零。
我自己通过爬山来解决这个问题的想法是,在第一步中,我们可以选择集合的一个随机子集(例如,主集合是我们选择了随机),那么这个状态的孩子可以通过添加一个元素来构建到或从中删除一个元素本身。这意味着每个州都有孩子们。目标函数可以是元素的总和我们想要最小化的。
这是一个很好的建模吗?是否有更好的建模或目标函数可以更智能地工作?
要实现的爬山算法如下:
Subset;Sum此外,将有两个整数 q 和 r,其作用定义如下。(a) 选择一个随机子集(multiset)的 S 作为current子集。
(b) 执行以下 ( hill climbing) r 次:
一世。找到当前子集的随机邻居 T(参见下面的邻居定义)。
ii. 如果邻居 T 的残差较小,则使 T 成为当前子集。
(c) 从子集开始时跟踪最终当前子集的残差 .
定义:子集(多重集)B ⊆ S 是 S 的子集 A 的邻居,如果你可以通过将一个或两个整数从 A 移动到 B,或者通过将一个或两个整数从 B 移动到 A,或者通过将 A 中的一个整数与 B 中的一个整数交换。生成 S 的子集 A 的随机邻居 B 的简单方法如下:
状态空间本身似乎还可以,但您的方法有一些缺点。首先,您需要选择大小的初始状态. 如果最优解是大小怎么办或者? 然后使用这种方法进行搜索可能需要很长时间,因为您开始的距离很远。如果有多个解决方案,您是否关心您找到哪一个或首选最小的零子集?我将假设空集不是解决方案,并且首选具有较小基数的解决方案。
我建议使用生成启发式来构建初始状态,然后从该状态运行您的爬山程序。例如,生成启发式可能是这样的:“选择一对元素 (,) 从这样尽可能接近零,并设置作为初始状态”。要应用此启发式方法,您需要首先检查对的子集。如果这不是一个解决方案,那么它有望非常接近状态空间中的解决方案,因此是一个很好的起点。
另一个问题是爬山不记得以前访问过的状态,当您允许移动以添加和删除元素时,您最终可能会无限循环. 例如,假设. 显然最优解是但是您的方法将添加元素到首先,然后删除,然后选择再次等等,因为这些状态的客观价值低于任何具有以下条件之一的状态或者在里面。所以我认为你需要使用更复杂的方法来防止两次访问同一个状态。