给定一组N个数字x1
, x2
, ..., xN
,如何找到它们的排序方式以最大化相邻数字之间的最小绝对差?这可能是一个NP困难问题,因此任何有效的近似方法都可以。
给定一组N个数字x1
, x2
, ..., xN
,如何找到它们的排序方式以最大化相邻数字之间的最小绝对差?这可能是一个NP困难问题,因此任何有效的近似方法都可以。
绝对值的限制条件确保了e(我们的最小间隔)不超过排序序列中每对相邻元素之间的间隔。然而,在线性优化模型中,绝对值是不允许的,通常需要添加一个二进制变量来表示绝对值大于或等于某个其他值。因此,让我们添加二进制变量r_j,其中j=2,...,n,并替换我们有问题的约束条件:
这里M是一个很大的数字;2(max(x)-min(x))应该足够大。现在,我们准备实际实施这个模型。您可以使用任何MIP求解器;我将在R中使用lpSolveAPI
,因为它是免费和易于访问的。p_{ij}存储在变量1到n ^ 2中; r_j存储在变量n ^ 2 + 1到n ^ 2 + n-1中; e存储在变量n ^ 2 + n中。
x = 1:5
n = length(x)
M = 2*(max(x) - min(x))
library(lpSolveAPI)
mod = make.lp(0, n^2+n)
set.type(mod, 1:(n^2+n-1), "binary")
set.objfn(mod, c(rep(0, n^2+n-1), 1))
lp.control(mod, sense="max")
for (j in 2:n) {
base.cons <- rep(0, n^2+n)
base.cons[seq(j-1, by=n, length.out=n)] = x
base.cons[seq(j, by=n, length.out=n)] = -x
base.cons[n^2+j-1] = M
first.cons = base.cons
first.cons[n^2+n] = -1
add.constraint(mod, first.cons, ">=", 0)
second.cons = -base.cons
second.cons[n^2+n] = -1
add.constraint(mod, second.cons, ">=", -M)
}
for (j in 1:n) {
this.cons = rep(0, n^2+n)
this.cons[seq(j, by=n, length.out=n)] = 1
add.constraint(mod, this.cons, "=", 1)
}
for (i in 1:n) {
this.cons = rep(0, n^2+n)
this.cons[seq((i-1)*n+1, i*n)] = 1
add.constraint(mod, this.cons, "=", 1)
}
现在我们已经准备好解决这个模型了:
solve(mod)
# [1] 0
get.objective(mod)
# [1] 2
get.variables(mod)
# [1] 1 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 1 0 0 1 0 0 1 1 0 1 2
sapply(1:n, function(j) sum(get.variables(mod)[seq(j, by=n, length.out=n)]*x))
# [1] 1 3 5 2 4