模型

使用针对 .NET 用户的 Concert Technology 类构建问题模型。

编写问题描述后,您可以通过 CPLEX 使用针对 .NET 用户的 Concert Technology 类构建模型。

步骤 2:打开文件

在集成开发环境(如 Microsoft Visual Studio)中打开文件 yourCPLEXhome \examples\src\tutorials\LPex1lesson.cs

步骤 3:创建模型对象

转至该文件中的注释步骤 3,然后添加以下语句来为应用程序创建 Cplex 模型。


    Cplex cplex = new Cplex();

该语句创建类 Cplex 的空实例。 在后续步骤中,您将添加使应用程序能够使用数据填充模型(按行、按列或按非零)的方法。

步骤 4:按行填充模型

现在,转至该文件中的注释步骤 4,然后添加下列行以使用数据按行填充空模型。


   internal static void PopulateByRow(IMPModeler model,
                                      INumVar[][] var,
                                      IRange[][] rng) {
     double[] lb = {0.0, 0.0, 0.0};
     double[] ub = {40.0, 
                    System.Double.MaxValue, 
                    System.Double.MaxValue};
     INumVar[] x  = model.NumVarArray(3, lb, ub);
     var[0] = x;
    
     double[] objvals = {1.0, 2.0, 3.0};
     model.AddMaximize(model.ScalProd(x, objvals));
    
     rng[0] = new IRange[2];
     rng[0][0] = model.AddLe(model.Sum(model.Prod(-1.0, x[0]),
                                       model.Prod( 1.0, x[1]),
                                       model.Prod( 1.0, x[2])), 20.0);
     rng[0][1] = model.AddLe(model.Sum(model.Prod( 1.0, x[0]),
                                       model.Prod(-3.0, x[1]),
                                       model.Prod( 1.0, x[2])), 30.0);
   }

这些行使用特定于此特定示例的数据来填充模型。 但是,您可以从其对接口 IMPModeler 的使用来了解如何向模型中添加范围约束IMPModeler 是通常用于构建数学规划 (MP) 矩阵模型的 Concert Technology 接口。 您将在步骤 5 和步骤 6 中再次看到它的使用。

步骤 5:按列填充模型

转至文件中的注释步骤 5,然后添加下列行以创建使用数据按列填充空模型的方法。


   internal static void PopulateByColumn(IMPModeler model,
                                INumVar[][] var,
                                IRange[][] rng) {
      IObjective obj = model.AddMaximize();
    
      rng[0] = new IRange[2];
      rng[0][0] = model.AddRange(-System.Double.MaxValue, 20.0);
      rng[0][1] = model.AddRange(-System.Double.MaxValue, 30.0);
    
      IRange r0 = rng[0][0];
      IRange r1 = rng[0][1];
    
      var[0] = new INumVar[3];
      var[0][0] = model.NumVar(model.Column(obj,  1.0).And(
                               model.Column(r0,  -1.0).And(
                               model.Column(r1,   1.0))),
                               0.0, 40.0);
      var[0][1] = model.NumVar(model.Column(obj,  2.0).And(
                               model.Column(r0,   1.0).And(
                               model.Column(r1,  -3.0))),
                               0.0, System.Double.MaxValue);
      var[0][2] = model.NumVar(model.Column(obj,  3.0).And(
                               model.Column(r0,   1.0).And(
                               model.Column(r1,   1.0))),
                               0.0, System.Double.MaxValue);
   }

同样,这些行也使用特定于此问题的数据来填充模型。 您可以从中了解如何使用接口 IMPModeler 向空模型中添加

尽管对于许多示例而言,按行填充看似最直接和自然,但在有些模型中更自然或更高效的实施方法是按列填充。 例如,具有网络结构的问题通常适合于按列建模。 熟悉矩阵代数的读者可能会将方法 populateByColumn 视为 populateByRow 的变换。

在此方法中,将创建范围对象以按列(仅对其下限和上限)建模。 未提供有关变量的表达式,因为此时将无法构建这些表达式,原因是尚未创建变量。 同样,创建目标函数仅旨在优化含义,而不具有任何表达式。

接下来,将在现有范围和目标中创建和安装变量。 这些新创建的变量通过列对象引入到范围和目标中,这些列对象在类 IColumn 中实现。 此类的对象使用方法 Cplex.Column 进行创建,并且可以与方法 IColumn.And 链接在一起以形成聚集 IColumn 对象。

使用方法 ICplex.Column 创建的 IColumn 对象包含有关如何使用此列将新变量引入到现有建模对象中的信息。 例如,如果 objIObjective 对象,那么 cplex.Column(obj, 2.0) 会创建 IColumn 对象,其中包含在 IObjective 对象 obj 的表达式中安装线性系数为 2.0 的新变量的信息。 Similarly, for an IRange constraint rng , the method call cplex.Column(rng, -1.0) creates an IColumn object containing the information to install a new variable into the expression of rng , as a linear term with coefficient -1.0 .

简言之,当您使用按列建模方法时,会在需要变量的所有现有建模对象中创建新列并将其安装为变量。 要使用 Concert Technology 执行此操作,请为要安装新变量的每个建模对象创建 IColumn 对象,并将其与方法 IColumn.And 链接在一起。

步骤 6:按非零填充模型

转至文件中的注释步骤 6,然后添加下列行以创建使用数据按非零填充空模型的方法。


    internal static void PopulateByNonzero(IMPModeler model,
                                 INumVar[][] var,
                                 IRange[][] rng) {
      double[]    lb = {0.0, 0.0, 0.0};
      double[]    ub = {40.0, System.Double.MaxValue, System.Double.MaxValue};
      INumVar[] x  = model.NumVarArray(3, lb, ub);
      var[0] = x;
    
      double[] objvals = {1.0, 2.0, 3.0};
      model.Add(model.Maximize(model.ScalProd(x, objvals)));
    
      rng[0] = new IRange[2];
      rng[0][0] = model.AddRange(-System.Double.MaxValue, 20.0);
      rng[0][1] = model.AddRange(-System.Double.MaxValue, 30.0);
    
      rng[0][0].Expr = model.Sum(model.Prod(-1.0, x[0]),
                                 model.Prod( 1.0, x[1]),
                                 model.Prod( 1.0, x[2]));
      rng[0][1].Expr = model.Sum(model.Prod( 1.0, x[0]),
                                 model.Prod(-3.0, x[1]),
                                 model.Prod( 1.0, x[2]));
   }

在这些行中,您可以了解如何使用指示约束矩阵的非零值的数据填充空模型。 这些行首先为没有表达式的目标和范围创建对象。 它们还创建没有列的变量;即,仅具有其界限的变量。 然后,这些行创建有关目标、范围和变量的表达式,并将表达式添加到模型。

步骤 7:添加接口

转至文件中的注释步骤 7,然后添加下列行以创建指示用户如何调用此应用程序的方法。


 internal static void Usage() {
    System.Console.WriteLine(“usage:   LPex1 <option>”);
    System.Console.WriteLine(“options: -r   build model row by row”);
    System.Console.WriteLine(“options: -c   build model column by column”);
    System.Console.WriteLine(“options: -n   build model nonzero by nonzero”);
 }

步骤 8:添加命令评估程序

转至文件中的注释步骤 8,然后添加下列行以创建用于评估应用程序用户可能输入的命令的 switch 语句。


         switch ( args[0].ToCharArray()[1] ) {
         case ‘r’: PopulateByRow(cplex, var, rng);
                   break;
         case ‘c’: PopulateByColumn(cplex, var, rng);
                   break;
         case ‘n’: PopulateByNonzero(cplex, var, rng);
                   break;
         default:  Usage();
                   return;
         }