Skip to content

LinExpr.add_var / LinExpr.add_expr / LinExpr.add_term are way too slow #163

@jachymb

Description

@jachymb

Consider the following function. It generates and solves a model structurally somewhat similar to a practical problem I am solving. (I tried to simplify it as much as possible)

def experiment_mip(n):
    start = time.time()

    model = mip.Model(sense=mip.MAXIMIZE, solver_name=mip.CBC)
    obj = []
    for i in range(n):
        var = model.add_var(f"var_{i}", lb=0.5, ub=1.0)
        a = random.random()  - 0.5  # Just a dummy value for illustration
        obj.append(var * a)
        constraint = mip.xsum(obj) <= 1.0
        model.add_constr(constraint, f"constraint_{i}")
    model.objective = mip.xsum(obj)

    construction_time = time.time() - start
    start = time.time()

    model.optimize()

    solution_time = time.time() - start
    return {"Model construction time": construction_time, "Solution time": solution_time}

Now, try running this for example for n=4000. The solution is much faster than the construction of the model. My measurements suggest that the solution time is asymptotically O(n^2) complexity but the construction is more than O(n^3). The profiler shows that that most time is spent in the LinExpr.add_var, LinExpr.add_expr and LinExpr.add_term functions. I think this is not acceptable and it should never take more time to construct than to solve a nontrivial problem.

I am not sure what the solution could be.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions