在Cplex中读取CSV文件 [英] read CSV file in Cplex

查看:344
本文介绍了在Cplex中读取CSV文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

my question is related to my previous question. I should make some change in my code. I have a number of nodes between 1 to 100 in the CSV file. I create another CSV file and generate 20 random numbers between the 100 nodes and called them demand points. Each of this demand point has specific demands which are the randomly generate numbers between 1 to 10. I want to read this demand points(the indexes) and their weights. this is the first part of my question? how can I read this? After that, I need to have a distance between each of these demand points and all nodes. I don't how can I just read the indexes of demand points and calculate the distance between them and all the nodes. Based on the code that I provided, I need the indexes of demand points for a lot of places. My main problem is that I don't know how should I get these indexes in Cplex through the CSV file. The demand points with their demands picture is: first column is demandpointindex and second column in their demands this file has 200 rows

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

I tried this code for reading the demand points:

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];

...

推荐答案

我希望我的解释正确.假设您有一个像这样的文件weight.csv:

I hope I got your explanation right. Assume you have a file weight.csv like this:

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

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

Here the first item in each row is the index of a demand point, the second item is its weight. Then you can parse this as before using this scripting block:

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);
}

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

Next you can create a set that contains the indeces of all the demand points:

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

假设文件test1.csv如下

Assume file test1.csv looks like this

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个功能(以使文件简短).您可以读取需求点和设施之间的距离,如下所示:

Here the first item is a demand point index, the second item is a facility index and the third item is the distance between first and second item. Note that there are no lines that start with 2 since there is no demand point with index 2 in weight.csv. Also note that I assume only 4 facilities here (to keep the file short). You can read the distance between demand points and facitilies as follows:

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);
}

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

The full script (including a dummy objective and constraints so that it can be run) looks:

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中有多少个逗号!上面发布的代码假定每行以逗号结尾.也就是说,每行都有与字段一样多的逗号.如果最后一个字段不是以逗号结尾,则必须调整解析器.

Be careful about how many commas you have in your csv! The code posted above assumes that each line ends with a comma. That is, each line has as many commas as it has fields. If the last field is not terminated by a comma then you have to adapt the parser.

如果test1.csv所有节点之间的距离都在test1.csv中,则有必要先将数据读取到数组float distance[facilities][facilities];中,然后根据该值定义数组d,这是有道理的

If you have in test1.csv the distance between all the nodes then it makes sense to first read the data into an array float distance[facilities][facilities]; and then define the array d based on that as

float d[i in demandpoints][j in facilities] = distance[i][j];

更新,以获取您在评论中提供的更详细的规范: 为了处理您在注释中解释的test1.csv,您可以定义一个新的元组:

Update for the more detailed specification you gave in the comments: In order to handle the test1.csv you explained in the comments you could define a new tuple:

tuple Distance {
   int demandpoint;
   int facility;
   float distance;
}
{Distance} distances = {};

并完全按照解析weight.csv文件的方式读取/解析(当然,还有一个附加字段). 然后,您可以像这样创建距离矩阵:

and read/parse this exactly as you did parse the weight.csv file (with one additional field, of course). Then you can create the distance matrix like so:

float d[i in I][j in J] = sum (dist in distances : dist.demandpoint == i && dist.facility == j) dist.distance;

此处IJ分别是需求点和设施的集合或范围.有关如何获取一组在元组集中定义的所有需求点的信息,请参见上文.创建的矩阵将为每个需求点/距离对都有一个条目.定义d的诀窍是有两种情况:

Here I and J are the sets or ranges of demand points and facilities, respectively. See above for how you can get a set of all demand points defined in the tuple set. The created matrix will have an entry for each demandpoint/distance pair. The trick in the definition d is that there are two cases:

  1. 如果在test1.csv中定义了一对(i,j),则总和将与distances中的一个元素完全匹配:一个元素定义了两个点之间的距离.
  2. 如果在test1.csv中未定义对(i,j),则总和将不匹配任何内容,因此距离矩阵中的对应项将为0.
  1. If a pair (i,j) is defined in test1.csv then the sum will match exactly one element in distances: the one that defines the distance between two points.
  2. If a pair (i,j) is not defined in test1.csv then the sum will not match anything and the corresponding entry in the distance matrix will thus be 0.

这篇关于在Cplex中读取CSV文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆