在Cplex

时间:2019-05-12 15:07:43

标签: csv cplex opl

我的问题与上一个问题有关。我应该对代码进行一些更改。 CSV文件中有1到100个节点。我创建另一个CSV文件,并在100个节点之间生成20个随机数,并将其称为需求点。每个需求点都有特定的需求,这些需求是1到10之间随机生成的数字。我想阅读此需求点(索引)及其权重。这是我问题的第一部分?我该怎么读? 之后,我需要在每个需求点与所有节点之间保持一定距离。我不知道如何读取需求点的索引并计算它们与所有节点之间的距离。 根据我提供的代码,我需要很多地方的需求点索引。我的主要问题是我不知道如何通过CSV文件在Cplex中获得这些索引。 需求点及其需求图为:  first column is demandpointindex and second column in their demands this file has 200 rows

我尝试了以下代码来读取需求点:

tuple demands
    {
    int demandpoint;
    int weight;
    }

    {demands} demand={};

    execute
    {
    var f=new IloOplInputFile("weight.csv");
    while (!f.eof)
    {
    var data = f.readline().split(",");
    if (ar.length==2) 
    demand.add(Opl.intValue(ar[0]),Opl.intValue(ar[1]));
    }
    f.close();
    }
    execute
    {
    writeln(demand);
    }

但这不是真的。

int n=100;
 int p=5;


    tuple demands
    {
    int demandpointindex;
    int weight;
    }

    {demands} demand={};

    execute
    {
    var f=new IloOplInputFile("weight.csv");
    while (!f.eof)
    {
    var data = f.readline().split(",");
    if (ar.length==2) 
    demand.add(Opl.intValue(ar[0]),Opl.intValue(ar[1]));
    }
    f.close();
    }
    execute
    {
    writeln(demand);
    }

 float d[demandpointindexes][facilities];

 execute {
   var f = new IloOplInputFile("test1.csv");
   while (!f.eof) {
      var data = f.readline().split(",");
      if (data.length == 3) 
         d[Opl.intValue(data[0])][Opl.intValue(data[1])] = Opl.floatValue(data[2]);
   }
   writeln(d);
   }

 dvar boolean x[demandpointindexe][facilities];

...

1 个答案:

答案 0 :(得分:2)

我希望你的解释正确。假设您有一个文件weight.csv,如下所示:

1,2,
3,7,
4,9,

此处每行的第一项是需求点的索引,第二项是其权重。然后,您可以像使用此脚本块之前一样对此进行解析:

tuple demandpoint {
    int index;
    int weight;
}

{demandpoint} demand={};

execute {
  var f = new IloOplInputFile("weight.csv");
  while (!f.eof) {
   var data = f.readline().split(",");
   if (data.length == 3)
     demand.add(Opl.intValue(data[0]), Opl.intValue(data[1]));
  }
  writeln(demand);
}

接下来,您可以创建一个包含所有需求点索引的集合:

{int} demandpoints = { d.index | d in demand };

假设文件test1.csv如下

1,1,0,
1,2,5,
1,3,6,
1,4,7,
3,1,1,
3,2,1.5,
3,3,0,
3,4,3.5,
4,1,1,
4,2,1.5,
4,3,1.7,
4,4,0,

这里第一项是需求点指数,第二项是设施指数,第三项是第一项和第二项之间的距离。请注意,由于weight.csv中没有索引为2的需求点,因此没有以2开头的行。另请注意,我在这里仅假设4个功能(以使文件简短)。您可以读取需求点和设施之间的距离,如下所示:

range facilities = 1..4;
float d[demandpoints][facilities];

execute {
  var f = new IloOplInputFile("test1.csv");
  while (!f.eof) {
    var data = f.readline().split(",");
    if (data.length == 4)
      d[Opl.intValue(data[0])][Opl.intValue(data[1])] = Opl.floatValue(data[2]);
  }
  writeln(d);
}

完整脚本(包括虚拟目标和约束,以便可以运行)看起来如下:

tuple demandpoint {
    int index;
    int weight;
}

{demandpoint} demand={};

execute {
  var f = new IloOplInputFile("weight.csv");
  while (!f.eof) {
   var data = f.readline().split(",");
   if (data.length == 3)
     demand.add(Opl.intValue(data[0]), Opl.intValue(data[1]));
  }
  writeln(demand);
}

// Create a set that contains all the indeces of demand points
// as read from weight.csv
{int} demandpoints = { d.index | d in demand };

range facilities = 1..4;
float d[demandpoints][facilities];

execute {
  var f = new IloOplInputFile("test1.csv");
  while (!f.eof) {
    var data = f.readline().split(",");
    if (data.length == 4)
      d[Opl.intValue(data[0])][Opl.intValue(data[1])] = Opl.floatValue(data[2]);
  }
  writeln(d);
}

minimize 0;
subject to {}

它打印

 {<1 2> <3 7> <4 9>}
 [[0 5 6 7]
  [1 1.5 0 3.5]
  [1 1.5 1.7 0]]

请注意您的csv中有多少个逗号!上面发布的代码假定每行以逗号结尾。也就是说,每行都有与字段一样多的逗号。如果最后一个字段不是以逗号结尾,则必须调整解析器。

如果在test1.csv中所有节点之间的距离是{em},则首先将数据读入数组float distance[facilities][facilities];,然后定义数组{{1 }}基于

d

更新以获取您在评论中提供的更详细的规范: 为了处理您在注释中说明的float d[i in demandpoints][j in facilities] = distance[i][j]; ,可以定义一个新的元组:

test1.csv

并完全按照解析tuple Distance { int demandpoint; int facility; float distance; } {Distance} distances = {}; 文件的方式读取/解析此文件(当然还有一个附加字段)。 然后,您可以像这样创建距离矩阵:

weight.csv

这里float d[i in I][j in J] = sum (dist in distances : dist.demandpoint == i && dist.facility == j) dist.distance; I分别是需求点和设施的集合或范围。有关如何获取在元组集中定义的所有需求点的集合,请参见上文。创建的矩阵将为每个需求点/距离对都有一个条目。定义J的诀窍是有两种情况:

  1. 如果在d中定义了一对(i,j),则总和将与test1.csv中的一个元素完全匹配:一个元素定义了两个点之间的距离。
  2. 如果distances中未定义对(i,j),则总和将不匹配任何内容,因此距离矩阵中的对应项将为0。