forked from jump-dev/JuMP.jl
-
Notifications
You must be signed in to change notification settings - Fork 0
/
simplelazy2.jl
90 lines (76 loc) · 2.76 KB
/
simplelazy2.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# Copyright 2015, Iain Dunning, Joey Huchette, Miles Lubin, and contributors
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#############################################################################
# JuMP
# An algebraic modelling langauge for Julia
# See http://github.com/JuliaOpt/JuMP.jl
#############################################################################
# simplelazy2.jl
#
# Builds on the simplelazy example by demonstrating how the logic of
# determing a new constraint can be seperated from the logic of the callback
# handler itself.
#############################################################################
using JuMP
using Gurobi
using Base.Test
function cornerChecker(x_val, y_val)
# This function does not depend on the model, and could
# be written anywhere. Instead, it returns a tuple of
# values (newcut, x_coeff, y_coeff, rhs) where newcut is a
# boolean if a cut is needed, x_coeff is the coefficient
# on the x variable, y_coeff is the coefficient on
# the y variable, and rhs is the right hand side
TOL = 1e-6
if y_val - x_val > 1 + TOL
return (true, -1.0, 1.0, 1.0) # Top left
elseif y_val + x_val > 3 + TOL
return (true, 1.0, 1.0, 3.0) # Top right
else
return (false, 0.0, 0.0, 0.0) # No cut
end
end
# A unit test for the cornerChecker function
function test_cornerChecker()
# Test the four corners - only two should produce cuts
newcut, x_coeff, y_coeff, rhs = cornerChecker(0, 0)
@test !newcut
newcut, x_coeff, y_coeff, rhs = cornerChecker(2, 0)
@test !newcut
newcut, x_coeff, y_coeff, rhs = cornerChecker(0, 2)
@test newcut
@test x_coeff == -1.0
@test y_coeff == 1.0
@test rhs == 1.0
newcut, x_coeff, y_coeff, rhs = cornerChecker(2, 2)
@test newcut
@test x_coeff == 1.0
@test y_coeff == 1.0
@test rhs == 3.0
end
function solveProblem()
m = Model(solver=GurobiSolver())
@defVar(m, 0 <= x <= 2, Int)
@defVar(m, 0 <= y <= 2, Int)
@setObjective(m, Max, y)
# Note that the callback is now a stub that passes off
# the work to the "algorithm"
function corners(cb)
x_val = getValue(x)
y_val = getValue(y)
println("In callback function, x=$x_val, y=$y_val")
newcut, x_coeff, y_coeff, rhs = cornerChecker(x_val, y_val)
if newcut
@addLazyConstraint(cb, x_coeff*x + y_coeff*y <= rhs)
end
end # End of callback function
addLazyCallback(m, corners)
solve(m)
println("Final solution: [ $(getValue(x)), $(getValue(y)) ]")
end
# Run tests
test_cornerChecker()
# Solve it
solveProblem()