【问题标题】:Gurobi C# optimization of box packingGurobi C# 优化盒子包装
【发布时间】:2015-02-10 10:39:58
【问题描述】:

我有三个产品和五个盒子:

var products = new string[] { "A", "B", "C"};
var boxes = new string[] { "1", "2", "3" ,"4","5"};

尺寸为:

double[,] boxDimensions = new double[,] 
                          {{8},
                          {15},
                          {30},
                          {40},
                          {50}};

double[,] productDimensions = new double[,] 
                        { { 5 },
                          { 10 },
                          { 20 } }; 

我想选择所有产品都可以装入的最小体积的盒子。

我编写了以下代码,并且我知道我应该添加约束以仅在其中选择 1 个框。 但它在当前状态下不起作用(给出不可行的 sol)。 代码如下:

在此先感谢您的帮助,

static void Main()
        {
            try
            {

                var products = new string[] { "A", "B", "C" };
                var boxes = new string[] { "1", "2", "3", "4", "5" };

                double[,] boxDimensions = new double[,] {{8},
                                          {15},
                                          {30},
                                          {40},
                                          {50}};

                double[,] productDimensions =
                    new double[,] { { 5 },
                                    { 5 },
                                    { 20 }};

                // Model
                GRBEnv env = new GRBEnv();
                GRBModel model = new GRBModel(env);
                model.Set(GRB.StringAttr.ModelName, "box");

                // Box decision variables: open[p] == 1 if box i is choosen.
                GRBVar[] open = new GRBVar[boxes.Length];
                for (int i = 0; i < boxes.Length; i++)
                {
                    open[i] = model.AddVar(0, 1, boxDimensions[i, 0], GRB.BINARY, boxes[i]);
                }

                GRBVar[] x = new GRBVar[products.Length];

                for (int j = 0; j < products.Length; j++)
                {
                    x[j] = model.AddVar(productDimensions[j, 0], productDimensions[j, 0], 0, GRB.CONTINUOUS, products[j]);
                }


                // The objective is to minimize the total fixed and variable costs
                model.Set(GRB.IntAttr.ModelSense, 1);

                // Update model to integrate new variables
                model.Update();
                GRBLinExpr lhs = 0.0;
                GRBLinExpr rhs = 0.0;
                // Production constraints
                // Note that the right-hand limit sets the production to zero if
                // the plant is closed
                // Constraint: assign exactly shiftRequirements[s] workers
                // to each shift s
                for (int s = 0; s < products.Length; ++s)
                {
                    lhs.AddTerm(1.0, x[s]);
                }

                for (int w = 0; w < boxes.Length; w++)
                {
                    rhs.AddTerm(boxDimensions[w, 0], open[w]);
                }

                model.AddConstr(lhs <= rhs, "BoxConstraint");

                model.GetEnv().Set(GRB.IntParam.Method, GRB.METHOD_BARRIER);

                // Solve
                model.Optimize();

                // Print solution
                int status = model.Get(GRB.IntAttr.Status);
                if (status == GRB.Status.UNBOUNDED)
                {
                    Console.WriteLine("The model cannot be solved "
                        + "because it is unbounded");
                    return;
                }
                if (status == GRB.Status.OPTIMAL)
                {
                    Console.WriteLine("The optimal objective is " +
                        model.Get(GRB.DoubleAttr.ObjVal));
                    return;
                }
                if ((status != GRB.Status.INF_OR_UNBD) &&
                    (status != GRB.Status.INFEASIBLE))
                {
                    Console.WriteLine("Optimization was stopped with status " + status);
                    return;
                }

                // Dispose of model and env
                model.Dispose();
                env.Dispose();

            }
            catch (GRBException e)
            {
                Console.WriteLine("Error code: " + e.ErrorCode + ". " + e.Message);
            }
        }

注意:我给出了简单的问题(1D),实际上我真正的问题是 3D 问题。在这种情况下,我只考虑产品和盒子的长度,但实际上我还应该考虑宽度和高度。

【问题讨论】:

  • 出了什么问题? (确切的)问题是什么?你用过调试器吗?将预期值与实际值进行比较?
  • 我们希望模型只选择 1 个盒子而不是其中的两个(最小尺寸)。 @Jodrell 在什么意义上你不明白?这是一维问题。都是盒子的长度(假设是棍子)。我们进一步的问题将是 3D
  • 为什么要使用多维数组?
  • @Jodrell 这并不重要。其实我的问题是3D。真实数组示例:(x,y,z) double[,] boxDimensions = new double[,] {{8,10,20}, {15,10,40}, {30,10,20}, {40, 10,20},{50,10,20}};我将维度从 3 减少到 1 以使问题更简单。

标签: c# mathematical-optimization cplex bin-packing gurobi


【解决方案1】:

您编写模型的一般方式是可以的。

尽管如此,对于 x,您将下限和上限设置为固定 x 的相同值。此外,我想知道你为什么让 Gurobi 使用屏障方法。我不确定这在您正在使用的 MIP 设置中是否正确。

【讨论】:

  • 感谢您的回答。实际上 x 不是变量而是它的参数,因为我是 c#-gurobi 接口的新手,所以我不知道如何定义参数。如果你知道你可以告诉我。再次因为同样的原因,我不知道方法的差异是什么。我是从其他示例模型中获取的。
  • 您可以使用 addConstant (gurobi.com/documentation/6.0/reference-manual/…) 添加常量表达式(或使用重载的 + 运算符构造表达式)。如果您不知道不同的优化方法,只需将选择留给求解器(因此只需使用 Optimize())
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多