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]
"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",
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"))
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
"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": {