Надеюсь, я правильно понял.Предположим, у вас есть файл 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
заключается в том, что есть два случая:
- Если пара (i, j) определена в
test1.csv
, то сумма будет соответствовать ровно одному элементу в distances
: тот, который определяет расстояние между двумя точками. - Если пара (i, j) не определена в
test1.csv
, то сумма не будет ничего совпадать, и поэтому соответствующая запись в матрице расстояний будет0.