40
40
using JuMP
41
41
import HiGHS
42
42
43
- # ## General rules for debugging
43
+ # ## Debugging Julia code
44
44
45
+ # Read the [Debugging chapter](https://benlauwens.github.io/ThinkJulia.jl/latest/book.html#chap21)
46
+ # in the book [ThinkJulia.jl](https://benlauwens.github.io/ThinkJulia.jl/latest/book.html).
47
+ # It has a number of great tips and tricks for debugging Julia code.
48
+
49
+ # ## Debugging an infeasible model
50
+
51
+ # A model is infeasible if there is no primal solution that satisfies all of
52
+ # the constraints. In general, an infeasible model means one of two things:
45
53
#
54
+ # * Your problem really has no feasible solution
55
+ # * There is a mistake in your model.
46
56
47
- # Before all else, read the [Debugging chapter](https://benlauwens.github.io/ThinkJulia.jl/latest/book.html#chap21)
48
- # in the book [ThinkJulia.jl](https://benlauwens.github.io/ThinkJulia.jl/latest/book.html).
57
+ # A simple example of an infeasible model is:
58
+
59
+ model = Model (HiGHS. Optimizer)
60
+ set_silent (model)
61
+ @variable (model, x >= 0 )
62
+ @objective (model, Max, 2 x + 1 )
63
+ @constraint (model, 2 x - 1 <= - 2 )
64
+
65
+ # because the bound says that `x >= 0`, but we can rewrite the constraint to be
66
+ # `x <= -1/2`. When the problem is infeasible, JuMP may return one of a number
67
+ # of statuses. The most common is `INFEASIBLE`:
49
68
69
+ optimize! (model)
70
+ termination_status (model)
71
+
72
+ # Depending on the solver, you may also receive `INFEASIBLE_OR_UNBOUNDED` or
73
+ # `LOCALLY_INFEASIBLE`.
74
+
75
+ # A termination status of `INFEASIBLE_OR_UNBOUNDED` means that the solver could
76
+ # not prove if the solver was infeasible or unbounded, only that the model does
77
+ # not have a finite feasible optimal solution.
78
+
79
+ # Nonlinear optimizers such as Ipopt may return the status `LOCALLY_INFEASIBLE`.
80
+ # This does not mean that the solver _proved_ no feasible solution exists, only
81
+ # that it could not find one. If you know a primal feasible point, try providing
82
+ # it as a starting point using [`set_start_value`](@ref) and re-optimize.
83
+
84
+ # Common sources of infeasibility are:
50
85
#
86
+ # * Invalid mathematical formulations
87
+ # * Incorrect units, for example, using a lower bound of megawatts and an upper
88
+ # bound of kilowatts
89
+ # * Using `+` instead of `-` in a constraint
90
+ # * Off-by-one and related errors, for example, using `x[t]` instead of
91
+ # `x[t-1]` in part of a constraint.
51
92
52
- # * Simplify the problem
93
+ # The simplest way to debug sources of innfeasibility is to iteratively comment
94
+ # out a constraint (or block of constraints) and resolve the problem. When you
95
+ # find a constraint that makes the problem infeasible when added, check the
96
+ # constraint carefully for errors.
53
97
54
- # ## Debugging an infeasible model
98
+ # If the problem is still infeasible with all constraints commented out, check
99
+ # all variable bounds. Do they use the right data?
100
+
101
+ # !!! tip
102
+ # Some solvers also have specialized support for debugging sources of
103
+ # infeasibility via an [irreducible infeasible subsystem](@ref Conflicts).
104
+ # To see if your solver has support, try calling [`compute_conflict!`](@ref):
105
+ # ```julia
106
+ # julia> compute_conflict!(model)
107
+ # ERROR: ArgumentError: The optimizer HiGHS.Optimizer does not support `compute_conflict!`
108
+ # ```
109
+ # In this case, HiGHS does not support computign conflicts, but other
110
+ # solvers such as Gurobi and CPLEX do. If the solver does support computing
111
+ # conflicts, read [Conflicts](@ref) for more details.
55
112
56
113
# ## Debugging an unbounded model
57
114
@@ -70,12 +127,15 @@ set_silent(model)
70
127
# because we can increase `x` without limit, and the objective value `2x + 1`
71
128
# gets better as `x` increases.
72
129
73
- # JuMP doesn't have an `UNBOUNDED` termination status. Instead, unbounded models
74
- # will return `DUAL_INFEASIBLE`:
130
+ # When the problem is unbounded, JuMP may return one of a number of statuses.
131
+ # The most common is `DUAL_INFEASIBLE`:
75
132
76
133
optimize! (model)
77
134
termination_status (model)
78
135
136
+ # Depending on the solver, you may also receive `INFEASIBLE_OR_UNBOUNDED` or
137
+ # an error code like `NORM_LIMIT`.
138
+
79
139
# Common sources of unboundedness are:
80
140
#
81
141
# * Using `Max` instead of `Min`
@@ -112,3 +172,13 @@ set_silent(model)
112
172
113
173
# This new model has a finite optimal solution, so we can solve it and then look
114
174
# for variables with large positive or negative values in the optimal solution.
175
+
176
+ optimize! (model)
177
+ for var in all_variables (model)
178
+ if var == objective
179
+ continue
180
+ end
181
+ if abs (value (var)) > 1e3
182
+ println (" Variable `$(name (var)) ` may be unbounded" )
183
+ end
184
+ end
0 commit comments