Food Manufacture 1

Model

import sasoptpy as so
import pandas as pd


def test(cas_conn):

    # Problem data
    OILS = ['veg1', 'veg2', 'oil1', 'oil2', 'oil3']
    PERIODS = range(1, 7)
    cost_data = [
        [110, 120, 130, 110, 115],
        [130, 130, 110, 90, 115],
        [110, 140, 130, 100,  95],
        [120, 110, 120, 120, 125],
        [100, 120, 150, 110, 105],
        [90, 100, 140,  80, 135]]
    cost = pd.DataFrame(cost_data, columns=OILS, index=PERIODS).transpose()
    hardness_data = [8.8, 6.1, 2.0, 4.2, 5.0]
    hardness = {OILS[i]: hardness_data[i] for i in range(len(OILS))}

    revenue_per_ton = 150
    veg_ub = 200
    nonveg_ub = 250
    store_ub = 1000
    storage_cost_per_ton = 5
    hardness_lb = 3
    hardness_ub = 6
    init_storage = 500

    # Problem initialization
    m = so.Model(name='food_manufacture_1', session=cas_conn)

    # Problem definition
    buy = m.add_variables(OILS, PERIODS, lb=0, name='buy')
    use = m.add_variables(OILS, PERIODS, lb=0, name='use')
    manufacture = m.add_implicit_variable((use.sum('*', p) for p in PERIODS),
                                          name='manufacture')
    last_period = len(PERIODS)
    store = m.add_variables(OILS, [0] + list(PERIODS), lb=0, ub=store_ub,
                            name='store')
    for oil in OILS:
        store[oil, 0].set_bounds(lb=init_storage, ub=init_storage)
        store[oil, last_period].set_bounds(lb=init_storage, ub=init_storage)
    VEG = [i for i in OILS if 'veg' in i]
    NONVEG = [i for i in OILS if i not in VEG]
    revenue = so.expr_sum(revenue_per_ton * manufacture[p] for p in PERIODS)
    rawcost = so.expr_sum(cost.at[o, p] * buy[o, p]
                           for o in OILS for p in PERIODS)
    storagecost = so.expr_sum(storage_cost_per_ton * store[o, p]
                               for o in OILS for p in PERIODS)
    m.set_objective(revenue - rawcost - storagecost, sense=so.MAX,
                    name='profit')

    # Constraints
    m.add_constraints((use.sum(VEG, p) <= veg_ub for p in PERIODS),
                      name='veg_ub')
    m.add_constraints((use.sum(NONVEG, p) <= nonveg_ub for p in PERIODS),
                      name='nonveg_ub')
    m.add_constraints((store[o, p-1] + buy[o, p] == use[o, p] + store[o, p]
                      for o in OILS for p in PERIODS),
                      name='flow_balance')
    m.add_constraints((so.expr_sum(hardness[o]*use[o, p] for o in OILS) >=
                      hardness_lb * manufacture[p] for p in PERIODS),
                      name='hardness_ub')
    m.add_constraints((so.expr_sum(hardness[o]*use[o, p] for o in OILS) <=
                      hardness_ub * manufacture[p] for p in PERIODS),
                      name='hardness_lb')

    # Solver call
    res = m.solve()

    # With other solve options
    m.solve(options={'with': 'lp', 'algorithm': 'PS'})
    m.solve(options={'with': 'lp', 'algorithm': 'IP'})
    m.solve(options={'with': 'lp', 'algorithm': 'NS'})

    if res is not None:
        print(so.get_solution_table(buy, use, store))

    return m.get_objective_value()

Output

In [1]: import os

In [2]: hostname = os.getenv('CASHOST')

In [3]: port = os.getenv('CASPORT')

In [4]: from swat import CAS

In [5]: cas_conn = CAS(hostname, port)

In [6]: import sasoptpy
In [7]: from examples.client_side.food_manufacture_1 import test

In [8]: test(cas_conn)
NOTE: Initialized model food_manufacture_1.
NOTE: Added action set 'optimization'.
NOTE: Converting model food_manufacture_1 to OPTMODEL.
NOTE: Submitting OPTMODEL code to CAS server.
NOTE: Problem generation will use 8 threads.
NOTE: The problem has 95 variables (0 free, 10 fixed).
NOTE: The problem has 54 linear constraints (18 LE, 30 EQ, 6 GE, 0 range).
NOTE: The problem has 210 linear constraint coefficients.
NOTE: The problem has 0 nonlinear constraints (0 LE, 0 EQ, 0 GE, 0 range).
NOTE: The OPTMODEL presolver is disabled for linear problems.
NOTE: The LP presolver value AUTOMATIC is applied.
NOTE: The LP presolver time is 0.00 seconds.
NOTE: The LP presolver removed 44 variables and 4 constraints.
NOTE: The LP presolver removed 48 constraint coefficients.
NOTE: The presolved problem has 51 variables, 50 constraints, and 162 constraint coefficients.
NOTE: The LP solver is called.
NOTE: The Dual Simplex algorithm is used.
                              Objective
         Phase Iteration        Value         Time
          D 2          1    4.755480E+05         0
          P 2         49    1.078426E+05         0
NOTE: Optimal.
NOTE: Objective = 107842.59259.
NOTE: The Dual Simplex solve time is 0.01 seconds.
NOTE: The output table 'SOLUTION' in caslib 'CASUSER(casuser)' has 95 rows and 6 columns.
NOTE: The output table 'DUAL' in caslib 'CASUSER(casuser)' has 54 rows and 4 columns.
NOTE: The CAS table 'solutionSummary' in caslib 'CASUSER(casuser)' has 13 rows and 4 columns.
NOTE: The CAS table 'problemSummary' in caslib 'CASUSER(casuser)' has 18 rows and 4 columns.
NOTE: Added action set 'optimization'.
NOTE: Converting model food_manufacture_1 to OPTMODEL.
NOTE: Submitting OPTMODEL code to CAS server.
NOTE: Problem generation will use 8 threads.
NOTE: The problem has 95 variables (0 free, 10 fixed).
NOTE: The problem has 54 linear constraints (18 LE, 30 EQ, 6 GE, 0 range).
NOTE: The problem has 210 linear constraint coefficients.
NOTE: The problem has 0 nonlinear constraints (0 LE, 0 EQ, 0 GE, 0 range).
NOTE: The LP presolver value AUTOMATIC is applied.
NOTE: The LP presolver time is 0.00 seconds.
NOTE: The LP presolver removed 44 variables and 4 constraints.
NOTE: The LP presolver removed 48 constraint coefficients.
NOTE: The presolved problem has 51 variables, 50 constraints, and 162 constraint coefficients.
NOTE: The LP solver is called.
NOTE: The Primal Simplex algorithm is used.
                              Objective
         Phase Iteration        Value         Time
          P 1          1    1.749040E+03         0
          P 2         32    3.638889E+04         0
          D 2         51    1.078426E+05         0
NOTE: Optimal.
NOTE: Objective = 107842.59259.
NOTE: The Primal Simplex solve time is 0.01 seconds.
NOTE: The output table 'SOLUTION' in caslib 'CASUSER(casuser)' has 95 rows and 6 columns.
NOTE: The output table 'DUAL' in caslib 'CASUSER(casuser)' has 54 rows and 4 columns.
NOTE: The CAS table 'solutionSummary' in caslib 'CASUSER(casuser)' has 13 rows and 4 columns.
NOTE: The CAS table 'problemSummary' in caslib 'CASUSER(casuser)' has 18 rows and 4 columns.
NOTE: Added action set 'optimization'.
NOTE: Converting model food_manufacture_1 to OPTMODEL.
NOTE: Submitting OPTMODEL code to CAS server.
NOTE: Problem generation will use 8 threads.
NOTE: The problem has 95 variables (0 free, 10 fixed).
NOTE: The problem has 54 linear constraints (18 LE, 30 EQ, 6 GE, 0 range).
NOTE: The problem has 210 linear constraint coefficients.
NOTE: The problem has 0 nonlinear constraints (0 LE, 0 EQ, 0 GE, 0 range).
NOTE: The LP presolver value AUTOMATIC is applied.
NOTE: The LP presolver time is 0.00 seconds.
NOTE: The LP presolver removed 44 variables and 4 constraints.
NOTE: The LP presolver removed 48 constraint coefficients.
NOTE: The LP presolver modified 0 constraint coefficients.
NOTE: The presolved problem has 51 variables, 50 constraints, and 162 constraint coefficients.
NOTE: The LP solver is called.
NOTE: The Interior Point algorithm is used.
NOTE: The deterministic parallel mode is enabled.
NOTE: The Interior Point algorithm is using up to 8 threads.
                                           Primal       Bound        Dual
         Iter  Complement Duality Gap      Infeas      Infeas      Infeas   Time
            0  1.1003E+04  1.3994E+01  2.0602E-02  1.1145E-02  1.2444E+00      0
            1  1.0498E+04  4.1015E+01  1.7385E-02  9.4051E-03  1.0928E+00      0
            2  7.2084E+03  7.4551E+00  5.6703E-03  3.0675E-03  6.8365E-01      0
            3  1.7518E+03  1.1221E+00  1.5798E-03  8.5465E-04  1.1852E-01      0
            4  4.1038E+02  2.5544E-01  5.6092E-04  3.0344E-04  1.1852E-03      0
            5  3.9774E+01  2.2775E-02  7.2994E-05  3.9488E-05  1.9281E-05      0
            6  9.9400E-01  5.6526E-04  7.9112E-07  4.2798E-07  7.7185E-07      0
            7  9.9572E-03  5.6615E-06  7.9420E-09  4.2964E-09  7.7239E-09      0
            8  0.0000E+00  1.8686E-08  1.6613E-07  1.1864E-10  6.2833E-07      0
NOTE: The Interior Point solve time is 0.02 seconds.
NOTE: The CROSSOVER option is enabled.
NOTE: The crossover basis contains 11 primal and 3 dual superbasic variables.
                              Objective
         Phase Iteration        Value         Time
          P C          1    1.014226E+03         0
          D C         13    9.697429E+00         0
          D 2         16    1.078426E+05         0
          P 2         17    1.078426E+05         0
          D 2         18    1.078426E+05         0
NOTE: The Crossover time is 0.01 seconds.
NOTE: Optimal.
NOTE: Objective = 107842.59259.
NOTE: The output table 'SOLUTION' in caslib 'CASUSER(casuser)' has 95 rows and 6 columns.
NOTE: The output table 'DUAL' in caslib 'CASUSER(casuser)' has 54 rows and 4 columns.
NOTE: The CAS table 'solutionSummary' in caslib 'CASUSER(casuser)' has 16 rows and 4 columns.
NOTE: The CAS table 'problemSummary' in caslib 'CASUSER(casuser)' has 18 rows and 4 columns.
NOTE: Added action set 'optimization'.
NOTE: Converting model food_manufacture_1 to OPTMODEL.
NOTE: Submitting OPTMODEL code to CAS server.
NOTE: Problem generation will use 8 threads.
NOTE: The problem has 95 variables (0 free, 10 fixed).
NOTE: The problem has 54 linear constraints (18 LE, 30 EQ, 6 GE, 0 range).
NOTE: The problem has 210 linear constraint coefficients.
NOTE: The problem has 0 nonlinear constraints (0 LE, 0 EQ, 0 GE, 0 range).
NOTE: The LP presolver value AUTOMATIC is applied.
NOTE: The LP presolver time is 0.00 seconds.
NOTE: The LP presolver removed 44 variables and 4 constraints.
NOTE: The LP presolver removed 48 constraint coefficients.
NOTE: The presolved problem has 51 variables, 50 constraints, and 162 constraint coefficients.
NOTE: The LP solver is called.
NOTE: The Network Simplex algorithm is used.
NOTE: The network has 20 rows (40.00%), 29 columns (56.86%), and 1 component.
NOTE: The network extraction and setup time is 0.03 seconds.
                           Primal         Primal           Dual
         Iteration      Objective  Infeasibility  Infeasibility     Time
                 1   3.750000E+03   5.000000E+02   1.551000E+03     0.03
                24   7.125000E+04   0.000000E+00   0.000000E+00     0.03
NOTE: The Network Simplex solve time is 0.00 seconds.
NOTE: The total Network Simplex solve time is 0.03 seconds.
NOTE: The Dual Simplex algorithm is used.
                              Objective
         Phase Iteration        Value         Time
          D 2          1    2.240180E+05         0
          P 2         43    1.078426E+05         0
NOTE: Optimal.
NOTE: Objective = 107842.59259.
NOTE: The Simplex solve time is 0.04 seconds.
NOTE: The output table 'SOLUTION' in caslib 'CASUSER(casuser)' has 95 rows and 6 columns.
NOTE: The output table 'DUAL' in caslib 'CASUSER(casuser)' has 54 rows and 4 columns.
NOTE: The CAS table 'solutionSummary' in caslib 'CASUSER(casuser)' has 14 rows and 4 columns.
NOTE: The CAS table 'problemSummary' in caslib 'CASUSER(casuser)' has 18 rows and 4 columns.
                 buy           use         store
veg1 1  0.000000e+00  8.518519e+01  4.148148e+02
veg1 2  0.000000e+00  1.592593e+02  2.555556e+02
veg1 3  2.842171e-14  0.000000e+00  2.555556e+02
veg1 4 -1.421085e-14  1.592593e+02  9.629630e+01
veg1 5  7.105427e-14  9.629630e+01  0.000000e+00
veg1 6  6.592593e+02  1.592593e+02  5.000000e+02
veg2 1 -5.684342e-14  1.148148e+02  3.851852e+02
veg2 2  0.000000e+00  4.074074e+01  3.444444e+02
veg2 3  2.842171e-14  2.000000e+02  1.444444e+02
veg2 4 -2.842171e-14  4.074074e+01  1.037037e+02
veg2 5  0.000000e+00  1.037037e+02  0.000000e+00
veg2 6  5.407407e+02  4.074074e+01  5.000000e+02
oil1 1  0.000000e+00  0.000000e+00  5.000000e+02
oil1 2  0.000000e+00  0.000000e+00  5.000000e+02
oil1 3  0.000000e+00  0.000000e+00  5.000000e+02
oil1 4  0.000000e+00 -1.744059e-14  5.000000e+02
oil1 5  0.000000e+00  0.000000e+00  5.000000e+02
oil1 6  0.000000e+00  0.000000e+00  5.000000e+02
oil2 1  0.000000e+00  0.000000e+00  5.000000e+02
oil2 2  2.500000e+02  2.500000e+02  5.000000e+02
oil2 3  0.000000e+00  2.273737e-13  5.000000e+02
oil2 4  2.842171e-14  2.500000e+02  2.500000e+02
oil2 5  0.000000e+00  2.500000e+02  0.000000e+00
oil2 6  7.500000e+02  2.500000e+02  5.000000e+02
oil3 1  0.000000e+00  2.500000e+02  2.500000e+02
oil3 2  0.000000e+00  0.000000e+00  2.500000e+02
oil3 3 -5.048710e-29  2.500000e+02 -2.842171e-13
oil3 4  2.842171e-13  0.000000e+00  0.000000e+00
oil3 5  5.000000e+02  0.000000e+00  5.000000e+02
oil3 6  0.000000e+00  0.000000e+00  5.000000e+02
veg1 0           NaN           NaN  5.000000e+02
veg2 0           NaN           NaN  5.000000e+02
oil1 0           NaN           NaN  5.000000e+02
oil2 0           NaN           NaN  5.000000e+02
oil3 0           NaN           NaN  5.000000e+02
Out[8]: 107842.59259259264