This notebook offers tricks for diagnosing problems in the optimization and debugging them.
What do you do when the model solver returns with "Infeasible model"?
Consider using the findinfeasiblepair(house, solver)
tool. It will give you a range within the matrix for which the results become minimally infeasible. In other words, suppose that the full linear programming matrix is $A$. It returns $i$, $j$, such that $A[1:i, :]$ is infeasible, but $A[1:i-1, :]$ is not, and $A[j:end, :]$ is infeasible but $A[j+1:end, :]$ is not.
You can then investigate individual rows by calling house.A[row,:]
.
Note that the linear programming problem is always solved as follows: $$ \max_x f' x $$ s.t. $A x < b$ and $x > 0$.
To find out what is constraining these values, look down at the Understanding constraints section.
The entries in the $f$ vector correspond to a sequences of parameter values, those of the $b$ vector correspond to variable values, and the rows and columns of $A$ correspond to variables and parameters respectively.
To find out which parameter a particular column of $A$ or value in $f$ corresponds to, use
cumsum(varlengths(house.model, house.paramcomps, house.parameters))
which gives the last index of each paramter.
To find out which variable a particular row of $A$ or value in $b$ corresponds to, use
cumsum(varlengths(house.model, house.constcomps, house.constraints, house.constdictionary))
which gives the last index of each variable.
The constraining
function will identify which constraints limit the value of each parameter. It's results depend on the value of the parameter lying within $1e-6 p + 1e-6$ of its constraining wall, for parameter value $p$, so the function can miss the constraint for certain solution sets.
In the most recent version of OptiMimi, you can specify an optional subset
constraint, a vector of indices of parameters to investigate. This works well with findinfeasiblepair
, but keep in mind that findinfeasiblepair
returns indices of constraints while constraining
looks at parameters. So, you need to do the following steps.
findinfeasiblepair
returns a set of bounds $I$ to $J$, and you want to understand why $I$ fails. You can always replace $J$ below with length(house.b)
.house.A[I,:]
. Record the range of parameter indices to investigate as $A$ to $B$.sol = houseoptimize(house, solver, subset=[I:J-1])
to get a valid solution.constraining(house, sol.sol, subset=[A:B])
.[I+1:J]
.