OSeMOSYS / otoole

OSeMOSYS Tools for Energy
https://otoole.readthedocs.io
MIT License
23 stars 17 forks source link

[FEATURE]: Add support for HiGHS #218

Open trevorb1 opened 6 months ago

trevorb1 commented 6 months ago

Feature Request

Add support for HiGHS solver. Looking at HiGHS documentation, and think it will be fairly straightforward as HiGHS will print out data in similar (or same!) format as other solvers!

I have supplied the the formats I think will be useful below, but dont really suggest a path forward. Originally I was thinking that the GLPK format would be best, since we have logic to process it currently. But having to supply the .lp file for this as an additional argument is a pain. So maybe just using the raw HiGHS format (last option) would be best.

Is your feature related to a bug?

No response

Suggested Solution

setup

I will assume that the user has a generic .lp file to start with. If you run this code, making sure to specify the integer value in the writeSolution call (see here for options)

import highspy
h = highspy.Highs()
filename = 'model.lp'
h.readModel(filename)
h.run()
h.writeSolution("highs.sol", 0)

GLPK Format

if the user specifies a 2 (ie. h.writeSolution("highs.sol", 2)) the output format will be identical to GLPK. While otoole can currently process GLPK, the user does also have to pass in the .lp file, which is a bit of a pain.

GLPK Output

c Problem:    OSeMOSYS
c Rows:       293715
c Columns:    366745
c Non-zeros:  794822
c Status:     OPTIMAL
c Objective:  cost = 4497.31967 (MINimum)
c
s bas 293715 366745 f f 4497.31967015205
i 1 b 4497.31967015205 0
i 2 s -1.59376124775045 -2.68631688302325
i 3 s -1.60167966406719 -2.55839703145071
i 4 s -1.6369526094781 -2.43656860138163
i 5 s -1.68590281943611 -2.32054152512536

HiGHS Output

(Identical to GLPK!)

c Problem:    model
c Rows:       293715
c Columns:    366745
c Non-zeros:  794822
c Status:     OPTIMAL
c Objective:  cost = 4497.31967 (MINimum)
c
s bas 293715 366745 f f 4497.319670152045
i 1 s -1.5937612477504 -2.6863168830232
i 2 s -1.6016796640672 -2.5583970314507
i 3 s -1.6369526094781 -2.4365686013816
i 4 s -1.6859028194361 -2.3205415251254
i 5 s -1.7463707258548 -2.2100395477384

CBC Format

if the user specifies a 0 (ie. h.writeSolution("highs.sol", 0)) the output format will be very similar to CBC. HiGHS does write out all the zeros if using the 0, else if you supply a 4, the zeros are removed.

HiGHS output

Model status
Optimal

# Primal solution values
Feasible
Objective 4497.319670152045
# Columns 366745
TotalDiscountedCost(SIMPLICITY,2014) 193.6038541621821
TotalDiscountedCost(SIMPLICITY,2015) 187.7238605093666
TotalDiscountedCost(SIMPLICITY,2016) 183.997629568643
TotalDiscountedCost(SIMPLICITY,2017) 181.7275229818637
TotalDiscountedCost(SIMPLICITY,2018) 218.7360421598646

CBC output

Optimal - objective value 4497.31967015
      0 TotalDiscountedCost(SIMPLICITY,2014)                                                193.60385                       0
      1 TotalDiscountedCost(SIMPLICITY,2015)                                                187.72386                       0
      2 TotalDiscountedCost(SIMPLICITY,2016)                                                183.99763                       0
      3 TotalDiscountedCost(SIMPLICITY,2017)                                                181.72752                       0
      4 TotalDiscountedCost(SIMPLICITY,2018)                                                218.73604                       0

HiGHS Format

Alternatively, if the user specifies a 1, (ie. h.writeSolution("highs.sol", 1)), the format provided below can allow us to easily extract out dual values and similar (see issue #191). We could just add logic to process this and then use the existing ReadWideResults class methods to finalize processing.

Columns
    Index Status        Lower        Upper       Primal         Dual  Type        Name
        0     BS            0          inf      193.604            0  Continuous  TotalDiscountedCost(SIMPLICITY,2014)
        1     BS            0          inf      187.724            0  Continuous  TotalDiscountedCost(SIMPLICITY,2015)
        2     BS            0          inf      183.998            0  Continuous  TotalDiscountedCost(SIMPLICITY,2016)
        3     BS            0          inf      181.728            0  Continuous  TotalDiscountedCost(SIMPLICITY,2017)
        4     BS            0          inf      218.736            0  Continuous  TotalDiscountedCost(SIMPLICITY,2018)

Additional Info

No response