Hi
I have a model and when of model’s constraints is corresponding to cycles in the graph, so I am trying to add these cycle constraints as lazy constraints within the callback, so in each iteration, I am solving the model search for cycle and adding a lazy constraint as you can see in the code below :
using JuMP
using Gurobi
using Random
#using Test
initial = 0
n = 61
s = 62
E = [(8, 3), (36, 20), (50, 20), (3, 14), (14, 38), (24, 51), (9, 62), (37, 62),
(9, 5), (36, 23), (50, 33), (0, 15), (16, 38), (29, 51), (62, 9), (62, 37),
(9, 6), (37, 8), (50, 42), (14, 16), (20, 38), (45, 51), (10, 62), (38, 62),
(10, 0), (37, 14), (50, 45), (1, 17), (33, 38), (50, 51), (62, 10), (62, 38),
(10, 2), (37, 16), (51, 4), (6, 17), (36, 39), (14, 52), (11, 62), (39, 62),
(13, 5), (37, 21), (51, 11), (9, 17), (0, 40), (29, 52), (62, 11), (62, 39),
(13, 6), (37, 33), (51, 18), (13, 17), (7, 40), (38, 52), (12, 62), (40, 62),
(13, 9), (37, 34), (51, 21), (15, 18), (14, 40), (40, 52), (62, 12), (62, 40),
(14, 0), (37, 36), (51, 23), (1, 19), (15, 40), (43, 53), (13, 62), (41, 62),
(14, 3), (38, 14), (51, 24), (7, 19), (33, 40), (1, 54), (62, 13), (62, 41),
(15, 0), (38, 16), (51, 29), (8, 20), (36, 40), (6, 54), (14, 62), (42, 62),
(16, 14), (38, 20), (51, 45), (16, 20), (37, 40), (7, 54), (62, 14), (62, 42),
(17, 1), (38, 33), (51, 50), (18, 20), (1, 41), (13, 54), (15, 62), (43, 62),
(17, 6), (39, 36), (52, 14), (18, 21), (9, 41), (19, 54), (62, 15), (62, 43),
(17, 9), (40, 0), (52, 29), (17, 22), (13, 41), (41, 54), (16, 62), (44, 62),
(17, 13), (40, 7), (52, 38), (14, 24), (0, 42), (15, 55), (62, 16), (62, 44),
(18, 15), (40, 14), (52, 40), (15, 24), (2, 42), (51, 55), (17, 62), (45, 62),
(19, 1), (40, 15), (53, 43), (18, 24), (10, 42), (5, 56), (62, 17), (62, 45),
(19, 7), (40, 33), (54, 1), (17, 25), (30, 42), (6, 56), (18, 62), (46, 62),
(20, 8), (40, 36), (54, 6), (1, 26), (14, 43), (5, 57), (62, 18), (62, 46),
(20, 16), (40, 37), (54, 7), (25, 26), (29, 43), (6, 57), (19, 62), (47, 62),
(20, 18), (41, 1), (54, 13), (1, 27), (33, 43), (9, 57), (62, 19), (62, 47),
(21, 18), (41, 9), (54, 19), (7, 27), (37, 43), (13, 57), (20, 62), (48, 62),
(22, 17), (41, 13), (54, 41), (17, 27), (38, 43), (17, 57), (62, 20), (62, 48),
(24, 14), (42, 0), (55, 15), (25, 27), (2, 44), (39, 57), (21, 62), (49, 62),
(24, 15), (42, 2), (55, 51), (26, 27), (20, 44), (41, 57), (62, 21), (62, 49),
(24, 18), (42, 10), (56, 5), (1, 28), (34, 44), (48, 57), (22, 62), (50, 62),
(25, 17), (42, 30), (56, 6), (8, 28), (38, 44), (54, 57), (62, 22), (62, 50),
(26, 1), (43, 14), (57, 5), (20, 28), (8, 45), (38, 58), (23, 62), (51, 62),
(26, 25), (43, 29), (57, 6), (10, 29), (15, 45), (3, 59), (62, 23), (62, 51),
(27, 1), (43, 33), (57, 9), (18, 29), (18, 45), (8, 59), (24, 62), (52, 62),
(27, 7), (43, 37), (57, 13), (21, 29), (21, 45), (15, 59), (62, 24), (62, 52),
(27, 17), (43, 38), (57, 17), (24, 29), (23, 45), (36, 59), (25, 62), (53, 62),
(27, 25), (44, 2), (57, 39), (7, 30), (24, 45), (45, 59), (62, 25), (62, 53),
(27, 26), (44, 20), (57, 41), (19, 30), (29, 45), (32, 60), (26, 62), (54, 62),
(28, 1), (44, 34), (57, 48), (28, 30), (37, 45), (2, 61), (62, 26), (62, 54),
(28, 8), (44, 38), (57, 54), (17, 31), (43, 46), (37, 61), (27, 62), (55, 62),
(28, 20), (45, 8), (58, 38), (9, 32), (0, 47), (53, 61), (62, 27), (62, 55),
(29, 10), (45, 15), (59, 3), (13, 32), (10, 47), (0, 62), (28, 62), (56, 62),
(29, 18), (45, 18), (59, 8), (12, 33), (20, 47), (62, 0), (62, 28), (62, 56),
(29, 21), (45, 21), (59, 15), (14, 33), (28, 47), (1, 62), (29, 62), (57, 62),
(29, 24), (45, 23), (59, 36), (16, 33), (30, 47), (62, 1), (62, 29), (62, 57),
(30, 7), (45, 24), (59, 45), (21, 33), (42, 47), (2, 62), (30, 62), (58, 62),
(30, 19), (45, 29), (60, 32), (14, 34), (34, 49), (62, 2), (62, 30), (62, 58),
(30, 28), (45, 37), (61, 2), (33, 34), (46, 49), (3, 62), (31, 62), (59, 62),
(31, 17), (46, 43), (61, 37), (29, 35), (14, 50), (62, 3), (62, 31), (62, 59),
(32, 9), (47, 0), (61, 53), (1, 36), (16, 50), (4, 62), (32, 62), (60, 62),
(32, 13), (47, 10), (3, 8), (20, 36), (20, 50), (62, 4), (62, 32), (62, 60),
(33, 12), (47, 20), (5, 9), (23, 36), (33, 50), (5, 62), (33, 62), (61, 62),
(33, 14), (47, 28), (6, 9), (8, 37), (42, 50), (62, 5), (62, 33), (62, 61),
(33, 16), (47, 30), (0, 10), (14, 37), (45, 50), (6, 62), (34, 62),
(33, 21), (47, 42), (2, 10), (16, 37), (4, 51), (62, 6), (62, 34),
(34, 14), (49, 34), (5, 13), (21, 37), (11, 51), (7, 62), (35, 62),
(34, 33), (49, 46), (6, 13), (33, 37), (18, 51), (62, 7), (62, 35),
(35, 29), (50, 14), (9, 13), (34, 37), (21, 51), (8, 62), (36, 62),
(36, 1), (50, 16), (0, 14), (36, 37), (23, 51), (62, 8), (62, 36)]
#####################################################
function example_lazy_constraint()
cec_model = direct_model(Gurobi.Optimizer())
set_optimizer_attribute(cec_model, "Threads", 1)
#set_optimizer_attribute(cec_model, "presolve", 0)
#################################################
@variable(cec_model,x[E],binary = true)
@variable(cec_model, y[v=initial:n],binary = true) # Bogi: y_s is not needed
####################################################
for i = initial:n
@constraint(cec_model,sum(x[(i,j)] for j in initial:s if (i,j) in E)
+sum(x[(j,i)] for j in initial:s if (j,i) in E) == 2*y[i])
end
@constraint(cec_model,sum(x[(s,i)] for i=initial:n) == 2)
for i = initial:n
for j=initial:s
if (i,j) in E
@constraint(cec_model,x[(i,j)] <= y[i])
end
if (j,i) in E
@constraint(cec_model,x[(j,i)] <= y[i])
end
end
end
for (i,j) in E
if i !=s && j!=s
@constraint(cec_model,x[(i,j)] >= y[i]+y[j]-1)
end
end
################################################
@objective(cec_model, Max, sum(y[i] for i in initial:n))
cb_calls = Cint[]
################################################
function my_callback_function(cb_data,cb_where::Cint)
# You can reference variables outside the function as normal
push!(cb_calls, cb_where)
# You can select where the callback is run
if cb_where != GRB_CB_MIPSOL && cb_where != GRB_CB_MIPNODE
return # exit
end
##########################################################
subtours = 0
current = 0
nextv = 0
newsubtours = 0
T = []
Next = []
termination = 0
prev = 0
temp = 0
while termination == 0
optimize!(cec_model)
#Before querying `callback_value`, you must call:
Gurobi.load_callback_variable_primal(cb_data, cb_where)
for a in initial:s
if callback_value(cb_data, y[a]) > 0
append!(T, a)
end
end
T=unique(T)
newsubtours = 0
while length(T) != 0
nextv = rand(T)
subtours += 1
W = []
current = nextv
#Before querying `callback_value`, you must call:
nodes=findall(b -> ((current,b) in E), T)
append!(Next,nodes)
Next = unique(Next)
prev = first(Next)
while current != nextv
append!(W,current)
posnex = findall(c -> ((current,c) in E) && (c != prev), T)
posnex=unique(posnex)
temp = rand(posnex)
prev = current
current = temp
end
W = unique(W)
T = setdiff(T,W)
if s in W
W= []
subtours = subtours-1
else
newsubtours = newsubtours+1
end
if length(W) != 0
con = @build_constraint(sum(y[node] for node in W) <= length(W)-1)
MOI.submit(cec_model, MOI.LazyConstraint(cb_data), con)
end
end
if newsubtours == 0
termination=1
end
end
end
# You _must_ set this parameter if using lazy constraints.
MOI.set(cec_model, MOI.RawParameter("LazyConstraints"), 1)
MOI.set(cec_model, Gurobi.CallbackFunction(), my_callback_function)
optimize!(cec_model)
end
example_lazy_constraint()
The code is working but going to infinity with really considering the part to add the last constraint !!