Я работаю над проектом, который использует этот пример кода по своей сути; использование пользовательской матрицы расстояния/времени для решения проблемы маршрутизации. Алгоритм работает отлично, но я не могу найти способ просмотреть результаты на графике. Запуск только примера кода без каких-либо изменений приводит к:
2015-07-07 11:56:33,354 [main] ПРЕДУПРЕЖДЕНИЕ jsprit.analysis.toolbox.Plotter - не удается построить vrp, так как отсутствует координата
Эта ошибка имеет смысл. Ничто не может быть нанесено на график, потому что на самом деле не указаны местоположения; мы указали только относительное расстояние/время между местоположениями. Я должен использовать пользовательскую матрицу, потому что я работаю в широте/долготе и мне нужно реальное расстояние между точками. Однако по мере того, как моя проблема увеличивается, мне было бы очень полезно просто присвоить каждому местоположению его широту/долготу и построить график, рассматривающий эти точки, как если бы они были декартовыми координатами. Зона охвата невелика, поэтому она все равно должна позволить мне быстро увидеть, имеет ли решение смысл, без необходимости делать более сложные графики. Итак, мой вопрос заключается в том, есть ли простой способ заставить jsprit решить проблему, используя пользовательскую матрицу расстояния/времени, но присваивая координаты местоположениям для построения графика? Не могу понять, заранее спасибо.
РЕДАКТИРОВАТЬ: я потратил много времени, работая над этим безрезультатно, даже с предложенными изменениями от Стефана. Я не могу найти способ сделать это без изменения базового кода, и я не хочу, чтобы это вызывало проблемы с тем, что у меня уже работает.
Создание местоположения — это хорошо, хотя оно немного отличается от предлагаемого кода:
Location.Builder.newInstance().setId("0").setCoordinate(Coordinate.newInstance(10.0, 10.0)).build();
Затем возникает проблема: когда я хочу создать Службу, текущий код вынуждает меня определить новое местоположение (Местоположение принимает только новый экземпляр):
Service s2 = Service.Builder.newInstance("2").addSizeDimension(0, 1).setLocation(Location.newInstance(6.0, 1.0)).build();
Я не могу найти существующий способ просто сказать, что Служба находится в заранее определенном месте.
Двигаясь дальше, я подумал о добавлении местоположений непосредственно в VehicleRoutingProblem.Builder. Обратите внимание, что добавление местоположения в построитель требует, чтобы оно было определено как «addLocation(String LocationID, координата координаты), поэтому оно не будет принимать заранее определенные местоположения явно; они должны быть определены в построителе. Это выглядит следующим образом:
VehicleType type = VehicleTypeImpl.Builder.newInstance("type").addCapacityDimension(0, 5).setCostPerDistance(1).setCostPerTime(2).build();
VehicleImpl vehicle = VehicleImpl.Builder.newInstance("vehicle")
.setStartLocation(Location.newInstance("0")).setType(type).build();
Service s1 = Service.Builder.newInstance("1").addSizeDimension(0, 1).setLocation(Location.newInstance("1")).build();
Service s2 = Service.Builder.newInstance("2").addSizeDimension(0, 1).setLocation(Location.newInstance("2")).build();
Service s3 = Service.Builder.newInstance("3").addSizeDimension(0, 1).setLocation(Location.newInstance("3")).build();
//define a matrix-builder building an asymmetric matrix
VehicleRoutingTransportCostsMatrix.Builder costMatrixBuilder = VehicleRoutingTransportCostsMatrix.Builder.newInstance(true);
costMatrixBuilder.addTransportDistance("0", "1", 19.13);
costMatrixBuilder.addTransportDistance("0", "2", 18.56);
costMatrixBuilder.addTransportDistance("0", "3", 21.68);
costMatrixBuilder.addTransportDistance("1", "0", 15.91);
costMatrixBuilder.addTransportDistance("1", "2", 15.01);
costMatrixBuilder.addTransportDistance("1", "3", 11.45);
costMatrixBuilder.addTransportDistance("2", "0", 19.42);
costMatrixBuilder.addTransportDistance("2", "1", 12.54);
costMatrixBuilder.addTransportDistance("2", "3", 11.13);
costMatrixBuilder.addTransportDistance("3", "0", 25.75);
costMatrixBuilder.addTransportDistance("3", "1", 9.94);
costMatrixBuilder.addTransportDistance("3", "2", 11.24);
costMatrixBuilder.addTransportTime("0", "1", 12);
costMatrixBuilder.addTransportTime("0", "2", 11);
costMatrixBuilder.addTransportTime("0", "3", 15);
costMatrixBuilder.addTransportTime("1", "0", 10);
costMatrixBuilder.addTransportTime("1", "2", 10);
costMatrixBuilder.addTransportTime("1", "3", 10);
costMatrixBuilder.addTransportTime("2", "0", 15);
costMatrixBuilder.addTransportTime("2", "1", 9);
costMatrixBuilder.addTransportTime("2", "3", 10);
costMatrixBuilder.addTransportTime("3", "0", 17);
costMatrixBuilder.addTransportTime("3", "1", 13);
costMatrixBuilder.addTransportTime("3", "2", 10);
VehicleRoutingTransportCosts costMatrix = costMatrixBuilder.build();
VehicleRoutingProblem vrp = VehicleRoutingProblem.Builder.newInstance().setFleetSize(FleetSize.FINITE).setRoutingCost(costMatrix)
.addVehicle(vehicle).addJob(s1).addJob(s2).addJob(s3)
.addLocation("0", Coordinate.newInstance(1.0, 1.0)).addLocation("1", Coordinate.newInstance(9.0, 2.0))
.addLocation("2", Coordinate.newInstance(5.0, 4.0)).addLocation("3", Coordinate.newInstance(4.0, 8.0))
.addLocation("4", Coordinate.newInstance(3.0, 7.0)).build();`
Это работает нормально. Но он все равно не будет отображаться, потому что он не устанавливает связь между индексами местоположения и возможностью их построения. Однако я могу подтвердить (как и было запрошено), что решатель использует только предопределенную матрицу затрат, поэтому напечатанный ответ по-прежнему верен.