【问题标题】:Integer nonlinear optimization with a fixed domain具有固定域的整数非线性优化
【发布时间】:2019-01-13 22:21:08
【问题描述】:

这是原始表格:

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

x1,x2,x3,x4表示交换后的新值

原来每一列的方差是:

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

我该如何解决? 谢谢。

【问题讨论】:

  • 我不明白为什么这个问题被认为过于宽泛。这肯定只是一个优化问题。你能告诉我这个问题有什么问题吗?
  • 我在另一个问题中再次编辑它。

标签: python r optimization


【解决方案1】:

我有时把它写成一组线性分配约束:

 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} 

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

【讨论】:

  • 你能告诉我你用哪个优化包来解决这个问题吗?
  • 我相信 R 中的一般 MINLP 模型没有很好的支持。如果模型是线性的,那么 OMPR 会很有趣。如果模型是二次模型,Cplex 或 Gurobi 是很好的候选者。
  • 谢谢。稍后我会告诉你结果。
  • 我重新编辑了这个问题。我认为它不是 MINLP 模型,而是整数非线性模型。能否请您给我一些关于如何在 R 中编写此示例的代码的具体指导?
  • 我仍然需要x1!=1、x2!=2、x3!=2、`x4'!=3。似乎这组约束不能表明这一点。 ....
【解决方案2】:

对于这种规模的问题,您可以轻松地使用暴力破解。

在 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)&gt;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)生成排列列表,然后使用推导将目标函数应用于迭代器。

【讨论】:

  • 是的。非常感谢。我忘记添加另一个条件,说变量 x1 不能是 1,x2 不能是 2,x3 不能是 2,x4 不能是 3。我知道有时没有可行的解决方案。所以首先我将使用另一个函数来测试是否有可行的解决方案。然后我会使用优化包得到最优解。
  • 顺便说一句,我希望这不是家庭作业......我可能应该在回答之前询问更多的背景信息,以及你的努力的更多证据......
  • 谢谢。这绝对不是我的功课。实际上我已经写了这种函数来处理这个问题。但是当域的长度变得非常大时,这种方法需要大量的计算时间......所以我来这里问一下R中是否有一些好的求解器可以快速解决这个问题。我不熟悉这种包。
  • OK:在你的问题中应该试着更好地理解一个现实的背景:你试图解决的问题有多大?你已经做了什么?否则,人们(比如我)会浪费时间重复你所做的事情......首先,请尝试按照我的答案中的“任务视图”链接。此外,您应该将问题描述为“我该如何解决?”而不是“有一个包”(即使“使用包 XX”结果是答案......)
  • 是的。非常感谢。我也知道之前的'任务视图'。那里的包真的很多,我之前放弃看了,因为我觉得我的问题很特殊,很难找到合适的包。所以特地来这里请教一些更具体的指导......不过现在我会仔细阅读'任务视图'......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-04-08
  • 2020-07-17
  • 1970-01-01
  • 1970-01-01
  • 2013-04-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多