# Gather Optimal Tableau Information using CPLEX.jl

**URL:** <https://discourse.julialang.org/t/gather-optimal-tableau-information-using-cplex-jl/101331>\
**Category:** Optimization (Mathematical)\
**Tags:** question, jump, optimization\
**Created:** [July 7, 2023, 8:56pm UTC](https://discourse.julialang.org/t/gather-optimal-tableau-information-using-cplex-jl/101331 "2023-07-07T20:56:12Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![afazevedo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/afazevedo/32/16394_2.png) [@afazevedo](https://discourse.julialang.org/u/afazevedo)\
**Post date:** [July 7, 2023, 8:56pm UTC](https://discourse.julialang.org/t/gather-optimal-tableau-information-using-cplex-jl/101331/1 "2023-07-07T20:56:12Z")

</div>

Hey! I’m currently working on implementing fractional Gomory cuts, and I need to know the optimal simplex tableau in order to obtain these constraints.

In this post on [Simplex tableau](https://discourse.julialang.org/t/simplex-tableau/6652), they suggested using `ccall` and mentioned the following code: `ccall((:CPXbinvarow,CPLEX.libcplex),Cint,(Ptr{Void},Ptr{Void},Cint,Ptr{Cdouble}),ci.env.ptr, ci.lp, j,row)`

I tried using this code, but the row results are only 1 or 0.

To better understand the result, I started with a small problem. Here’s the code:

```julia
# Create a model with the CPLEX solver

model = Model(CPLEX.Optimizer)

# Define variables as continuous (for the linear relaxation)

@variable(model, x1 >= 0)

@variable(model, x2 >= 0)

# Define constraints

@constraint(model, x1 + x2 <= 7)

@constraint(model, 2*x1 <= 11)

@constraint(model, 2*x2 <= 7)

# Define the objective function

@objective(model, Max, x1 + 2*x2)

```

I attempted to retrieve the tableau like this:

```julia
# Solve the model
optimize!(model)

# Retrieve the number of constraints
num_const = MOI.get(model, MOI.NumberOfConstraints{MOI.ScalarAffineFunction{Float64}, MOI.LessThan{Float64}}())

# Retrieve the number of variables plus slack variables
num_vars = MOI.get(model, MOI.NumberOfVariables()) + num_const

# Initialize the tableau
tableau = zeros(num_const, num_vars)

for j in 0:num_const-1
    tableau[j+1,:] = getrow(j, model)
end

```

The `getrow` function is defined as follows:

```julia
function getrow(j, model)
    ci = backend(model).optimizer.model
    num_vars = MOI.get(model, MOI.NumberOfVariables()) + MOI.get(model, MOI.NumberOfConstraints{MOI.ScalarAffineFunction{Float64}, MOI.LessThan{Float64}}())
    row = zeros(num_vars)
    status = ccall((:CPXbinvarow, CPLEX.libcplex), Cint, 
                   (Ptr{Nothing}, Ptr{Nothing}, Cint, Ptr{Cdouble}), 
                   ci.env.ptr, ci.lp, j, row)
    if status != 0
        error("CPXbinvarow failed, return code $status.")
    end
    return row
end

```

In a video I watched, I learned that the optimal tableau should look like this:

 ![image](https://global.discourse-cdn.com/julialang/original/3X/1/c/1c9af1810d3f6873117d94f0ee8e7527aa2bc157.jpeg)

Can you please help me with this?

---

<div class="post-metadata">

**Author:** ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)\
**Post date:** [July 7, 2023, 9:54pm UTC](https://discourse.julialang.org/t/gather-optimal-tableau-information-using-cplex-jl/101331/2 "2023-07-07T21:54:45Z")

</div>

Did you want `CPXbinvrow` instead? Here’s how I would call it:

```plaintext
using JuMP, CPLEX
model = direct_model(CPLEX.Optimizer())
@variable(model, x1 >= 0)
@variable(model, x2 >= 0)
@constraint(model, x1 + x2 <= 7)
@constraint(model, 2*x1 <= 11)
@constraint(model, 2*x2 <= 7)
@objective(model, Max, x1 + 2*x2)
optimize!(model)
num_const = num_constraints(model, AffExpr, MOI.LessThan{Float64})
num_vars = num_variables(model) + num_const
tableau = zeros(num_const, num_vars)
cpx = backend(model)
data = zeros(num_vars)
for j in 1:num_const
    status = CPLEX.CPXbinvrow(cpx.env, cpx.lp, Cint(j - 1), data)
    @assert status == 0
    tableau[j, :] .= data
end

```

Here are the docs: [IBM Documentation](https://www.ibm.com/docs/en/icos/22.1.0?topic=b-cpxxbinvrow-cpxbinvrow)

---

<div class="post-metadata">

**Author:** ![afazevedo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/afazevedo/32/16394_2.png) [@afazevedo](https://discourse.julialang.org/u/afazevedo)\
**Post date:** [July 7, 2023, 10:08pm UTC](https://discourse.julialang.org/t/gather-optimal-tableau-information-using-cplex-jl/101331/3 "2023-07-07T22:08:24Z")

</div>

If I understood correctly, `CPXbinvrow` is used to gather the inverse basis, while `CPXbinvarow` is used for the tableau. Could you please confirm if my understanding is accurate? Thank you very much for your quick response as always, @odow.

---

<div class="post-metadata">

**Author:** ![afazevedo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/afazevedo/32/16394_2.png) [@afazevedo](https://discourse.julialang.org/u/afazevedo)\
**Post date:** [July 8, 2023, 2:56pm UTC](https://discourse.julialang.org/t/gather-optimal-tableau-information-using-cplex-jl/101331/4 "2023-07-08T14:56:24Z")

</div>

I wanted to update you and let you know that I have figured out what was causing the issue. Thanks to @odow for clarifying the functions. As I initially mentioned, I’ve been using the `CPXbinvarow` to gather rows from the tableau. The error occurred because I hadn’t incorporated the slack variables into the model. Once I added these slack variables, the results from `CPXbinvarow` matched up correctly.
