Ejemplo n.º 1
0
                           inclusive_max=False)
input_schema.set_data_type("demand",
                           "Quantity",
                           min=0,
                           max=float("inf"),
                           inclusive_min=True,
                           inclusive_max=False)
input_schema.set_data_type("supply",
                           "Quantity",
                           min=0,
                           max=float("inf"),
                           inclusive_min=True,
                           inclusive_max=False)

# The default-default of zero makes sense everywhere except for Capacity
input_schema.set_default_value("arcs", "Capacity", float("inf"))


# we check that the same commodity node pairs don't appear both in supply and demand
def _supply_pairs(dat):
    return {
        "supply_pairs":
        {row[:2]
         for row in dat.supply.itertuples(index=False)}
    }


def _demand_pairs(dat):
    return {
        "demand_pairs":
        {row[:2]
Ejemplo n.º 2
0
                               "Minimize Total Cost"
                           ],
                           number_allowed=False)
input_schema.set_data_type("warehouses",
                           "Fixed Cost",
                           min=0,
                           max=float("inf"),
                           inclusive_min=True,
                           inclusive_max=False)
input_schema.set_data_type("warehouses",
                           "Max Assignment Capacity",
                           min=0,
                           max=float("inf"),
                           inclusive_min=True,
                           inclusive_max=True)
input_schema.set_default_value("warehouses", "Max Assignment Capacity",
                               float("inf"))
input_schema.set_data_type("products",
                           "Warehouse Volume",
                           min=0,
                           max=float("inf"),
                           inclusive_min=False,
                           inclusive_max=False)
input_schema.set_default_value("products", "Warehouse Volume", 1)
input_schema.set_data_type("demand",
                           "Demand",
                           min=0,
                           max=float("inf"),
                           inclusive_min=True,
                           inclusive_max=False)
input_schema.set_data_type("supply",
                           "Supply",
Ejemplo n.º 3
0
    def test_diet_amplpy(self):
        dat = _diet_input_pdf.copy_to_ampl(
            _diet_dat,
            field_renamings={
                ("foods", "Cost"): "cost",
                ("categories", "Min Nutrition"): "n_min",
                ("categories", "Max Nutrition"): "n_max",
                ("nutrition_quantities", "Quantity"): "amt",
                ("nutrition_quantities", "Other Quantity"): "other_amt"
            })
        self.assertTrue({"n_min",
                         "n_max"}.issubset(dat.categories.toPandas().columns))
        ampl = amplpy.AMPL()
        ampl.setOption('solver', 'gurobi')
        ampl.eval(_diet_mod)
        _diet_input_pdf.set_ampl_data(dat, ampl, {
            "categories": "CAT",
            "foods": "FOOD"
        })
        ampl.solve()

        sln = _diet_sln_pdf.copy_from_ampl_variables({
            ("buy_food", "Quantity"):
            ampl.getVariable("Buy"),
            ("consume_nutrition", "Quantity"):
            ampl.getVariable("Consume")
        })
        sln.parameters.loc[0] = [
            'Total Cost',
            ampl.getObjective('Total_Cost').value()
        ]

        _missing_field_pdf = PanDatFactory(
            **{
                t: [pks, (["Max Nutrition"] if t == "categories" else dfs)]
                for t, (pks, dfs) in _diet_input_pdf.schema().items()
            })
        dat = _missing_field_pdf.copy_to_ampl(
            _diet_dat,
            field_renamings={
                ("foods", "Cost"): "cost",
                ("categories", "Min Nutrition"): "n_min",
                ("categories", "Max Nutrition"): "n_max",
                ("nutrition_quantities", "Quantity"): "amt",
                ("nutrition_quantities", "Other Quantity"): "other_amt"
            })
        self.assertTrue({"n_min",
                         "n_max"}.issubset(dat.categories.toPandas().columns))
        ampl = amplpy.AMPL()
        ampl.setOption('solver', 'gurobi')
        ampl.eval(_diet_mod)
        _diet_input_pdf.set_ampl_data(dat, ampl, {
            "categories": "CAT",
            "foods": "FOOD"
        })
        ampl.solve()
        sln_2 = _diet_sln_pdf.copy_from_ampl_variables({
            ("buy_food", "Quantity"):
            ampl.getVariable("Buy"),
            ("consume_nutrition", "Quantity"):
            ampl.getVariable("Consume")
        })
        sln_2.parameters.loc[0] = [
            'Total Cost',
            ampl.getObjective('Total_Cost').value()
        ]
        self.assertTrue(_diet_sln_pdf._same_data(sln, sln_2))

        diet_dat_two = _diet_input_pdf.copy_to_tic_dat(_diet_dat)
        for r in diet_dat_two.nutrition_quantities.values():
            r["Quantity"], r["Other Quantity"] = [0.5 * r["Quantity"]] * 2
        diet_dat_two = pan_dat_maker(_diet_input_pdf.schema(), diet_dat_two)

        dat = _diet_input_pdf.copy_to_ampl(
            diet_dat_two,
            field_renamings={
                ("foods", "Cost"): "cost",
                ("categories", "Min Nutrition"): "n_min",
                ("categories", "Max Nutrition"): "n_max",
                ("nutrition_quantities", "Quantity"): "amt",
                ("nutrition_quantities", "Other Quantity"): "other_amt"
            })
        ampl = amplpy.AMPL()
        ampl.setOption('solver', 'gurobi')
        ampl.eval(_diet_mod)
        _diet_input_pdf.set_ampl_data(dat, ampl, {
            "categories": "CAT",
            "foods": "FOOD"
        })
        ampl.solve()
        self.assertTrue("solved" == ampl.getValue("solve_result"))

        sln = _diet_sln_pdf.copy_from_ampl_variables({
            ("buy_food", "Quantity"):
            ampl.getVariable("Buy"),
            ("consume_nutrition", "Quantity"):
            ampl.getVariable("Consume")
        })
        sln.parameters.loc[0] = [
            'Total Cost',
            ampl.getObjective('Total_Cost').value()
        ]

        self.assertTrue(
            _diet_sln_pdf._same_data(sln, _diet_sln_pandat, epsilon=1e-5))

        dat = _diet_input_pdf.copy_to_ampl(
            _diet_dat, {
                ("foods", "Cost"): "cost",
                ("categories", "Min Nutrition"): "",
                ("categories", "Max Nutrition"): "n_max"
            }, ["nutrition_quantities"])
        self.assertFalse(hasattr(dat, "nutrition_quantities"))
        self.assertTrue({"n_min", "n_max"}.intersection(
            dat.categories.toPandas().columns) == {"n_max"})

        sln_tdf_2 = PanDatFactory(buy_food=[["Food"], ["Quantity"]],
                                  consume_nutrition=[["Category"], []])
        sln_tdf_2.set_default_value("buy_food", "Quantity", 1)
        sln_2 = sln_tdf_2.copy_from_ampl_variables({
            ("buy_food", False):
            ampl.getVariable("Buy"),
            ("consume_nutrition", False):
            (ampl.getVariable("Consume"), lambda x: x < 100)
        })
        self.assertTrue(set(sln_2.buy_food["Quantity"]) == {1})
        self.assertTrue(
            set(sln_2.buy_food["Food"]) == set(sln.buy_food["Food"]))
        self.assertTrue(len(sln_2.consume_nutrition) > 0)
        self.assertTrue(
            set(sln_2.consume_nutrition["Category"]) ==
            set(sln.consume_nutrition[sln.consume_nutrition["Quantity"] < 100]
                ["Category"]))

        diet_dat_two = _diet_input_pdf.copy_to_tic_dat(_diet_dat)
        diet_dat_two.categories["calories"] = [0, 200]
        diet_dat_two = pan_dat_maker(_diet_input_pdf.schema(), diet_dat_two)
        dat = _diet_input_pdf.copy_to_ampl(
            diet_dat_two,
            field_renamings={
                ("foods", "Cost"): "cost",
                ("categories", "Min Nutrition"): "n_min",
                ("categories", "Max Nutrition"): "n_max",
                ("nutrition_quantities", "Quantity"): "amt",
                ("nutrition_quantities", "Other Quantity"): "other_amt"
            })
        ampl = amplpy.AMPL()
        ampl.setOption('solver', 'gurobi')
        ampl.eval(_diet_mod)
        _diet_input_pdf.set_ampl_data(dat, ampl, {
            "categories": "CAT",
            "foods": "FOOD"
        })
        ampl.solve()
        self.assertTrue("infeasible" == ampl.getValue("solve_result"))

        diet_dat_two = _diet_input_pdf.copy_to_tic_dat(_diet_dat)
        for v in diet_dat_two.categories.values():
            v["Max Nutrition"] = float("inf")
        diet_dat_two.foods["hamburger"] = -1
        diet_dat_two = pan_dat_maker(_diet_input_pdf.schema(), diet_dat_two)
        dat = _diet_input_pdf.copy_to_ampl(
            diet_dat_two,
            field_renamings={
                ("foods", "Cost"): "cost",
                ("categories", "Min Nutrition"): "n_min",
                ("categories", "Max Nutrition"): "n_max",
                ("nutrition_quantities", "Quantity"): "amt",
                ("nutrition_quantities", "Other Quantity"): "other_amt"
            })
        ampl = amplpy.AMPL()
        ampl.setOption('solver', 'gurobi')
        ampl.eval(_diet_mod)
        _diet_input_pdf.set_ampl_data(dat, ampl, {
            "categories": "CAT",
            "foods": "FOOD"
        })
        ampl.solve()
        self.assertTrue("unbounded" == ampl.getValue("solve_result"))
Ejemplo n.º 4
0
                           inclusive_max=False)
input_schema.set_data_type("nutrition_quantities",
                           "Quantity",
                           min=0,
                           max=float("inf"),
                           inclusive_min=True,
                           inclusive_max=False)

# We also want to insure that Max Nutrition doesn't fall below Min Nutrition
input_schema.add_data_row_predicate(
    "categories",
    predicate_name="Min Max Check",
    predicate=lambda row: row["Max Nutrition"] >= row["Min Nutrition"])

# The default-default of zero makes sense everywhere except for Max Nutrition
input_schema.set_default_value("categories", "Max Nutrition", float("inf"))
# ---------------------------------------------------------------------------------

# ------------------------ define the output schema -------------------------------
# There are three solution tables, with 3 primary key fields and 3 data fields.
solution_schema = PanDatFactory(parameters=[["Parameter"], ["Value"]],
                                buy_food=[["Food"], ["Quantity"]],
                                consume_nutrition=[["Category"], ["Quantity"]])

# ---------------------------------------------------------------------------------


# ------------------------ create a solve function --------------------------------
def solve(dat):
    """
    core solving routine
Ejemplo n.º 5
0
                               "Maximize Percent High Service Demand"
                           ],
                           number_allowed=False)
input_schema.set_data_type("cities",
                           "Demand",
                           min=0,
                           max=float("inf"),
                           inclusive_min=True,
                           inclusive_max=False)
input_schema.set_data_type("cities",
                           "Max Assignment Capacity",
                           min=0,
                           max=float("inf"),
                           inclusive_min=True,
                           inclusive_max=True)
input_schema.set_default_value("cities", "Max Assignment Capacity",
                               float("inf"))
input_schema.set_data_type("distances",
                           "Distance",
                           min=0,
                           max=float("inf"),
                           inclusive_min=True,
                           inclusive_max=False)
input_schema.add_foreign_key("distances", "cities", ['Source', 'Name'])
input_schema.add_foreign_key("distances", "cities", ['Destination', 'Name'])


# The distance matrix is bi-directionally safe. I.e. if the same source/dest and dest/source exist then the
# distances must match. If only one is present, it can fall back to the other in the code.
def _distance_matrix(dat):
    return {
        "distance_matrix": {