Commit 00fb0844 authored by Vladislav Kiselev's avatar Vladislav Kiselev

Refactoring.

parent d233ebf1
......@@ -3,7 +3,11 @@
rm -f raw_result.txt
rm -f result.txt
java -classpath "../out/production/Conversion" inport.Main to_MiniZinc in.ipp conversion_0.dzn
java -classpath "../out/production/Conversion" inport.Main to_MiniZinc_0 in.ipp conversion_0.dzn
mzn2fzn -o model.fzn "../constraints/conversion_0.mzn" conversion_0.dzn
N_LINES=$(wc -l model.fzn)
echo "Model size : $N_LINES"
START=$(date +%s.%N)
......@@ -12,6 +16,6 @@ minizinc --solver Gecode "../constraints/conversion_0.mzn" conversion_0.dzn >> r
END=$(date +%s.%N)
DIFF=$(echo "$END - $START" | bc)
echo $(DIFF)
echo $DIFF
java -classpath "../out/production/Conversion" inport.Main resolve_result in.ipp raw_result.txt result.txt
......@@ -257,24 +257,46 @@ public class ConversionUtil {
return true;
}
static public void portToMiniZinc(TaskCase task, String fileName) throws IOException {
try(FileWriter writer = new FileWriter(fileName, false)) {
int n_intervals = (int)task.getPlanningInterval();
writer.write("n_intervals = " + n_intervals + ";\n");
writer.write("n_operations = " + task.getTemplates().size() + ";\n");
ArrayList<Berth> berths = new ArrayList<>(task.getBerths());
Map<Pair<Integer, Boolean>, Integer> locationNumberById = new TreeMap<>(new PairComparator());
private static class Task {
private FileWriter writer = null;
private final String fileName;
private final TaskCase task;
private final int n_intervals;
private final ArrayList<Berth> berths;
private final Map<Pair<Integer, Boolean>, Integer> locationNumberById;
private final BiFunction<Integer, Boolean, Integer> getLocNById;
private final ArrayList<MovingObject> movingObjects;
private final Function<MovingObject, Integer> mObjToN;
private final ArrayList<OperationTemplate> operationTemplates;
private final ArrayList<Storage> storages;
private final ArrayList<Cargo> cargoes;
private final int nObjWithStorage;
private final Map<Integer, Integer> storNById;
private final Map<Integer, Integer> cargoNById;
Task(TaskCase task, String fileName) {
this.fileName = fileName;
this.task = task;
n_intervals = (int)task.getPlanningInterval();
berths = new ArrayList<>(task.getBerths());
locationNumberById = new TreeMap<>(new PairComparator());
for (Berth berth : berths) {
locationNumberById.put(new Pair<>(berth.getId(), false), locationNumberById.size());
locationNumberById.put(new Pair<>(berth.getId(), true), locationNumberById.size());
}
writer.write("n_locations = " + locationNumberById.size() + ";\n");
BiFunction<Integer, Boolean, Integer> getLocNById =
(Integer id, Boolean isMoored) -> locationNumberById.get(new Pair<>(id, isMoored));
getLocNById = (Integer id, Boolean isMoored) -> locationNumberById.get(new Pair<>(id, isMoored));
ArrayList<MovingObject> movingObjects = new ArrayList<>();
movingObjects = new ArrayList<>();
Map<Integer, Integer> mObjNumberById = new TreeMap<>();
for (MovingObject obj : task.getShips()) {
mObjNumberById.put(obj.getId(), movingObjects.size());
......@@ -288,365 +310,421 @@ public class ConversionUtil {
mObjNumberById.put(obj.getId(), movingObjects.size());
movingObjects.add(obj);
}
writer.write("n_moving_obj = " + movingObjects.size() + ";\n");
writer.write("\n");
Function<MovingObject, Integer> mObjToN = (MovingObject obj) -> mObjNumberById.get(obj.getId());
ArrayList<OperationTemplate> operationTemplates = new ArrayList<>(task.getTemplates());
{ // Операции прибытия/отбытия в локацию. (В том числе и швартовка.)
ArrayList<ArrayList<ArrayList<Integer>>> arrivalOp = new ArrayList<>();
ArrayList<ArrayList<ArrayList<Integer>>> departureOp = new ArrayList<>();
for (int i = 0; i < movingObjects.size(); i++) {
arrivalOp.add(new ArrayList<>());
departureOp.add(new ArrayList<>());
for (int j = 0; j < locationNumberById.size(); j++) {
arrivalOp.get(i).add(new ArrayList<>());
departureOp.get(i).add(new ArrayList<>());
}
}
mObjToN = (MovingObject obj) -> mObjNumberById.get(obj.getId());
operationTemplates = new ArrayList<>(task.getTemplates());
for (int i = 0; i < operationTemplates.size(); i++) {
if (operationTemplates.get(i) instanceof MovingTemplate) {
MovingTemplate op = (MovingTemplate)operationTemplates.get(i);
storages = new ArrayList<>(task.getStorages());
cargoes = new ArrayList<>(task.getCargoes());
ArrayList<Integer> movingObjN = new ArrayList<>();
for (MovingObject obj : op.getResources()) {
movingObjN.add(mObjToN.apply(obj));
}
movingObjN.add(mObjToN.apply(op.getMover()));
storNById = new TreeMap<>();
for (int i = 0; i < storages.size(); i++) {
storNById.put(storages.get(i).getId(), i);
}
for (Integer n : movingObjN) {
arrivalOp .get(n).get(getLocNById.apply(op.getDestination().getId(), false)).add(i + 1);
departureOp.get(n).get(getLocNById.apply(op.getStartLocation().getId(), false)).add(i + 1);
}
} else if (operationTemplates.get(i) instanceof MooringTemplate) {
MooringTemplate op = (MooringTemplate)operationTemplates.get(i);
cargoNById = new TreeMap<>();
for (int i = 0; i < task.getCargoes().size(); i++) {
cargoNById.put(cargoes.get(i).getId(), i);
}
ArrayList<Integer> movingObjN = new ArrayList<>();
for (MovingObject obj : op.getResources()) {
movingObjN.add(mObjToN.apply(obj));
}
movingObjN.add(mObjToN.apply(op.getMoorer()));
nObjWithStorage = movingObjects.size() + storages.size();
}
for (Integer n : movingObjN) {
arrivalOp .get(n).get(getLocNById.apply(op.getStartLocation().getId(), op.isDirect())).add(i + 1);
departureOp.get(n).get(getLocNById.apply(op.getStartLocation().getId(), !op.isDirect())).add(i + 1);
}
}
}
write2DArrayOfSetAs3DArray(writer, "arrival_op", arrivalOp);
write2DArrayOfSetAs3DArray(writer, "departure_op", departureOp);
writer.write("\n");
}
{ // Начальные положения объектов.
ArrayList<Integer> initialStates = integerArray(movingObjects.size(), 0);
for (MovingObjectState state : task.getVesselInitialState()) {
initialStates.set(mObjToN.apply(state.getVessel()), getLocNById.apply(state.getLocation().getId(), false));
}
writeArray(writer, "initial_m_obj_loc", initialStates, (Integer p) -> p + 1);
writer.write("\n");
}
{ // Окна погоды.
ArrayList<Integer> bw_op = new ArrayList<>();
ArrayList<Integer> bw_start = new ArrayList<>();
ArrayList<Integer> bw_fin = new ArrayList<>();
for (int i = 0; i < operationTemplates.size(); i++) {
final int id = i;
operationTemplates.get(i).getTimeWindows().forEach(
(Double start, Double duration) -> {
bw_op.add(id + 1);
bw_start.add((int)Math.floor(start));
bw_fin.add((int)Math.ceil(start + duration));
}
);
/* Операции прибытия/отбытия в локацию. (В том числе и швартовка.) */
private void arrivalAndDepartureOperations() throws IOException {
ArrayList<ArrayList<ArrayList<Integer>>> arrivalOp = new ArrayList<>();
ArrayList<ArrayList<ArrayList<Integer>>> departureOp = new ArrayList<>();
for (int i = 0; i < movingObjects.size(); i++) {
arrivalOp.add(new ArrayList<>());
departureOp.add(new ArrayList<>());
for (int j = 0; j < locationNumberById.size(); j++) {
arrivalOp.get(i).add(new ArrayList<>());
departureOp.get(i).add(new ArrayList<>());
}
writer.write("n_bad_weather_windows = " + bw_op.size() + ";\n");
writeArray(writer, "bw_op", bw_op);
writeArray(writer, "bw_start", bw_start);
writeArray(writer, "bw_fin", bw_fin);
writer.write("\n");
}
{ // Непрерывность перемещения и швартовки.
ArrayList<Integer> operationsDuration = integerArray(operationTemplates.size(), 0);
ArrayList<Boolean> isMovingObj = new ArrayList<>();
for (int i = 0; i < operationTemplates.size(); i++) {
if (operationTemplates.get(i) instanceof MovingTemplate) {
MovingTemplate op = (MovingTemplate)operationTemplates.get(i);
operationsDuration.set(i, (int)Math.ceil(op.getDuration()));
isMovingObj.add(true);
} else if (operationTemplates.get(i) instanceof MooringTemplate) {
MooringTemplate op = (MooringTemplate) operationTemplates.get(i);
for (int i = 0; i < operationTemplates.size(); i++) {
if (operationTemplates.get(i) instanceof MovingTemplate) {
MovingTemplate op = (MovingTemplate)operationTemplates.get(i);
operationsDuration.set(i, (int)Math.ceil(op.getDuration()));
isMovingObj.add(true);
} else {
isMovingObj.add(false);
ArrayList<Integer> movingObjN = new ArrayList<>();
for (MovingObject obj : op.getResources()) {
movingObjN.add(mObjToN.apply(obj));
}
}
writeArray(writer, "operations_duration", operationsDuration);
writeArray(writer, "is_continuous_operation", isMovingObj);
}
{ // Конечные положения объектов.
ArrayList<Integer> finalStates = integerArray(movingObjects.size(), -1);
for (MovingObjectState state : task.getVesselEndState()) {
finalStates.set(mObjToN.apply(state.getVessel()), getLocNById.apply(state.getLocation().getId(), false));
}
writeArray(writer, "final_m_obj_loc", finalStates, (Integer p) -> p + 1);
}
{ // Наличие всех ресурсов на месте, в том числе и самого корабля.
// TODO ресурсы покрываются "Конфликтующими операциями" (кроме наличия корабля на месте).
ArrayList<Set<Integer>> operationsResources = new ArrayList<>();
ArrayList<Integer> operationsStartLoc = integerArray(operationTemplates.size(), 0);
for (int i = 0; i < operationTemplates.size(); i++) {
operationsResources.add(new TreeSet<>());
if (operationTemplates.get(i) instanceof MovingTemplate) { // Перемещение.
MovingTemplate op = (MovingTemplate)operationTemplates.get(i);
Set<Integer> s = new TreeSet<>();
s.add(mObjToN.apply(op.getMover()) + 1);
for (MovingObject obj : op.getResources()) {
s.add(mObjToN.apply(obj) + 1);
}
operationsResources.set(i, s);
operationsStartLoc.set(i, getLocNById.apply(op.getStartLocation().getId(), false) + 1);
} else if (operationTemplates.get(i) instanceof MooringTemplate) { // Швартовка.
MooringTemplate op = (MooringTemplate)operationTemplates.get(i);
Set<Integer> s = new TreeSet<>();
s.add(mObjToN.apply(op.getMoorer()) + 1);
for (MovingObject obj : op.getResources()) {
s.add(mObjToN.apply(obj) + 1);
}
operationsResources.set(i, s);
operationsStartLoc.set(i, getLocNById.apply(op.getStartLocation().getId(), !op.isDirect()) + 1);
} else if (operationTemplates.get(i) instanceof LoadingTemplate) { // Погрузка.
LoadingTemplate op = (LoadingTemplate) operationTemplates.get(i);
movingObjN.add(mObjToN.apply(op.getMover()));
Set<Integer> s = new TreeSet<>();
s.add(mObjToN.apply(op.getLoader()) + 1);
for (Integer n : movingObjN) {
arrivalOp .get(n).get(getLocNById.apply(op.getDestination().getId(), false)).add(i + 1);
departureOp.get(n).get(getLocNById.apply(op.getStartLocation().getId(), false)).add(i + 1);
}
} else if (operationTemplates.get(i) instanceof MooringTemplate) {
MooringTemplate op = (MooringTemplate)operationTemplates.get(i);
// TODO ресурсы у операции погрузки.
ArrayList<Integer> movingObjN = new ArrayList<>();
for (MovingObject obj : op.getResources()) {
movingObjN.add(mObjToN.apply(obj));
}
movingObjN.add(mObjToN.apply(op.getMoorer()));
operationsResources.set(i, s);
operationsStartLoc.set(i, getLocNById.apply(op.getStartLocation().getId(), true) + 1);
for (Integer n : movingObjN) {
arrivalOp .get(n).get(getLocNById.apply(op.getStartLocation().getId(), op.isDirect())).add(i + 1);
departureOp.get(n).get(getLocNById.apply(op.getStartLocation().getId(), !op.isDirect())).add(i + 1);
}
// TODO швартовка, погрузка.
}
writeArray(writer, "operations_start_loc", operationsStartLoc);
//writeArray(writer, "operations_resources", operationsResources, ConversionUtil::setToString);
writeArrayOfSetAs2DArray(writer, "operations_resources", operationsResources);
writer.write("\n");
}
{ // Конфликтующие операции.
ArrayList<Pair<Integer, Integer>> conflictingPairs = new ArrayList<>();
for (int i = 0; i < operationTemplates.size(); i++) {
for (int j = i + 1; j < operationTemplates.size(); j++) {
if (!isCompatible(operationTemplates.get(i), operationTemplates.get(j))) {
conflictingPairs.add(new Pair<>(i + 1, j + 1));
}
}
}
writer.write("n_conflicting_op = " + conflictingPairs.size() + ";\n");
writeArray(writer, "confl_op_1", conflictingPairs, Pair::getKey);
writeArray(writer, "confl_op_2", conflictingPairs, Pair::getValue);
writer.write("\n");
write2DArrayOfSetAs3DArray(writer, "arrival_op", arrivalOp);
write2DArrayOfSetAs3DArray(writer, "departure_op", departureOp);
writer.write("\n");
}
/* Начальные положения объектов. */
private void initialLocations() throws IOException {
ArrayList<Integer> initialStates = integerArray(movingObjects.size(), 0);
for (MovingObjectState state : task.getVesselInitialState()) {
initialStates.set(mObjToN.apply(state.getVessel()), getLocNById.apply(state.getLocation().getId(), false));
}
// Грузоообработка.
writeArray(writer, "initial_m_obj_loc", initialStates, (Integer p) -> p + 1);
writer.write("\n");
}
ArrayList<Storage> storages = new ArrayList<>(task.getStorages());
ArrayList<Cargo> cargoes = new ArrayList<>(task.getCargoes());
/* Окна погоды. */
private void weatherWindows() throws IOException {
ArrayList<Integer> bw_op = new ArrayList<>();
ArrayList<Integer> bw_start = new ArrayList<>();
ArrayList<Integer> bw_fin = new ArrayList<>();
for (int i = 0; i < operationTemplates.size(); i++) {
final int id = i;
operationTemplates.get(i).getTimeWindows().forEach(
(Double start, Double duration) -> {
bw_op.add(id + 1);
bw_start.add((int)Math.floor(start));
bw_fin.add((int)Math.ceil(start + duration));
}
);
}
writer.write("n_bad_weather_windows = " + bw_op.size() + ";\n");
writeArray(writer, "bw_op", bw_op);
writeArray(writer, "bw_start", bw_start);
writeArray(writer, "bw_fin", bw_fin);
writer.write("\n");
}
Map<Integer, Integer> storNById = new TreeMap<>();
for (int i = 0; i < storages.size(); i++) {
storNById.put(storages.get(i).getId(), i);
/* Непрерывность перемещения и швартовки. */
private void operationsContinuity() throws IOException {
ArrayList<Integer> operationsDuration = integerArray(operationTemplates.size(), 0);
ArrayList<Boolean> isMovingObj = new ArrayList<>();
for (int i = 0; i < operationTemplates.size(); i++) {
if (operationTemplates.get(i) instanceof MovingTemplate) {
MovingTemplate op = (MovingTemplate)operationTemplates.get(i);
operationsDuration.set(i, (int)Math.ceil(op.getDuration()));
isMovingObj.add(true);
} else if (operationTemplates.get(i) instanceof MooringTemplate) {
MooringTemplate op = (MooringTemplate) operationTemplates.get(i);
operationsDuration.set(i, (int)Math.ceil(op.getDuration()));
isMovingObj.add(true);
} else {
isMovingObj.add(false);
}
}
writeArray(writer, "operations_duration", operationsDuration);
writeArray(writer, "is_continuous_operation", isMovingObj);
}
Map<Integer, Integer> cargoNById = new TreeMap<>();
for (int i = 0; i < task.getCargoes().size(); i++) {
cargoNById.put(cargoes.get(i).getId(), i);
/* Конечные положения объектов. */
private void finalLocations() throws IOException {
ArrayList<Integer> finalStates = integerArray(movingObjects.size(), -1);
for (MovingObjectState state : task.getVesselEndState()) {
finalStates.set(mObjToN.apply(state.getVessel()), getLocNById.apply(state.getLocation().getId(), false));
}
writeArray(writer, "final_m_obj_loc", finalStates, (Integer p) -> p + 1);
}
int nObjWithStorage = movingObjects.size() + storages.size();
/* Наличие всех ресурсов на месте, в том числе и самого корабля. */
private void presenceOfResourcesInLocation() throws IOException {
// TODO ресурсы покрываются "Конфликтующими операциями" (кроме наличия корабля на месте).
ArrayList<Set<Integer>> operationsResources = new ArrayList<>();
ArrayList<Integer> operationsStartLoc = integerArray(operationTemplates.size(), 0);
for (int i = 0; i < operationTemplates.size(); i++) {
operationsResources.add(new TreeSet<>());
if (operationTemplates.get(i) instanceof MovingTemplate) { // Перемещение.
MovingTemplate op = (MovingTemplate)operationTemplates.get(i);
Set<Integer> s = new TreeSet<>();
s.add(mObjToN.apply(op.getMover()) + 1);
for (MovingObject obj : op.getResources()) {
s.add(mObjToN.apply(obj) + 1);
}
operationsResources.set(i, s);
operationsStartLoc.set(i, getLocNById.apply(op.getStartLocation().getId(), false) + 1);
} else if (operationTemplates.get(i) instanceof MooringTemplate) { // Швартовка.
MooringTemplate op = (MooringTemplate)operationTemplates.get(i);
Set<Integer> s = new TreeSet<>();
s.add(mObjToN.apply(op.getMoorer()) + 1);
for (MovingObject obj : op.getResources()) {
s.add(mObjToN.apply(obj) + 1);
}
operationsResources.set(i, s);
operationsStartLoc.set(i, getLocNById.apply(op.getStartLocation().getId(), !op.isDirect()) + 1);
} else if (operationTemplates.get(i) instanceof LoadingTemplate) { // Погрузка.
LoadingTemplate op = (LoadingTemplate) operationTemplates.get(i);
writer.write("n_obj_with_storage = " + nObjWithStorage + ";\n");
writer.write("n_cargo_types = " + cargoes.size() + ";\n");
Set<Integer> s = new TreeSet<>();
s.add(mObjToN.apply(op.getLoader()) + 1);
{ // Ограничения на вместимость.
ArrayList<Integer> maxStorageVol = new ArrayList<>();
// TODO ресурсы у операции погрузки.
for (MovingObject obj : movingObjects) {
if (obj instanceof TransportShip) {
maxStorageVol.add((int)Math.ceil(((TransportShip) obj).getCargoMax()));
} else {
maxStorageVol.add(0);
}
operationsResources.set(i, s);
operationsStartLoc.set(i, getLocNById.apply(op.getStartLocation().getId(), true) + 1);
}
for (Storage storage : storages) {
maxStorageVol.add((int)Math.ceil(storage.getVolume()));
// TODO швартовка, погрузка.
}
writeArray(writer, "operations_start_loc", operationsStartLoc);
//writeArray(writer, "operations_resources", operationsResources, ConversionUtil::setToString);
writeArrayOfSetAs2DArray(writer, "operations_resources", operationsResources);
writer.write("\n");
}
/* Конфликтующие операции. */
private void conflictingOperations() throws IOException {
ArrayList<Pair<Integer, Integer>> conflictingPairs = new ArrayList<>();
for (int i = 0; i < operationTemplates.size(); i++) {
for (int j = i + 1; j < operationTemplates.size(); j++) {
if (!isCompatible(operationTemplates.get(i), operationTemplates.get(j))) {
conflictingPairs.add(new Pair<>(i + 1, j + 1));
}
}
writeArray(writer, "max_storage_vol", maxStorageVol);
writer.write("\n");
}
{ // Граничные условия хранилищ.
// TODO выделить отдельно общий код.
ArrayList<ArrayList<Integer>> initialStorageVol = new ArrayList<>();
ArrayList<ArrayList<Integer>> finalStorageVol = new ArrayList<>();
writer.write("n_conflicting_op = " + conflictingPairs.size() + ";\n");
writeArray(writer, "confl_op_1", conflictingPairs, Pair::getKey);
writeArray(writer, "confl_op_2", conflictingPairs, Pair::getValue);
writer.write("\n");
}
/* Ограничения на вместимость. */
private void maxStorageVolume() throws IOException {
ArrayList<Integer> maxStorageVol = new ArrayList<>();
for (int i = 0; i < nObjWithStorage; i++) {
initialStorageVol.add(integerArray(cargoes.size(), 0));
finalStorageVol .add(integerArray(cargoes.size(), -1));
for (MovingObject obj : movingObjects) {
if (obj instanceof TransportShip) {
maxStorageVol.add((int)Math.ceil(((TransportShip) obj).getCargoMax()));
} else {
maxStorageVol.add(0);
}
for (StorageState st : task.getStorageInitialState()) {
int cargoN = cargoNById.get(st.getCargo().getId());
int val = (int)st.getCargoState();
if (st.getStorage() instanceof Storage) {
Storage storage = (Storage) st.getStorage();
int stN = storNById.get(storage.getId());
initialStorageVol.get(movingObjects.size() + stN).set(cargoN, val);
} else if (st.getStorage() instanceof TransportShip) {
TransportShip ship = (TransportShip) st.getStorage();
initialStorageVol.get(mObjToN.apply(ship)).set(cargoN, val);
}
}
for (Storage storage : storages) {
maxStorageVol.add((int)Math.ceil(storage.getVolume()));
}
writeArray(writer, "max_storage_vol", maxStorageVol);
writer.write("\n");
}
/* Граничные состояния хранилищ. */
private void boundaryStorageStates() throws IOException {
// TODO выделить отдельно общий код.
ArrayList<ArrayList<Integer>> initialStorageVol = new ArrayList<>();
ArrayList<ArrayList<Integer>> finalStorageVol = new ArrayList<>();
for (int i = 0; i < nObjWithStorage; i++) {
initialStorageVol.add(integerArray(cargoes.size(), 0));
finalStorageVol .add(integerArray(cargoes.size(), -1));
}
for (StorageState st : task.getStorageInitialState()) {
int cargoN = cargoNById.get(st.getCargo().getId());
int val = (int)st.getCargoState();
if (st.getStorage() instanceof Storage) {
Storage storage = (Storage) st.getStorage();
int stN = storNById.get(storage.getId());
initialStorageVol.get(movingObjects.size() + stN).set(cargoN, val);
} else if (st.getStorage() instanceof TransportShip) {
TransportShip ship = (TransportShip) st.getStorage();
initialStorageVol.get(mObjToN.apply(ship)).set(cargoN, val);
}
for (StorageState st : task.getStorageEndState()) {
int cargoN = cargoNById.get(st.getCargo().getId());
int val = (int)st.getCargoState();
if (st.getStorage() instanceof Storage) {
Storage storage = (Storage) st.getStorage();
int stN = storNById.get(storage.getId());
finalStorageVol.get(movingObjects.size() + stN).set(cargoN, val);
} else if (st.getStorage() instanceof TransportShip) {
TransportShip ship = (TransportShip) st.getStorage();
finalStorageVol.get(mObjToN.apply(ship)).set(cargoN, val);
}
}
for (StorageState st : task.getStorageEndState()) {
int cargoN = cargoNById.get(st.getCargo().getId());
int val = (int)st.getCargoState();
if (st.getStorage() instanceof Storage) {
Storage storage = (Storage) st.getStorage();
int stN = storNById.get(storage.getId());
finalStorageVol.get(movingObjects.size() + stN).set(cargoN, val);
} else if (st.getStorage() instanceof TransportShip) {
TransportShip ship = (TransportShip) st.getStorage();
finalStorageVol.get(mObjToN.apply(ship)).set(cargoN, val);
}
write2DArrayOfInt(writer, "initial_storage_vol", initialStorageVol);
write2DArrayOfInt(writer, "final_storage_vol", finalStorageVol);
}
{ // Потоки грузов.
ArrayList<ArrayList<ArrayList<Integer>>> cargoFlows = new ArrayList<>();
for (int i = 0; i < nObjWithStorage; i++) {
cargoFlows.add(new ArrayList<>());
for (int j = 0; j < n_intervals + 2; j++) {
cargoFlows.get(i).add(new ArrayList<>());
for (int k = 0; k < cargoes.size(); k++) {
cargoFlows.get(i).get(j).add(0);
}
}
write2DArrayOfInt(writer, "initial_storage_vol", initialStorageVol);
write2DArrayOfInt(writer, "final_storage_vol", finalStorageVol);
}
/* Потоки грузов. */
private void cargoFlows() throws IOException {
ArrayList<ArrayList<ArrayList<Integer>>> cargoFlows = new ArrayList<>();
for (int i = 0; i < nObjWithStorage; i++) {
cargoFlows.add(new ArrayList<>());
for (int j = 0; j < n_intervals + 2; j++) {
cargoFlows.get(i).add(new ArrayList<>());
for (int k = 0; k < cargoes.size(); k++) {
cargoFlows.get(i).get(j).add(0);
}
}
for (CargoFlow flow : task.getCargoFlows()) {
int storageN = storNById.get(flow.getStorage().getId());
int cargoN = cargoNById.get(flow.getCargo().getId());
for (int i = 1; i < n_intervals + 2; i++) {
cargoFlows.get(storageN + movingObjects.size()).get(i).set(cargoN, (int)flow.getCurrentValue(i - 0.1));
}
}
for (CargoFlow flow : task.getCargoFlows()) {
int storageN = storNById.get(flow.getStorage().getId());
int cargoN = cargoNById.get(flow.getCargo().getId());
for (int i = 1; i < n_intervals + 2; i++) {
cargoFlows.get(storageN + movingObjects.size()).get(i).set(cargoN, (int)flow.getCurrentValue(i - 0.1));
}
writer.write("cargo_flows = array3d(1..n_obj_with_storage, 0..(n_intervals + 1), 1..n_cargo_types, [");
boolean isFirst = true;
for (int i = 0; i < nObjWithStorage; i++) {
for (int j = 0; j < n_intervals + 2; j++) {
for (int k = 0; k < cargoes.size(); k++) {
if (isFirst) {
isFirst = false;
} else {
writer.write(", ");
}
writer.write(cargoFlows.get(i).get(j).get(k).toString());
}
writer.write("cargo_flows = array3d(1..n_obj_with_storage, 0..(n_intervals + 1), 1..n_cargo_types, [");
boolean isFirst = true;
for (int i = 0; i < nObjWithStorage; i++) {
for (int j = 0; j < n_intervals + 2; j++) {
for (int k = 0; k < cargoes.size(); k++) {
if (isFirst) {
isFirst = false;
} else {
writer.write(", ");
}
writer.write(cargoFlows.get(i).get(j).get(k).toString());
}
}
writer.write("]);\n\n");
}
{ // Грузовые операции со всеми хранилищами.
ArrayList<ArrayList<ArrayList<Integer>>> involvedOperations = new ArrayList<>();
ArrayList<Integer> loadingOpDelta = new ArrayList<>();
ArrayList<Integer> loadingOpN = new ArrayList<>();
writer.write("]);\n\n");
}
for (int i = 0; i < nObjWithStorage; i++) {
involvedOperations.add(new ArrayList<>());
for (int j = 0; j < cargoes.size(); j++) {
involvedOperations.get(i).add(new ArrayList<>());
}
/* Грузовые операции со всеми хранилищами. */
private void cargoOperations() throws IOException {
ArrayList<ArrayList<ArrayList<Integer>>> involvedOperations = new ArrayList<>();
ArrayList<Integer> loadingOpDelta = new ArrayList<>();
ArrayList<Integer> loadingOpN = new ArrayList<>();
for (int i = 0; i < nObjWithStorage; i++) {
involvedOperations.add(new ArrayList<>());
for (int j = 0; j < cargoes.size(); j++) {
involvedOperations.get(i).add(new ArrayList<>());
}
}
for (int i = 0; i < operationTemplates.size(); i++) {
if (operationTemplates.get(i) instanceof LoadingTemplate) {
LoadingTemplate op = (LoadingTemplate) operationTemplates.get(i);
int storageN = storNById.get(op.getStorage().getId());
int shipN = mObjToN.apply(op.getLoader());
int cargoN = cargoNById.get(op.getStorage().getCargo().getId());// TODO в TaskCase пока не реализовано, пересмотреть.
for (int i = 0; i < operationTemplates.size(); i++) {
if (operationTemplates.get(i) instanceof LoadingTemplate) {
LoadingTemplate op = (LoadingTemplate) operationTemplates.get(i);
int storageN = storNById.get(op.getStorage().getId());
int shipN = mObjToN.apply(op.getLoader());
int cargoN = cargoNById.get(op.getStorage().getCargo().getId());// TODO в TaskCase пока не реализовано, пересмотреть.
loadingOpDelta.add(-(int)op.getIntensity());
loadingOpN.add(i);
involvedOperations.get(storageN + movingObjects.size()).get(cargoN).add(loadingOpDelta.size());
loadingOpDelta.add(-(int)op.getIntensity());
loadingOpN.add(i);
involvedOperations.get(storageN + movingObjects.size()).get(cargoN).add(loadingOpDelta.size());
loadingOpDelta.add((int)op.getIntensity());
loadingOpN.add(i);
involvedOperations.get(shipN).get(cargoN).add(loadingOpDelta.size());
}
loadingOpDelta.add((int)op.getIntensity());
loadingOpN.add(i);
involvedOperations.get(shipN).get(cargoN).add(loadingOpDelta.size());
}
writer.write("n_loading_op = " + loadingOpDelta.size() + ";\n");
// write2DArrayOfSet(writer, "involved_operations", involvedOperations);
write2DArrayOfSetAs3DArray(writer, "involved_operations", involvedOperations);
writeArray(writer, "loading_op_delta", loadingOpDelta);
writeArray(writer, "loading_op_n", loadingOpN, (Integer i) -> i + 1);
writer.write("\n");
}
{ // Ограничение на необходимость полезной операции между движениями к одному пункту назначения.
ArrayList<Set<Integer>> objUsefulOperations = new ArrayList<>();
writer.write("n_loading_op = " + loadingOpDelta.size() + ";\n");
// write2DArrayOfSet(writer, "involved_operations", involvedOperations);
write2DArrayOfSetAs3DArray(writer, "involved_operations", involvedOperations);
writeArray(writer, "loading_op_delta", loadingOpDelta);
writeArray(writer, "loading_op_n", loadingOpN, (Integer i) -> i + 1);
writer.write("\n");
}
/* Ограничение на необходимость полезной операции между движениями к одному пункту назначения. */
private void constraintOnUsefulOperationBetweenMovements() throws IOException {
ArrayList<Set<Integer>> objUsefulOperations = new ArrayList<>();
ArrayList<Set<Integer>> movingOpOfObj = new ArrayList<>();
ArrayList<Set<Integer>> movingOpOfObj = new ArrayList<>();
BiConsumer<MovingObject, Integer> addUsOp = (MovingObject obj, Integer op) ->
BiConsumer<MovingObject, Integer> addUsOp = (MovingObject obj, Integer op) ->
objUsefulOperations.get(mObjToN.apply(obj)).add(op + 1);
for (int i = 0; i < movingObjects.size(); i++) {
movingOpOfObj.add(new TreeSet<>());
objUsefulOperations.add(new TreeSet<>());
}
for (int i = 0; i < movingObjects.size(); i++) {
movingOpOfObj.add(new TreeSet<>());
objUsefulOperations.add(new TreeSet<>());
}
for (int i = 0; i < operationTemplates.size(); i++) {
OperationTemplate t = operationTemplates.get(i);
if (t instanceof MovingTemplate) {
MovingTemplate op = (MovingTemplate)t;
for (int i = 0; i < operationTemplates.size(); i++) {
OperationTemplate t = operationTemplates.get(i);
if (t instanceof MovingTemplate) {
MovingTemplate op = (MovingTemplate)t;
int id = mObjToN.apply(op.getMover());
movingOpOfObj.get(id).add(i + 1);
int id = mObjToN.apply(op.getMover());
movingOpOfObj.get(id).add(i + 1);
for (MovingObject obj : op.getResources()) {
addUsOp.accept(obj, i);
}
} else if (t instanceof MooringTemplate) {
MooringTemplate op = (MooringTemplate)t;
for (MovingObject obj : op.getResources()) {
addUsOp.accept(obj, i);
}
} else if (t instanceof MooringTemplate) {
MooringTemplate op = (MooringTemplate)t;
int id = mObjToN.apply(op.getMoorer());
movingOpOfObj.get(id).add(i + 1);
int id = mObjToN.apply(op.getMoorer());
movingOpOfObj.get(id).add(i + 1);
for (MovingObject obj : op.getResources()) {
addUsOp.accept(obj, i);
}
for (MovingObject obj : op.getResources()) {
addUsOp.accept(obj, i);
}
if (!op.isDirect()) { // Отшвартовка.
addUsOp.accept(op.getMoorer(), i);
}
} else if (t instanceof LoadingTemplate) {
LoadingTemplate op = (LoadingTemplate)t;
addUsOp.accept(op.getLoader(), i);
if (!op.isDirect()) { // Отшвартовка.
addUsOp.accept(op.getMoorer(), i);
}
} else if (t instanceof LoadingTemplate) {
LoadingTemplate op = (LoadingTemplate)t;
addUsOp.accept(op.getLoader(), i);
}
}
writeArrayOfSetAs2DArray(writer, "obj_useful_operations", objUsefulOperations);
writeArrayOfSetAs2DArray(writer, "moving_op_of_obj", movingOpOfObj);
writeArrayOfSetAs2DArray(writer, "obj_useful_operations", objUsefulOperations);
writeArrayOfSetAs2DArray(writer, "moving_op_of_obj", movingOpOfObj);
writer.write("\n");
}
void portToMiniZinc_0() throws IOException {
try {
writer = new FileWriter(fileName, false);
writer.write("n_intervals = " + n_intervals + ";\n");
writer.write("n_operations = " + task.getTemplates().size() + ";\n");
writer.write("n_locations = " + locationNumberById.size() + ";\n");
writer.write("n_moving_obj = " + movingObjects.size() + ";\n");
writer.write("\n");
arrivalAndDepartureOperations();
initialLocations();
weatherWindows();
operationsContinuity();
finalLocations();
presenceOfResourcesInLocation();
conflictingOperations();
writer.write("n_obj_with_storage = " + nObjWithStorage + ";\n");
writer.write("n_cargo_types = " + cargoes.size() + ";\n");
maxStorageVolume();
boundaryStorageStates();
cargoFlows();
cargoOperations();
constraintOnUsefulOperationBetweenMovements();
} finally {
if (writer != null) {
writer.close();
}
}
}
}
static public void portToMiniZinc_0(TaskCase task, String fileName) throws IOException {
Task taskData = new Task(task, fileName);
taskData.portToMiniZinc_0();
}
static public void resolveMiniZincResults(TaskCase task, String fileName) throws IOException, ParserException {
List<Operation> operations = null;
Integer result = null;
......
......@@ -11,13 +11,13 @@ public class Main {
String type = args[0];
switch (type) {
case "to_MiniZinc" : {
case "to_MiniZinc_0" : {
String input = args[1];
String output = args[2];
TaskCase task = new TaskCase();
try {
task.deserialize(input);
ConversionUtil.portToMiniZinc(task, output);
ConversionUtil.portToMiniZinc_0(task, output);
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment