可再现的例子:
我描述了一个简单的0/1-背包问题lpSolveAPI在ř,它应该返回2级的解决方案:
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)
问题:
但get.solutioncount(lp_model)
表明1
找到了解决方案:
> lp_model Model name: C1 C2 C3 Maximize 100 100 200 R1 100 100 200 <= 350 Kind Std Std Std Type Int Int Int Upper 1 1 1 Lower 0 0 0 > solve(lp_model) [1] 0 > get.variables(lp_model) [1] 1 0 1 > get.objective(lp_model) [1] 300 > get.constr.value((lp_model)) [1] 350 > get.total.iter(lp_model) [1] 6 > get.solutioncount(lp_model) [1] 1
我希望有两种解决方案:1 0 1
和0 1 1
.
我试图传递num.bin.solns
的参数lpSolve用solve(lp_model, num.bin.solns=2)
,但解决方案的数量保持1
.
题:
我怎样才能得到两个正确的解决方案?我更喜欢使用lpSolveAPI,因为API非常好.如果可能的话,我想避免直接使用lpSolve.
看起来好像坏了.以下是针对您特定型号的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)我们的想法是通过添加约束来切断当前的整数解决方案.然后解决.当不再优化或目标开始恶化时停止.这是一些数学背景.
你现在应该看到:
> sols [[1]] [1] 1 0 1 [[2]] [1] 0 1 1更新
在评论中,有人问为什么切割的系数具有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 [[2]] [1] 1 1使用建议的"错误"削减将只给出:
> sols [[1]] [1] 0 1