我正在尝试使用邻域算法实现子集和问题。
这是伪代码:
1. Generate a random solution for the problem and call it S
2. Compute the neighborhood of S and choose S' as the best solution in the neighborhood
3. If S' is better than S then go to step 4, else go to step 6
4. S = S'
5. Go to step 2
6. Return S as the best solution encountered
给定10个元素的集合X(+ ve和-ve),我必须找到X的子集,使得总和尽可能接近0。
遵循伪代码,我已经生成了一个随机解S,但是我在构建邻域S时遇到了一些困难。
如何计算S的邻域?什么是S的邻居?
E.g。
X = [x0,x1,x2,x3,x4,x5,x6,x7,x8,x9]
S = [x1,x7,x2,x3]
S的邻居是什么?
答案 0 :(得分:0)
社区没有独特的定义,这取决于问题。在你的情况下,一个好的定义可以是all the tuples that have (at most) n different elements from the current solution
,其中n可以是1, 2 , size - 1
(如果你采用n = size
,你正在考虑整个解空间,并且说邻域已经没有意义了。)
在您的示例中,将以下一个步骤与当前解决方案不同的所有解决方案在以下解决方案集中结束:
D = [[x0,x7,x2,x3],[x4,x7,x2,x3],[x5,x7,x2,x3],[x6,x7,x2,x3],[x8,x7 ,x2,x3],[x9,x7,x2,x3],[x1,x0,x2,x3],[x1,x4,x2,x3],...]
答案 1 :(得分:0)
让我们使用例子:
S是一个解决方案,让我们看看我们如何从中生成另一个解决方案:
使用上述操作之一从S获得的每个此类解决方案都是S的邻居。所有这些解决方案构成了邻域。
请记住,[x1,x3,x2]和[x1,x2,x3]是相同的解决方案,因为元素的顺序无关紧要。
正式每个解决方案都是长度为10的二进制向量v,由0和1组成,如 v [i] == 1如果相应的解包含x_i。
与示例中的S对应的向量如下所示: S = [0,1,1,1,0,0,0,1,0,0]
每个这样的向量都是解决方案图中的顶点。如果可以使用某种简单的操作(如上所述)将一个顶点转换为另一个顶点,则存在两个这样的顶点之间的边缘。
我希望这会有所帮助。