固定域的整数非线性优化

时间:2018-08-06 22:22:57

标签: python r optimization

这是原始表:

       Column1   Column2
Row1    4 (x1)    6(x3)
Row2    5 (x2)    4(x4)

x1x2x3x4表示交换后的新值

最初,每列的差异为:

Var(column1)= var(c(4,5))=0.5
Var(column2)= var(c(6,4))=2

交换原始表中小于10的值后,两列的新方差分别为:

New_Var(column1)=(x1-(x1+x2)/2)^2+(x2-(x1+x2)/2)^2
New_Var(column2)=(x3-(x3+x4)/2)^2+(x4-(x3+x4)/2)^2

我的目标是

Minimize  | New_Var(column1) – 0.5 | + | New_Var(column2) – 2 |

此处表示法‘| |’表示绝对。

约束是x1x2x3x4只能分别从固定域(这里说{4, 5, 4, 6})获取值。并且所有四个变量都需要交换为不同的值,例如x1不能为4,x3不能为6,依此类推。

请注意,此处原始表中的所有值都大于10,因为我只是想使问题看起来简单。

实际上,该表是6000*10,非常大。因此,输出所有唯一的排列和测试是不合适的方法。

我已经阅读了R中的task view of optimization。那里有很多优化包。所以我需要更具体的指导。

以下是可以将小于10的值分别交换为小于10的不同值的函数。希望对您有所帮助。

derangement <- function(x){
  if(max(table(x)) > length(x)/2) return(NA)
  while(TRUE){
    y <- sample(x)
    if(all(y != x)) return(y)
  }
}

swapFun <- function(x, n = 10){
  inx <- which(x < n)
  y <- derangement(x[inx])
  if(length(y) == 1) return(NA) 
  x[inx] <- y
  x
}

set.seed(10)
swapFun(c(1,2,3,10,4,11,2,12))
#[1]  2  4 10  2 11  1 12

我该如何解决? 谢谢。

2 个答案:

答案 0 :(得分:0)

对于这种大小的问题,您可以轻松使用蛮力。

在R中:

library(combinat)
pp <- permn(c(1,2,2,3)) ## construct list of permutations
pp <- unique(pp)        ## unique permutations only

应用(新)约束“ x1不能为1,x2不能为2,x3不能为2,x4不能为3”:

ok <- function(X) {
   !(X[1]==1 | X[2]==2 | X[3]==2 | X[4]==3)
}
pp <- pp[sapply(pp,ok)]

length(pp) == 2个不相同的有效组合(您可以测试length(pp)>0是否存在剩余的有效组合)。

## define objective function
f <- function(X) { (X[1]-X[2])^2 + (X[1]-X[3])^2+ 
        (X[2]-X[3]-X[4])^2+X[4]^2+X[3]^2 }
## compute obj function for all permutations
vals <- sapply(pp,f)
## identify minima
pp[which(vals==min(vals))]
## [[1]]
## [1] 2 3 1 2 

这会随着域的增长而分解,并且(n!)的大小会变大...此时,您可能需要开始在整数编程领域进行研究(例如,请参见Optimization Task View

在Python中,您将首先使用itertools.permutations生成置换列表(请参见this question),然后使用理解将目标函数应用于迭代器。

答案 1 :(得分:0)

我有时将此写为一组线性分配约束:

 sum(i, δ[i,j]) = 1  forall j
 sum(j, δ[i,j]) = 1  forall i
 x[i] = sum(j, δ[i,j] * v[j])
 δ[i,j] ∈ {0,1}     (binary variables)
 v = [1, 2, 2, 3]   (constants)  
 i,j ∈ {1..4}       (indices} 

这里δ是一个二进制变量,其性能类似于置换矩阵。