订购一组数字以最大化相邻差异

时间:2014-05-02 21:46:40

标签: sorting mathematical-optimization

给定一组N个数x1x2,...,xN,您如何找到它们的排序以最大化相邻数字之间的最小绝对差异?这可能是一个NP难题,所以任何有效的近似方法都可以。

1 个答案:

答案 0 :(得分:0)

我们假设您已将数据定义为x_i,i = 1,...,n。我们可以为i = 1,...,n和j = 1,...,n定义二进制变量p_ {ij},如果数字i是按排序顺序j则为1,否则为0。添加变量e,我们的优化模型将类似于:

first try

绝对值的约束确保e(我们的最小间隙)不超过排序序列中每对相邻元素之间的间隙。但是,线性优化模型中不允许使用绝对值,并且通常需要添加二进制变量来模拟绝对值大于或等于某个其他值。所以让我们添加二进制变量r_j,j = 2,...,n,并替换我们有问题的约束:

second try

这里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