Can I provide a solver in Google’s ortools package with a BFS to start?

I’m solving a very large LP — one which doesn’t have 0 as a Basic feasible solution (BFS). I’m wondering if by passing the solver a basic feasible solution, I can speed up the process. Looking for something along the lines of: solver.setBasicFeasibleSolution(). I’ll formulate a toy instance below (with a lot fewer constraints) and show you what I mean.

from ortools.linear_solver import pywraplp


def main():  
    # Instantiate solver
    solver = pywraplp.Solver('Toy',
                       pywraplp.Solver.GLOP_LINEAR_PROGRAMMING)

    # Variables
    x = solver.NumVar(-1, solver.infinity(), 'x')
    y = solver.NumVar(-1, solver.infinity(), 'y')
    z = solver.NumVar(-1, solver.infinity(), 'z')

    # Constraint 1: x + y >= 10.
    constraint1 = solver.Constraint(10, solver.infinity())
    constraint1.SetCoefficient(x, 1)
    constraint1.SetCoefficient(y, 1)

    # Constraint 2: x + z >= 5.
    constraint2 = solver.Constraint(5, solver.infinity())
    constraint2.SetCoefficient(x, 1)
    constraint2.SetCoefficient(z, 1)

    # Constraint 3: y + z >= 15.
    constraint2 = solver.Constraint(15, solver.infinity())
    constraint2.SetCoefficient(y, 1)
    constraint2.SetCoefficient(z, 1)

    # Objective function: min 2x + 3y + 4z.
    objective = solver.Objective()
    objective.SetCoefficient(x, 2)
    objective.SetCoefficient(y, 3)
    objective.SetCoefficient(z, 4)
    objective.SetMinimization()

    # What I want:
    """
    solver.setBasicFeasibleSolution({x: 10, y: 5, z: 15})
    """

    solver.Solve()

    [print val.solution_value() for val in [x, y, z]]

Hoping something like this will speed things up (in case the solver has to use two phase simplex to find an initial BFS or the big M method).

Also, if anyone can point me to python API docs — not Google provided examples — that would be really helpful. Looking to understand what objects are available in ortools’ solvers, what their methods are, and what their return values and patterns are. Sort of like the C++ docs.

Of course, other resources are also welcomed.

Answer

Crawling the docs, this seems to be the API-docs for the C++-based solver and swig-based python-binding is mentioned.

Within this, you will find MPSolver with this:

SetStartingLpBasis

Return type: void

Arguments: const std::vector& variable_statuses, const std::vector& constraint_statuses

Advanced usage: Incrementality. This function takes a starting basis to be used in the next LP Solve() call. The statuses of a current solution can be retrieved via the basis_status() function of a MPVariable or a MPConstraint. WARNING: With Glop, you should disable presolve when using this because this information will not be modified in sync with the presolve and will likely not mean much on the presolved problem.

The warning somewhat makes me wonder if this will work out for you (in terms of saving time).

If you don’t have a good reason to stick with GLOP (looks interesting!), use CoinORs Clp (depressing state of docs; but imho the best open-source LP-solver including some interesting crashing-procedures)! I think it’s even interfaced within ortools. (Mittelmann Benchmarks, where it’s even beating CPLEX. But in regards to a scientific-eval it only shows that it’s very competetive!)

Or if it’s very large and you don’t need Simplex-like solutions, go for an Interior-point method (Clp has one; no info about quality).

Leave a Reply

Your email address will not be published. Required fields are marked *