如何解决爬山的零子集和问题?

人工智能 人工智能设计 爬山 本地搜索
2021-10-19 02:29:59

我想用爬山算法解决零子集和问题,但我不确定我是否找到了一个好的状态空间。

这就是问题所在:考虑我们有一组数字,我们想要找到这个集合的一个子集,使得这个子集中的元素之和为零。

我自己通过爬山来解决这个问题的想法是,在第一步中,我们可以选择集合的一个随机子集(例如,主集合是X={X1,,Xn}我们选择了X={Xi1,,Xik}随机),那么这个状态的孩子可以通过添加一个元素来构建XXX或从中删除一个元素X本身。这意味着每个州都有n孩子们。目标函数可以是元素的总和X我们想要最小化的。

这是一个很好的建模吗?是否有更好的建模或目标函数可以更智能地工作?

2个回答

要实现的爬山算法如下:

  1. 该算法应该有四个输入:和往常一样,会有一个多重集 S 和整数 k,它们是子集和问题的 和SubsetSum此外,将有两个整数 q 和 r,其作用定义如下。
  2. 执行以下 q 次:

(a) 选择一个随机子集(multiset)S0的 S 作为current子集。

(b) 执行以下 ( hill climbing) r 次:

一世。找到当前子集的随机邻居 T(参见下面的邻居定义)。

ii. 如果邻居 T 的残差较小,则使 T 成为当前子集。

(c) 从子集开始时跟踪最终当前子集的残差 S0.

  1. 返回算法测试的 q 个子集的最小残差。

定义:子集(多重集)B ⊆ S 是 S 的子集 A 的邻居,如果你可以通过将一个或两个整数从 A 移动到 B,或者通过将一个或两个整数从 B 移动到 A,或者通过将 A 中的一个整数与 B 中的一个整数交换。生成 S 的子集 A 的随机邻居 B 的简单方法如下:

  1. 将 S 的元素排序为x1,x2,...,xn.
  2. 将 B 初始化为 A 的克隆。
  3. 选择两个不同的随机索引 i 和 j,其中1i;jn.
  4. 如果xi在 A 中,将其从 B 中删除。否则,将 xi 添加到 B。
  5. 如果xj在 A 中,则以 0.5 的概率将其从 B 中移除。如果xj不在 A 中,则以 0.5 的概率添加xj给 B。

状态空间本身似乎还可以,但您的方法有一些缺点。首先,您需要选择大小的初始状态n. 如果最优解是大小怎么办n4或者10n? 然后使用这种方法进行搜索可能需要很长时间,因为您开始的距离很远。如果有多个解决方案,您是否关心您找到哪一个或首选最小的零子集?我将假设空集X={}不是解决方案,并且首选具有较小基数的解决方案。

我建议使用生成启发式来构建初始状态,然后从该状态运行您的爬山程序。例如,生成启发式可能是这样的:“选择一对元素 (x1,x2) 从X这样x1+x2尽可能接近零,并设置X={x1,x2}作为初始状态”。要应用此启发式方法,您需要首先检查n(n1)对的子集。如果这不是一个解决方案,那么它有望非常接近状态空间中的解决方案,因此是一个很好的起点。

另一个问题是爬山不记得以前访问过的状态,当您允许移动以添加和删除元素时,您最终可能会无限循环X. 例如,假设X={1},X={3,50,50,100}. 显然最优解是X={50,50,100}但是您的方法将添加元素3X首先,然后删除3,然后选择3再次等等,因为这些状态的客观价值低于任何具有以下条件之一的状态50或者100在里面。所以我认为你需要使用更复杂的方法来防止两次访问同一个状态。