使用带有Concert Technology的CPLEX编写C ++程序

问题描述 投票:0回答:1

这是我在堆栈溢出网站中的第一个问题。我当时正在用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(公吨)狗,猫和兔子的食品。但是,该公司只能采购上表中列出的可用金额用于每种成分和列出的每公斤价格。为了确保产品的完整性,他们必须坚持一公斤狗,猫和狗的各种营养素的最小和最大单位兔粮。

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,以检查数组的内容。内容似乎很好。我之所以在IloIntVarArray(env, nbIngr, 0, 50000)中使用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.
c++ cplex
1个回答
2
投票

您可以使用冲突细化器来分析不可行性。可以通过调用cplex.refineConflict()来完成。对于小问题,导出模型并在交互式优化器中分析冲突更为简单。为此,在呼叫cplex.exportModel("food.lp")之前先呼叫cplex.solve()。然后在控制台中调用交互式优化器(在Windows上为cplex.exe,在其他操作系统上为cplex),并在提示符下执行以下操作:

CPLEX> read food.lp
CPLEX> tools conflict
CPLEX> display conflict all

这将找到一组最小的冲突约束并显示它们。就您而言,冲突是:

Subject To
 c7:  x9 + x10 + x11 + x12 >= 9000
 c19: 8 x9 + 6 x10 + 6 x11 + 9 x12 - Rgc19  = 36000
\Sum of equality rows in the conflict:
\ sum_eq: 8 x9 + 6 x10 + 6 x11 + 9 x12 - Rgc19  = 36000
Bounds
      x9 >= 0
      x10 Free
      x11 Free
      x12 >= 0
 -Inf <= Rgc19 <= 9000
Generals
 x9  x10  x11  x12

如果在程序中为变量和约束分配名称,则可以提高可读性。

无论如何,您可以看到c7要求四个变量的总和等于9000或更大。这意味着在第二个约束中,总和8 x9 + 6 x10 + 6 x11 + 9 x12至少为6 * 9000 =54000。考虑到Rgct19的上限为9000,很明显,由于54000 - 9000 <= 36000永远不会满足,因此永远无法满足该约束。真正。您的数据似乎有问题。

© www.soinside.com 2019 - 2024. All rights reserved.