Commit 10add7b3 authored by Vladislav Kiselev's avatar Vladislav Kiselev

Обновлён формат тестов, исправлено пару багов.

parent 62bd0d72
......@@ -4,10 +4,7 @@
*/
package inport;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.*;
/**
*
......@@ -17,14 +14,14 @@ public class CargoFlow {
private Storage storage;
private Cargo cargo;
Map<Double, Double> flow;
SortedMap<Double, Double> flow;
public Map<Double, Double> getFlow() {
return flow;
}
public void setFlow(Map<Double, Double> flow) {
this.flow = flow;
this.flow = new TreeMap<>(flow);
}
/**
......@@ -54,7 +51,7 @@ public class CargoFlow {
}
public CargoFlow() {
this.flow = new HashMap<>();
this.flow = new TreeMap<>();
}
public CargoFlow(Storage storage, Cargo cargo) {
......@@ -71,7 +68,7 @@ public class CargoFlow {
double prevKey = -1.0;
for (Double keyTime : keyTimes)
{
if (forTime>=prevKey && forTime<keyTime)
if (forTime >= prevKey && forTime<keyTime)
{
res = flow.get(prevKey);
isFound = true;
......@@ -92,7 +89,7 @@ public class CargoFlow {
double prevKey = -1.0;
for (Double keyTime : keyTimes)
{
if (forTime>prevKey && forTime<keyTime)
if (forTime >= prevKey && forTime<keyTime)
{
res += flow.get(prevKey)*(forTime-prevKey);
isFound = true;
......@@ -103,7 +100,7 @@ public class CargoFlow {
prevKey = keyTime;
}
}
if (!isFound && forTime>prevKey)
if (!isFound && forTime >= prevKey)
res += flow.get(prevKey)*(forTime-prevKey);
return res;
}
......
......@@ -478,7 +478,7 @@ public class ConversionUtil {
// TODO ресурсы у операции погрузки.
operationsResources.set(i, s);
operationsStartLoc.set(i, getLocNById.apply(op.getStartLocation().getId(), true) + 1);
operationsStartLoc.set(i, getLocNById.apply(op.getStartLocation().getId(), op.getWithMooring()) + 1);
}
// TODO швартовка, погрузка.
}
......@@ -616,7 +616,7 @@ public class ConversionUtil {
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 пока не реализовано, пересмотреть.
int cargoN = cargoNById.get(op.getCargo().getId());
loadingOpDelta.add(-(int)op.getIntensity());
loadingOpN.add(i);
......
......@@ -17,7 +17,8 @@ public class LoadingTemplate extends OperationTemplate {
private Storage storage;
private List<LoadingEquipment> resources;
private double intensity;
private boolean withMooring;
private Cargo cargo;
/**
* Get the value of resources
......@@ -61,6 +62,22 @@ public class LoadingTemplate extends OperationTemplate {
this.storage = storage;
}
public void setWithMooring(boolean withMooring) {
this.withMooring = withMooring;
}
public boolean getWithMooring() {
return withMooring;
}
public void setCargo(Cargo cargo) {
this.cargo = cargo;
}
public Cargo getCargo() {
return cargo;
}
public LoadingTemplate(TransportShip loader, Berth berth, Storage storage, double intensity, int id) {
super(id, berth);
this.loader = loader;
......
......@@ -4,8 +4,6 @@
*/
package inport;
import javafx.util.Pair;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
......@@ -13,7 +11,11 @@ import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
......@@ -500,7 +502,13 @@ public class TaskCase {
mt.setStorage((Storage)m_storage.get(key));
direct = 1;
}
// Груз. Пока не нужен
// Груз.
key = Integer.parseInt(tokens[4].trim());;
for (Cargo cargo : cargoes) {
if (cargo.getId() == key) {
mt.setCargo(cargo);
}
}
// Приемник. Пока пара - это только хранилище-судно. С бункеровкой будем разбираться потом
key = Integer.parseInt(tokens[5].trim());
if (m_vessel.containsKey(key))
......@@ -522,9 +530,11 @@ public class TaskCase {
key = Integer.parseInt(crs.trim());
mt.getResources().add(m_equiopment.get(key));
}
mt.setIntensity(direct*Double.parseDouble(tokens[8].trim()));
templates.add(mt);
m_template.put(mt.getId(), mt);
mt.setIntensity(direct*Double.parseDouble(tokens[8].trim()));
mt.setWithMooring(tokens[9].trim().equals("M"));
templates.add(mt);
m_template.put(mt.getId(), mt);
}
break;
case 9:
......@@ -651,7 +661,7 @@ public class TaskCase {
// Это начало блока
operation = new Operation();
operation.setTemplate(template);
operation.setStart(i+1);
operation.setStart(i);
inBlock = true;
}
} else
......@@ -1484,24 +1494,18 @@ public class TaskCase {
// Состояние загрузки судов
writer.write("* Ship Loading States \n");
// Тут пок огшраничение только на местонахождение транспортных судов
// Тут пока ограничение только на местонахождение транспортных судов
for (TransportShip s : ships)
{
StorageState state1 = null;
StorageState state2 = null;
List<StorageState> state1List = new ArrayList<StorageState>();
List<StorageState> state2List = new ArrayList<StorageState>();
MovingObjectState eState = null;
for (StorageState state : storageInitialState)
if (state.getStorage().equals(s))
{
state1 = (StorageState)state;
break;
}
if (state.getStorage().equals(s))
state1List.add((StorageState)state);
for (StorageState state : storageEndState)
if (state.getStorage().equals(s))
{
state2 = (StorageState)state;
break;
}
if (state.getStorage().equals(s))
state2List.add((StorageState)state);
for (MovingObjectState state : vesselEndState)
if (state.getVessel().equals(s))
{
......@@ -1512,12 +1516,25 @@ public class TaskCase {
{
int start = 0;
int finish = 0;
if (state1!=null && state1.getCargo().equals(c))
start = (int)state1.getCargoState();
if (state2!=null && state2.getCargo().equals(c))
finish = (int)state2.getCargoState();
for (StorageState state1 : state1List)
{
if (state1!=null && state1.getCargo().equals(c))
{
start = (int)state1.getCargoState();
break;
}
}
for (StorageState state2 : state2List)
{
if (state2!=null && state2.getCargo().equals(c))
{
finish = (int)state2.getCargoState();
break;
}
}
List<Integer> vc = new ArrayList<Integer>();
List<Integer> intens = new ArrayList<Integer>();
int epsilon = 0; // Точность оценки остатка в судовом хранилище
for (OperationTemplate tp : templates)
if (tp instanceof LoadingTemplate)
{
......@@ -1526,9 +1543,15 @@ public class TaskCase {
if (ltp.getLoader().equals(s) && ltp.getStorage().getCargo().equals(c))
{
vc.add(i);
intens.add((int)ltp.getIntensity());
int itsv = (int)ltp.getIntensity();
intens.add(itsv);
// Пока забъем....
//if (Math.abs(itsv)>epsilon)
// epsilon = Math.abs(itsv);
}
}
if (epsilon>1)
epsilon--;
for (int j=0; j<nTimes; j++)
{
String clause = "";
......@@ -1555,21 +1578,25 @@ public class TaskCase {
// Положительность груза на судне в каждый момент времени
if (summinus<-start)
{
writer.write(clause + " >= -" + start + " ;\n");
writer.write(clause + " >= -" + (start + epsilon) + " ;\n");
nCons++;
}
// Ограничение на грузоподъемность судна
int maxLoad = (int)(s.getCargoMax()+1.0);
if (sumplus > (maxLoad - start))
{
writer.write(clause + " <= " + (maxLoad - start) + " ;\n");
writer.write(clause + " <= " + (maxLoad - start + epsilon) + " ;\n");
nCons++;
}
}
else
{
// Конечное состояние судна
writer.write(clause + " = " + (finish - start) + " ;\n");
// writer.write(clause + " = " + (finish - start) + " ;\n");
// nCons++;
writer.write(clause + " >= " + (finish - start - epsilon) + " ;\n");
nCons++;
writer.write(clause + " <= " + (finish - start + epsilon) + " ;\n");
nCons++;
}
}
......@@ -1600,28 +1627,31 @@ public class TaskCase {
}
// Невозможность одновременного нахождения двух пришвартованных судов у одного причала
// Невозможность одновременного нахождения двух пришвартованных судов у одного причала
writer.write("* No more than 1 vessel moored to berth \n");
if (isMooring)
if (ships.size()>1)
{
for (Berth b : berths)
if (isMooring)
{
if (b.getIsRaid())
continue;
int bdx = berths.indexOf(b);
for (int j=1; j<nTimes; j++)
for (Berth b : berths)
{
String clause = "";
for (TransportShip v : ships)
if (b.getIsRaid())
continue;
int bdx = berths.indexOf(b);
for (int j=1; j<nTimes; j++)
{
int rdx = vss.indexOf(v);
clause += " +1 " + wrbj(rdx, bdx, j, nBerths, nTimes, nVars, isMooring, true, true);
String clause = "";
for (TransportShip v : ships)
{
int rdx = vss.indexOf(v);
clause += " +1 " + wrbj(rdx, bdx, j, nBerths, nTimes, nVars, isMooring, true, true);
}
writer.write(clause + " <= 1 ;\n");
nCons++;
}
writer.write(clause + " <= 1 ;\n");
nCons++;
}
}
}
}
writer.flush();
writer.close();
......@@ -1638,183 +1668,5 @@ public class TaskCase {
writer.close();
return nOperations;
}
private static List<String> makeList(String... strings) {
return Arrays.asList(strings);
}
private static ArrayList<Set<Integer>> initArray(int size) {
ArrayList<Set<Integer>> res = new ArrayList<>(size);
for (int i = 0; i < size; i++) {
res.add(new TreeSet<>());
}
return res;
}
public void simpleMiniZincConversion(String fileName) throws IOException, ConversionException {
try(FileWriter writer = new FileWriter(fileName, false)) {
writer.write("include \"globals.mzn\";\n");
int n_intervals = (int)getPlanningInterval();
writer.write("int: n_intervals = " + n_intervals + ";\n");
ArrayList<TransportShip> ships = new ArrayList<>(getShips());
Map<Integer, Integer> shipNumberById = new TreeMap<>();
for (int i = 0; i < ships.size(); i++) {
shipNumberById.put(ships.get(i).getId(), i);
}
writer.write("int: n_transports = " + ships.size() + ";\n");
ArrayList<Berth> berths = new ArrayList<>(getBerths());
Map<Integer, Integer> berthNumberById = new TreeMap<>();
for (int i = 0; i < berths.size(); i++) {
berthNumberById.put(berths.get(i).getId(), i);
}
writer.write("int: n_berths = " + berths.size() + ";\n");
ArrayList<Tow> tows = new ArrayList<>(getTows());
Map<Integer, Integer> towNumberById = new TreeMap<>();
for (int i = 0; i < tows.size(); i++) {
towNumberById.put(tows.get(i).getId(), i);
}
writer.write("int: n_tows = " + tows.size() + ";\n");
writer.write("\n");
writer.write("set of int: Operations_identifiers = {-2, -1");
for(OperationTemplate operation : getTemplates()) {
writer.write(", " + operation.getId());
}
writer.write("};\n");
writer.write("enum Berth_status = {free, moored, berthing, de_berthing};\n");
writer.write("array [1..n_berths, 0..n_intervals] of var 0..n_transports : transport_in_berthing;\n");
writer.write("array [1..n_berths, 0..n_intervals] of var Berth_status : berths_status;\n");
// -2 - занят, -1 - свободен, i - начало i-той операции.
writer.write("array [1..n_berths, 0..n_intervals] of var Operations_identifiers : berths_operations;\n\n");
writer.write("enum Moving_obj_status = {in_the_way, in_place};\n");
writer.write("array [1..n_transports, 0..n_intervals] of var 1..n_berths : transports_destination;\n");
writer.write("array [1..n_transports, 0..n_intervals] of var Moving_obj_status : transports_status;\n");
writer.write("array [1..n_transports, 0..n_intervals] of var Operations_identifiers : transports_operations;\n\n");
writer.write("array [1..n_tows, 0..n_intervals] of var 1..n_berths : tows_destination;\n");
writer.write("array [1..n_tows, 0..n_intervals] of var Moving_obj_status : tows_status;\n");
writer.write("array [1..n_tows, 0..n_intervals] of var Operations_identifiers : tows_operations;\n\n");
{ // Пункт назначения может измениться только в начале новой реальной операции.
for (String name : makeList("transports", "tows")) {
writer.write("constraint forall (i in 1..n_" + name + ", j in 1..n_intervals)" +
"((" + name + "_operations[i, j] in {-2, -1}) -> " +
"(" + name + "_destination[i, j] == " + name + "_destination[i, j - 1]));\n");
}
// Из свободного состояния нельзя перейти в "занято".
for (String name : makeList("berths", "transports", "tows")) {
writer.write("constraint forall (i in 1..n_" + name + ", j in 1..n_intervals) " +
"((" + name + "_operations[i, j] == -2) -> (" + name + "_operations[i, j - 1] != -1));\n");
}
writer.write("\n");
}
{ // Начальные состояния.
// Все объекты на своих местах.
for (MovingObjectState state : getVesselInitialState()) {
int dest_n = berthNumberById.get(state.getLocation().getId());
int obj_id = state.getVessel().getId();
if (shipNumberById.containsKey(obj_id)) {
writer.write("constraint (transports_destination[" + (shipNumberById.get(obj_id) + 1) + ", 0] == " + (dest_n + 1) + ");\n");
continue;
}
if (towNumberById.containsKey(obj_id)) {
writer.write("constraint (tows_destination[" + (towNumberById.get(obj_id) + 1) + ", 0] == " + (dest_n + 1) + ");\n");
continue;
}
throw new ConversionException("Unknown id " + obj_id + " - not transport and not tow.");
}
writer.write("\n");
// Никто ничего не делает.
for (String name : makeList("berths", "transports", "tows")) {
writer.write("constraint forall (i in 1..n_" + name + ") (" + name + "_operations[i, 0] == -1);\n");
}
writer.write("\n");
// Все на месте.
for (String name : makeList("transports", "tows")) {
writer.write("constraint forall (i in 1..n_" + name + ") (" + name + "_status[i, 0] == in_place);\n");
}
writer.write("\n");
// Все причалы изначально пусты.
// TODO учесть операции в процессе.
writer.write("constraint forall (i in 1..n_berths) (transport_in_berthing[i, 0] == 0);\n\n");
}
{ // Конечные состояния.
// TODO
}
// Причал свободен <=> его не занимает ни один корабль (фиктивный корабль с индексом 0).
writer.write("constraint forall (i in 1..n_berths, j in 1..n_intervals)" +
"((berths_status[i, j] == free) == (transport_in_berthing[i, j] == 0));\n");
// Причал занят кораблём -> пункт назначения корабля - данный причал, и он на месте.
writer.write("constraint forall (i in 1..n_berths, j in 1..n_intervals)" +
"(transport_in_berthing[i, j] > 0 -> " +
"((transports_destination[transport_in_berthing[i, j], j] == i)) /\\ (transports_status[transport_in_berthing[i, j], j] == in_place));\n");
ArrayList<Set<Integer>> usingOperationsWithThisBerth = initArray(getBerths().size());
ArrayList<Set<Integer>> usingOperationsWithThisTransport = initArray(getShips().size());
ArrayList<Set<Integer>> usingOperationsWithThisTow = initArray(getTows().size());
{ // Операции перемещения.
for (OperationTemplate t : getTemplates()) {
if (t instanceof MovingTemplate) {
MovingTemplate operation = (MovingTemplate)t;
// TODO рассмотреть общий случай, ввести отдельный движущийся объект.
int transportNo = shipNumberById.get(operation.getMover().getId());
int destNo = berthNumberById.get(operation.getDestination().getId());
usingOperationsWithThisBerth.get(destNo).add(operation.getId());
usingOperationsWithThisTransport.get(transportNo).add(operation.getId());
{ // Если операция началась - то началась у всех.
// TODO
}
// operation.getResources();
}
}
writer.write("\n");
}
{ // Запрещаем все операции, которые не используют данный объект.
ArrayList<Pair<ArrayList<Set<Integer>>, String>> classesOfObjects = new ArrayList<>();
classesOfObjects.add(new Pair<>(usingOperationsWithThisBerth, "berths"));
classesOfObjects.add(new Pair<>(usingOperationsWithThisTransport, "transports"));
classesOfObjects.add(new Pair<>(usingOperationsWithThisTow, "tows"));
for (Pair<ArrayList<Set<Integer>>, String> p : classesOfObjects) {
for (int key = 0; key < p.getKey().size(); key++) {
writer.write("constraint forall (j in 0..n_intervals) (" + p.getValue() + "_operations[" + (key + 1) + ", j] in {-2, -1");
for (Integer usedOperation : p.getKey().get(key)) {
writer.write(", " + usedOperation);
}
writer.write("});\n");
}
}
writer.write("\n");
}
writer.write("\nsolve satisfy;\n\n");
writer.write("output [");
for (String name : makeList("transport_in_berthing", "berths_status", "berths_operations",
"transports_destination", "transports_status", "transports_operations",
"tows_destination", "tows_status", "tows_operations")) {
writer.write("\"" + name + " = \", show(" + name + "), \"\\n\",\n ");
}
writer.write("];\n");
}
}
}
......@@ -31,7 +31,7 @@ Templates
201; mrn; []; 11; 5; []; 1
202; unm; []; 11; 5; []; 1
301; loa; []; 1001; 0; 11; 5; []; 2
301; loa; []; 1001; 0; 11; 5; []; 2; M
Cargo Flows
Initial Vessel State
......
......@@ -16,7 +16,7 @@ Templates
103; mov; []; 11; 1; 2;[]; 1
201; mrn; []; 11; 2; []; 1
202; unm; []; 11; 2; []; 1
301; loa; []; 1001; 0; 11; 2; []; 1
301; loa; []; 1001; 0; 11; 2; []; 1; M
Cargo Flows
1001; 0; [0:0, 5:1, 8:0]
......
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