читать файл CSV в Cplex - PullRequest
       18

читать файл CSV в Cplex

0 голосов
/ 12 мая 2019

мой вопрос связан с моим предыдущим вопросом.Я должен внести некоторые изменения в мой код.У меня есть количество узлов от 1 до 100 в файле CSV.Я создаю еще один CSV-файл и генерирую 20 случайных чисел между 100 узлами и называю их точками спроса.Каждая из этих точек спроса имеет определенные требования, которые случайным образом генерируют числа от 1 до 10. Я хочу прочитать эти точки спроса (индексы) и их веса.это первая часть моего вопроса?как я могу это прочитать?После этого мне нужно иметь расстояние между каждой из этих точек спроса и всеми узлами.Я не умею просто читать индексы точек спроса и вычислять расстояние между ними и всеми узлами.Исходя из предоставленного мною кода, мне нужны индексы точек спроса для многих мест.Моя главная проблема в том, что я не знаю, как мне получить эти индексы в Cplex через файл CSV.Точки спроса с изображением их требований: первый столбец - это pointpointindex, а второй столбец в их требованиях этот файл содержит 200 строк

Я пробовал этот код для чтения спросаОчки:

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 Ответ

2 голосов
/ 13 мая 2019

Надеюсь, я правильно понял.Предположим, у вас есть файл 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,

Здесь первый элемент - это индекс точки спроса, второй элемент - это индекс объекта, а третий элемент - это расстояние между первым и вторым элементами.Обратите внимание, что нет строк, начинающихся с 2, поскольку в weight.csv отсутствует точка спроса с индексом 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 расстояние между всеми узлами, то имеет смысл сначала прочитатьданные в массив float distance[facilities][facilities];, а затем определить массив 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 - наборы или диапазоны точек спроса и объектов, соответственно.Смотрите выше, как вы можете получить набор всех точек спроса, определенных в наборе кортежей.Созданная матрица будет иметь запись для каждой пары «точка спроса / расстояние».Хитрость в определении d заключается в том, что есть два случая:

  1. Если пара (i, j) определена в test1.csv, то сумма будет соответствовать ровно одному элементу в distances: тот, который определяет расстояние между двумя точками.
  2. Если пара (i, j) не определена в test1.csv, то сумма не будет ничего совпадать, и поэтому соответствующая запись в матрице расстояний будет0.
...