Это мой первый вопрос на сайте переполнения стека. Я изучал концертные технологии на C ++. После того, как я получил некоторое понимание, я попытался решить следующую проблему. Я закодировал проблему, но я получаю неосуществимое решение. Может кто-то взглянуть на это и попытаться найти, где я делаю ошибку? Большое спасибо!
Вот проблема:
Компания по производству кормов для домашних животных производит корма для собак, кошек и кроликов. Для этого они смешивают кукурузу, известняк, сою и фантастическую еду. Эти ингредиенты содержат следующие питательные вещества: витамины, белок, кальций и сырой жир. Содержание питательных веществ в стандартных единицах измерения для каждого килограмма ингредиентов приведено в следующей таблице.
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
Компания заключила контракт на производство 12, 8 и 9 (метри c) тонн корм для собак, кошек и кроликов. Тем не менее, компания может получить только ту сумму, которая указана в таблице выше для каждого ингредиента и указана цена за килограмм. Чтобы обеспечить целостность своего продукта, они должны придерживаться минимальных и максимальных единиц различных питательных веществ для килограмма пищи для собак, кошек и кроликов.
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
Сформулируйте эту проблему как линейную программу таким образом, что компания минимизирует затраты.
Как вы можете видеть, я делал cout
после каждого блока кода для проверки содержимого массивов. Содержание, казалось, было в порядке. И причина, по которой я использовал 50000 в IloIntVarArray(env, nbIngr, 0, 50000)
, заключается в том, что это просто очень большой верхний предел для моей переменной решения. Это может быть бесконечность.
Вот код:
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();
}
Вот вывод:
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.