VNS介绍
变邻域搜索算法(VNS)就是一种改进型的局部搜索算法。它利用不同的动作构成的邻域结构进行交替搜索,在集中性和疏散性之间达到很好的平衡。其思想可以概括为“变则通”。
变邻域搜索算法依赖于以下事实:
-
一个邻域结构的局部最优解不一定是另一个邻域结构的局部最优解。
-
全局最优解是所有可能邻域的局部最优解。
变邻域搜索算法主要由以下两个部分组成:
1) VARIABLE NEIGHBORHOOD DESCENT (VND)
2) SHAKING PROCEDURE
参考文章:干货 | 变邻域搜索算法(Variable Neighborhood Search,VNS)超详细一看就懂 (qq.com)
0-1背包问题
0-1 背包问题:给定 n 种物品和一个容量为 C 的背包,物品 i 的重量是 w_i,其价值为 v_i。
问:应该如何选择装入背包的物品,使得装入背包中的物品的总价值最大?
此代码是干货 | 变邻域搜索算法解决0-1背包问题(Knapsack Problem)代码实例 (qq.com)的代码复现
详细代码
原文使用的是C++,这里使用的是Golang,版本1.18.3。
package main
import (
"fmt"
"math/rand"
)
var (
//物品总数
num = 100
//背包容量
maxWeight = num * 5
//物品的重量和价值
values, weights []int
//最大邻域数量
maxFlip = 3
//迭代次数
iterator = 1000
//随机数种子
seed int64 = 5113
//邻域解决方案
neighborhoodSolution [][]int
//方案检查总数
solutionCount = 0
//方案替换总数
solutionUpdate = 0
//记录所有方案的物品价值和重量
solutionValue, solutionWeight = make([]int, 0), make([]int, 0)
)
func main() {
//设置随机数种子
rand.Seed(seed)
//初始化每个物品的价值
values = randSlice(num, 10, 100)
weights = randSlice(num, 5, 10)
initCheck()
//初始化解决方案
solution := randSlice(num, 0, 1)
solutionValue = append(solutionValue, getTotal(solution, values))
solutionWeight = append(solutionWeight, getTotal(solution, weights))
//给邻域空间分配内存
neighborhoodSolution = make([