Warm starting Xpress with a full basis using JuMP

Dear all,

I have tried setting initial values/duals of similar problems in JuMP/Xpress for LP problems but we have not been very successful for LP, for MIP we have been though.

I was wondering whether Xpress.writebasis and Xpress.readbasisfrom Xpress would be of any help. What I see, however, is that these functions are only available when the model is built directly from Xpress.jl without JuMP.

Is there a way of using these Xpress.jl functions in a problem built using JuMP?

Thank you!

Not easily.

But if you use direct_model, Models · JuMP, then backend(model) is the Xpress optimizer, on which you can use the Xpress C API calls.

Some guidance would be ultra useful here, I have honestly tried everything regarding set_start_value but unluckily have not had any success, even loading the values generated by the same exact model does not lead to any savings in time with Xpress…

It seems that what is needed is the Xpress problem and not the Xpress Optimizer object, see:

int XPRS_CC XPRSwritebasis (XPRSprob prob, const char *_sfilename, const char *_sflags);

I have tried using direct_model on a small reproducible example, but it seems I am stuck in the same place as before, how would you read and write a basis using a model created with direct_model?

Thanks


using JuMP
using Xpress

model = direct_model(Xpress.Optimizer());

@variable(model, x[1:2]);
@constraint(model, x[1] + x[2] <= 2)
@variable(model, FO >= 0)
@constraint(model, objfun, FO == 2 * x[1] + x[2] )
@objective(model, Min, FO)

optimize!(model)

Xpress.writebasis(backend(model),“basis.bas”, “”)

I don’t have Xpress installed, so I can’t test, but you probably need something like this:

using JuMP
using Xpress
model = direct_model(Xpress.Optimizer());
@variable(model, x[1:2]);
@constraint(model, x[1] + x[2] <= 2)
@variable(model, FO >= 0)
@constraint(model, objfun, FO == 2 * x[1] + x[2] )
@objective(model, Min, FO)
optimize!(model)
b = backend(model)
Xpress.writebasis(b.inner, "basis.bas", "")

Using the C API of the solver is largely undocumented and requires advanced knowledge of the C APIs. (It’s also too easy to make a mistake when using them, see, e.g., https://discourse.julialang.org/t/slow-model-construction-in-jump/95455.)

Your best bet is reading the source code to see how the MOI wrapper calls things: Xpress.jl/src/MOI at master · jump-dev/Xpress.jl · GitHub.

The internal Xpress C wrapper is also a bit rough. Work is currently underway to improve things: use Lib. directly by joaquimg · Pull Request #194 · jump-dev/Xpress.jl · GitHub.

Thank you,

with what you shared I have been able to create and read a basis from disk. However, I have been unable to properly load it as (it seems) the basis is stored without providing a name so it is unable to locate in the model the columns stored, see:

    ?131 Warning: No column: C1
    ?131 Warning: No column: C2
    ?131 Warning: No column: C3

How should I overcome this limitation?

Thank you

D


using JuMP
using Xpress

function create_optimization_problem()
model = direct_model(Xpress.Optimizer());
@variable(model, x >= 0, Int)
@variable(model, y >= 0, Int)
@variable(model, FO >= 0)
@constraint(model, c1, 10x + 20y <= 220 )
@constraint(model, c2, 11x + 19y <= 220 )
@constraint(model, c3, 12x + 18y <= 220 )
@constraint(model, c4, 13x + 17y <= 220 )
@constraint(model, c5, 14x + 16y <= 220 )
@constraint(model, c6, 15x + 15y <= 220 )
@constraint(model, c7, 16x + 14y <= 220 )
@constraint(model, c8, 17x + 13y <= 220 )
@constraint(model, c9, 18x + 12y <= 220 )
@constraint(model, c10, 19x + 11y <= 220 )
@constraint(model, c11, 20x + 10y <= 220 )
@constraint(model, c12, FO == x + y )
@objective(model, Max, FO)
return model
end

model = create_optimization_problem()

@time optimize!(model)

Xpress.writebasis(backend(model).inner, “basis.bas”, “”)

model = create_optimization_problem()

Xpress.readbasis(backend(model).inner, “basis.bas”, “”)

@time optimize!(model)

The issue seems to be related with the lack of proving the variable and constraint names to Xpress, I have tried with set_optimizer_attributes(model, “LOADNAMES” => true) but this function does not seem to be available.

The low-level C APIs for each solver are accessible, but (by design) they aren’t set up so things work smoothly.

I don’t know the details, but it seems like Xpress.jl currently doesn’t pass the names to the inner model: add variable and constraint name by viniciusjusten · Pull Request #193 · jump-dev/Xpress.jl · GitHub.

So if you want this, you’ll likely need to manually call other C API methods.