예제 #1
0
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)
예제 #2
0
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
예제 #3
0
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
예제 #4
0
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
예제 #5
0
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
예제 #6
0
    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
예제 #7
0
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
예제 #9
0
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
예제 #10
0
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
예제 #11
0
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
예제 #12
0
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
예제 #13
0
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
예제 #14
0
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")
예제 #15
0
파일: diet.py 프로젝트: nandi6uc/ticdat
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
예제 #16
0
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))
}
예제 #17
0
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
예제 #18
0
파일: ora.py 프로젝트: oliveradameck/ORA
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 = []
예제 #19
0
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
예제 #20
0
파일: netflow.py 프로젝트: nandi6uc/ticdat
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
예제 #21
0
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
예제 #22
0
# -*- 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
예제 #23
0
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:
예제 #24
0
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
예제 #25
0
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]))
예제 #26
0
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")
예제 #27
0
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
예제 #28
0
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
예제 #29
0
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}}"