def amplSubTourElimination(ampl: AMPL): # Add the constraint and the needed parameters subToursAMPL = """param nSubtours >= 0 integer, default 0; set SUB {1..nSubtours} within NODES; subject to Subtour_Elimination {k in 1..nSubtours}: sum {i in SUB[k], j in NODES diff SUB[k]} if (i,j) in PAIRS then X[i,j] else X[j,i] >= 2;""" ampl.eval(subToursAMPL) AMPLnSubtours = ampl.getParameter("nSubtours") AMPLSubtours = ampl.getSet("SUB") allsubtours = list() while True: # Repeat until the solution contains only one tour ampl.solve() # Get solution ARCS = ampl.getData("{(i,j) in PAIRS : X[i,j]>0} X[i,j];") ARCS = set([(i, j) for (i, j, k) in ARCS.toList()]) nodes = NODES.copy() subtours = findSubTours(ARCS, nodes) # If we have only one tour, the solution is valid if len(subtours) <= 1: break if PLOTSUBTOURS: plotTours(subtours, CPOINTS) # Else add the current tours to the list of subtours allsubtours.extend(subtours) # And add those to the constraints by assigning the values to # the parameter and the set AMPLnSubtours.set(len(allsubtours)) for (i, tour) in enumerate(allsubtours): AMPLSubtours[i + 1].setValues(tour)
def tsp_model(tsp_data, enable_mtz=True): from amplpy import AMPL from math import sqrt ampl = AMPL() ampl.eval(''' param n; set V := 1..n; set A := {(i,j) in V cross V : i != j}; param c{A} >= 0 default Infinity; var x{A}, binary; var u{V} >= 0; minimize total: sum{(i,j) in A} c[i,j] * x[i,j]; s.t. enter{j in V}: sum{i in V: i != j} x[i, j] == 1; s.t. leave{i in V}: sum{j in V: j != i} x[i, j] == 1; ''') if enable_mtz: ampl.eval(''' # subtour elimination Miller, Tucker and Zemlin (MTZ) (1960) subject to MTZ{(i,j) in A: i != 1}: u[i]-u[j] + (n-1)*x[i,j] <= n-2; ''') n, xs, ys = load_tsp_data(tsp_data) dist = {(i + 1, j + 1): sqrt((xs[j] - xs[i])**2 + (ys[j] - ys[i])**2) for i in range(n) for j in range(n) if i != j} ampl.param['n'] = n ampl.param['c'] = dist return ampl
def solve(dat): """ core solving routine :param dat: a good ticdat for the input_schema :return: a good ticdat for the solution_schema, or None """ assert input_schema.good_tic_dat_object(dat) assert not input_schema.find_foreign_key_failures(dat) assert not input_schema.find_data_type_failures(dat) assert not input_schema.find_data_row_failures(dat) # use default parameters, unless they are overridden by user-supplied parameters full_parameters = dict( default_parameters, **{k: v["Value"] for k, v in dat.parameters.items()}) sln = solution_schema.TicDat() # create an empty solution' ampl_dat = input_schema.copy_to_ampl( dat, excluded_tables=set(input_schema.all_tables).difference( {"load_amounts"})) # solve a distinct MIP for each pair of (# of one-way-trips, amount leftover) for number_trips, amount_leftover in product(dat.number_of_one_way_trips, dat.amount_leftover): ampl = AMPL() ampl.setOption('solver', 'gurobi') # use the ampl_format function for AMPL friendly key-named text substitutions ampl.eval( ampl_format(""" set LOAD_AMTS; var Num_Visits {LOAD_AMTS} integer >= 0; var Amt_Leftover >= {{amount_leftover_lb}}, <= {{amount_leftover_ub}}; minimize Total_Visits: sum {la in LOAD_AMTS} Num_Visits[la]; subj to Set_Amt_Leftover: Amt_Leftover = sum {la in LOAD_AMTS} la * Num_Visits[la] - {{one_way_price}} * {{number_trips}};""", number_trips=number_trips, one_way_price=full_parameters["One Way Price"], amount_leftover_lb=amount_leftover if full_parameters["Amount Leftover Constraint"] == "Equality" else 0, amount_leftover_ub=amount_leftover)) input_schema.set_ampl_data(ampl_dat, ampl, {"load_amounts": "LOAD_AMTS"}) ampl.solve() if ampl.getValue("solve_result") != "infeasible": # store the results if and only if the model is feasible for la, x in ampl.getVariable( "Num_Visits").getValues().toDict().items(): if round(x) > 0: sln.load_amount_details[number_trips, amount_leftover, la] = round(x) sln.load_amount_summary[number_trips, amount_leftover]["Number Of Visits"]\ += round(x) return sln
def solve(dat): """ core solving routine :param dat: a good pandat for the input_schema :return: a good pandat for the solution_schema, or None """ assert input_schema.good_pan_dat_object(dat) assert not input_schema.find_duplicates(dat) assert not input_schema.find_foreign_key_failures(dat) assert not input_schema.find_data_type_failures(dat) assert not input_schema.find_data_row_failures(dat) # build the AMPL math model if AMPL is None: # even if you don't have amplpy installed, you can still import this file for other uses print("*****\namplpy needs to be installed for this example code to solve!\n*****\n") ampl = AMPL() ampl.setOption('solver', 'gurobi') ampl.eval(""" set CAT; set FOOD; param cost {FOOD} >= 0, < Infinity; param n_min {CAT} >= 0, < Infinity; param n_max {i in CAT} >= n_min[i]; param amt {FOOD, CAT} >= 0, < Infinity; var Buy {j in FOOD} >= 0; var Consume {i in CAT } >= n_min [i], <= n_max [i]; minimize Total_Cost: sum {j in FOOD} cost[j] * Buy[j]; subject to Diet {i in CAT}: Consume[i] = sum {j in FOOD} amt[j,i] * Buy[j]; """) # copy the tables to amplpy.DataFrame objects, renaming the data fields as needed dat = input_schema.copy_to_ampl(dat, field_renamings={ ("foods", "Cost"): "cost", ("categories", "Min Nutrition"): "n_min", ("categories", "Max Nutrition"): "n_max", ("nutrition_quantities", "Quantity"): "amt"}) # load the amplpy.DataFrame objects into the AMPL model, explicitly identifying how to populate the AMPL sets input_schema.set_ampl_data(dat, ampl, {"categories": "CAT", "foods": "FOOD"}) # solve and recover the solution if feasible ampl.solve() if ampl.getValue("solve_result") != "infeasible": # solution tables are populated by mapping solution (table, field) to AMPL variable sln = solution_schema.copy_from_ampl_variables( {("buy_food", "Quantity"): ampl.getVariable("Buy"), ("consume_nutrition", "Quantity"): ampl.getVariable("Consume")}) # append the solution KPI results to the solution parameters table sln.parameters.loc[0] = ['Total Cost', ampl.getObjective('Total_Cost').value()] return sln
def solve(dat): assert input_schema.good_tic_dat_object(dat) # copy the data over to amplpy.DataFrame objects, renaming the data fields as needed dat = input_schema.copy_to_ampl(dat, field_renamings={ ("foods", "Cost"): "cost", ("categories", "Min Nutrition"): "n_min", ("categories", "Max Nutrition"): "n_max", ("nutrition_quantities", "Quantity"): "amt" }) # create and AMPL object and load it with .mod code ampl = AMPL() ampl.setOption('solver', 'gurobi') ampl.eval(""" set CAT; set FOOD; param cost {FOOD} > 0; param n_min {CAT} >= 0; param n_max {i in CAT} >= n_min[i]; param amt {FOOD, CAT} >= 0; var Buy {j in FOOD} >= 0; var Consume {i in CAT } >= n_min [i], <= n_max [i]; minimize Total_Cost: sum {j in FOOD} cost[j] * Buy[j]; subject to Diet {i in CAT}: Consume[i] = sum {j in FOOD} amt[j,i] * Buy[j]; """) # set the AMPL object with the amplpy.DataFrame data and solve input_schema.set_ampl_data(dat, ampl, { "categories": "CAT", "foods": "FOOD" }) ampl.solve() if ampl.getValue("solve_result") != "infeasible": sln = solution_schema.copy_from_ampl_variables({ ("buy_food", "Quantity"): ampl.getVariable("Buy"), ("consume_nutrition", "Quantity"): ampl.getVariable("Consume") }) sln.parameters['Total Cost'] = ampl.getObjective('Total_Cost').value() return sln
def run_ampl_model(self, data): # Intiialize AMPL choose solver and load model ampl = AMPL() ampl.eval('option solver cplex;') ampl.read('model/ampl/model.mod') # Generate and load temporary data file data_file = self.generate_temp_data_file(data) ampl.readData(data_file.name) data_file.close() ampl.solve() return ampl
def solve(dat): """ core solving routine :param dat: a good ticdat for the input_schema :return: a good ticdat for the solution_schema, or None """ assert input_schema.good_tic_dat_object(dat) assert not input_schema.find_foreign_key_failures(dat) assert not input_schema.find_data_type_failures(dat) # copy the data over to amplpy.DataFrame objects, renaming the data fields as needed dat = input_schema.copy_to_ampl(dat, field_renamings={("arcs", "Capacity"): "capacity", ("cost", "Cost"): "cost", ("inflow", "Quantity"): "inflow"}) # for instructional purposes, the following code anticipates extreme sparsity and doesn't generate # conservation of flow records unless they are really needed ampl = AMPL() ampl.setOption('solver', 'gurobi') ampl.eval(""" set NODES; set ARCS within {i in NODES, j in NODES: i <> j}; set COMMODITIES; param capacity {ARCS} >= 0; set SHIPMENT_OPTIONS within {COMMODITIES,ARCS}; param cost {SHIPMENT_OPTIONS} > 0; set INFLOW_INDEX within {COMMODITIES,NODES}; param inflow {INFLOW_INDEX}; var Flow {SHIPMENT_OPTIONS} >= 0; minimize TotalCost: sum {(h,i,j) in SHIPMENT_OPTIONS} cost[h,i,j] * Flow[h,i,j]; subject to Capacity {(i,j) in ARCS}: sum {(h,i,j) in SHIPMENT_OPTIONS} Flow[h,i,j] <= capacity[i,j]; subject to Conservation {h in COMMODITIES, j in NODES: card {(h,i,j) in SHIPMENT_OPTIONS} > 0 or card {(h,j,i) in SHIPMENT_OPTIONS} > 0 or (h,j) in INFLOW_INDEX}: sum {(h,i,j) in SHIPMENT_OPTIONS} Flow[h,i,j] + (if (h,j) in INFLOW_INDEX then inflow[h,j]) = sum {(h,j,i) in SHIPMENT_OPTIONS} Flow[h,j,i]; """) input_schema.set_ampl_data(dat, ampl, {"nodes": "NODES", "arcs": "ARCS", "commodities": "COMMODITIES", "cost":"SHIPMENT_OPTIONS", "inflow":"INFLOW_INDEX"}) ampl.solve() if ampl.getValue("solve_result") != "infeasible": sln = solution_schema.copy_from_ampl_variables( {('flow' ,'Quantity'):ampl.getVariable("Flow")}) sln.parameters["Total Cost"] = ampl.getObjective('TotalCost').value() return sln
def compute_defense(att_stg, prod_dist, num_of_hp=args.fix_honeypots, rationality=args.fix_rationality): # production ports and attacker"s strategy df = DataFrame('P') ports = getRelPorts(att_stg, prod_dist, num=25) df.setColumn('P', list(ports)) #ports = getAllPorts(att_stg, prod_dist) #print(('Considered ports are: ', ports)) att = [att_stg.get(x, 0) for x in ports] prod = [prod_dist.get(x, 0) for x in ports] #print(('Attack ports: ', att, len(att))) #print(('Dist ports: ', prod, len(prod))) df.addColumn('s', prod) df.addColumn('p', att) ampl = AMPL(Environment(args.ampl)) ampl.setOption('solver', args.solver) # ampl.setOption('verbosity', 'terse') # Read the model file ampl.read(args.model) # Assign data to s ampl.setData(df, 'P') ampl.eval('let L := {}; let rat := {};'.format(num_of_hp, rationality)) #print(df) # Solve the model with suppress_stdout(): ampl.solve() reward = ampl.getObjective("reward").value() hp_stg = ampl.getData("{j in P} h[j]") output = dict() stg_json = list() for k, v in hp_stg.toDict().items(): stg_json.append({"port": int(k), "prob": v}) output.update({"stg": stg_json}) output.update({"reward": reward}) output.update({"rationality": rationality}) output.update({"num_of_hp": num_of_hp}) output.update({"used_hps": ampl.getData("tot").toDict().popitem()[1]}) ampl.close() return output
def solve(dat): ampl = AMPL() ampl.setOption('solver', 'gurobi') ampl = AMPL() ampl.setOption('solver', 'gurobi') ampl.eval(""" set NODES; set ARCS within {i in NODES, j in NODES: i <> j}; set COMMODITIES; param volume {COMMODITIES} > 0, < Infinity; param capacity {ARCS} >= 0; param cost {COMMODITIES,ARCS} >= 0, < Infinity; param inflow {COMMODITIES,NODES} > -Infinity, < Infinity; var Flow {COMMODITIES,ARCS} >= 0; minimize TotalCost: sum {h in COMMODITIES, (i,j) in ARCS} cost[h,i,j] * Flow[h,i,j]; subject to Capacity {(i,j) in ARCS}: sum {h in COMMODITIES} Flow[h,i,j] * volume[h] <= capacity[i,j]; subject to Conservation {h in COMMODITIES, j in NODES}: sum {(i,j) in ARCS} Flow[h,i,j] + inflow[h,j] = sum {(j,i) in ARCS} Flow[h,j,i]; """) # copy the tables to amplpy.DataFrame objects, renaming the data fields as needed dat = input_schema.copy_to_ampl(dat, field_renamings={ ("commodities", "Volume"): "volume", ("arcs", "Capacity"): "capacity", ("cost", "Cost"): "cost", ("inflow", "Quantity"): "inflow" }) # load the amplpy.DataFrame objects into the AMPL model, explicitly identifying how to populate the AMPL sets input_schema.set_ampl_data(dat, ampl, { "nodes": "NODES", "arcs": "ARCS", "commodities": "COMMODITIES" }) ampl.solve() if ampl.getValue("solve_result") != "infeasible": # solution tables are populated by mapping solution (table, field) to AMPL variable sln = solution_schema.copy_from_ampl_variables({ ('flow', 'Quantity'): ampl.getVariable("Flow") }) # append the solution KPI results to the solution parameters table sln.parameters.loc[0] = [ 'Total Cost', ampl.getObjective('TotalCost').value() ] return sln
def solve(dat): """ core solving routine :param dat: a good ticdat for the input_schema :return: a good ticdat for the solution_schema, or None """ assert input_schema.good_tic_dat_object(dat) assert not input_schema.find_foreign_key_failures(dat) assert not input_schema.find_data_type_failures(dat) # copy the data over to amplpy.DataFrame objects, renaming the data fields as needed dat = input_schema.copy_to_ampl(dat, field_renamings={("arcs", "Capacity"): "capacity", ("cost", "Cost"): "cost", ("inflow", "Quantity"): "inflow"}) ampl = AMPL() ampl.setOption('solver', 'gurobi') ampl.eval(""" set NODES; set ARCS within {i in NODES, j in NODES: i <> j}; set COMMODITIES; param capacity {ARCS} >= 0; param cost {COMMODITIES,ARCS} > 0; param inflow {COMMODITIES,NODES}; var Flow {COMMODITIES,ARCS} >= 0; minimize TotalCost: sum {h in COMMODITIES, (i,j) in ARCS} cost[h,i,j] * Flow[h,i,j]; subject to Capacity {(i,j) in ARCS}: sum {h in COMMODITIES} Flow[h,i,j] <= capacity[i,j]; subject to Conservation {h in COMMODITIES, j in NODES}: sum {(i,j) in ARCS} Flow[h,i,j] + inflow[h,j] = sum {(j,i) in ARCS} Flow[h,j,i]; """) input_schema.set_ampl_data(dat, ampl, {"nodes": "NODES", "arcs": "ARCS", "commodities": "COMMODITIES"}) ampl.solve() if ampl.getValue("solve_result") != "infeasible": sln = solution_schema.copy_from_ampl_variables( {('flow' ,'Quantity'):ampl.getVariable("Flow")}) sln.parameters["Total Cost"] = ampl.getObjective('TotalCost').value() return sln
def solve(dat): # build the AMPL math model ampl = AMPL() ampl.setOption('solver', 'gurobi') ampl.eval(""" set CAT; set FOOD; param cost {FOOD} > 0, < Infinity; param n_min {CAT} >= 0, < Infinity; param n_max {i in CAT} >= n_min[i]; param amt {FOOD, CAT} >= 0, < Infinity; var Buy {j in FOOD} >= 0; var Consume {i in CAT } >= n_min [i], <= n_max [i]; minimize Total_Cost: sum {j in FOOD} cost[j] * Buy[j]; subject to Diet {i in CAT}: Consume[i] = sum {j in FOOD} amt[j,i] * Buy[j]; """) # copy the tables to amplpy.DataFrame objects, renaming the data fields as needed dat = input_schema.copy_to_ampl(dat, field_renamings={ ("foods", "Cost"): "cost", ("categories", "Min Nutrition"): "n_min", ("categories", "Max Nutrition"): "n_max", ("nutrition_quantities", "Quantity"): "amt"}) # load the amplpy.DataFrame objects into the AMPL model, explicitly identifying how to populate the AMPL sets input_schema.set_ampl_data(dat, ampl, {"categories": "CAT", "foods": "FOOD"}) # solve and recover the solution if feasible ampl.solve() if ampl.getValue("solve_result") != "infeasible": # solution tables are populated by mapping solution (table, field) to AMPL variable sln = solution_schema.copy_from_ampl_variables( {("buy_food", "Quantity"): ampl.getVariable("Buy"), ("consume_nutrition", "Quantity"): ampl.getVariable("Consume")}) # append the solution KPI results to the solution parameters table sln.parameters.loc[0] = ['Total Cost', ampl.getObjective('Total_Cost').value()] return sln
def main(argc, argv): from amplpy import AMPL, DataFrame os.chdir(os.path.dirname(__file__) or os.curdir) try: # Create an AMPL instance ampl = AMPL() """ # If the AMPL installation directory is not in the system search path: from amplpy import Environment ampl = AMPL( Environment('full path to the AMPL installation directory')) """ ampl.eval('set CITIES; set LINKS within (CITIES cross CITIES);') ampl.eval('param cost {LINKS} >= 0; param capacity {LINKS} >= 0;') ampl.eval('data; set CITIES := PITT NE SE BOS EWR BWI ATL MCO;') cost = [2.5, 3.5, 1.7, 0.7, 1.3, 1.3, 0.8, 0.2, 2.1] capacity = [250, 250, 100, 100, 100, 100, 100, 100, 100] LinksFrom = ['PITT', 'PITT', 'NE', 'NE', 'NE', 'SE', 'SE', 'SE', 'SE'] LinksTo = ['NE', 'SE', 'BOS', 'EWR', 'BWI', 'EWR', 'BWI', 'ATL', 'MCO'] df = DataFrame(('LINKSFrom', 'LINKSTo'), ('cost', 'capacity')) df.setColumn('LINKSFrom', LinksFrom) df.setColumn('LINKSTo', LinksTo) df.setColumn('cost', cost) df.setColumn('capacity', capacity) print(df) ampl.setData(df, 'LINKS') except Exception as e: print(e) raise
def main(argc, argv): from amplpy import AMPL, DataFrame os.chdir(os.path.dirname(__file__) or os.curdir) try: ampl = AMPL() ampl.eval('set CITIES; set LINKS within (CITIES cross CITIES);') ampl.eval('param cost {LINKS} >= 0; param capacity {LINKS} >= 0;') ampl.eval('data; set CITIES := PITT NE SE BOS EWR BWI ATL MCO;') cost = [2.5, 3.5, 1.7, 0.7, 1.3, 1.3, 0.8, 0.2, 2.1] capacity = [250, 250, 100, 100, 100, 100, 100, 100, 100] LinksFrom = ['PITT', 'PITT', 'NE', 'NE', 'NE', 'SE', 'SE', 'SE', 'SE'] LinksTo = ['NE', 'SE', 'BOS', 'EWR', 'BWI', 'EWR', 'BWI', 'ATL', 'MCO'] df = DataFrame(('LINKSFrom', 'LINKSTo'), ('cost', 'capacity')) df.setColumn('LINKSFrom', LinksFrom) df.setColumn('LINKSTo', LinksTo) df.setColumn('cost', cost) df.setColumn('capacity', capacity) print(df) ampl.setData(df, 'LINKS') except Exception as e: print(e) raise
def main(argc, argv): from amplpy import AMPL, DataFrame os.chdir(os.path.dirname(__file__) or os.curdir) # Create an AMPL instance ampl = AMPL() """ # If the AMPL installation directory is not in the system search path: from amplpy import Environment ampl = AMPL( Environment('full path to the AMPL installation directory')) """ ampl.eval("set CITIES; set LINKS within (CITIES cross CITIES);") ampl.eval("param cost {LINKS} >= 0; param capacity {LINKS} >= 0;") ampl.eval("data; set CITIES := PITT NE SE BOS EWR BWI ATL MCO;") cost = [2.5, 3.5, 1.7, 0.7, 1.3, 1.3, 0.8, 0.2, 2.1] capacity = [250, 250, 100, 100, 100, 100, 100, 100, 100] links_from = ["PITT", "PITT", "NE", "NE", "NE", "SE", "SE", "SE", "SE"] links_to = ["NE", "SE", "BOS", "EWR", "BWI", "EWR", "BWI", "ATL", "MCO"] # Using amplpy.DataFrame df = DataFrame(("LINKSFrom", "LINKSTo"), ("cost", "capacity")) df.set_column("LINKSFrom", links_from) df.set_column("LINKSTo", links_to) df.set_column("cost", cost) df.set_column("capacity", capacity) print(df) ampl.set_data(df, "LINKS") ampl.display("LINKS") # Using pandas.DataFrame (recommended) df = pd.DataFrame( list(zip(links_from, links_to, cost, capacity)), columns=["LINKSFrom", "LINKSTo", "cost", "capacity"], ).set_index(["LINKSFrom", "LINKSTo"]) print(df) ampl.eval("reset data LINKS;") ampl.set_data(df, "LINKS") ampl.display("LINKS")
def solve(dat): """ core solving routine :param dat: a good ticdat for the input_schema :return: a good ticdat for the solution_schema, or None """ assert input_schema.good_tic_dat_object(dat) assert not input_schema.find_foreign_key_failures(dat) assert not input_schema.find_data_type_failures(dat) assert not input_schema.find_data_row_failures(dat) # copy the data over to amplpy.DataFrame objects, renaming the data fields as needed dat = input_schema.copy_to_ampl(dat, field_renamings={ ("foods", "Cost"): "cost", ("categories", "Min Nutrition"): "n_min", ("categories", "Max Nutrition"): "n_max", ("nutrition_quantities", "Quantity"): "amt" }) ampl = AMPL() ampl.setOption('solver', 'gurobi') ampl.eval(""" set CAT; set FOOD; param cost {FOOD} > 0; param n_min {CAT} >= 0; param n_max {i in CAT} >= n_min[i]; param amt {FOOD, CAT} >= 0; var Buy {j in FOOD} >= 0; var Consume {i in CAT } >= n_min [i], <= n_max [i]; minimize Total_Cost: sum {j in FOOD} cost[j] * Buy[j]; subject to Diet {i in CAT}: Consume[i] = sum {j in FOOD} amt[j,i] * Buy[j]; """) input_schema.set_ampl_data(dat, ampl, { "categories": "CAT", "foods": "FOOD" }) ampl.solve() if ampl.getValue("solve_result") != "infeasible": sln = solution_schema.copy_from_ampl_variables({ ("buy_food", "Quantity"): ampl.getVariable("Buy"), ("consume_nutrition", "Quantity"): ampl.getVariable("Consume") }) sln.parameters['Total Cost'] = ampl.getObjective('Total_Cost').value() return sln
orders = { 1630: 172, 1625: 714, 1620: 110, 1617: 262, 1540: 32, 1529: 100, 1528: 76, 1505: 110, 1504: 20, 1484: 58, 1466: 15, 1450: 10, 1283: 40, 1017: 50, 970: 70, 930: 8, 916: 210, 898: 395, 894: 49, 881: 17, 855: 20, 844: 10, 805: 718, 787: 17, 786: 710, 780: 150, 754: 34, 746: 15, 707: 122, 698: 7, 651: 10, 644: 15, 638: 10, 605: 10, 477: 4, 473: 34, 471: 25, 468: 10, 460: 908, 458: 161, 453: 765, 447: 21, 441: 20, 422: 318, 421: 22, 419: 382, 396: 22, 309: 123,266: 35 } widths = list(sorted(orders.keys(), reverse=True)) Master = AMPL() #Master.eval(_ampl_cells[0]) Master.eval(master) # Send scalar values Master.param['nPatterns'] = len(widths) Master.param['overrun'] = overrun Master.param['rawWidth'] = roll_width # Send order vector Master.set['WIDTHS'] = widths Master.param['order'] = orders # Generate and send initial pattern matrix Master.param['rolls'] = { (widths[i], 1+i): int(floor(roll_width/widths[i])) for i in range(len(widths)) }
def main(argc, argv): from amplpy import AMPL os.chdir(os.path.dirname(__file__) or os.curdir) try: modelDirectory = os.path.join( argv[2] if argc == 3 else os.path.join('..', 'models'), 'qpmv') # Create an AMPL instance ampl = AMPL() """ # If the AMPL installation directory is not in the system search path: from amplpy import Environment ampl = AMPL( Environment('full path to the AMPL installation directory')) """ # Number of steps of the efficient frontier steps = 10 if argc > 1: ampl.setOption('solver', argv[1]) ampl.setOption('reset_initial_guesses', True) ampl.setOption('send_statuses', False) ampl.setOption('solver', 'cplex') # Load the AMPL model from file ampl.read(os.path.join(modelDirectory, 'qpmv.mod')) ampl.read(os.path.join(modelDirectory, 'qpmvbit.run')) # Set tables directory (parameter used in the script above) ampl.getParameter('data_dir').set(modelDirectory) # Read tables ampl.readTable('assetstable') ampl.readTable('astrets') portfolioReturn = ampl.getVariable('portret') averageReturn = ampl.getParameter('averret') targetReturn = ampl.getParameter('targetret') variance = ampl.getObjective('cst') # Relax the integrality ampl.setOption('relax_integrality', True) # Solve the problem ampl.solve() # Calibrate the efficient frontier range minret = portfolioReturn.value() values = averageReturn.getValues() col = values.getColumn('averret') maxret = max(col) stepsize = (maxret - minret) / steps returns = [None] * steps variances = [None] * steps for i in range(steps): print('Solving for return = {:g}'.format(maxret - (i - 1) * stepsize)) # Set target return to the desired point targetReturn.set(maxret - (i - 1) * stepsize) ampl.eval('let stockopall:={};let stockrun:=stockall;') # Relax integrality ampl.setOption('relax_integrality', True) ampl.solve() print('QP result = {:g}'.format(variance.value())) # Adjust included stocks ampl.eval('let stockrun:={i in stockrun:weights[i]>0};') ampl.eval('let stockopall:={i in stockrun:weights[i]>0.5};') # Set integrality back ampl.setOption('relax_integrality', False) ampl.solve() print('QMIP result = {:g}'.format(variance.value())) # Store data of corrent frontier point returns[i] = maxret - (i - 1) * stepsize variances[i] = variance.value() # Display efficient frontier points print('RETURN VARIANCE') for i in range(steps): print('{:-6f} {:-6f}'.format(returns[i], variances[i])) except Exception as e: print(e) raise
amplcode.set_param("weeks", data=weeks) # amplcode.set_set('rooms', '{' + ','.join(map(str, rooms)) + '}') amplcode.set_set('rooms', '{' + ','.join(map(str, rooms)) + '}') amplcode.set_set('courses', '{1..%i}' % course_count) amplcode.set_set('departments', list(departmentHQ.keys())) amplcode.set_param_data("capacity", data=capacity.items()) amplcode.set_param_data("courseFrequency", data=course_frequency.items()) amplcode.set_param_data("departmentHQ", departmentHQ.items()) amplcode.set_param_data("departmentAssign", department_assign.items()) amplcode.set_param_data_3d("distance", distance_matrix.items()) amplcode.export("ora_export.txt") ampl.eval(amplcode.code) ### transform output print("Values from Ampl (where x[c, r, t] = 1)") print("c, r, t") values = ampl.getVariable('x').getValues().toPandas() data = [] for key, value in zip(values.index.tolist(), values.values.tolist()): if value[0] == 1: print(key) data.append(key) print("Number of Entries", len(data)) all_days = DpW * weeks arranged_data = []
def solve(dat): """ core solving routine :param dat: a good pandat for the input_schema :return: a good pandat for the solution_schema, or None """ assert input_schema.good_pan_dat_object(dat) assert not input_schema.find_duplicates(dat) assert not input_schema.find_foreign_key_failures(dat) assert not input_schema.find_data_type_failures(dat) assert not input_schema.find_data_row_failures(dat) # use default parameters, unless they are overridden by user-supplied parameters full_parameters = dict(default_parameters) for k,v in dat.parameters.itertuples(index=False): full_parameters[k] = v # build the AMPL math model ampl = AMPL() ampl.setOption('solver', 'gurobi') ampl.eval(""" param amount_leftover_lb >= 0, < Infinity; param amount_leftover_ub >= amount_leftover_lb; param one_way_price >= 0, < Infinity; param number_trips >= 0, < Infinity; set LOAD_AMTS; var Num_Visits {LOAD_AMTS} integer >= 0; var Amt_Leftover >= amount_leftover_lb, <= amount_leftover_ub; minimize Total_Visits: sum {la in LOAD_AMTS} Num_Visits[la]; subj to Set_Amt_Leftover: Amt_Leftover = sum {la in LOAD_AMTS} la * Num_Visits[la] - one_way_price * number_trips;""") # copy the Load Amounts table to an amplpy.DataFrame object ampl_dat = input_schema.copy_to_ampl(dat, excluded_tables= set(input_schema.all_tables).difference({"load_amounts"})) # populate the LOAD_AMTS set with the Load Amounts table input_schema.set_ampl_data(ampl_dat, ampl, {"load_amounts": "LOAD_AMTS"}) # we will build the Load Amount Details report sub-problem by sub-problem load_amount_details = DataFrame(columns=['Number One Way Trips', 'Amount Leftover', 'Load Amount', 'Number Of Visits']) # solve a distinct MIP for each pair of (# of one-way-trips, amount leftover) for number_trips, amount_leftover in product(list(dat.number_of_one_way_trips["Number"]), list(dat.amount_leftover["Amount"])): # set the appropriate parameters for this sub-problem ampl.param['amount_leftover_lb'] = amount_leftover \ if full_parameters["Amount Leftover Constraint"] == "Equality" else 0 ampl.param['amount_leftover_ub'] = amount_leftover ampl.param['number_trips'] = number_trips ampl.param['one_way_price'] = full_parameters["One Way Price"] # solve and recover the solution if feasible ampl.solve() if ampl.getValue("solve_result") != "infeasible": # convert the Num_Visits AMPL variable into a pandas.DataFrame that can be appended # to the load_amount_details report df = ampl.getVariable("Num_Visits").getValues().toPandas().reset_index() df.rename(columns = {df.columns[0]: "Load Amount", df.columns[1]: "Number Of Visits"}, inplace=True) df["Number One Way Trips"] = number_trips df["Amount Leftover"] = amount_leftover load_amount_details = load_amount_details.append(df[df["Number Of Visits"] > 0]) # pandas has amazing convenience routines for sorting and sub-totaling load_amount_details.sort_values(by=["Number One Way Trips", "Amount Leftover", "Load Amount"], inplace=True) load_amount_summary = DataFrame(columns=['Number One Way Trips', 'Amount Leftover', 'Number Of Visits']) if len(load_amount_details): cols = ["Number One Way Trips", "Amount Leftover"] load_amount_summary = load_amount_details.set_index(cols, drop=False).groupby(level=cols).aggregate( {"Number Of Visits":sum}).reset_index().sort_values(by=cols) sln = solution_schema.PanDat(load_amount_details=load_amount_details, load_amount_summary=load_amount_summary) return sln
def solve(dat): """ core solving routine :param dat: a good pandat for the input_schema :return: a good pandat for the solution_schema, or None """ assert input_schema.good_pan_dat_object(dat) assert not input_schema.find_duplicates(dat) assert not input_schema.find_foreign_key_failures(dat) assert not input_schema.find_data_type_failures(dat) # build the AMPL math model # for instructional purposes, the following code anticipates extreme sparsity and doesn't generate # conservation of flow records unless they are really needed ampl = AMPL() ampl.setOption('solver', 'gurobi') ampl.eval(""" set NODES; set ARCS within {i in NODES, j in NODES: i <> j}; set COMMODITIES; param volume {COMMODITIES} > 0, < Infinity; param capacity {ARCS} >= 0; set SHIPMENT_OPTIONS within {COMMODITIES,ARCS}; param cost {SHIPMENT_OPTIONS} >= 0, < Infinity; set INFLOW_INDEX within {COMMODITIES,NODES}; param inflow {INFLOW_INDEX} > -Infinity, < Infinity; var Flow {SHIPMENT_OPTIONS} >= 0; minimize TotalCost: sum {(h,i,j) in SHIPMENT_OPTIONS} cost[h,i,j] * Flow[h,i,j]; subject to Capacity {(i,j) in ARCS}: sum {(h,i,j) in SHIPMENT_OPTIONS} Flow[h,i,j] * volume[h] <= capacity[i,j]; subject to Conservation {h in COMMODITIES, j in NODES: card {(h,i,j) in SHIPMENT_OPTIONS} > 0 or card {(h,j,i) in SHIPMENT_OPTIONS} > 0 or (h,j) in INFLOW_INDEX}: sum {(h,i,j) in SHIPMENT_OPTIONS} Flow[h,i,j] + (if (h,j) in INFLOW_INDEX then inflow[h,j]) = sum {(h,j,i) in SHIPMENT_OPTIONS} Flow[h,j,i]; """) # copy the tables to amplpy.DataFrame objects, renaming the data fields as needed dat = input_schema.copy_to_ampl(dat, field_renamings={ ("commodities", "Volume"): "volume", ("arcs", "Capacity"): "capacity", ("cost", "Cost"): "cost", ("inflow", "Quantity"): "inflow" }) # load the amplpy.DataFrame objects into the AMPL model, explicitly identifying how to populate the AMPL sets input_schema.set_ampl_data( dat, ampl, { "nodes": "NODES", "arcs": "ARCS", "commodities": "COMMODITIES", "cost": "SHIPMENT_OPTIONS", "inflow": "INFLOW_INDEX" }) # solve and recover the solution if feasible ampl.solve() if ampl.getValue("solve_result") != "infeasible": # solution tables are populated by mapping solution (table, field) to AMPL variable sln = solution_schema.copy_from_ampl_variables({ ('flow', 'Quantity'): ampl.getVariable("Flow") }) # append the solution KPI results to the solution parameters table sln.parameters.loc[0] = [ 'Total Cost', ampl.getObjective('TotalCost').value() ] return sln
def solve(dat): assert input_schema.good_pan_dat_object(dat) assert not input_schema.find_duplicates(dat) assert not input_schema.find_foreign_key_failures(dat) assert not input_schema.find_data_type_failures(dat) assert not input_schema.find_data_row_failures(dat) parameters = input_schema.create_full_parameters_dict(dat) # for our purposes, its fine to assume all those drafted by someone else are drafted # prior to any players drafted by me dat.players["_temp_sort_column"] = dat.players["Average Draft Position"] dat.players.loc[dat.players["Draft Status"] == "Drafted By Someone Else", "_temp_sort_column"] = -2 dat.players.loc[dat.players["Draft Status"] == "Drafted By Me", "_temp_sort_column"] = -1 dat.players.sort_values(by="_temp_sort_column", inplace=True) dat.players.reset_index( drop=True, inplace=True) # get rid of the index that has become scrambled dat.players.reset_index( drop=False, inplace=True) # turn the sequential index into a column dat.players["Expected Draft Position"] = dat.players["index"] + 1 dat.players.drop(["index", "_temp_sort_column"], inplace=True, axis=1) # BE CAREFUL - this is https://github.com/ticdat/ticdat/issues/54 Not sure why this is needed dat.my_draft_positions.sort_values("Draft Position", inplace=True) assert list(dat.players["Expected Draft Position"]) == list( range(1, len(dat.players) + 1)) ampl = AMPL() ampl.setOption('solver', 'gurobi') ampl.eval(""" param max_number_of_flex_starters>=0; param starter_weight >=0; param reserve_weight >= 0; set MY_DRAFT_POSITIONS ordered; set POSITIONS; param min_number_starters{POSITIONS} >= 0, < Infinity; param max_number_starters{p in POSITIONS} >= min_number_starters[p]; param min_number_reserve{POSITIONS} >= 0, < Infinity; param max_number_reserve{p in POSITIONS} >= min_number_reserve[p]; param flex_status{POSITIONS} symbolic within {'Flex Eligible', 'Flex Ineligible'}; set PLAYERS; param draft_status{PLAYERS} symbolic within {'Un-drafted', 'Drafted By Me', 'Drafted By Someone Else'} ; param position{PLAYERS} symbolic within {POSITIONS}; param expected_draft_position{PLAYERS} >=1, < Infinity; param expected_points{PLAYERS} > -Infinity, < Infinity; set DRAFTABLE_PLAYERS within PLAYERS = {p in PLAYERS : draft_status[p] <> 'Drafted By Someone Else'}; var Starters {DRAFTABLE_PLAYERS} binary; var Reserves {DRAFTABLE_PLAYERS} binary; subject to Already_Drafted_By_Me {p in PLAYERS: draft_status[p] = 'Drafted By Me'}: Starters[p] + Reserves[p] = 1; subject to Cant_Draft_Twice {p in PLAYERS: draft_status[p] = 'Un-drafted'}: Starters[p] + Reserves[p] <= 1; subject to At_Most_X_Can_Be_Ahead_Of_Y {d in MY_DRAFT_POSITIONS}: sum{p in DRAFTABLE_PLAYERS: expected_draft_position[p] < d}(Starters[p] + Reserves[p]) <= ord(d, MY_DRAFT_POSITIONS) - 1; var My_Draft_Size >= card({p in PLAYERS: draft_status[p] = 'Drafted By Me'}), <= card(MY_DRAFT_POSITIONS); subject to Set_My_Draft_Size: sum{p in PLAYERS: draft_status[p] <> 'Drafted By Someone Else'}(Starters[p] + Reserves[p]) = My_Draft_Size; subject to Min_Number_Starters{p in POSITIONS}: sum{pl in DRAFTABLE_PLAYERS: position[pl] = p}Starters[pl] >= min_number_starters[p]; subject to Max_Number_Starters{p in POSITIONS}: sum{pl in DRAFTABLE_PLAYERS: position[pl] = p}Starters[pl] <= max_number_starters[p]; subject to Min_Number_Reserve{p in POSITIONS}: sum{pl in DRAFTABLE_PLAYERS: position[pl] = p}Reserves[pl]>= min_number_reserve[p]; subject to Max_Number_Reserve{p in POSITIONS}: sum{pl in DRAFTABLE_PLAYERS: position[pl] = p}Reserves[pl] <= max_number_reserve[p]; subject to Max_Number_Flex_Starters: sum{p in DRAFTABLE_PLAYERS: flex_status[position[p]] = 'Flex Eligible'}Starters[p] <= max_number_of_flex_starters; maximize Total_Yield: sum{p in DRAFTABLE_PLAYERS}(expected_points[p] * (starter_weight * Starters[p] + reserve_weight * Reserves[p])); """) # copy the tables to amplpy.DataFrame objects, renaming the data fields as needed ampl_dat = input_schema.copy_to_ampl( dat, excluded_tables={"parameters" }, # this table isn't passed directly to AMPL field_renamings={ ("players", "Expected Draft Position"): "expected_draft_position", ("players", "Position"): "position", ("players", 'Average Draft Position'): "", # this column isn't passed to AMPL ("players", 'Expected Points'): "expected_points", ("players", 'Draft Status'): "draft_status", ("roster_requirements", 'Min Num Starters'): 'min_number_starters', ("roster_requirements", 'Max Num Starters'): 'max_number_starters', ("roster_requirements", 'Min Num Reserve'): 'min_number_reserve', ("roster_requirements", 'Max Num Reserve'): 'max_number_reserve', ("roster_requirements", 'Flex Status'): 'flex_status', }) input_schema.set_ampl_data( ampl_dat, ampl, { "players": "PLAYERS", "my_draft_positions": "MY_DRAFT_POSITIONS", "roster_requirements": "POSITIONS" }) ampl.param['max_number_of_flex_starters'] = min( parameters['Maximum Number of Flex Starters'], len(dat.my_draft_positions)) ampl.param['starter_weight'] = parameters['Starter Weight'] ampl.param['reserve_weight'] = parameters['Reserve Weight'] # solve and recover solutions next ampl.solve() if ampl.getValue("solve_result") == "infeasible": print("No draft at all is possible!") return def selected_players(df, starter_or_reserve): assert len( df.columns ) == 1 # df.columns[0] is the name of the column that holds the solution variable result # only capture those rows where the solution variable is nearly 1 df = df[(df[df.columns[0]] - 1).abs() < 0.00001] df = df.join(dat.players.set_index('Player Name')) df.reset_index(inplace=True) df.rename(columns={df.columns[0]: "Player Name"}, inplace=True) df["Planned Or Actual"] = "Actual" df.loc[df["Draft Status"] == "Un-drafted", "Planned Or Actual"] = "Planned" df["Starter Or Reserve"] = starter_or_reserve return df[[ "Player Name", "Position", "Planned Or Actual", "Starter Or Reserve", "Expected Draft Position" ]] starters = selected_players( ampl.getVariable("Starters").getValues().toPandas(), "Starter") reserves = selected_players( ampl.getVariable("Reserves").getValues().toPandas(), "Reserve") my_draft = starters.append(reserves) my_draft = my_draft.sort_values(by="Expected Draft Position").drop( "Expected Draft Position", axis=1) my_draft.reset_index( drop=True, inplace=True) # now its index is sorted by Expected Draft Position sorted_draft_positions = dat.my_draft_positions.sort_values( by='Draft Position').reset_index(drop=True) if len(my_draft) < len(sorted_draft_positions): print( "Your model is over-constrained, and thus only a partial draft was possible" ) # my_draft and sorted_draft_positions both have sequential index values. join will use these by default sln = solution_schema.PanDat( my_draft=my_draft.join(sorted_draft_positions)) sln.parameters.loc[0] = [ "Total Yield", ampl.getObjective('Total_Yield').value() ] sln.parameters.loc[1] = [ "Draft Performed", "Complete" if len(sln.my_draft) == len(dat.my_draft_positions) else "Partial" ] return sln
# -*- coding: utf-8 -*- """ Created on Sat Aug 11 17:20:23 2018 @author: donja """ from amplpy import AMPL, Environment ampl = AMPL(Environment('D:\\amplide.mswin64\\amplide.mswin64')) ampl.option['solver'] = 'cplexamp' ampl.read('example.mod') #read the model ampl.eval('objective z; solve;') ampl.display('z', 'roth', 'traditional', 'surplus') pstring = """ objective function = {z} bi-weekly roth contribution = ${roth} bi-weekly traditional contribution = ${traditional} surplus (amount left after optimal allocation) = ${surplus} total (without surplus) = ${total} total (with surplus) = ${totalS} """ z = ampl.getValue('z') roth = ampl.getValue('roth') traditional = ampl.getValue('traditional') surplus = ampl.getValue('surplus') annual_roth_amt = roth * 12 * 2 annual_traditional_amt = traditional * 12 * 2
from amplpy import AMPL import amplpy_gurobi as ampls ampl = AMPL() ampl.eval(''' set A:=1..10; param n{a in A} := a*2; var x{A} >=0 integer; maximize z: sum{a in A} x[a]/2; c{a in A}: x[a] <= n[a]; ''') CALL_COUNT_MIP = 0 CALL_COUNT_MIPSOL = 0 class MyCallback(ampls.GurobiCallback): def run(self): try: where = self.getAMPLWhere() global CALL_COUNT_MIP, CALL_COUNT_MIPSOL if where == ampls.GRB_CB_MIPSOL: CALL_COUNT_MIPSOL += 1 print(self.getSolutionVector()) print("GRB_CB_MIP_SOL #{}!".format(CALL_COUNT_MIPSOL)) elif where == ampls.GRB_CB_MIP: CALL_COUNT_MIP += 1 print("GRB_CB_MIP #{}!".format(CALL_COUNT_MIP)) print(self.getSolutionVector()) if CALL_COUNT_MIP >= 10:
def solve(dat): assert input_schema.good_tic_dat_object(dat) assert not input_schema.find_foreign_key_failures(dat) assert not input_schema.find_data_type_failures(dat) assert not input_schema.find_data_row_failures(dat) dat = input_schema.copy_to_ampl(dat, field_renamings={ ("roster", "Grade"):"grade", ("positions", "Position Importance"): "position_importance", ("positions", "Position Group"): "position_group", ("player_ratings", "Rating"): "player_rating", ("innings", "Inning Group"): "inning_group", ("position_constraints", "Min Players"): "min_players", ("position_constraints", "Max Players"): "max_players" }) ampl = AMPL() ampl.setOption('solver', 'gurobi') mod_str = """ # Players and grades set PLAYERS; param grade {PLAYERS} symbolic; set GRADES = setof {pl in PLAYERS} grade[pl]; set IN_GRADE {g in GRADES} = {pl in PLAYERS: grade[pl] = g}; # Positions and position groups; player ratings set POSITIONS; param position_importance {POSITIONS}; param position_group {POSITIONS} symbolic; set POSITION_GROUPS = setof {p in POSITIONS} position_group[p]; set IN_POSITION_GROUP {pg in POSITION_GROUPS} = {p in POSITIONS: position_group[p] = pg}; param player_rating {PLAYERS,POSITION_GROUPS}; # Innings and inning groups; player limits set INNINGS; param inning_group {INNINGS} symbolic; set INNING_GROUPS = setof {i in INNINGS} inning_group[i]; set IN_INNING_GROUP {ig in INNING_GROUPS} = {i in INNINGS: inning_group[i] = ig}; set POSITION_CONSTRAINTS within {POSITION_GROUPS,INNING_GROUPS,GRADES}; param min_players {POSITION_CONSTRAINTS}; param max_players {POSITION_CONSTRAINTS}; # Decision variables: 1 ==> assignment of a player to a position in an inning var Play {INNINGS,POSITIONS,PLAYERS} binary; # Objective function: Maximize desirability of the assignment maximize TotalImportance: sum {i in INNINGS, p in POSITIONS, pl in PLAYERS} position_importance[p] * player_rating[pl,position_group[p]] * Play[i,p,pl]; # Exactly one player per position per inning subject to AllPositionsFilledPerInning {i in INNINGS, p in POSITIONS}: sum {pl in PLAYERS} Play[i,p,pl] = 1; # At most one possition per player per inning subject to AtMostOnePositionPerInning {i in INNINGS, pl in PLAYERS}: sum {p in POSITIONS} Play[i,p,pl] <= 1; # Total roster slots assigned, for listed combinations of # position group, inning group, and grade, must be within specified limits subject to MinMaxPlayers {(pg,ig,g) in POSITION_CONSTRAINTS}: min_players[pg,ig,g] <= sum {p in IN_POSITION_GROUP[pg], i in IN_INNING_GROUP[ig], pl in IN_GRADE[g]} Play[i,p,pl] <= max_players[pg,ig,g]; """ ampl.eval(mod_str) input_schema.set_ampl_data(dat, ampl, {"roster": "PLAYERS", "positions": "POSITIONS", "innings": "INNINGS", "position_constraints": "POSITION_CONSTRAINTS"}) ampl.solve() if ampl.getValue("solve_result") != "infeasible": sln = solution_schema.TicDat() for (i,p,pl),x in ampl.getVariable("Play").getValues().toDict().items(): if round(x[0]) > 0: sln.lineup[i,p] = pl sln.parameters["Total Cost"] = ampl.getObjective('TotalImportance').value() return sln
def main(argc, argv): # You can install amplpy with "python -m pip install amplpy" from amplpy import AMPL os.chdir(os.path.dirname(__file__) or os.curdir) model_directory = os.path.join( argv[2] if argc == 3 else os.path.join("..", "models"), "qpmv") # Create an AMPL instance ampl = AMPL() """ # If the AMPL installation directory is not in the system search path: from amplpy import Environment ampl = AMPL( Environment('full path to the AMPL installation directory')) """ # Number of steps of the efficient frontier steps = 10 if argc > 1: ampl.set_option("solver", argv[1]) ampl.set_option("reset_initial_guesses", True) ampl.set_option("send_statuses", False) ampl.set_option("solver", "cplex") # Load the AMPL model from file ampl.read(os.path.join(model_directory, "qpmv.mod")) ampl.read(os.path.join(model_directory, "qpmvbit.run")) # Set tables directory (parameter used in the script above) ampl.get_parameter("data_dir").set(model_directory) # Read tables ampl.read_table("assetstable") ampl.read_table("astrets") portfolio_return = ampl.getVariable("portret") average_return = ampl.get_parameter("averret") target_return = ampl.get_parameter("targetret") variance = ampl.get_objective("cst") # Relax the integrality ampl.set_option("relax_integrality", True) # Solve the problem ampl.solve() # Calibrate the efficient frontier range minret = portfolio_return.value() values = average_return.get_values() col = values.get_column("averret") maxret = max(col) stepsize = (maxret - minret) / steps returns = [None] * steps variances = [None] * steps for i in range(steps): print("Solving for return = {:g}".format(maxret - i * stepsize)) # Set target return to the desired point target_return.set(maxret - i * stepsize) ampl.eval("let stockopall:={};let stockrun:=stockall;") # Relax integrality ampl.set_option("relax_integrality", True) ampl.solve() print("QP result = {:g}".format(variance.value())) # Adjust included stocks ampl.eval("let stockrun:={i in stockrun:weights[i]>0};") ampl.eval("let stockopall:={i in stockrun:weights[i]>0.5};") # Set integrality back ampl.set_option("relax_integrality", False) # Solve the problem ampl.solve() # Check if the problem was solved successfully solve_result = ampl.get_value("solve_result") if solve_result != "solved": raise Exception( "Failed to solve (solve_result: {})".format(solve_result)) print("QMIP result = {:g}".format(variance.value())) # Store data of corrent frontier point returns[i] = maxret - (i - 1) * stepsize variances[i] = variance.value() # Display efficient frontier points print("RETURN VARIANCE") for i in range(steps): print("{:-6f} {:-6f}".format(returns[i], variances[i]))
def main(argc, argv): # You can install amplpy with "python -m pip install amplpy" from amplpy import AMPL os.chdir(os.path.dirname(__file__) or os.curdir) # Create an AMPL instance ampl = AMPL() """ # If the AMPL installation directory is not in the system search path: from amplpy import Environment ampl = AMPL( Environment('full path to the AMPL installation directory')) """ if argc > 1: # ampl.set_option('solver', argv[1]) pass # Must be solved with a solver supporting the suffix dunbdd ampl.set_option("solver", "cplex") ampl.set_option("presolve", False) ampl.set_option("omit_zero_rows", False) model_directory = os.path.join( argv[2] if argc == 3 else os.path.join("..", "models"), "locationtransportation" ) # Load the AMPL model from file ampl.read(os.path.join(model_directory, "trnloc2.mod")) # Read data ampl.read_data(os.path.join(model_directory, "trnloc.dat")) # Get references to AMPL's model entities for easy access. ship_cost = ampl.get_objective("Ship_Cost") max_ship_cost = ampl.get_variable("Max_Ship_Cost") build_var = ampl.get_variable("Build") supply = ampl.get_constraint("Supply") demand = ampl.get_constraint("Demand") num_cut_param = ampl.get_parameter("nCUT") cut_type = ampl.get_parameter("cut_type") build_param = ampl.get_parameter("build") supply_price = ampl.get_parameter("supply_price") demand_price = ampl.get_parameter("demand_price") num_cut_param.set(0) max_ship_cost.set_value(0) build_param.set_values([1] * ampl.get_set("ORIG").size()) num_cuts = 0 while True: num_cuts += 1 print("Iteration {}".format(num_cuts)) ampl.display("build") # Solve the subproblem. ampl.eval("solve Sub;") result = ship_cost.result() if result == "infeasible": # Add a feasibility cut. num_cut_param.set(num_cuts) cut_type.set(num_cuts, "ray") for index, value in supply.get_values(["dunbdd"]): supply_price[index, num_cuts] = value for index, value in demand.get_values(["dunbdd"]): demand_price[index, num_cuts] = value elif ship_cost.value() > max_ship_cost.value() + 0.00001: # Add an optimality cut. num_cut_param.set(num_cuts) cut_type.set(num_cuts, "point") ampl.set_option("display_1col", 0) ampl.display("Ship") for index, value in supply.get_values(): supply_price[index, num_cuts] = value for index, value in demand.get_values(): demand_price[index, num_cuts] = value else: break # Re-solve the master problem. print("RE-SOLVING MASTER PROBLEM") ampl.eval("solve Master;") solve_result = ampl.get_value("solve_result") if solve_result != "solved": raise Exception("Failed to solve (solve_result: {})".format(solve_result)) # Copy the data from the Build variable used in the master problem # to the build parameter used in the subproblem. build_param.set_values(build_var.get_values()) print("\nProcedure completed in {} iterations\n".format(num_cuts)) ampl.display("Ship")
def clearing_algorithm(id, v_e, li, c, ref_entities): """Stress testing algorithm : Solve the clearing problem. type : number of infeasible solutions num of non maximal solutions recovery rate vector equity vector of error in the update function Parameters ---------- id : string v_ea : 2d array ( post externall assets; vector of assets after shock) li : 2d array (liability matrix, debt contract) c : 3d array (cds contracts) ref_entities : list (set of reference entities) """ id_file_nonmax = open('id_file_nonmax.txt', 'a') id_file_infeasible = open('id_file_infeasible.txt', 'a') nBanks = len(v_e[0]) fixed_vec = list() alpha, beta = 0.6, 0.6 externalAssets, liability, CDS_contract, reference = v_e[ 0], li, c, ref_entities ## call AMPL ampl = AMPL() # set default cost parameters ampl.read('models/clearing_optimization.mod') #c2.mod ampl.readData( 'data/clearing_optimization.dat' ) # change this to irrational.dat if you don't have default costs #Set ampl options ampl.setOption('display_precision', 0) ampl.setOption('solution_precision', 0) # we will use Knitro as the solver, other options: lgo, loqo, conopt, ... ampl.setOption('solver', 'knitro') ampl.setOption('presolve_eps', 1.0e-6) ampl.setOption('outlev', 0) ampl.setOption('show_stats', 0) # set knitro options ampl.setOption( 'knitro_options', 'par_msnumthreads =32 ms_maxsolves=1 outlev=0 ma_terminate = 2 feastol = 1.0e-9 infeastol= 1.0e-1 feastol_abs= 1.0e-9 ms_deterministic=0 ma_terminate = 1 ma_outsub =1 bar_refinement=1 bar_slackboundpush=1.0 delta=1.0e-1 gradopt=1 hessopt=1 honorbnds=0 linesearch=0 linsolver_ooc=0 ms_enable=1 tuner=0 soc=0 initpenalty=3.0e10 bar_penaltyrule=1' ) # derivcheck=3') # another set of options to use, the above options has been tested and compared to other optio sets, # it obtained the most accurate results # one can use his/her options : see # ampl.setOption('knitro_options', 'par_msnumthreads =16 ms_maxsolves=10 ma_terminate = 2 feastol = 1.0e-9 infeastol= 1.0e-1 feastol_abs= 1.0e-9 ms_deterministic=0 ma_terminate = 1 ma_outsub =1 bar_refinement=1 bar_slackboundpush=1.0 delta=1.0e-1 gradopt=1 hessopt=1 honorbnds=0 linesearch=0 linsolver_ooc=0 ms_enable=1 tuner=0 soc=0 initpenalty=3.0e10 bar_penaltyrule=1 derivcheck=3')# out_csvinfo=1 restarts=10 ms_maxsolves=0 soc=1 tuner=1 #bar_relaxcons=2 #bar_watchdog=1 solver_status_maximal = "" ### prepare ampl, and initialize it by setting the data ampl_alpha = ampl.getParameter('alpha') ampl_beta = ampl.getParameter('betta') ampl_alpha.setValues(alpha) ampl_beta.setValues(beta) banks = [i for i in xrange(nBanks)] #vector of indices ampl.getSet('Banks').setValues(banks) ampl.getSet('reference').setValues(d) ampl_liab = array_to_ampl_dataframe(nBanks, liability) ampl.setData(ampl_liab) ampl_external_assets = DataFrame('Banks', 'externalAssets') ampl_external_assets.setColumn('Banks', banks) ampl_external_assets.setColumn('externalAssets', externalAssets) ampl.setData(ampl_external_assets) ampl_CDSs = DataFrame(('i', 'j', 'k'), 'CDS_contract') for i in xrange(nBanks): for j in xrange(nBanks): for k in d: ampl_CDSs.addRow(i, j, k, c[i][j][k]) ampl.setData(ampl_CDSs) maximal_out = [] infeasible_out = [] total_recovery_rates = [] total_equity = [] f_vec = [] """ set the objective, named recov if we have this objective funtion then the problem become Clearing Feasibility Problem as the value of recovery_rate_no_debts is constant """ ampl.eval('maximize recov : sum{i in Banks} recovery_rate_no_debts[i];') ''' for each element of the post external asset we need to solve the clearing problem remark: post_externall_assets are defined in the cl_btie_main.py or cl_uni_main.py; they contain external assets after applying shocks since we need to run the clearing algorithm for various array of external assets (see shock_gen.py) and we don't want to have AMPL's loading and initializing overhead at every time. we will just update the externall assets parameter at each round.''' for m in range(len(v_e)): # if external asset is zero then, obviously, we don't do the clearing: # shock on a bank without externall assets does not change the vector of externall assets if v_e[0][m] != 0: equity = [1000000000000 for i in range(nBanks)] # set value of previous equity to infinity as we want this constraint be redundant in solving # the Clearing Optimization Problem and checking if the problem is infeasible prev_eq = ampl.getParameter('preveq') #.getValues() prev_eq.setValues(equity) # drop the Clearing Optimization objective ampl.obj['recov'].drop() # restore new objective which is constant: to use if for the Clearing Feasibility Problem, and checking maximality #Solve the clearing optimization problem, # we solve the model given our data, but this time the objective function is maximizing 'total_equity' # as defined in the clearing_optimization.mod . ampl.obj['Tot_recov'].restore() ea = ampl.getParameter('externalAssets') ea.setValues(v_e[m]) # set ampl options again ## Clearing Optimization Problem, checking feasibility ampl.setOption( 'knitro_options', 'par_msnumthreads =32 ms_maxsolves=10 outlev=0 ma_terminate = 2 feastol = 1.0e-9 infeastol= 1.0e-1 feastol_abs= 1.0e-9 ms_deterministic=0 ma_terminate = 1 ma_outsub =1 bar_refinement=1 bar_slackboundpush=1.0 delta=1.0e-1 gradopt=1 hessopt=1 honorbnds=0 linesearch=0 linsolver_ooc=0 ms_enable=1 tuner=0 soc=0 initpenalty=3.0e10 bar_penaltyrule=1' ) # derivcheck=3') ampl.solve() tot_payment_1 = ampl.obj['Tot_recov'] solver_status = tot_payment_1.result() tot_payment_1 = tot_payment_1.drop() ampl.obj['Tot_recov'].drop() ampl.obj['recov'].restore() recoveryRate = ampl.getVariable('result').getValues().toList() equity = (ampl.getVariable('equity').getValues()).toList() ## update recovery results by rounding those near to 1, to 1 for x in xrange(len(recoveryRate)): if recoveryRate[x][1] > 1 or recoveryRate[x][1] > 0.99999999: recoveryRate[x] = 1 else: recoveryRate[x] = (recoveryRate[x])[1] for x in range(len(equity)): equity[x] = equity[x][1] ''' #retrieve alpha and beta alpha = ampl.getParameter('alpha').getValues() alpha = ((alpha.toList())[0][0]) beta = ampl.getParameter('betta').getValues() beta = ((beta.toList())[0][0]) ''' CDSs = d # s is the result of update function, i.e., the difference of approximate and actual value s = abs( uf.update_f(alpha, beta, nBanks, CDSs, v_e[m], b, c, recoveryRate)) if solver_status == 'solved': ## CLearing Feasibility Problem (maximality check) maximality = 'maximal' prev_eq.setValues(equity) ampl.setOption( 'knitro_options', 'par_msnumthreads =32 ms_maxsolves=1 outlev=0 ma_terminate = 2 feastol = 1.0e-9 infeastol= 1.0e-1 feastol_abs= 1.0e-9 ms_deterministic=0 ma_terminate = 1 ma_outsub =1 bar_refinement=1 bar_slackboundpush=1.0 delta=1.0e-1 gradopt=1 hessopt=1 honorbnds=0 linesearch=0 linsolver_ooc=0 ms_enable=1 tuner=0 soc=0 initpenalty=3.0e10 bar_penaltyrule=1' ) # derivcheck=3') ## solve the clearing feasibility problem, this time to check if the previous solution is maximal # if it returns infeasible, then the solution of Clearing Optimization program is not maximal, other wise # we have found a maximal solution ampl.solve() tot_payment_2 = ampl.getObjective('recov') solver_status_maximal = tot_payment_2.result() tot_payment_2 = tot_payment_2.drop() if solver_status_maximal == 'solved': maximality = 'non_maximal' else: maximality = 'maximal' else: maximality = 'none' total_equity.append(sum(equity)) total_recovery_rates.append( np.count_nonzero(np.array(recoveryRate) - 1)) if solver_status != 'infeasible': f_vec.append(s) if maximality == 'non_maximal': maximal_out.append(m) status = 'nonmax' id_file_nonmax.write(id) generate_polynomials(status, id, v_e[m], li, c, ref_entities, alpha, beta) if solver_status == 'infeasible': infeasible_out.append(m) status = 'infeasible' id_file_infeasible.write(id) generate_polynomials(status, id, v_e[m], li, c, ref_entities, alpha, beta) ampl.reset() return f_vec, total_recovery_rates, total_equity, infeasible_out, maximal_out
def solve(dat): """ core solving routine :param dat: a good ticdat for the input_schema :return: a good ticdat for the solution_schema, or None """ assert input_schema.good_pan_dat_object(dat) assert not input_schema.find_duplicates(dat) assert not input_schema.find_foreign_key_failures(dat) assert not input_schema.find_data_type_failures(dat) # build the AMPL math model ampl = AMPL() ampl.setOption('solver', 'gurobi') ampl.eval(""" set Workers; set Shifts; set Availability within {Workers,Shifts}; param Pay{Workers}; param Shift_Require{Shifts}; var x{Availability} binary; var slack{Shifts}>=0; var totShifts{Workers}; var totSlack; minimize Total_slack: totSlack; subject to reqCts{s in Shifts}: slack[s]+sum{(w,s) in Availability} x[w,s]== Shift_Require[s]; subject to TotalSlack:totSlack==sum{s in Shifts}slack[s]; subject to TotalShifts{w in Workers}:totShifts[w]==sum{(w,s) in Availability} x[w,s]; """) # copy the tables to amplpy.DataFrame objects, renaming the data fields as needed dat = input_schema.copy_to_ampl(dat, field_renamings={ ("shifts", "Requirement"): "Shift_Require", ("workers", "Payment"): "Pay"}) # load the amplpy.DataFrame objects into the AMPL model, explicitly identifying how to populate the AMPL sets input_schema.set_ampl_data(dat, ampl, {"workers": "Workers", "shifts": "Shifts", "availability": "Availability"}) ampl.solve() if ampl.getValue("solve_result") != "infeasible": # lexicographical solve 2 - minimize Total Payments while restricting Total Slack to be as small as possible totalSlack = ampl.getValue("totSlack") ampl.eval(""" param maxSlack; subject to MaximumSlack: totSlack <= maxSlack; var totPayments; subject to TotalPayments: totPayments = sum{(w,s) in Availability}x[w,s]*Pay[w]; minimize Total_payments: totPayments; objective Total_payments; """) ampl.param["maxSlack"] = totalSlack ampl.solve() if ampl.getValue("solve_result") != "infeasible": # lexicographical solve 2 - minimize imbalance among workers while restricting # Total Slack and Total Payments to be as small as possible totalPayments = ampl.getValue("Total_payments") ampl.eval(""" param maxTotalPayments; subject to MaximumTotalPayments: totPayments <= maxTotalPayments; var avgShifts; var diffShifts{Workers}; subject to avgShiftsC: card(Workers)*avgShifts==sum{w in Workers} totShifts[w]; subject to Diff{w in Workers}: diffShifts[w]==totShifts[w]-avgShifts; minimize Total_Imbalance: sum{w in Workers}diffShifts[w] * diffShifts[w]; objective Total_Imbalance; """) ampl.param["maxTotalPayments"] = totalPayments ampl.solve() if ampl.getValue("solve_result") != "infeasible": sln = solution_schema.copy_from_ampl_variables( {('assignments' ,''): (ampl.getVariable("x"), lambda x: abs(x-1) < 1e-5), ('slacks', 'Slack'): ampl.getVariable("slack"), ('total_shifts', 'Total Number Of Shifts'): ampl.getVariable("totShifts") }) sln.parameters.loc[0] = ['Total Slack', ampl.getValue("Total_slack")] sln.parameters.loc[1] = ['Total Payments', ampl.getValue("Total_payments")] sln.parameters.loc[2] = ['Variance of Total Shifts', ampl.getValue("Total_Imbalance/card(Workers)")] return sln
var X {PAIRS} binary; minimize Tour_Length: sum {(i,j) in PAIRS} distance[i,j] * X[i,j]; subject to Visit_All {i in NODES}: sum {(i,j) in PAIRS} X[i,j] + sum {(j,i) in PAIRS} X[j,i] = 2;""" # Set execution parameters PLOTSUBTOURS = False INTTOL = 1e-4 solver = "gurobi" tspFile = "tsp/gr96.tsp" # Load model in AMPL ampl = AMPL() ampl.eval(tspAMPLModel) ampl.option["solver"] = solver def getDictFromTspFile(tspFile): p = tsp.load(tspFile) if not p.is_depictable: printf("Problem is not depictable!") # Amendments as we need the nodes lexographically ordered nnodes = len(list(p.get_nodes())) i = 0 while nnodes > 1: nnodes = nnodes / 10 i += 1 formatString = f"{{:0{i}d}}"