Here is the optimization-problem, I am trying to solve (with a little twist, with the opl code I use.
The opl code gives me two solutions namely: {Product12,Product31}
When I translate this to the python language using docplex using this code:
from docplex.mp.model import Model
from docplex.util.environment import get_environment
# ----------------------------------------------------------------------------
# Initialize the problem data
# ----------------------------------------------------------------------------
Categories_groups = {"Carbs": ["Meat","Milk"],"Protein":["Pasta","Bread"], "Fat": ["Oil","Butter"]}
Groups_Products = {"Meat":["Product11","Product12"], "Milk": ["Product21","Product22","Product23"], "Pasta": ["Product31","Product32"],
"Bread":["Product41","Product42"], "Oil":["Product51"],"Butter":["Product61","Product62"]}
Products_Prices ={"Product11":1,"Product12":1, "Product21":3,"Product22":3,"Product23":2,"Product31":1,"Product32":2,
"Product41":1,"Product42":3, "Product51": 1,"Product61":2,"Product62":1}
Uc={"Protein":1,"Carbs": 0, "Fat": 0}
Ug = {"Meat": 0.8, "Milk": 0.2, "Pasta": 0.1, "Bread": 1, "Oil": 0.01, "Butter": 0.6}
budget=2
def build_userbasket_model(**kwargs):
allcategories = Categories_groups.keys()
allgroups = Groups_Products.keys()
allproducts = Products_Prices.keys()
# Model
mdl = Model(name='userbasket', **kwargs)
z = mdl.binary_var_dict(allproducts, name='%s')
xg = {g: mdl.sum(z[p] for p in Groups_Products[g]) for g in allgroups}
xc = {c: 1 <= mdl.sum(xg[g] for g in Categories_groups[c]) for c in allcategories}
mdl.add_constraint(mdl.sum(Products_Prices[p] * z[p] for p in allproducts) <= budget)
for g in allgroups:
mdl.add_constraint(xg[g]==1 )
for c in allcategories:
mdl.add_constraint(Uc[c] == xc[c])
mdl.maximize(mdl.sum(Uc[c] * xc[c] for c in allcategories) + mdl.sum(
xg[g] * Uc[c] * Ug[g] for c in allcategories for g in Categories_groups[c] ))
return mdl
if __name__ == '__main__':
"""DOcplexcloud credentials can be specified with url and api_key in the code block below.
Alternatively, Context.make_default_context() searches the PYTHONPATH for
the following files:
* cplex_config.py
* cplex_config_<hostname>.py
* docloud_config.py (must only contain context.solver.docloud configuration)
These files contain the credentials and other properties. For example,
something similar to::
context.solver.docloud.url = "https://docloud.service.com/job_manager/rest/v1"
context.solver.docloud.key = "example api_key"
"""
url = None
key = None
mdl = build_userbasket_model()
# will use IBM Decision Optimization on cloud.
if not mdl.solve(url=url, key=key):
print("*** Problem has no solution")
else:
mdl.float_precision = 3
print("* model solved as function:")
mdl.print_solution()
'''
Solution displayed using the line of code above
solution = mdl.solution
for index, dvar in enumerate(solution.iter_variables()):
print index, dvar.to_string(), solution[dvar], solution.get_var_value(dvar)
# Save the CPLEX solution as "solution.json" program output
with get_environment().get_output_stream("solution.json") as fp:
mdl.solution.export(fp, "json")
I get this:
*** Problem has no solution
I don't understand why I am having different results, can anybody help me with this please.
Thank you in advance.
Regards
If one problem provide a feasible solution and the other is claimed infeasible, then most likely you are not solving the same problem. There are several things you can do:
Double-check that your Python code is correct.
Export your model as LP file from OPL and from your Python code and compare the two models.
Use the conflict refiner to learn why the Python model is claimed infeasible. From this you may be able to tell where the problem with your Python model is.