R 使用lpSolveAPI获得0/1背包MILP的多个解决方案

R 使用lpSolveAPI获得0/1背包MILP的多个解决方案,r,linear-programming,constraint-programming,lpsolve,R,Linear Programming,Constraint Programming,Lpsolve,可复制示例: 我描述了in的一个简单问题,它应该返回两个解决方案: library(lpSolveAPI) lp_model= make.lp(0, 3) set.objfn(lp_model, c(100, 100, 200)) add.constraint(lp_model, c(100,100,200), "<=", 350) lp.control(lp_model, sense= "max") set.type(lp_model, 1:3, "binary") lp_model

可复制示例:

我描述了in的一个简单问题,它应该返回两个解决方案:

library(lpSolveAPI)

lp_model= make.lp(0, 3)
set.objfn(lp_model, c(100, 100, 200))
add.constraint(lp_model, c(100,100,200), "<=", 350)
lp.control(lp_model, sense= "max")
set.type(lp_model, 1:3, "binary")

lp_model
solve(lp_model)
get.variables(lp_model)
get.objective(lp_model)
get.constr.value((lp_model))
get.total.iter(lp_model)
get.solutioncount(lp_model)
我希望有两种解决方案:
101
011

我试图通过
solve(lp_模型,num.bin.solns=2)
传递的
num.bin.solns
参数,但解决方案的数量仍然是
1

问题:

我怎样才能得到两个正确的解决方案? 我更喜欢使用API,因为API非常好。
如果可能的话,我想避免直接使用

看起来好像坏了。以下是针对您的特定车型的DIY方法:

# first problem
rc<-solve(lp_model)
sols<-list()
obj0<-get.objective(lp_model)
# find more solutions
while(TRUE) {
   sol <- round(get.variables(lp_model))
   sols <- c(sols,list(sol))
   add.constraint(lp_model,2*sol-1,"<=", sum(sol)-1)
   rc<-solve(lp_model)
   if (rc!=0) break;
   if (get.objective(lp_model)<obj0-1e-6) break;
}
sols
更新

在下面的评论中,有人问为什么切割系数的形式为2*sol-1。再看一看。下面是一个反例:

           C1   C2        
Maximize    0   10        
R1          1    1  <=  10
Kind      Std  Std        
Type      Int  Int        
Upper       1    1        
Lower       0    0       
使用建议的“错误”切割只会:

> sols
[[1]]
[1] 0 1

lpSolveAPI的作者Kjell Konis写信给我:lp_solve(lpSolveAPI的底层软件)的当前版本不支持MILP的多个解决方案。您可以通过添加约束(lpSolve包就是这么做的)来实现自己的功能。我不理解新约束的lhs:2*sol-1。你能详细说明一下吗?我们需要用系数c[j]创建一个约束,如下所示:如果sol[j]=0,则c[j]=-1;如果sol[j]=1,则c[j]=+1。这对应于c[j]=2*sol[j]-1。为什么不这样做呢:如果sol[j]=0,c[j]=0,如果sol[j]=1,c[j]=1?对这个数据有效,但一般不适用。正确的切割具有这些-1系数。添加了一个反例
           C1   C2        
Maximize    0   10        
R1          1    1  <=  10
Kind      Std  Std        
Type      Int  Int        
Upper       1    1        
Lower       0    0       
> sols
[[1]]
[1] 0 1

[[2]]
[1] 1 1
> sols
[[1]]
[1] 0 1