Here is a description of the optimization problem I need to solve, but with a small twist. I need to add two constraints:
- The first constraint: From each group we want to choose only one product, which means that we can't allow two products from the same group to be in the same basket(i.e. Product11 and Product12 should never be in the same basket )
- The second constraint: In the user basket we only want products from the categories that the user is interested in. i.e if user is interested in the category 'Protein' he should never find in his basket a product from the category 'Carbs' nor 'Fat'.
Accordingly I have changed the OPL code products.mod:
{string} categories=...;
{string} groups[categories]=...;
{string} allGroups=union (c in categories) groups[c];
{string} products[allGroups]=...;
{string} allProducts=union (g in allGroups) products[g];
float prices[allProducts]=...;
int Uc[categories]=...;
float Ug[allGroups]=...;
float budget=...;
dvar boolean z[allProducts]; // product out or in ?
dexpr int xg[g in allGroups]=(sum(p in products[g]) z[p]);
dexpr int xc[c in categories]=(1<=sum(g in groups[c]) xg[g]);
maximize
sum(c in categories) Uc[c]*xc[c]+
sum(c in categories) sum(g in groups[c]) Uc[c]*Ug[g]*xg[g];
subject to
{
ctBudget:// first constraint
sum(p in allProducts) z[p]*prices[p]<=budget;
ctGroups: // second constraint
forall( g in allGroups )
xg[g]==1;
ctCategories: // third constraint
forall( c in categories )
Uc[c]==xc[c];
}
{string} solution={p | p in allProducts : z[p]==1};
execute
{
writeln("xg=",xc);
writeln("xg=",xg);
writeln("Solution=",solution);
}
Here the code for products.data
categories={"Carbs","Protein","Fat"};
groups=[{"Meat","Milk"},{"Pasta","Bread"},{"Oil","Butter"}];
products=[
{"Product11","Product12"},{"Product21","Product22","Product23"},
{"Product31","Product32"},{"Product41","Product42"},
{"Product51"},{"Product61","Product62"}];
prices=[1,1,3,3,2,1,2,1,3,1,2,1];
Uc=[1,0,0];
Ug=[0.8,0.2,0.1,1,0.01,0.6];
budget=2;
The results given by IBM Studio are the following: {Product12,Product31}; while the result I want is either {Product11} or {Product12}.
I have also noticed this in the conflicts tab:
And this in the relaxation tab:
So I have five questions:
- I don't see any conflicts between the constraints, because if we choose the product "Product12" (or Product11") we respect all the constraint and the budget would be <= 2 because price["Product12"]==1.
- I don't understand why does the optimizer chose to not respect the last constraint, and to maximize the objective function instead.
- If the optimizer did not use any relaxation, would this lead to an infeasible model (no solution to the problem)? I don't understand why? For me choosing only "Product12" (or "Product11") is a perfect solution with no need to any relaxation.
How to oblige the optimizer to not relax the last constraint? (Note that changing the settings file, products.ops to relax only labeled constraints as in the documentation did not help, as I want to relax only one constraint )
In the documentation about relaxing infeasible models I found this:
Be aware, however, that infeasibility may be the consequence of an error in the modeling of another constraint.
Is this my case?
Thank you in advance for the help
ctBudget:// first constraint, ctGroups: // second constraint, ctCategories: // third constraint
if you want all constraint to be respected as they are with the given data...