给定一组N个数x1
,x2
,...,xN
,您如何找到它们的排序以最大化相邻数字之间的最小绝对差异?这可能是一个NP难题,所以任何有效的近似方法都可以。
答案 0 :(得分:0)
我们假设您已将数据定义为x_i,i = 1,...,n。我们可以为i = 1,...,n和j = 1,...,n定义二进制变量p_ {ij},如果数字i是按排序顺序j则为1,否则为0。添加变量e,我们的优化模型将类似于:
绝对值的约束确保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
最后我们可以使用x_i和p_ {ij}变量提取排序列表:
sapply(1:n, function(j) sum(get.variables(mod)[seq(j, by=n, length.out=n)]*x))
# [1] 1 3 5 2 4