def test(cas_conn, num_guests=20, max_table_size=3, max_tables=None): m = so.Model("wedding", session=cas_conn) # Check max. tables if max_tables is None: max_tables = math.ceil(num_guests / max_table_size) # Sets guests = range(1, num_guests + 1) tables = range(1, max_tables + 1) guest_pairs = [[i, j] for i in guests for j in range(i + 1, num_guests + 1)] # Variables x = m.add_variables(guests, tables, vartype=so.BIN, name="x") unhappy = m.add_variables(tables, name="unhappy", lb=0) # Objective m.set_objective(unhappy.sum('*'), sense=so.MIN, name="obj") # Constraints m.add_constraints((x.sum(g, '*') == 1 for g in guests), name="assigncon") m.add_constraints((x.sum('*', t) <= max_table_size for t in tables), name="tablesizecon") m.add_constraints((unhappy[t] >= abs(g - h) * (x[g, t] + x[h, t] - 1) for t in tables for [g, h] in guest_pairs), name="measurecon") # Solve res = m.solve(options={ 'with': 'milp', 'decomp': { 'method': 'set' }, 'presolver': 'none' }) if res is not None: print(so.get_solution_table(x)) # Print assignments for t in tables: print('Table {} : [ '.format(t), end='') for g in guests: if x[g, t].get_value() == 1: print('{} '.format(g), end='') print(']') return m.get_objective_value()
def test(cas_conn, sols=False): # Upload data to server first xy_raw = pd.DataFrame([ [0.0, 1.0], [0.5, 0.9], [1.0, 0.7], [1.5, 1.5], [1.9, 2.0], [2.5, 2.4], [3.0, 3.2], [3.5, 2.0], [4.0, 2.7], [4.5, 3.5], [5.0, 1.0], [5.5, 4.0], [6.0, 3.6], [6.6, 2.7], [7.0, 5.7], [7.6, 4.6], [8.5, 6.0], [9.0, 6.8], [10.0, 7.3] ], columns=['x', 'y']) xy_data = cas_conn.upload_frame(xy_raw, casout={'name': 'xy_data', 'replace': True}) # Read observations POINTS, (x, y), xy_table_ref = so.read_table(xy_data, columns=['x', 'y']) # Parameters and variables order = so.Parameter(name='order') beta = so.VariableGroup(so.exp_range(0, order), name='beta') estimate = so.ImplicitVar( (beta[0] + so.quick_sum(beta[k] * x[i] ** k for k in so.exp_range(1, order)) for i in POINTS), name='estimate') surplus = so.VariableGroup(POINTS, name='surplus', lb=0) slack = so.VariableGroup(POINTS, name='slack', lb=0) objective1 = so.Expression( so.quick_sum(surplus[i] + slack[i] for i in POINTS), name='objective1') abs_dev_con = so.ConstraintGroup( (estimate[i] - surplus[i] + slack[i] == y[i] for i in POINTS), name='abs_dev_con') minmax = so.Variable(name='minmax') objective2 = so.Expression(minmax + 0.0, name='objective2') minmax_con = so.ConstraintGroup( (minmax >= surplus[i] + slack[i] for i in POINTS), name='minmax_con') order.set_init(1) L1 = so.Model(name='L1', session=cas_conn) L1.set_objective(objective1, sense=so.MIN) L1.include(POINTS, x, y, xy_table_ref) L1.include(order, beta, estimate, surplus, slack, abs_dev_con) L1.add_statement('print x y estimate surplus slack;', after_solve=True) L1.solve(verbose=True) sol_data1 = L1.response['Print3.PrintTable'].sort_values('x') print(so.get_solution_table(beta)) print(sol_data1.to_string()) Linf = so.Model(name='Linf', session=cas_conn) Linf.include(L1, minmax, minmax_con) Linf.set_objective(objective2, sense=so.MIN) Linf.solve() sol_data2 = Linf.response['Print3.PrintTable'].sort_values('x') print(so.get_solution_table(beta)) print(sol_data2.to_string()) order.set_init(2) L1.solve() sol_data3 = L1.response['Print3.PrintTable'].sort_values('x') print(so.get_solution_table(beta)) print(sol_data3.to_string()) Linf.solve() sol_data4 = Linf.response['Print3.PrintTable'].sort_values('x') print(so.get_solution_table(beta)) print(sol_data4.to_string()) if sols: return (sol_data1, sol_data2, sol_data3, sol_data4) else: return Linf.get_objective_value()
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 max_num_oils_used = 3 min_oil_used_threshold = 20 # Problem initialization m = so.Model(name='food_manufacture_2', 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.quick_sum(revenue_per_ton * manufacture[p] for p in PERIODS) rawcost = so.quick_sum(cost.at[o, p] * buy[o, p] for o in OILS for p in PERIODS) storagecost = so.quick_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.quick_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.quick_sum(hardness[o] * use[o, p] for o in OILS) <= hardness_ub * manufacture[p] for p in PERIODS), name='hardness_lb') # Additions to the first problem isUsed = m.add_variables(OILS, PERIODS, vartype=so.BIN, name='is_used') for p in PERIODS: for o in VEG: use[o, p].set_bounds(ub=veg_ub) for o in NONVEG: use[o, p].set_bounds(ub=nonveg_ub) m.add_constraints((use[o, p] <= use[o, p]._ub * isUsed[o, p] for o in OILS for p in PERIODS), name='link') m.add_constraints( (isUsed.sum('*', p) <= max_num_oils_used for p in PERIODS), name='logical1') m.add_constraints((use[o, p] >= min_oil_used_threshold * isUsed[o, p] for o in OILS for p in PERIODS), name='logical2') m.add_constraints((isUsed[o, p] <= isUsed['oil3', p] for o in ['veg1', 'veg2'] for p in PERIODS), name='logical3') res = m.solve() if res is not None: print(so.get_solution_table(buy, use, store, isUsed)) return m.get_objective_value()
def test(cas_conn): m = so.Model(name='decentralization', session=cas_conn) DEPTS = ['A', 'B', 'C', 'D', 'E'] CITIES = ['Bristol', 'Brighton', 'London'] benefit_data = pd.DataFrame( [['Bristol', 10, 15, 10, 20, 5], ['Brighton', 10, 20, 15, 15, 15]], columns=['city'] + DEPTS).set_index('city') comm_data = pd.DataFrame( [['A', 'B', 0.0], ['A', 'C', 1.0], ['A', 'D', 1.5], ['A', 'E', 0.0], ['B', 'C', 1.4], ['B', 'D', 1.2], ['B', 'E', 0.0], ['C', 'D', 0.0], ['C', 'E', 2.0], ['D', 'E', 0.7]], columns=['i', 'j', 'comm']).set_index(['i', 'j']) cost_data = pd.DataFrame( [['Bristol', 'Bristol', 5], ['Bristol', 'Brighton', 14], ['Bristol', 'London', 13], ['Brighton', 'Brighton', 5], ['Brighton', 'London', 9], ['London', 'London', 10]], columns=['i', 'j', 'cost']).set_index(['i', 'j']) max_num_depts = 3 benefit = {} for city in CITIES: for dept in DEPTS: try: benefit[dept, city] = benefit_data.loc[city, dept] except: benefit[dept, city] = 0 comm = {} for row in comm_data.iterrows(): (i, j) = row[0] comm[i, j] = row[1]['comm'] comm[j, i] = comm[i, j] cost = {} for row in cost_data.iterrows(): (i, j) = row[0] cost[i, j] = row[1]['cost'] cost[j, i] = cost[i, j] assign = m.add_variables(DEPTS, CITIES, vartype=so.BIN, name='assign') IJKL = [(i, j, k, l) for i in DEPTS for j in CITIES for k in DEPTS for l in CITIES if i < k] product = m.add_variables(IJKL, vartype=so.BIN, name='product') totalBenefit = so.expr_sum(benefit[i, j] * assign[i, j] for i in DEPTS for j in CITIES) totalCost = so.expr_sum(comm[i, k] * cost[j, l] * product[i, j, k, l] for (i, j, k, l) in IJKL) m.set_objective(totalBenefit - totalCost, name='netBenefit', sense=so.MAX) m.add_constraints((so.expr_sum(assign[dept, city] for city in CITIES) == 1 for dept in DEPTS), name='assign_dept') m.add_constraints((so.expr_sum(assign[dept, city] for dept in DEPTS) <= max_num_depts for city in CITIES), name='cardinality') product_def1 = m.add_constraints( (assign[i, j] + assign[k, l] - 1 <= product[i, j, k, l] for (i, j, k, l) in IJKL), name='pd1') product_def2 = m.add_constraints( (product[i, j, k, l] <= assign[i, j] for (i, j, k, l) in IJKL), name='pd2') product_def3 = m.add_constraints( (product[i, j, k, l] <= assign[k, l] for (i, j, k, l) in IJKL), name='pd3') m.solve() print(m.get_problem_summary()) m.drop_constraints(product_def1) m.drop_constraints(product_def2) m.drop_constraints(product_def3) m.add_constraints( (so.expr_sum(product[i, j, k, l] for j in CITIES if (i, j, k, l) in IJKL) == assign[k, l] for i in DEPTS for k in DEPTS for l in CITIES if i < k), name='pd4') m.add_constraints( (so.expr_sum(product[i, j, k, l] for l in CITIES if (i, j, k, l) in IJKL) == assign[i, j] for k in DEPTS for i in DEPTS for j in CITIES if i < k), name='pd5') m.solve() print(m.get_problem_summary()) totalBenefit.set_name('totalBenefit') totalCost.set_name('totalCost') print(so.get_solution_table(totalBenefit, totalCost)) print(so.get_solution_table(assign).unstack(level=-1)) return m.get_objective_value()
def test(cas_conn, **kwargs): m = so.Model(name='refinery_optimization', session=cas_conn) crude_data = pd.DataFrame([ ['crude1', 20000], ['crude2', 30000] ], columns=['crude', 'crude_ub']).set_index(['crude']) arc_data = pd.DataFrame([ ['source', 'crude1', 6], ['source', 'crude2', 6], ['crude1', 'light_naphtha', 0.1], ['crude1', 'medium_naphtha', 0.2], ['crude1', 'heavy_naphtha', 0.2], ['crude1', 'light_oil', 0.12], ['crude1', 'heavy_oil', 0.2], ['crude1', 'residuum', 0.13], ['crude2', 'light_naphtha', 0.15], ['crude2', 'medium_naphtha', 0.25], ['crude2', 'heavy_naphtha', 0.18], ['crude2', 'light_oil', 0.08], ['crude2', 'heavy_oil', 0.19], ['crude2', 'residuum', 0.12], ['light_naphtha', 'regular_petrol', np.nan], ['light_naphtha', 'premium_petrol', np.nan], ['medium_naphtha', 'regular_petrol', np.nan], ['medium_naphtha', 'premium_petrol', np.nan], ['heavy_naphtha', 'regular_petrol', np.nan], ['heavy_naphtha', 'premium_petrol', np.nan], ['light_naphtha', 'reformed_gasoline', 0.6], ['medium_naphtha', 'reformed_gasoline', 0.52], ['heavy_naphtha', 'reformed_gasoline', 0.45], ['light_oil', 'jet_fuel', np.nan], ['light_oil', 'fuel_oil', np.nan], ['heavy_oil', 'jet_fuel', np.nan], ['heavy_oil', 'fuel_oil', np.nan], ['light_oil', 'light_oil_cracked', 2], ['light_oil_cracked', 'cracked_oil', 0.68], ['light_oil_cracked', 'cracked_gasoline', 0.28], ['heavy_oil', 'heavy_oil_cracked', 2], ['heavy_oil_cracked', 'cracked_oil', 0.75], ['heavy_oil_cracked', 'cracked_gasoline', 0.2], ['cracked_oil', 'jet_fuel', np.nan], ['cracked_oil', 'fuel_oil', np.nan], ['reformed_gasoline', 'regular_petrol', np.nan], ['reformed_gasoline', 'premium_petrol', np.nan], ['cracked_gasoline', 'regular_petrol', np.nan], ['cracked_gasoline', 'premium_petrol', np.nan], ['residuum', 'lube_oil', 0.5], ['residuum', 'jet_fuel', np.nan], ['residuum', 'fuel_oil', np.nan], ], columns=['i', 'j', 'multiplier']).set_index(['i', 'j']) octane_data = pd.DataFrame([ ['light_naphtha', 90], ['medium_naphtha', 80], ['heavy_naphtha', 70], ['reformed_gasoline', 115], ['cracked_gasoline', 105], ], columns=['i', 'octane']).set_index(['i']) petrol_data = pd.DataFrame([ ['regular_petrol', 84], ['premium_petrol', 94], ], columns=['petrol', 'octane_lb']).set_index(['petrol']) vapour_pressure_data = pd.DataFrame([ ['light_oil', 1.0], ['heavy_oil', 0.6], ['cracked_oil', 1.5], ['residuum', 0.05], ], columns=['oil', 'vapour_pressure']).set_index(['oil']) fuel_oil_ratio_data = pd.DataFrame([ ['light_oil', 10], ['cracked_oil', 4], ['heavy_oil', 3], ['residuum', 1], ], columns=['oil', 'coefficient']).set_index(['oil']) final_product_data = pd.DataFrame([ ['premium_petrol', 700], ['regular_petrol', 600], ['jet_fuel', 400], ['fuel_oil', 350], ['lube_oil', 150], ], columns=['product', 'profit']).set_index(['product']) vapour_pressure_ub = 1 crude_total_ub = 45000 naphtha_ub = 10000 cracked_oil_ub = 8000 lube_oil_lb = 500 lube_oil_ub = 1000 premium_ratio = 0.40 ARCS = arc_data.index.tolist() arc_mult = arc_data['multiplier'].fillna(1) FINAL_PRODUCTS = final_product_data.index.tolist() final_product_data['profit'] = final_product_data['profit'] / 100 profit = final_product_data['profit'] ARCS = ARCS + [(i, 'sink') for i in FINAL_PRODUCTS] flow = m.add_variables(ARCS, name='flow', lb=0) NODES = np.unique([i for j in ARCS for i in j]) m.set_objective(so.expr_sum(profit[i] * flow[i, 'sink'] for i in FINAL_PRODUCTS if (i, 'sink') in ARCS), name='totalProfit', sense=so.MAX) m.add_constraints((so.expr_sum(flow[a] for a in ARCS if a[0] == n) == so.expr_sum(arc_mult[a] * flow[a] for a in ARCS if a[1] == n) for n in NODES if n not in ['source', 'sink']), name='flow_balance') CRUDES = crude_data.index.tolist() crudeDistilled = m.add_variables(CRUDES, name='crudesDistilled', lb=0) crudeDistilled.set_bounds(ub=crude_data['crude_ub']) m.add_constraints((flow[i, j] == crudeDistilled[i] for (i, j) in ARCS if i in CRUDES), name='distillation') OILS = ['light_oil', 'heavy_oil'] CRACKED_OILS = [i+'_cracked' for i in OILS] oilCracked = m.add_variables(CRACKED_OILS, name='oilCracked', lb=0) m.add_constraints((flow[i, j] == oilCracked[i] for (i, j) in ARCS if i in CRACKED_OILS), name='cracking') octane = octane_data['octane'] PETROLS = petrol_data.index.tolist() octane_lb = petrol_data['octane_lb'] vapour_pressure = vapour_pressure_data['vapour_pressure'] m.add_constraints((so.expr_sum(octane[a[0]] * arc_mult[a] * flow[a] for a in ARCS if a[1] == p) >= octane_lb[p] * so.expr_sum(arc_mult[a] * flow[a] for a in ARCS if a[1] == p) for p in PETROLS), name='blending_petrol') m.add_constraint(so.expr_sum(vapour_pressure[a[0]] * arc_mult[a] * flow[a] for a in ARCS if a[1] == 'jet_fuel') <= vapour_pressure_ub * so.expr_sum(arc_mult[a] * flow[a] for a in ARCS if a[1] == 'jet_fuel'), name='blending_jet_fuel') fuel_oil_coefficient = fuel_oil_ratio_data['coefficient'] sum_fuel_oil_coefficient = sum(fuel_oil_coefficient) m.add_constraints((sum_fuel_oil_coefficient * flow[a] == fuel_oil_coefficient[a[0]] * flow.sum('*', ['fuel_oil']) for a in ARCS if a[1] == 'fuel_oil'), name='blending_fuel_oil') m.add_constraint(crudeDistilled.sum('*') <= crude_total_ub, name='crude_total_ub') m.add_constraint(so.expr_sum(flow[a] for a in ARCS if a[0].find('naphtha') > -1 and a[1] == 'reformed_gasoline') <= naphtha_ub, name='naphtba_ub') m.add_constraint(so.expr_sum(flow[a] for a in ARCS if a[1] == 'cracked_oil') <= cracked_oil_ub, name='cracked_oil_ub') m.add_constraint(flow['lube_oil', 'sink'] == [lube_oil_lb, lube_oil_ub], name='lube_oil_range') m.add_constraint(flow.sum('premium_petrol', '*') >= premium_ratio * flow.sum('regular_petrol', '*'), name='premium_ratio') res = m.solve(**kwargs) if res is not None: print(so.get_solution_table(crudeDistilled)) print(so.get_solution_table(oilCracked)) print(so.get_solution_table(flow)) octane_sol = [] for p in PETROLS: octane_sol.append(so.expr_sum(octane[a[0]] * arc_mult[a] * flow[a].get_value() for a in ARCS if a[1] == p) / sum(arc_mult[a] * flow[a].get_value() for a in ARCS if a[1] == p)) octane_sol = pd.Series(octane_sol, name='octane_sol', index=PETROLS) print(so.get_solution_table(octane_sol, octane_lb)) print(so.get_solution_table(vapour_pressure)) vapour_pressure_sol = sum(vapour_pressure[a[0]] * arc_mult[a] * flow[a].get_value() for a in ARCS if a[1] == 'jet_fuel') /\ sum(arc_mult[a] * flow[a].get_value() for a in ARCS if a[1] == 'jet_fuel') print('Vapour_pressure_sol: {:.4f}'.format(vapour_pressure_sol)) num_fuel_oil_ratio_sol = [arc_mult[a] * flow[a].get_value() / sum(arc_mult[b] * flow[b].get_value() for b in ARCS if b[1] == 'fuel_oil') for a in ARCS if a[1] == 'fuel_oil'] num_fuel_oil_ratio_sol = pd.Series(num_fuel_oil_ratio_sol, name='num_fuel_oil_ratio_sol', index=[a[0] for a in ARCS if a[1] == 'fuel_oil']) print(so.get_solution_table(fuel_oil_coefficient, num_fuel_oil_ratio_sol)) return m.get_objective_value()
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.quick_sum(revenue_per_ton * manufacture[p] for p in PERIODS) rawcost = so.quick_sum(cost.at[o, p] * buy[o, p] for o in OILS for p in PERIODS) storagecost = so.quick_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.quick_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.quick_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': 'PS'}) m.solve(options={'with': 'lp', 'algorithm': 'PS'}) if res is not None: print(so.get_solution_table(buy, use, store)) return m.get_objective_value()
def test(cas_conn): m = so.Model(name='farm_planning', session=cas_conn) # Input Data cow_data_raw = [] for age in range(12): if age < 2: row = { 'age': age, 'init_num_cows': 10, 'acres_needed': 2 / 3.0, 'annual_loss': 0.05, 'bullock_yield': 0, 'heifer_yield': 0, 'milk_revenue': 0, 'grain_req': 0, 'sugar_beet_req': 0, 'labour_req': 10, 'other_costs': 50 } else: row = { 'age': age, 'init_num_cows': 10, 'acres_needed': 1, 'annual_loss': 0.02, 'bullock_yield': 1.1 / 2, 'heifer_yield': 1.1 / 2, 'milk_revenue': 370, 'grain_req': 0.6, 'sugar_beet_req': 0.7, 'labour_req': 42, 'other_costs': 100 } cow_data_raw.append(row) cow_data = pd.DataFrame(cow_data_raw).set_index(['age']) grain_data = pd.DataFrame([['group1', 20, 1.1], ['group2', 30, 0.9], ['group3', 20, 0.8], ['group4', 10, 0.65]], columns=['group', 'acres', 'yield']).set_index(['group']) num_years = 5 num_acres = 200 bullock_revenue = 30 heifer_revenue = 40 dairy_cow_selling_age = 12 dairy_cow_selling_revenue = 120 max_num_cows = 130 sugar_beet_yield = 1.5 grain_cost = 90 grain_revenue = 75 grain_labour_req = 4 grain_other_costs = 15 sugar_beet_cost = 70 sugar_beet_revenue = 58 sugar_beet_labour_req = 14 sugar_beet_other_costs = 10 nominal_labour_cost = 4000 nominal_labour_hours = 5500 excess_labour_cost = 1.2 capital_outlay_unit = 200 num_loan_years = 10 annual_interest_rate = 0.15 max_decrease_ratio = 0.50 max_increase_ratio = 0.75 # Sets AGES = cow_data.index.tolist() init_num_cows = cow_data['init_num_cows'] acres_needed = cow_data['acres_needed'] annual_loss = cow_data['annual_loss'] bullock_yield = cow_data['bullock_yield'] heifer_yield = cow_data['heifer_yield'] milk_revenue = cow_data['milk_revenue'] grain_req = cow_data['grain_req'] sugar_beet_req = cow_data['sugar_beet_req'] cow_labour_req = cow_data['labour_req'] cow_other_costs = cow_data['other_costs'] YEARS = list(range(1, num_years + 1)) YEARS0 = [0] + YEARS # Variables numCows = m.add_variables(AGES + [dairy_cow_selling_age], YEARS0, lb=0, name='numCows') for age in AGES: numCows[age, 0].set_bounds(lb=init_num_cows[age], ub=init_num_cows[age]) numCows[dairy_cow_selling_age, 0].set_bounds(lb=0, ub=0) numBullocksSold = m.add_variables(YEARS, lb=0, name='numBullocksSold') numHeifersSold = m.add_variables(YEARS, lb=0, name='numHeifersSold') GROUPS = grain_data.index.tolist() acres = grain_data['acres'] grain_yield = grain_data['yield'] grainAcres = m.add_variables(GROUPS, YEARS, lb=0, name='grainAcres') for group in GROUPS: for year in YEARS: grainAcres[group, year].set_bounds(ub=acres[group]) grainBought = m.add_variables(YEARS, lb=0, name='grainBought') grainSold = m.add_variables(YEARS, lb=0, name='grainSold') sugarBeetAcres = m.add_variables(YEARS, lb=0, name='sugarBeetAcres') sugarBeetBought = m.add_variables(YEARS, lb=0, name='sugarBeetBought') sugarBeetSold = m.add_variables(YEARS, lb=0, name='sugarBeetSold') numExcessLabourHours = m.add_variables(YEARS, lb=0, name='numExcessLabourHours') capitalOutlay = m.add_variables(YEARS, lb=0, name='capitalOutlay') yearly_loan_payment = (annual_interest_rate * capital_outlay_unit) /\ (1 - (1+annual_interest_rate)**(-num_loan_years)) # Objective function revenue = { year: bullock_revenue * numBullocksSold[year] + heifer_revenue * numHeifersSold[year] + dairy_cow_selling_revenue * numCows[dairy_cow_selling_age, year] + so.expr_sum(milk_revenue[age] * numCows[age, year] for age in AGES) + grain_revenue * grainSold[year] + sugar_beet_revenue * sugarBeetSold[year] for year in YEARS } cost = { year: grain_cost * grainBought[year] + sugar_beet_cost * sugarBeetBought[year] + nominal_labour_cost + excess_labour_cost * numExcessLabourHours[year] + so.expr_sum(cow_other_costs[age] * numCows[age, year] for age in AGES) + so.expr_sum(grain_other_costs * grainAcres[group, year] for group in GROUPS) + sugar_beet_other_costs * sugarBeetAcres[year] + so.expr_sum(yearly_loan_payment * capitalOutlay[y] for y in YEARS if y <= year) for year in YEARS } profit = {year: revenue[year] - cost[year] for year in YEARS} totalProfit = so.expr_sum(profit[year] - yearly_loan_payment * (num_years - 1 + year) * capitalOutlay[year] for year in YEARS) m.set_objective(totalProfit, sense=so.MAX, name='totalProfit') # Constraints m.add_constraints( (so.expr_sum(acres_needed[age] * numCows[age, year] for age in AGES) + so.expr_sum(grainAcres[group, year] for group in GROUPS) + sugarBeetAcres[year] <= num_acres for year in YEARS), name='num_acres') m.add_constraints((numCows[age + 1, year + 1] == (1 - annual_loss[age]) * numCows[age, year] for age in AGES if age != dairy_cow_selling_age for year in YEARS0 if year != num_years), name='aging') m.add_constraints((numBullocksSold[year] == so.expr_sum( bullock_yield[age] * numCows[age, year] for age in AGES) for year in YEARS), name='numBullocksSold_def') m.add_constraints((numCows[0, year] == so.expr_sum(heifer_yield[age] * numCows[age, year] for age in AGES) - numHeifersSold[year] for year in YEARS), name='numHeifersSold_def') m.add_constraints((so.expr_sum(numCows[age, year] for age in AGES) <= max_num_cows + so.expr_sum(capitalOutlay[y] for y in YEARS if y <= year) for year in YEARS), name='max_num_cows_def') grainGrown = {(group, year): grain_yield[group] * grainAcres[group, year] for group in GROUPS for year in YEARS} m.add_constraints( (so.expr_sum(grain_req[age] * numCows[age, year] for age in AGES) <= so.expr_sum(grainGrown[group, year] for group in GROUPS) + grainBought[year] - grainSold[year] for year in YEARS), name='grain_req_def') sugarBeetGrown = {(year): sugar_beet_yield * sugarBeetAcres[year] for year in YEARS} m.add_constraints( (so.expr_sum(sugar_beet_req[age] * numCows[age, year] for age in AGES) <= sugarBeetGrown[year] + sugarBeetBought[year] - sugarBeetSold[year] for year in YEARS), name='sugar_beet_req_def') m.add_constraints((so.expr_sum(cow_labour_req[age] * numCows[age, year] for age in AGES) + so.expr_sum(grain_labour_req * grainAcres[group, year] for group in GROUPS) + sugar_beet_labour_req * sugarBeetAcres[year] <= nominal_labour_hours + numExcessLabourHours[year] for year in YEARS), name='labour_req_def') m.add_constraints((profit[year] >= 0 for year in YEARS), name='cash_flow') m.add_constraint(so.expr_sum(numCows[age, num_years] for age in AGES if age >= 2) / sum(init_num_cows[age] for age in AGES if age >= 2) == [ 1 - max_decrease_ratio, 1 + max_increase_ratio ], name='final_dairy_cows_range') res = m.solve() if res is not None: so.pd.display_all() print(so.get_solution_table(numCows)) revenue_df = so.dict_to_frame(revenue, cols=['revenue']) cost_df = so.dict_to_frame(cost, cols=['cost']) profit_df = so.dict_to_frame(profit, cols=['profit']) print( so.get_solution_table(numBullocksSold, numHeifersSold, capitalOutlay, numExcessLabourHours, revenue_df, cost_df, profit_df)) gg_df = so.dict_to_frame(grainGrown, cols=['grainGrown']) print(so.get_solution_table(grainAcres, gg_df)) sbg_df = so.dict_to_frame(sugarBeetGrown, cols=['sugerBeetGrown']) print( so.get_solution_table(grainBought, grainSold, sugarBeetAcres, sbg_df, sugarBeetBought, sugarBeetSold)) num_acres = m.get_constraint('num_acres') na_df = num_acres.get_expressions() max_num_cows_con = m.get_constraint('max_num_cows_def') mnc_df = max_num_cows_con.get_expressions() print(so.get_solution_table(na_df, mnc_df)) return m.get_objective_value()
def test(cas_conn): # Input data demand_data = pd.DataFrame([ [0, 2000, 1500, 1000], [1, 1000, 1400, 1000], [2, 500, 2000, 1500], [3, 0, 2500, 2000] ], columns=['period', 'unskilled', 'semiskilled', 'skilled'])\ .set_index(['period']) worker_data = pd.DataFrame( [['unskilled', 0.25, 0.10, 500, 200, 1500, 50, 500], ['semiskilled', 0.20, 0.05, 800, 500, 2000, 50, 400], ['skilled', 0.10, 0.05, 500, 500, 3000, 50, 400]], columns=[ 'worker', 'waste_new', 'waste_old', 'recruit_ub', 'redundancy_cost', 'overmanning_cost', 'shorttime_ub', 'shorttime_cost' ]).set_index(['worker']) retrain_data = pd.DataFrame([ ['unskilled', 'semiskilled', 200, 400], ['semiskilled', 'skilled', math.inf, 500], ], columns=['worker1', 'worker2', 'retrain_ub', 'retrain_cost']).\ set_index(['worker1', 'worker2']) downgrade_data = pd.DataFrame( [['semiskilled', 'unskilled'], ['skilled', 'semiskilled'], ['skilled', 'unskilled']], columns=['worker1', 'worker2']) semiskill_retrain_frac_ub = 0.25 downgrade_leave_frac = 0.5 overmanning_ub = 150 shorttime_frac = 0.5 # Sets WORKERS = worker_data.index.tolist() PERIODS0 = demand_data.index.tolist() PERIODS = PERIODS0[1:] RETRAIN_PAIRS = [i for i, _ in retrain_data.iterrows()] DOWNGRADE_PAIRS = [(row['worker1'], row['worker2']) for _, row in downgrade_data.iterrows()] waste_old = worker_data['waste_old'] waste_new = worker_data['waste_new'] redundancy_cost = worker_data['redundancy_cost'] overmanning_cost = worker_data['overmanning_cost'] shorttime_cost = worker_data['shorttime_cost'] retrain_cost = retrain_data['retrain_cost'].unstack(level=-1) # Initialization m = so.Model(name='manpower_planning', session=cas_conn) # Variables numWorkers = m.add_variables(WORKERS, PERIODS0, name='numWorkers', lb=0) demand0 = demand_data.loc[0] for w in WORKERS: numWorkers[w, 0].set_bounds(lb=demand0[w], ub=demand0[w]) numRecruits = m.add_variables(WORKERS, PERIODS, name='numRecruits', lb=0) worker_ub = worker_data['recruit_ub'] for w in WORKERS: for p in PERIODS: numRecruits[w, p].set_bounds(ub=worker_ub[w]) numRedundant = m.add_variables(WORKERS, PERIODS, name='numRedundant', lb=0) numShortTime = m.add_variables(WORKERS, PERIODS, name='numShortTime', lb=0) shorttime_ub = worker_data['shorttime_ub'] for w in WORKERS: for p in PERIODS: numShortTime.set_bounds(ub=shorttime_ub[w]) numExcess = m.add_variables(WORKERS, PERIODS, name='numExcess', lb=0) retrain_ub = pd.DataFrame() for i in PERIODS: retrain_ub[i] = retrain_data['retrain_ub'] numRetrain = m.add_variables(RETRAIN_PAIRS, PERIODS, name='numRetrain', lb=0, ub=retrain_ub) numDowngrade = m.add_variables(DOWNGRADE_PAIRS, PERIODS, name='numDowngrade', lb=0) # Constraints m.add_constraints( (numWorkers[w, p] - (1 - shorttime_frac) * numShortTime[w, p] - numExcess[w, p] == demand_data.loc[p, w] for w in WORKERS for p in PERIODS), name='demand') m.add_constraints( (numWorkers[w, p] == (1 - waste_old[w]) * numWorkers[w, p - 1] + (1 - waste_new[w]) * numRecruits[w, p] + (1 - waste_old[w]) * numRetrain.sum('*', w, p) + (1 - downgrade_leave_frac) * numDowngrade.sum('*', w, p) - numRetrain.sum(w, '*', p) - numDowngrade.sum(w, '*', p) - numRedundant[w, p] for w in WORKERS for p in PERIODS), name='flow_balance') m.add_constraints((numRetrain['semiskilled', 'skilled', p] <= semiskill_retrain_frac_ub * numWorkers['skilled', p] for p in PERIODS), name='semiskill_retrain') m.add_constraints( (numExcess.sum('*', p) <= overmanning_ub for p in PERIODS), name='overmanning') # Objectives redundancy = so.Expression(numRedundant.sum('*', '*'), name='redundancy') cost = so.Expression( so.expr_sum(redundancy_cost[w] * numRedundant[w, p] + shorttime_cost[w] * numShortTime[w, p] + overmanning_cost[w] * numExcess[w, p] for w in WORKERS for p in PERIODS) + so.expr_sum(retrain_cost.loc[i, j] * numRetrain[i, j, p] for i, j in RETRAIN_PAIRS for p in PERIODS), name='cost') m.set_objective(redundancy, sense=so.MIN, name='redundancy_obj') res = m.solve() if res is not None: print('Redundancy:', redundancy.get_value()) print('Cost:', cost.get_value()) print( so.get_solution_table(numWorkers, numRecruits, numRedundant, numShortTime, numExcess)) print(so.get_solution_table(numRetrain)) print(so.get_solution_table(numDowngrade)) m.set_objective(cost, sense=so.MIN, name='cost_obj') res = m.solve() if res is not None: print('Redundancy:', redundancy.get_value()) print('Cost:', cost.get_value()) print( so.get_solution_table(numWorkers, numRecruits, numRedundant, numShortTime, numExcess)) print(so.get_solution_table(numRetrain)) print(so.get_solution_table(numDowngrade)) return m.get_objective_value()
def test(cas_conn): m = so.Model(name='factory_planning_1', session=cas_conn) # Input data product_list = ['prod{}'.format(i) for i in range(1, 8)] product_data = pd.DataFrame([10, 6, 8, 4, 11, 9, 3], columns=['profit'], index=product_list) demand_data = [ [500, 1000, 300, 300, 800, 200, 100], [600, 500, 200, 0, 400, 300, 150], [300, 600, 0, 0, 500, 400, 100], [200, 300, 400, 500, 200, 0, 100], [0, 100, 500, 100, 1000, 300, 0], [500, 500, 100, 300, 1100, 500, 60]] demand_data = pd.DataFrame( demand_data, columns=product_list, index=range(1, 7)) machine_types_data = [ ['grinder', 4], ['vdrill', 2], ['hdrill', 3], ['borer', 1], ['planer', 1]] machine_types_data = pd.DataFrame(machine_types_data, columns=[ 'machine_type', 'num_machines']).set_index(['machine_type']) machine_type_period_data = [ ['grinder', 1, 1], ['hdrill', 2, 2], ['borer', 3, 1], ['vdrill', 4, 1], ['grinder', 5, 1], ['vdrill', 5, 1], ['planer', 6, 1], ['hdrill', 6, 1]] machine_type_period_data = pd.DataFrame(machine_type_period_data, columns=[ 'machine_type', 'period', 'num_down']) machine_type_product_data = [ ['grinder', 0.5, 0.7, 0, 0, 0.3, 0.2, 0.5], ['vdrill', 0.1, 0.2, 0, 0.3, 0, 0.6, 0], ['hdrill', 0.2, 0, 0.8, 0, 0, 0, 0.6], ['borer', 0.05, 0.03, 0, 0.07, 0.1, 0, 0.08], ['planer', 0, 0, 0.01, 0, 0.05, 0, 0.05]] machine_type_product_data = \ pd.DataFrame(machine_type_product_data, columns=['machine_type'] + product_list).set_index(['machine_type']) store_ub = 100 storage_cost_per_unit = 0.5 final_storage = 50 num_hours_per_period = 24 * 2 * 8 # Problem definition PRODUCTS = product_list PERIODS = range(1, 7) MACHINE_TYPES = machine_types_data.index.values num_machine_per_period = pd.DataFrame() for i in range(1, 7): num_machine_per_period[i] = machine_types_data['num_machines'] for _, row in machine_type_period_data.iterrows(): num_machine_per_period.at[row['machine_type'], row['period']] -= row['num_down'] make = m.add_variables(PRODUCTS, PERIODS, lb=0, name='make') sell = m.add_variables(PRODUCTS, PERIODS, lb=0, ub=demand_data.transpose(), name='sell') store = m.add_variables(PRODUCTS, PERIODS, lb=0, ub=store_ub, name='store') for p in PRODUCTS: store[p, 6].set_bounds(lb=final_storage, ub=final_storage+1) storageCost = storage_cost_per_unit * store.sum('*', '*') revenue = so.expr_sum(product_data.at[p, 'profit'] * sell[p, t] for p in PRODUCTS for t in PERIODS) m.set_objective(revenue-storageCost, sense=so.MAX, name='total_profit') production_time = machine_type_product_data m.add_constraints(( so.expr_sum(production_time.at[mc, p] * make[p, t] for p in PRODUCTS) <= num_hours_per_period * num_machine_per_period.at[mc, t] for mc in MACHINE_TYPES for t in PERIODS), name='machine_hours') m.add_constraints(((store[p, t-1] if t-1 in PERIODS else 0) + make[p, t] == sell[p, t] + store[p, t] for p in PRODUCTS for t in PERIODS), name='flow_balance') res = m.solve() if res is not None: print(so.get_solution_table(make, sell, store)) return m.get_objective_value()
def test(cas_conn): m = so.Model(name='factory_planning_2', session=cas_conn) # Input data product_list = ['prod{}'.format(i) for i in range(1, 8)] product_data = pd.DataFrame([10, 6, 8, 4, 11, 9, 3], columns=['profit'], index=product_list) demand_data = [ [500, 1000, 300, 300, 800, 200, 100], [600, 500, 200, 0, 400, 300, 150], [300, 600, 0, 0, 500, 400, 100], [200, 300, 400, 500, 200, 0, 100], [0, 100, 500, 100, 1000, 300, 0], [500, 500, 100, 300, 1100, 500, 60]] demand_data = pd.DataFrame( demand_data, columns=product_list, index=range(1, 7)) machine_type_product_data = [ ['grinder', 0.5, 0.7, 0, 0, 0.3, 0.2, 0.5], ['vdrill', 0.1, 0.2, 0, 0.3, 0, 0.6, 0], ['hdrill', 0.2, 0, 0.8, 0, 0, 0, 0.6], ['borer', 0.05, 0.03, 0, 0.07, 0.1, 0, 0.08], ['planer', 0, 0, 0.01, 0, 0.05, 0, 0.05]] machine_type_product_data = \ pd.DataFrame(machine_type_product_data, columns=['machine_type'] + product_list).set_index(['machine_type']) machine_types_data = [ ['grinder', 4, 2], ['vdrill', 2, 2], ['hdrill', 3, 3], ['borer', 1, 1], ['planer', 1, 1]] machine_types_data = pd.DataFrame(machine_types_data, columns=[ 'machine_type', 'num_machines', 'num_machines_needing_maintenance'])\ .set_index(['machine_type']) store_ub = 100 storage_cost_per_unit = 0.5 final_storage = 50 num_hours_per_period = 24 * 2 * 8 # Problem definition PRODUCTS = product_list profit = product_data['profit'] PERIODS = range(1, 7) MACHINE_TYPES = machine_types_data.index.tolist() num_machines = machine_types_data['num_machines'] make = m.add_variables(PRODUCTS, PERIODS, lb=0, name='make') sell = m.add_variables(PRODUCTS, PERIODS, lb=0, ub=demand_data.transpose(), name='sell') store = m.add_variables(PRODUCTS, PERIODS, lb=0, ub=store_ub, name='store') for p in PRODUCTS: store[p, 6].set_bounds(lb=final_storage, ub=final_storage) storageCost = so.quick_sum( storage_cost_per_unit * store[p, t] for p in PRODUCTS for t in PERIODS) revenue = so.quick_sum(profit[p] * sell[p, t] for p in PRODUCTS for t in PERIODS) m.set_objective(revenue-storageCost, sense=so.MAX, name='total_profit') num_machines_needing_maintenance = \ machine_types_data['num_machines_needing_maintenance'] numMachinesDown = m.add_variables(MACHINE_TYPES, PERIODS, vartype=so.INT, lb=0, name='numMachinesDown') production_time = machine_type_product_data m.add_constraints(( so.quick_sum(production_time.at[mc, p] * make[p, t] for p in PRODUCTS) <= num_hours_per_period * (num_machines[mc] - numMachinesDown[mc, t]) for mc in MACHINE_TYPES for t in PERIODS), name='machine_hours_con') m.add_constraints((so.quick_sum(numMachinesDown[mc, t] for t in PERIODS) == num_machines_needing_maintenance[mc] for mc in MACHINE_TYPES), name='maintenance_con') m.add_constraints(((store[p, t-1] if t-1 in PERIODS else 0) + make[p, t] == sell[p, t] + store[p, t] for p in PRODUCTS for t in PERIODS), name='flow_balance_con') res = m.solve() if res is not None: print(so.get_solution_table(make, sell, store)) print(so.get_solution_table(numMachinesDown).unstack(level=-1)) print(m.get_solution_summary()) print(m.get_problem_summary()) return m.get_objective_value()
def test(cas_conn): m = so.Model(name='mining_optimization', session=cas_conn) mine_data = pd.DataFrame([ ['mine1', 5, 2, 1.0], ['mine2', 4, 2.5, 0.7], ['mine3', 4, 1.3, 1.5], ['mine4', 5, 3, 0.5], ], columns=['mine', 'cost', 'extract_ub', 'quality']).\ set_index(['mine']) year_data = pd.DataFrame([ [1, 0.9], [2, 0.8], [3, 1.2], [4, 0.6], [5, 1.0], ], columns=['year', 'quality_required']).set_index(['year']) max_num_worked_per_year = 3 revenue_per_ton = 10 discount_rate = 0.10 MINES = mine_data.index.tolist() cost = mine_data['cost'] extract_ub = mine_data['extract_ub'] quality = mine_data['quality'] YEARS = year_data.index.tolist() quality_required = year_data['quality_required'] isOpen = m.add_variables(MINES, YEARS, vartype=so.BIN, name='isOpen') isWorked = m.add_variables(MINES, YEARS, vartype=so.BIN, name='isWorked') extract = m.add_variables(MINES, YEARS, lb=0, name='extract') [extract[i, j].set_bounds(ub=extract_ub[i]) for i in MINES for j in YEARS] extractedPerYear = {j: extract.sum('*', j) for j in YEARS} discount = {j: 1 / (1 + discount_rate)**(j - 1) for j in YEARS} totalRevenue = revenue_per_ton *\ so.quick_sum(discount[j] * extractedPerYear[j] for j in YEARS) totalCost = so.quick_sum(discount[j] * cost[i] * isOpen[i, j] for i in MINES for j in YEARS) m.set_objective(totalRevenue - totalCost, sense=so.MAX, name='totalProfit') m.add_constraints((extract[i, j] <= extract[i, j]._ub * isWorked[i, j] for i in MINES for j in YEARS), name='link') m.add_constraints( (isWorked.sum('*', j) <= max_num_worked_per_year for j in YEARS), name='cardinality') m.add_constraints( (isWorked[i, j] <= isOpen[i, j] for i in MINES for j in YEARS), name='worked_implies_open') m.add_constraints((isOpen[i, j] <= isOpen[i, j - 1] for i in MINES for j in YEARS if j != 1), name='continuity') m.add_constraints((so.quick_sum(quality[i] * extract[i, j] for i in MINES) == quality_required[j] * extractedPerYear[j] for j in YEARS), name='quality_con') res = m.solve() if res is not None: print(so.get_solution_table(isOpen, isWorked, extract)) quality_sol = { j: so.quick_sum(quality[i] * extract[i, j].get_value() for i in MINES) / extractedPerYear[j].get_value() for j in YEARS } qs = so.dict_to_frame(quality_sol, ['quality_sol']) epy = so.dict_to_frame(extractedPerYear, ['extracted_per_year']) print(so.get_solution_table(epy, qs, quality_required)) return m.get_objective_value()
def test(cas_conn): m = so.Model(name='economic_planning', session=cas_conn) industry_data = pd.DataFrame([ ['coal', 150, 300, 60], ['steel', 80, 350, 60], ['transport', 100, 280, 30] ], columns=['industry', 'init_stocks', 'init_productive_capacity', 'demand']).set_index(['industry']) production_data = pd.DataFrame([ ['coal', 0.1, 0.5, 0.4], ['steel', 0.1, 0.1, 0.2], ['transport', 0.2, 0.1, 0.2], ['manpower', 0.6, 0.3, 0.2], ], columns=['input', 'coal', 'steel', 'transport']).set_index(['input']) productive_capacity_data = pd.DataFrame([ ['coal', 0.0, 0.7, 0.9], ['steel', 0.1, 0.1, 0.2], ['transport', 0.2, 0.1, 0.2], ['manpower', 0.4, 0.2, 0.1], ], columns=['input', 'coal', 'steel', 'transport']).set_index(['input']) manpower_capacity = 470 num_years = 5 YEARS = list(range(1, num_years+1)) YEARS0 = [0] + list(YEARS) INDUSTRIES = industry_data.index.tolist() [init_stocks, init_productive_capacity, demand] = so.read_frame( industry_data) # INPUTS = production_data.index.tolist() production_coeff = so.flatten_frame(production_data) productive_capacity_coeff = so.flatten_frame(productive_capacity_data) static_production = m.add_variables(INDUSTRIES, lb=0, name='static_production') m.set_objective(0, sense=so.MIN, name='Zero') m.add_constraints((static_production[i] == demand[i] + so.quick_sum( production_coeff[i, j] * static_production[j] for j in INDUSTRIES) for i in INDUSTRIES), name='static_con') m.solve() print(so.get_solution_table(static_production, sort=True)) final_demand = so.get_solution_table( static_production, sort=True)['static_production'] # Alternative way # final_demand = {} # for i in INDUSTRIES: # final_demand[i] = static_production.get_value() production = m.add_variables(INDUSTRIES, range(0, num_years+2), lb=0, name='production') stock = m.add_variables(INDUSTRIES, range(0, num_years+2), lb=0, name='stock') extra_capacity = m.add_variables(INDUSTRIES, range(1, num_years+3), lb=0, name='extra_capacity') productive_capacity = {} for i in INDUSTRIES: for year in range(1, num_years+2): productive_capacity[i, year] = init_productive_capacity[i] +\ so.quick_sum(extra_capacity[i, y] for y in range(2, year+1)) for i in INDUSTRIES: production[i, 0].set_bounds(ub=0) stock[i, 0].set_bounds(lb=init_stocks[i], ub=init_stocks[i]) total_productive_capacity = sum(productive_capacity[i, num_years] for i in INDUSTRIES) total_production = so.quick_sum(production[i, year] for i in INDUSTRIES for year in [4, 5]) total_manpower = so.quick_sum(production_coeff['manpower', i] * production[i, year+1] + productive_capacity_coeff['manpower', i] * extra_capacity[i, year+2] for i in INDUSTRIES for year in YEARS) continuity_con = m.add_constraints(( stock[i, year] + production[i, year] == (demand[i] if year in YEARS else 0) + so.quick_sum(production_coeff[i, j] * production[j, year+1] + productive_capacity_coeff[i, j] * extra_capacity[j, year+2] for j in INDUSTRIES) + stock[i, year+1] for i in INDUSTRIES for year in YEARS0), name='continuity_con') manpower_con = m.add_constraints(( so.quick_sum(production_coeff['manpower', j] * production[j, year] + productive_capacity_coeff['manpower', j] * extra_capacity[j, year+1] for j in INDUSTRIES) <= manpower_capacity for year in range(1, num_years+2)), name='manpower_con') capacity_con = m.add_constraints((production[i, year] <= productive_capacity[i, year] for i in INDUSTRIES for year in range(1, num_years+2)), name='capacity_con') for i in INDUSTRIES: production[i, num_years+1].set_bounds(lb=final_demand[i]) for i in INDUSTRIES: for year in [num_years+1, num_years+2]: extra_capacity[i, year].set_bounds(ub=0) problem1 = so.Model(name='Problem1', session=cas_conn) problem1.include(production, stock, extra_capacity, continuity_con, manpower_con, capacity_con) problem1.set_objective(total_productive_capacity, sense=so.MAX, name='total_productive_capacity') problem1.solve() productive_capacity_fr = so.dict_to_frame(productive_capacity, cols=['productive_capacity']) print(so.get_solution_table(production, stock, extra_capacity, productive_capacity_fr, sort=True)) print(so.get_solution_table(manpower_con.get_expressions(), sort=True)) # Problem 2 problem2 = so.Model(name='Problem2', session=cas_conn) problem2.include(problem1) problem2.set_objective(total_production, name='total_production', sense=so.MAX) for i in INDUSTRIES: for year in YEARS: continuity_con[i, year].set_rhs(0) problem2.solve() print(so.get_solution_table(production, stock, extra_capacity, productive_capacity, sort=True)) print(so.get_solution_table(manpower_con.get_expressions(), sort=True)) # Problem 3 problem3 = so.Model(name='Problem3', session=cas_conn) problem3.include(production, stock, extra_capacity, continuity_con, capacity_con) problem3.set_objective(total_manpower, sense=so.MAX, name='total_manpower') for i in INDUSTRIES: for year in YEARS: continuity_con[i, year].set_rhs(demand[i]) problem3.solve() print(so.get_solution_table(production, stock, extra_capacity, productive_capacity, sort=True)) print(so.get_solution_table(manpower_con.get_expressions(), sort=True)) return problem3.get_objective_value()