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

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

...


person MOn    schedule 12.05.2019    source источник
comment
Не могли бы вы подробнее рассказать, в чем именно заключается проблема? Кажется, у вас есть код для чтения файлов CSV, и, насколько я могу судить, этот код должен работать. Может быть, этот CSV имеет другой формат, чем вы ожидаете? Можете ли вы показать этот CSV-файл, ожидаемые результаты и результаты, которые вы действительно получили?   -  person Daniel Junglas    schedule 12.05.2019
comment
У меня есть файл, содержащий 20 точек спроса, их индексы и их веса. У меня есть другой файл, в котором есть 100 узлов и их расстояния между ними. Точки спроса выбираются из 100 узлов. Я не знаю, как получить матрицу расстояний между точками спроса и всеми узлами. Я должен получить индексы точек спроса, чтобы найти их в узлах и узнать расстояние, но я не знаю, как?   -  person MOn    schedule 13.05.2019
comment
int index [точки спроса]; выполнить {var f = new IloOplInputFile (weight.csv); в то время как (! f.eof) {var data = f.readline (). split (,); if (data.length == 3) index [Opl.intValue (data [0])] = Opl.intValue (data [1]); } Writeln (индекс); } float d [точки спроса] [объекты]; выполнить {var f = new IloOplInputFile (test1.csv); в то время как (! f.eof) {var data = f.readline (). split (,); if (data.length == 3) d [точки спроса] [Opl.intValue (data [1])] = Opl.floatValue (data [2]); } Writeln (d); }   -  person MOn    schedule 13.05.2019


Ответы (1)


Надеюсь, я правильно понял ваше объяснение. Предположим, у вас есть файл 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, поскольку нет точки спроса с индексом 2 в weight.csv. Также обратите внимание, что я предполагаю здесь только 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.
person Daniel Junglas    schedule 13.05.2019
comment
Я очень ценю твой ответ. Однако моя проблема в том, что файл text1 уже создан, он имеет 100 узлов и 200 дуг (это означает, что существует всего 200 расстояний). Что мне нужно сделать, так это найти каждый из индексов точек спроса в файле test 1 и посмотреть, есть ли какое-либо расстояние между этой точкой и любой другой точкой или нет. Есть ли у вас какое-нибудь решение? - person MOn; 13.05.2019
comment
Я добавляю изображение файла test1 рядом с файлом веса. первый столбец и второй столбец - это i и j, а третий столбец - это расстояние. поскольку существует 200 расстояний, некоторые из узлов имеют более одной дуги к другим узлам. Я должен найти здесь индексы точек спроса и их расстояния до других узлов и создать матрицу расстояний. расстояние между точками спроса и другими узлами. Я надеюсь, что смогу правильно объяснить. - person MOn; 13.05.2019
comment
Спасибо за ваше сообщение. И извините, что повторил свой вопрос. Это потому, что я не видел, что вы обновили, и мне нужно больше мест для объяснения моего вопроса, чем комментариев, которые я использую. - person MOn; 15.05.2019
comment
У меня есть еще один вопрос. Я не понимаю, как вы определяете float d. Почему вы используете Sum? Моя целевая функция: минимизировать сумму (i в точках спроса, j в пунктах обслуживания) d [i] [j] * x [i] [j] * w [i]; и когда я использую d в этой цели, это дает мне ошибку. - person MOn; 15.05.2019
comment
Вам нужно будет показать ваш полный .mod-файл и фактическую ошибку, которую вы получите, чтобы ответить на свой вопрос. В своем ответе я объяснил, почему я использовал сумму: это уловка, позволяющая справиться со случаем, когда пара i, j существует и случай, когда пара i, j не существует. Если пара существует, то сумма превышает ровно один элемент, а d[i][j] - это расстояние между i и j. Если пара не существует, то сумма больше нуля элементов и, следовательно, d[i][j] = 0. - person Daniel Junglas; 15.05.2019
comment
Спасибо за ваш ответ. Код - это то, что вы мне помогли, а целевая функция - это то, что я написал в предыдущем комментарии. Я получаю следующее сообщение об ошибке: 1. Невозможно загрузить модель 2. Это не массив, и он подчеркнут красным цветом под d [i] [j] * x [i] [j] * w [i] - person MOn; 15.05.2019
comment
Вы уверены, что ошибка исходит от d? Может быть, x или w не относятся к типу массива? Ошибка исчезнет, ​​если вы просто удалите d из своей цели? - person Daniel Junglas; 15.05.2019
comment
Вы были правы, ошибка пришла откуда-то еще. Итак, x определяется как: dvar boolean x [точки спроса] [объекты]; И w определяется как: {int} w = {d.weight | d востребован}; Вы хоть представляете, в чем проблема? - person MOn; 15.05.2019
comment
Думаю, проблема в том, что w - это набор, а не массив. Следовательно, вы не можете индексировать его. Чтобы подтвердить это, удалите w из своей цели и посмотрите, исчезнет ли ошибка. - person Daniel Junglas; 16.05.2019
comment
Привет, @maahnoosh, если этот или какой-либо ответ помог решить ваш вопрос, пожалуйста, примите его, нажав галочку. Это показывает широкому сообществу, что вы нашли решение, и дает некоторую репутацию как автору, так и вам. Это не обязательно. - person Xavier Nodet; 16.05.2019
comment
да, ты был прав. Как я могу определить w как массив? потому что w равен весу, который является набором кортежа. Также не могли бы вы представить источники, из которых я могу научиться программировать в CPLEX? - person MOn; 16.05.2019
comment
@XavierNodet Извините, я не знаком с этим сайтом. Я принял это. - person MOn; 16.05.2019
comment
Хорошей отправной точкой для изучения CPLEX являются документация по продукту и обучающие материалы здесь: ibm.com/support/knowledgecenter/SSSA5P_12.9.0/. Я не знаю, как записать w в виде массива, так как я не знаю, что такое i и j в вашем случае и как выглядит остальная часть модели. Поскольку теперь это не зависит от исходного вопроса (который касался чтения данных из CSV), я предлагаю вам начать новый вопрос по проблеме с w и также опубликовать там свою полную модель. Так вам будет намного проще помочь. - person Daniel Junglas; 16.05.2019