Checking if the solver found a feasible solution or not

1,558 views
Skip to first unread message

carlo.b...@gmail.com

unread,
May 8, 2015, 10:01:53 AM5/8/15
to pyomo...@googlegroups.com
I am working on a MIP model and since the model is quite complex I have set a time limit to stop the solver after 10 minutes.
How can I check if the solver has been able to find a feasible solution within the assigned time?
I have tried to use solver.status, solution.status and solver.termination_condition, but in both cases these parameters assume the same values.

Thanks,

Carlo

Michael Bynum

unread,
May 9, 2015, 11:58:33 PM5/9/15
to pyomo...@googlegroups.com
Carlo,

I do not know the best answer to this, but it may help to print the solver output. This can be done by passing "tee=True" to the solve method. For example:

results = opt.solve(instance, tee = True)

I think most MIP/MILP solvers will show both the best lower bound (from relaxing the integer variables) and the incumbent solution objective. An incumbent solution is a feasible solution (I think it is actually the best feasible solution found so far), so if the solver shows an incumbent objective, then it has found a feasible solution.

Regarding the return values of solution.status, solver.status, etc., I do not know. I just ran a MIP with a time limit myself, and solution.status returned a value of 'optimal' even though the gap had not reached the tolerance criteria (although a warning is printed when the results are loaded). Maybe someone else can comment on this.

Thanks,
Michael Bynum

--
You received this message because you are subscribed to the Google Groups "Pyomo Forum" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pyomo-forum...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

carlo.b...@gmail.com

unread,
May 11, 2015, 6:38:51 AM5/11/15
to pyomo...@googlegroups.com
Thanks for your reply Michael.

I had already set the solver to print the output and I am actually able to see if the solution found by the solver within the time limit is optimal or not.
However, my problem is that I need to execute automatically some commands depending on the solver status. As I said, I have to distinguish the situations in which the solver find the optimal solution and in which the solver find a feasible, but not optimal, solution.
I could try to automatically extract some information from the output but I would like to avoid it. Do you know whether the results object has a member (something like results.solver.status, etc.) that returns the value of the optimality gap of the incumbent solution? That would probably fix my problem.

Thanks again,

Carlo

Carl Laird

unread,
May 11, 2015, 7:00:34 AM5/11/15
to pyomo...@googlegroups.com
Hi Carlo,

There is a blog post on pyomo.org that discusses this need. Here is a link.

carlo.b...@gmail.com

unread,
May 11, 2015, 8:33:58 AM5/11/15
to pyomo...@googlegroups.com
Thanks Carl, I already read that blog post, but unfortunately it does not answer my question. I try to explain it better. When I set a time limit to the solver, there are different possibilities:

1. The solver finds an optimal solution
       results.solver.status=ok
       results.solution.status=optimal
       results.solver.termination_condition=optimal

2. The solver finds a feasible, but not optimal solution
       results.solver.status=warning
       results.solution.status=stoppedByLimit
       results.solver.termination_condition=maxIterations

3. The solver does not find a feasible solution and it does not detect any infeasibility
       results.solver.status=warning
       results.solution.status=stoppedByLimit
       results.solver.termination_condition=maxIterations

4. The solver detects that the model is infeasible
       results.solver.status=warning
       results.solution.status=infeasible
       results.solver.termination_condition=infeasible

My problem is that I cannot distinguish between the situations of points 2 and 3. Each of the reported parameters, in fact, returns the same value in both the cases. 

Carl Laird

unread,
May 11, 2015, 8:54:18 AM5/11/15
to pyomo...@googlegroups.com
Hi Carlo,

I can send you some code to check the feasibility of the model within Pyomo. The code basically loops through all the constraints, evaluates them, and reports if any are infeasible (residual greater than a specified tolerance). Would that help?

The Pyomo team has been considering changes to the results object structure, and this would be something that may be addressed. However, I don’t think the timeline on that development is known at this point.

Regards,

Carl D. Laird
Associate Professor, School of Chemical Engineering, Purdue University
Ph: 765.494.0085


carlo.b...@gmail.com

unread,
May 11, 2015, 9:15:03 AM5/11/15
to pyomo...@googlegroups.com
Thanks again Carl, I think that it would be useful to check if the model is feasible or not, but I am afraid that it would not tell me if the solver has found a feasible solution within the time limit. I suppose that the only way will be to extract all the information I need from the solver output. With regard to this point, I would take the opportunity to ask you if you know how to print the solver output in a text file.

Thanks a lot for your help,

Carlo

Christopher Hagmann

unread,
May 11, 2015, 9:33:19 AM5/11/15
to pyomo...@googlegroups.com
I have a function that I call redirect that I made exactly for this purpose though there might be a built-in way to do it now that I am not aware of.

import sys
from contextlib import contextmanager


@contextmanager
def Redirect(filename, mode='w'):
    '''
    Redirect output from stdout and stderr to a file
    
    with Redirect('foo.txt', 'w'):
        print 'Hello'
        print 'World'
        
    would yield the same results as
    
    with open('foo.txt', 'w') as f:
        f.write('Hello' + \\n)
        f.write('World')
        
    Most useful when some function call prints to stdout and doesn't give the
    option to pipe to a file.
    
    def foo():
        print 'Hello World'
        
    with Redirect('foo.txt', 'w'):
        foo()
    '''
    old_stdout, old_stderr = sys.stdout, sys.stderr
    with open(filename, mode) as f:
        sys.stdout, sys.stderr = f, f
        yield
    sys.stdout, sys.stderr = old_stdout, old_stderr

 Now that the function is defined, you can use it like

with Redirect('temp.txt', 'w'):
results = opt.solve(instance, tee=True)

Another useful thing to print is the transformed results. This should contain the best feasible solution found if there was one.

transformed_results = instance.update_results(results)
with Redirect('transformed_results.txt', 'w'):
    transformed_results.write()


carlo.b...@gmail.com

unread,
May 11, 2015, 10:15:08 AM5/11/15
to pyomo...@googlegroups.com
Thanks a lot Christopher, it perfectly works!

Carl Laird

unread,
May 11, 2015, 10:29:17 AM5/11/15
to pyomo...@googlegroups.com
Sorry, Carlo, I should have been more clear. This code does NOT check if the model itself is feasible (that is indeed a difficult problem). It checks that the point returned by the solver is a feasible point.

The code I have does not require any file parsing, and it makes use of Pyomo objects to determine this. If you are happy with the code Chris sent you, then I won’t worry about it.


Regards,

Carl D. Laird
Associate Professor, School of Chemical Engineering, Purdue University
Ph: 765.494.0085



carlo.b...@gmail.com

unread,
May 12, 2015, 6:59:02 AM5/12/15
to pyomo...@googlegroups.com
Thanks Carl, that would be great. I was resigned to the fact I would have to parse the solver output. Your code would definitely help. I would be very grateful if you could send it to me.

Thanks again,

Carlo.

Thomas Frei

unread,
May 13, 2015, 9:45:11 AM5/13/15
to pyomo...@googlegroups.com
Hi Carl

I'm trying to find out the same things. Can you send me the code as well, please?

Thank you very much

giac...@gmail.com

unread,
Jan 23, 2017, 9:54:09 PM1/23/17
to Pyomo Forum
Hi all,
sorry to bring up this old thread. Is there a better way now to do what the original post asked, i.e., check if the model has an integer feasible solution when a limit (e.g. time limit) for the solver is hit?
Or do we still have to access the solution and check integrality and feasibility by hand?
It is a very common task, I have the impression that it might make sense to have an "official" way of doing that.

Thanks!

Giacomo
Message has been deleted

Garrett Dowdy

unread,
Jun 4, 2019, 9:15:27 PM6/4/19
to Pyomo Forum
Is there still no solution to this?

Andrea

unread,
Sep 16, 2022, 8:19:13 AM9/16/22
to Pyomo Forum
Do you know if now we have an official solution?
Thanks
AB

Michael Bynum

unread,
Sep 16, 2022, 10:23:51 AM9/16/22
to Pyomo Forum
If the solve method is called with load_solutions=False, then you should be able to check the length of solution object on the results object:

res = opt.solve(model, load_solutions=False)
if len(res.solution) > 0:
    print('found a feasible solution')
else:
    print('did not find a feasible solution')

Michael

Solver Max

unread,
Sep 18, 2022, 11:09:08 PM9/18/22
to Pyomo Forum
You can use the termination_condition property to check the solution status.
Reply all
Reply to author
Forward
0 new messages