Skip to content

Integer Optimality Cut? #895

@WalterMadelim

Description

@WalterMadelim

Why isn't there a module to add integer optimality cut? I wonder.

It's not difficult to implement, for example, my version is like

function add_I_cut(mst, sub; ITE) # add Integer Optimality Cut to the master
    Cd = lps.Cd
    x_check = mst.Xl
    xllen = sub.xllen
    x_check .= 0
    Gurobi.GRBsetdblattrarray(sub.o, "Obj", 1, xllen, x_check) # not a multiplier method
    b2len = sub.b2len
    BTv = fill(Cchar('B'), xllen + b2len)
    Gurobi.GRBsetcharattrarray(sub.o, "VType", 1, xllen + b2len, BTv) # solve integer subproblems always
    Gurobi.GRBsetcharattrarray(mst.o, "VType", 1+S, xllen, BTv) # always generate integer trial points
    θ_LB = Settings.getxdblattrelement(mst, S, "LB") # need to calculate this once at the beginning, before calling of this method
    Settings.opt_and_ter(mst)
    for ite = 1:ITE
        lb,θ_check = Settings.getmodeldblattr(mst, "ObjBound"),Settings.getxdblattrelement(mst,S,"X")
        Gurobi.GRBgetdblattrarray(mst.o, "X", 1+S, xllen, x_check)
        @. x_check = round(x_check)
        Gurobi.GRBsetdblattrarray(sub.o, "LB", 1, xllen, x_check)
        Gurobi.GRBsetdblattrarray(sub.o, "UB", 1, xllen, x_check)
        Settings.opt_ass_opt(sub)
        ObjVal = Settings.getmodeldblattr(sub, "ObjVal")
        vio = ObjVal - θ_check
        println("(I) ite = $ite, vio = $vio, lb = $lb")
        vio < 1e-4 && break
        DIFF = ObjVal - θ_LB
        for (i,e) = enumerate(x_check)
            Cd[i] = e < 0.5 ? DIFF : -DIFF
        end
        Cd[xllen+1] = 1.0
        Cn = ObjVal - DIFF * count(>(0.5), x_check)
        Gurobi.GRBaddconstr(mst.o,xllen+1,sub.Ci,Cd,Cchar('>'),Cn,C_NULL)
        Settings.opt_and_ter(mst)
    end
end;

where, the θ_LB is set by calling the following function beforehand

function give_theta_LB(mst, sub, lps, S; VType)
    xllen = sub.xllen
    b2len = sub.b2len
    BTv = fill(Cchar(VType), xllen + b2len)
    Gurobi.GRBsetcharattrarray(sub.o, "VType", 1, xllen + b2len, BTv)
    Flv = fill(0., xllen)
    Gurobi.GRBsetdblattrarray(sub.o, "Obj", 1, xllen, Flv)
    Gurobi.GRBsetdblattrarray(sub.o, "LB", 1, xllen, Flv)
    Flv .= 1; Gurobi.GRBsetdblattrarray(sub.o, "UB", 1, xllen, Flv)
    Settings.opt_ass_opt(sub)
    lb = Settings.getmodeldblattr(sub, "ObjBound")
    Settings.setxdblattrelement(mst, S, "LB", lb)
    Settings.setxdblattrelement(mst, S, "Obj", 1.0/S) # This will change for multi-scene
    Settings.opt_ass_opt(mst)
end;

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions