# Is there any way to solve a containg Binvary variables Nonconvex problem?

Hi there,

I’m solving a Nonconvex problem, and the nonconvex terms are:

@constraint(gNet, gasPipeFlow[pipeline, time]^2 == ETA*(gasNodePres[AheadNode, time]^2 - gasNodePres[TailNode, time]^2))

gasPipeFlow and gasNodePres are continuous variables, the nonconvex problem can be solved by Gurobi and KNITRO, while when I add some BINARY variables to the model, the problem can be solved by Gurobi as a MIP (Actually a Mixed Integer(MI) Nonconvex problem), while KNITRO cannot solve it, thus, I think the above-mentioned nonconvex terms make the problem unfeasible to solve by KNITRO (In fact, I doubt the solution of Gurobi). So, is there any way to solve the MI Nonconvex problem? Or is there any way to linearize the nonconvex terms?

1 Like

The continuous variables are all nonnegative, by the way.

I assume the variables are `gasPipeFlow` and `gasNodePres`, and the rest are constants? What are the binary variables?

What does KNITRO report?
Why do you doubt the solution of Gurobi?

It’s hard to offer advice without a reproducible example of the model.

there are other nonnegative continuous variables, and I use the binary variables in the following constraints.

@constraint(gNet, [time in 1:SCHTIME],
gasPowerInj[time] == GHV*(gasPipeFlow[1, time] + gasNodeCom[1, time] + gasNodeLoad[1, time] + gasStoreTurnOn[time]*gasStoreMount[time] - gasReleaseTurnOn[time]*gasReleaseMount[time])/Kappa)

@constraint(gNet, [time in 2:SCHTIME],
gasSOC[time] == gasSOC[time - 1] + gasStoreTurnOn[time - 1]*gasStoreMount[time - 1] - gasReleaseTurnOn[time - 1]*gasReleaseMount[time - 1])

@constraint(gNet, [time in 1:SCHTIME],
gasStoreTurnOn[time] + gasReleaseTurnOn[time] <= 1)

It’s a typical gas storage model, gasReleaseTurnOn and gasStoreTurnOn are binary variables, and gasReleaseMount and gasStoreMount are continuous variables (>= 0). When I solve it by Gurobi (NonConvex = 2), it gives me a solution, while KNITRO and Lindoapi (GitHub - lindosystems/lindoapi.jl: The Julia Interface to LINDO API.) show that the problem is infeasible (Without the binary variables, which means without the gas storage, only gas transmission, the problem can be solved for all the solvers).

With the binary variables, solved by KNITRO, it gives the problem is infeasible without any error log, alternatively, solved by Lindoapi. it gives me the following log.

termination_status(gNet) = MathOptInterface.LOCALLY_INFEASIBLE
ERROR: Lindo API Error ==> Requested information is not available.
Stacktrace:
[1] error(s::String)
@ Base .\error.jl:35
[2] _check_ret(model::Lindoapi.Optimizer, ret::Int32)
@ Lindoapi D:\Julia-1.8.2\juliaPKG\packages\Lindoapi\Eb7IH\src\MOI\MOI_wrapper.jl:586
[3] get
@ D:\Julia-1.8.2\juliaPKG\packages\Lindoapi\Eb7IH\src\MOI\MOI_wrapper.jl:916 [inlined]
[4] get(b::MathOptInterface.Bridges.LazyBridgeOptimizer{Lindoapi.Optimizer}, attr::MathOptInterface.ObjectiveValue)
@ MathOptInterface.Bridges D:\Julia-1.8.2\juliaPKG\packages\MathOptInterface\NCblk\src\Bridges\bridge_optimizer.jl:1002
[5] _get_model_attribute(model::MathOptInterface.Utilities.CachingOptimizer{MathOptInterface.Bridges.LazyBridgeOptimizer{Lindoapi.Optimizer}, MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}, attr::MathOptInterface.ObjectiveValue)
@ MathOptInterface.Utilities D:\Julia-1.8.2\juliaPKG\packages\MathOptInterface\NCblk\src\Utilities\cachingoptimizer.jl:828
[6] get
@ D:\Julia-1.8.2\juliaPKG\packages\MathOptInterface\NCblk\src\Utilities\cachingoptimizer.jl:876 [inlined]
[7] _moi_get_result(model::MathOptInterface.Utilities.CachingOptimizer{MathOptInterface.Bridges.LazyBridgeOptimizer{Lindoapi.Optimizer}, MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}, args::MathOptInterface.ObjectiveValue)
@ JuMP D:\Julia-1.8.2\juliaPKG\packages\JuMP\7XtRG\src\optimizer_interface.jl:680
[8] get(model::Model, attr::MathOptInterface.ObjectiveValue)
@ JuMP D:\Julia-1.8.2\juliaPKG\packages\JuMP\7XtRG\src\optimizer_interface.jl:700
[9] objective_value(model::Model; result::Int64)
@ JuMP D:\Julia-1.8.2\juliaPKG\packages\JuMP\7XtRG\src\objective.jl:54
[10] objective_value(model::Model)
@ JuMP D:\Julia-1.8.2\juliaPKG\packages\JuMP\7XtRG\src\objective.jl:50
[11] top-level scope
@ e:\workspace\Julia\gas network gurobi.jl:145

In sum, I guess that the nonconvex terms make the problem hard or infeasible to solve, and I want to get help, thank you.

show that the problem is infeasible
MathOptInterface.LOCALLY_INFEASIBLE

These two things are not quite the same. See Debugging · JuMP

Nonlinear optimizers such as Ipopt may return the status `LOCALLY_INFEASIBLE` . This does not mean that the solver proved no feasible solution exists, only that it could not find one. If you know a primal feasible point, try providing it as a starting point using `set_start_value` and re-optimize.

If Gurobi gives you a solution, I’d use that. You could also try solving using KNITRO from the solution identified by Gurobi?

I transfer the value of binary variables identified by Gurobi to my model, the model is tested infeasible by Gurobi, KNITRO, and Lindoapi. Maybe my model has problems, but actually it (the model without binary variables identified by Gurobi) can be solved by Gurobi with binary variables. How strange.

By replacing @constraint() with @NLconstraint() where nonconvex terms are, the model can be solved by Lindoapi, the solution is the same as the one obtained from Gurobi, while KNITRO fails and report the model is infeasible.