This is my first question in stack overflow website. I was learning concert technology in C++. After I gained some understanding, I have tried to solve the following problem. I have coded the problem but I am getting infeasible solution. Can someone look at it and try to find where I am making mistake? Thank you so much!
Here is the problem:
A pet food company produces feed for dogs, cats, and rabbits. To do this, they mix corn, lime-stone, soybeans, and fish meal. These ingredients contain the following nutrients: vitamins, protein,calcium, and crude fat. The contents of the nutrients in standard units for each kilogram of the ingredients are summarized in the following table.
Ingredient Vitamins Protein Calcium Crude Fat Amount Available Price per kg
Corn 8 10 6 8 9 tons $0.20
Limestone 6 5 10 6 12 tons $0.12
Soybeans 10 12 6 6 5 tons $0.24
Fish meal 4 8 6 9 6 tons $0.1
The company in contracted to produce 12, 8, and 9 (metric) tons of dog, cat, and rabbit food. However, the company is only able to procure the amount available listed in the above table for each ingredient and the listed price per kilogram. To ensure the integrity of their product, they must adhere to the minimal and maximal units of the various nutrients for a kilogram of the dog, cat, and rabbit food.
Vitamins Protein Calcium Crude Fat
Product Min Max Min Max Min Max Min Max
Dog Food 6 ∞ 6 ∞ 7 ∞ 4 8
Cat Food 6 ∞ 6 ∞ 6 ∞ 4 6
Rabbit Food 4 6 6 ∞ 6 ∞ 4 5
Formulate this problem as a linear program such that the company minimizes costs.
As you can see I did cout
after each block of code to check the content of the arrays. The contents seemed to be fine. And reason why I used 50000 inIloIntVarArray(env, nbIngr, 0, 50000)
is that It just a really big upper limit for my decision variable. It could be infinity.
Here is the code:
using namespace std;
#include <ilcplex/ilocplex.h>
#include <iostream>;
typedef IloArray<IloIntVarArray> IloIntVarArray2; // creating two-dimentional array
int main() {
IloEnv env;
try {
IloInt i,j,k;
IloInt nbFood = 3; // Number of food type (Dog food, Cat food, Rabbit food)
IloInt nbIngr = 4; // Number of ingredient type (Corn, Limestone, Soybeans, Fish meal)
IloInt nbNut = 4; // Number of nutrient type (Vitamins, Protein, Calcium, Crude fat)
// Decision variable
// kgs of ingredient j in food i
IloIntVarArray2 ingredientInFoodX(env, nbFood);
for (i = 0; i < nbFood; i++) {
ingredientInFoodX[i] = IloIntVarArray(env, nbIngr, 0, 50000);
}
for (i = 0; i < nbFood; i++) {
for (j = 0; j < nbIngr; j++) {
cout << "content is: " << ingredientInFoodX[i][j] << endl;
}
}
cout << typeid(ingredientInFoodX).name() << endl;
cout << endl;
// Parametrs
IloNumArray costIngr(env, nbIngr, 0.2, 0.12, 0.24, 0.12); // cost per kg of ingredient
for (j = 0; j < nbIngr; j++) {
cout << "content is: " << costIngr[j] << endl;
}
cout << endl;
IloArray<IloNumArray> nutrientPerIngr(env, nbIngr); // amount of nutrient k for each kg of ingredient j
nutrientPerIngr[0] = IloNumArray(env, nbNut, 8, 10, 6, 8);
nutrientPerIngr[1] = IloNumArray(env, nbNut, 6, 5, 10, 6);
nutrientPerIngr[2] = IloNumArray(env, nbNut, 10, 12, 6, 6);
nutrientPerIngr[3] = IloNumArray(env, nbNut, 4, 8, 6, 9);
for (j = 0; j < nbIngr; j++) {
for (k = 0; k < nbNut; k++) {
cout << "content is: " << nutrientPerIngr[j][k] << endl;
}
}
cout << endl;
IloNumArray availableIngr(env, nbIngr, 9000, 12000, 5000, 6000); // amount available (kg) of ingredient j
for (j = 0; j < nbIngr; j++) {
cout << "content is: " << availableIngr[j] << endl;
}
cout << endl;
IloNumArray foodDemand(env, nbFood, 12000, 8000, 9000); // demand for food i
for (i = 0; i < nbFood; i++) {
cout << "content is: " << foodDemand[i] << endl;
}
cout << endl;
IloNumArray2 foodMinNutrient(env, nbFood); // minimum nutrient k requirement in food i
foodMinNutrient[0] = IloNumArray(env, nbNut, 6, 6, 7, 4);
foodMinNutrient[1] = IloNumArray(env, nbNut, 6, 6, 6, 4);
foodMinNutrient[2] = IloNumArray(env, nbNut, 4, 6, 6, 4);
for (i = 0; i < nbFood; i++) {
for (k = 0; k < nbNut; k++) {
cout << "content is: " << foodMinNutrient[i][k] << endl;
}
}
cout << endl;
IloNumArray2 foodMaxNutrient(env, nbFood); // maximum nutrient k requirement in food i
foodMaxNutrient[0] = IloNumArray(env, nbNut, 10000, 10000, 10000, 8);
foodMaxNutrient[1] = IloNumArray(env, nbNut, 10000, 10000, 10000, 6);
foodMaxNutrient[2] = IloNumArray(env, nbNut, 6, 10000, 10000, 5);
for (i = 0; i < nbFood; i++) {
for (k = 0; k < nbNut; k++) {
cout << "content is: " << foodMaxNutrient[i][k] << endl;
}
}
cout << endl;
IloModel model(env);
// Objective function (minimize production cost)
IloExpr objective_func(env);
for (i = 0; i < nbFood; i++) {
for (j = 0; j < nbIngr; j++)
objective_func += costIngr[j] * ingredientInFoodX[i][j];
}
model.add(IloMinimize(env, objective_func));
objective_func.end();
// Constraints
//limit amount of available ingredient k
for (j = 0; j < nbIngr; j++) {
IloExpr expr(env);
for (i = 0; i < nbFood; i++) {
expr += ingredientInFoodX[i][j];
}
model.add(expr <= availableIngr[j]);
expr.end();
}
// Ensure demand for food i is satisfied
for (i = 0; i < nbFood; i++) {
IloExpr expr(env);
for (j = 0; j < nbIngr; j++) {
expr += ingredientInFoodX[i][j];
}
model.add(expr >= foodDemand[i]);
expr.end();
}
// Min and Max nutrient requirement in food i
for (i = 0; i < nbFood; i++) {
for (k = 0; k < nbNut; k++) {
IloExpr expr(env);
for (j = 0; j < nbIngr; j++) {
expr += nutrientPerIngr[j][k] * ingredientInFoodX[i][j];
}
model.add(foodMinNutrient[i][k] * foodDemand[i] <= expr <= foodMaxNutrient[i][k] * foodDemand[i]);
expr.end();
}
}
cout << model << endl;
IloCplex cplex(model);
cplex.solve();
cplex.setOut(env.getNullStream()); // removes unnecessary information from the output window
cout << "Solution status is: " << cplex.getStatus() << endl;
cout << "Objective function value is: " << cplex.getObjValue() << endl;
cout << ingredientInFoodX[i][j] << endl;
}
catch (IloException & ex) {
cerr << "Error: " << ex << endl;
}
catch (...) {
cerr << "Error" << endl;
}
env.end();
}
Here is the output:
content is: IloIntVar(0)[0..50000]
content is: IloIntVar(1)[0..50000]
content is: IloIntVar(2)[0..50000]
content is: IloIntVar(3)[0..50000]
content is: IloIntVar(4)[0..50000]
content is: IloIntVar(5)[0..50000]
content is: IloIntVar(6)[0..50000]
content is: IloIntVar(7)[0..50000]
content is: IloIntVar(8)[0..50000]
content is: IloIntVar(9)[0..50000]
content is: IloIntVar(10)[0..50000]
content is: IloIntVar(11)[0..50000]
class IloArray<class IloIntVarArray>
content is: 0.2
content is: 0.12
content is: 0.24
content is: 0.12
content is: 8
content is: 10
content is: 6
content is: 8
content is: 6
content is: 5
content is: 10
content is: 6
content is: 10
content is: 12
content is: 6
content is: 6
content is: 4
content is: 8
content is: 6
content is: 9
content is: 9000
content is: 12000
content is: 5000
content is: 6000
content is: 12000
content is: 8000
content is: 9000
content is: 6
content is: 6
content is: 7
content is: 4
content is: 6
content is: 6
content is: 6
content is: 4
content is: 4
content is: 6
content is: 6
content is: 4
content is: 10000
content is: 10000
content is: 10000
content is: 8
content is: 10000
content is: 10000
content is: 10000
content is: 6
content is: 6
content is: 10000
content is: 10000
content is: 5
IloModel model12 = {
obj14 = (0.2 * IloIntVar(0)[0..50000] + 0.12 * IloIntVar(1)[0..50000] + 0.24 * IloIntVar(2)[0..50000] + 0.12 * IloIntVar(3)[0..50000] + 0.2 * IloIntVar(4)[0..50000] + 0.12 * IloIntVar(5)[0..50000] + 0.24 * IloIntVar(6)[0..50000] + 0.12 * IloIntVar(7)[0..50000] + 0.2 * IloIntVar(8)[0..50000] + 0.12 * IloIntVar(9)[0..50000] + 0.24 * IloIntVar(10)[0..50000] + 0.12 * IloIntVar(11)[0..50000] , IloObjective, Minimize);
IloIntVar(0)[0..50000] + IloIntVar(4)[0..50000] + IloIntVar(8)[0..50000] <= 9000
IloIntVar(1)[0..50000] + IloIntVar(5)[0..50000] + IloIntVar(9)[0..50000] <= 12000
IloIntVar(2)[0..50000] + IloIntVar(6)[0..50000] + IloIntVar(10)[0..50000] <= 5000
IloIntVar(3)[0..50000] + IloIntVar(7)[0..50000] + IloIntVar(11)[0..50000] <= 6000
12000 <= IloIntVar(0)[0..50000] + IloIntVar(1)[0..50000] + IloIntVar(2)[0..50000] + IloIntVar(3)[0..50000]
8000 <= IloIntVar(4)[0..50000] + IloIntVar(5)[0..50000] + IloIntVar(6)[0..50000] + IloIntVar(7)[0..50000]
9000 <= IloIntVar(8)[0..50000] + IloIntVar(9)[0..50000] + IloIntVar(10)[0..50000] + IloIntVar(11)[0..50000]
72000 <= 8 * IloIntVar(0)[0..50000] + 6 * IloIntVar(1)[0..50000] + 10 * IloIntVar(2)[0..50000] + 4 * IloIntVar(3)[0..50000] <= 1.2e+08
72000 <= 10 * IloIntVar(0)[0..50000] + 5 * IloIntVar(1)[0..50000] + 12 * IloIntVar(2)[0..50000] + 8 * IloIntVar(3)[0..50000] <= 1.2e+08
84000 <= 6 * IloIntVar(0)[0..50000] + 10 * IloIntVar(1)[0..50000] + 6 * IloIntVar(2)[0..50000] + 6 * IloIntVar(3)[0..50000] <= 1.2e+08
48000 <= 8 * IloIntVar(0)[0..50000] + 6 * IloIntVar(1)[0..50000] + 6 * IloIntVar(2)[0..50000] + 9 * IloIntVar(3)[0..50000] <= 96000
48000 <= 8 * IloIntVar(4)[0..50000] + 6 * IloIntVar(5)[0..50000] + 10 * IloIntVar(6)[0..50000] + 4 * IloIntVar(7)[0..50000] <= 8e+07
48000 <= 10 * IloIntVar(4)[0..50000] + 5 * IloIntVar(5)[0..50000] + 12 * IloIntVar(6)[0..50000] + 8 * IloIntVar(7)[0..50000] <= 8e+07
48000 <= 6 * IloIntVar(4)[0..50000] + 10 * IloIntVar(5)[0..50000] + 6 * IloIntVar(6)[0..50000] + 6 * IloIntVar(7)[0..50000] <= 8e+07
32000 <= 8 * IloIntVar(4)[0..50000] + 6 * IloIntVar(5)[0..50000] + 6 * IloIntVar(6)[0..50000] + 9 * IloIntVar(7)[0..50000] <= 48000
36000 <= 8 * IloIntVar(8)[0..50000] + 6 * IloIntVar(9)[0..50000] + 10 * IloIntVar(10)[0..50000] + 4 * IloIntVar(11)[0..50000] <= 54000
54000 <= 10 * IloIntVar(8)[0..50000] + 5 * IloIntVar(9)[0..50000] + 12 * IloIntVar(10)[0..50000] + 8 * IloIntVar(11)[0..50000] <= 9e+07
54000 <= 6 * IloIntVar(8)[0..50000] + 10 * IloIntVar(9)[0..50000] + 6 * IloIntVar(10)[0..50000] + 6 * IloIntVar(11)[0..50000] <= 9e+07
36000 <= 8 * IloIntVar(8)[0..50000] + 6 * IloIntVar(9)[0..50000] + 6 * IloIntVar(10)[0..50000] + 9 * IloIntVar(11)[0..50000] <= 45000
}
Solution status is: Infeasible
Error: CPLEX Error 1217: No solution exists.