我有三个产品和五个盒子:
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 问题。在这种情况下,我只考虑产品和盒子的长度,但实际上我还应该考虑宽度和高度。