I think I was able to reproduce the same kind of problem in this example:
using JuMP
using Gurobi
slvr=GurobiSolver(Method=0)
# \min \{y_1 + 4y_2 + 2x_1 + 3x_2 \}
# s.t. y_1 - 3y_2 + x_1 -2x_2 \leq -2
# y_1 + 3y_2 + x_1 + x_2 \geq 3
# x_1,x_2\geq 0 , y_1,y_2 positive integers
#Initially we choose y_1^1 = y_2^1 = 0 , z^1=-\infty
function definemaster(d,D,b,λ)
PM = Model(solver=slvr)
@variable(PM, z)
@variable(PM, y[i in 1:length(d)] >= 0, Int)
λD= [sum(D[j,i]*λ[j] for j=1:length(b)) for i=1:length(d)]
@constraint(PM,Ep[k in 1:1],z>= sum(y[i]*(d[i]-λD[i]) for i =1:length(d)) + sum(λ[j]*b[j] for j =1:length(b)) )
# println(Ep[1])
@objective(PM, :Min, z)
return PM,y,z
end
function solvesubproblem(b,Dy,A,c)
sub=Model(solver=slvr)
@variable(sub,λ[j in 1:length(b)]>=0)
@constraint(sub,x[i =1:length(c)], sum( A[j,i] * λ[j] for j =1:length(b) ) <= c[i])
@objective(sub,:Max,sum( (b[j]-Dy[j])*λ[j] for j =1:length(b) ))
status=solve(sub)
if status==:Optimal
return :Optimal,getvalue(λ),getobjectivevalue(sub),getdual(x)
elseif status==:Unbounded
return :Unbounded,getvalue(λ)
else
println("I'm in a really bad shape, status is ",status)
return status
end
end
function solvebenders(c,d,A,D,b)
out=solvesubproblem(b,zeros(b),A,c)
PM,y,z=definemaster(d,D,b,out[2])
function cut(cb)
println("----\nInside cut callback")
masterval=getvalue(z);
println("Current objective value of master problem is: ", masterval)
𝐲=getvalue(y)
println("Solution for 𝐲 is: ", 𝐲)
Dy=[sum(D[j,i]*𝐲[i] for i=1:length(d)) for j=1:length(b)]
out=solvesubproblem(b,Dy,A,c)
λ=out[2]
λD= [sum(D[j,i]*λ[j] for j=1:length(b)) for i=1:length(d)]
expr=zero(AffExpr)
if out[1]==:Unbounded
expr+= sum( b[j]*λ[j] for j =1:length(b) )
for j in 1:length(d)
push!(expr,-λD[j],y[j])
end
elseif out[1]==:Optimal
if -0.0001+ sum( b[j]*λ[j] for j =1:length(b)) + sum( (d[j]-λD[j])*𝐲[j] for j = 1:length(d) )<=masterval<=0.0001+ sum( b[j]*λ[j] for j =1:length(b)) + sum( (d[j]-λD[j])*𝐲[j] for j = 1:length(d) )
println("masterval=",masterval)
println( sum( b[j]*λ[j] for j =1:length(b)) + sum( (d[j]-λD[j])*𝐲[j] for j = 1:length(d)))
return
end
expr+= sum( b[j]*λ[j] for j =1:length(b) )
for j in 1:length(d)
push!(expr,d[j]-λD[j],y[j])
end
push!(expr,-1.0,z)
else
println("please break")
end
println(expr)
@lazyconstraint(cb,expr<= 0)
println("The master problem to solve:")
print(PM)
end
addlazycallback(PM, cut)
solve(PM)
obj=getobjectivevalue(PM)
𝐲=getvalue(y)
end
b=[2,3]
D=[-1 3 ; 1 3]
A=[-1 2 ; 1 1]
c=[2,3]
d=[1,4]
obj,y,out,x=solvebenders(c,d,A,D,b)
It should finish with the solution \lambda=(0,0), x=(0,0), y=(0,1),z=4, but returns
WARNING: Not solved to optimality, status: Unbounded
WARNING: Unbounded ray not available
WARNING: Variable value not defined for component of y. Check that the model was properly solved.