在我追求模拟退火启发式来解决问题的过程中,我试图找到生成我当前提出的解决方案的邻居的最佳方法。
解决方案以整数位置向量 (p1,...,pN) 的形式出现,我将其理解为二进制链
0 0 0 0 1 0 ... 0 0 1 0 ... 0 1 0 0
p1 pj pN
有一些限制(对于所有 j,pj - p(j-1) > D,并且 p1 > D/2,长度 - pN > D/2)。
现在,我的想法是使用类似于 Levenshtein 距离的东西来创建新的解决方案,所以如果我有 [0,1,0,0,1,0] (D=3) 并且我想要一个距离更小的新状态或等于 1,那么我可以得到 [1,0,0,0,1,0],例如,但不是 [1,0,0,1,0,0]。
我所做的(在 R 中)如下:
GenNewSeq <- function(seq, D, dist){
for(i in 1:dist){
Diffs <- c((ceiling(D/2)+seq[1]),diff(seq),(ceiling(D/2)+seq[length(seq)]))
position <- sample((2:length(seq))[Diffs > D], size=1)
move <- sample(c(-1*as.integer(Diffs[position-1]>D),0,1*as.integer(Diffs[position]>D)), size = 1)
seq[position-1] <- seq[position-1]+move
}
seq
}
也许它有点晦涩,如果你愿意,我可以更好地解释它的作用。问题是,这是 1) 慢(我不知道如何避免for
),2) 奇怪地没有按预期工作。总是只移动最后一个位置和/或稳定地向前和向后移动相同的元素往往太过分了,所以我的模拟退火结果有偏差。
我曾想过消除距离的限制并将其放在适应度函数中(类似于exp(D-(pj-p(j-1)))
),所以我可以简单地用法线移动它们,或者让它们完全移动然后振荡......我开始认为它会成为最简单的方法。但是,我非常感谢您参考如何做一个有效且可靠的算法来满足我的要求,我不介意我是否必须在 C 中这样做。我已经检查过但我无法来解决我的疑惑。
非常感谢您的帮助。