diff --git a/contribs/application/pom.xml b/contribs/application/pom.xml index 0ac05d56158..83422007fee 100644 --- a/contribs/application/pom.xml +++ b/contribs/application/pom.xml @@ -87,7 +87,7 @@ com.github.matsim-org gtfs2matsim - fc8b13954d + 0bd5850fd6 diff --git a/contribs/application/src/main/java/org/matsim/application/ApplicationUtils.java b/contribs/application/src/main/java/org/matsim/application/ApplicationUtils.java index 083a315ecb5..0a13fbe9311 100644 --- a/contribs/application/src/main/java/org/matsim/application/ApplicationUtils.java +++ b/contribs/application/src/main/java/org/matsim/application/ApplicationUtils.java @@ -440,12 +440,17 @@ public static Path matchInput(String name, Path dir) { if (path.isPresent()) return path.get(); - // Match more general pattern at last - path = matchPattern(".+\\.[a-zA-Z0-9]*_" + name + "\\..+", dir); + // Match more general pattern + path = matchPattern(".+\\.[a-zA-Z0-9\\-]*_" + name + "\\..+", dir); if (path.isPresent()) return path.get(); - throw new IllegalArgumentException("Could not match input file: " + name); + // Even more permissive pattern + path = matchPattern(".+[a-zA-Z0-9_.\\-]*(_|\\.)" + name + ".+", dir); + if (path.isPresent()) + return path.get(); + + throw new IllegalArgumentException("Could not match input file: %s (in %s)".formatted(name, dir)); } private static Optional matchSuffix(String suffix, Path dir) { diff --git a/contribs/application/src/main/java/org/matsim/application/analysis/noise/NoiseAnalysis.java b/contribs/application/src/main/java/org/matsim/application/analysis/noise/NoiseAnalysis.java index 1892de7fb74..a3f321c7f38 100644 --- a/contribs/application/src/main/java/org/matsim/application/analysis/noise/NoiseAnalysis.java +++ b/contribs/application/src/main/java/org/matsim/application/analysis/noise/NoiseAnalysis.java @@ -7,6 +7,7 @@ import org.locationtech.jts.geom.Envelope; import org.matsim.api.core.v01.Coord; import org.matsim.api.core.v01.Scenario; +import org.matsim.api.core.v01.TransportMode; import org.matsim.application.ApplicationUtils; import org.matsim.application.CommandSpec; import org.matsim.application.MATSimAppCommand; @@ -20,6 +21,7 @@ import org.matsim.core.config.Config; import org.matsim.core.config.ConfigUtils; import org.matsim.core.scenario.ScenarioUtils; +import org.matsim.core.utils.collections.CollectionUtils; import org.matsim.core.utils.geometry.CoordinateTransformation; import org.matsim.core.utils.io.IOUtils; import picocli.CommandLine; @@ -28,10 +30,7 @@ import java.nio.file.Path; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; -import java.util.Locale; -import java.util.Map; -import java.util.Objects; -import java.util.Set; +import java.util.*; @CommandLine.Command( name = "noise-analysis", @@ -88,10 +87,18 @@ public Integer call() throws Exception { NoiseConfigGroup noiseParameters = ConfigUtils.addOrGetModule(config, NoiseConfigGroup.class); if(overrideParameters){ - log.warn("no NoiseConfigGroup was configured before. Will set some standards. You should check the next lines in the log file!"); + log.warn("no NoiseConfigGroup was configured before. Will set some standards. You should check the next lines in the log file and the output_config.xml!"); noiseParameters.setConsideredActivitiesForReceiverPointGridArray(considerActivities.toArray(String[]::new)); noiseParameters.setConsideredActivitiesForDamageCalculationArray(considerActivities.toArray(String[]::new)); + { + Set set = CollectionUtils.stringArrayToSet( new String[]{TransportMode.bike, TransportMode.walk, TransportMode.transit_walk, TransportMode.non_network_walk} ); + noiseParameters.setNetworkModesToIgnoreSet( set ); + } + { + String[] set = new String[]{"freight"}; + noiseParameters.setHgvIdPrefixesArray( set ); + } //use actual speed and not freespeed noiseParameters.setUseActualSpeedLevel(true); //use the valid speed range (recommended by IK) @@ -181,7 +188,7 @@ private Config prepareConfig() { config.transit().setTransitScheduleFile(null); config.transit().setVehiclesFile(null); config.plans().setInputFile(ApplicationUtils.matchInput("plans", input.getRunDirectory()).toAbsolutePath().toString()); - config.facilities().setInputFile(null); + config.facilities().setInputFile(ApplicationUtils.matchInput("facilities", input.getRunDirectory()).toAbsolutePath().toString()); config.eventsManager().setNumberOfThreads(null); config.eventsManager().setEstimatedNumberOfEvents(null); //ts, aug '24: not sure if and why we need to set 1 thread diff --git a/contribs/application/src/main/java/org/matsim/application/analysis/population/TripAnalysis.java b/contribs/application/src/main/java/org/matsim/application/analysis/population/TripAnalysis.java index 6d6ee80f8c1..893c05cf9fd 100644 --- a/contribs/application/src/main/java/org/matsim/application/analysis/population/TripAnalysis.java +++ b/contribs/application/src/main/java/org/matsim/application/analysis/population/TripAnalysis.java @@ -2,6 +2,8 @@ import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntList; +import it.unimi.dsi.fastutil.ints.IntOpenHashSet; +import it.unimi.dsi.fastutil.ints.IntSet; import it.unimi.dsi.fastutil.objects.Object2IntLinkedOpenHashMap; import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2LongMap; @@ -15,6 +17,7 @@ import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.GeometryFactory; import org.locationtech.jts.geom.Point; +import org.matsim.application.ApplicationUtils; import org.matsim.application.CommandSpec; import org.matsim.application.MATSimAppCommand; import org.matsim.application.options.CsvOptions; @@ -32,6 +35,7 @@ import java.math.BigDecimal; import java.math.RoundingMode; import java.nio.file.Files; +import java.nio.file.Path; import java.util.*; import java.util.stream.IntStream; @@ -43,48 +47,43 @@ produces = { "mode_share.csv", "mode_share_per_dist.csv", "mode_users.csv", "trip_stats.csv", "mode_share_per_%s.csv", "population_trip_stats.csv", "trip_purposes_by_hour.csv", - "mode_share_distance_distribution.csv", + "mode_share_distance_distribution.csv", "mode_shift.csv", "mode_choices.csv", "mode_choice_evaluation.csv", "mode_choice_evaluation_per_mode.csv", "mode_confusion_matrix.csv", "mode_prediction_error.csv" } ) public class TripAnalysis implements MATSimAppCommand { - private static final Logger log = LogManager.getLogger(TripAnalysis.class); - /** * Attributes which relates this person to a reference person. */ - public static String ATTR_REF_ID = "ref_id"; + public static final String ATTR_REF_ID = "ref_id"; /** * Person attribute that contains the reference modes of a person. Multiple modes are delimited by "-". */ - public static String ATTR_REF_MODES = "ref_modes"; + public static final String ATTR_REF_MODES = "ref_modes"; /** * Person attribute containing its weight for analysis purposes. */ - public static String ATTR_REF_WEIGHT = "ref_weight"; - + public static final String ATTR_REF_WEIGHT = "ref_weight"; + private static final Logger log = LogManager.getLogger(TripAnalysis.class); + @CommandLine.Option(names = "--person-filter", description = "Define which persons should be included into trip analysis. Map like: Attribute name (key), attribute value (value). " + + "The attribute needs to be contained by output_persons.csv. Persons who do not match all filters are filtered out.", split = ",") + private final Map personFilters = new HashMap<>(); @CommandLine.Mixin private InputOptions input = InputOptions.ofCommand(TripAnalysis.class); @CommandLine.Mixin private OutputOptions output = OutputOptions.ofCommand(TripAnalysis.class); - @CommandLine.Option(names = "--input-ref-data", description = "Optional path to reference data", required = false) private String refData; - @CommandLine.Option(names = "--match-id", description = "Pattern to filter agents by id") private String matchId; - @CommandLine.Option(names = "--dist-groups", split = ",", description = "List of distances for binning", defaultValue = "0,1000,2000,5000,10000,20000") private List distGroups; - @CommandLine.Option(names = "--modes", split = ",", description = "List of considered modes, if not set all will be used") private List modeOrder; - @CommandLine.Option(names = "--shp-filter", description = "Define how the shp file filtering should work", defaultValue = "home") private LocationFilter filter; - @CommandLine.Mixin private ShpOptions shp; @@ -131,6 +130,20 @@ private static double[] calcHistogram(double[] data, double[] bins) { return hist; } + private static Map getColumnTypes() { + Map columnTypes = new HashMap<>(Map.of("person", ColumnType.TEXT, + "trav_time", ColumnType.STRING, "wait_time", ColumnType.STRING, "dep_time", ColumnType.STRING, + "longest_distance_mode", ColumnType.STRING, "main_mode", ColumnType.STRING, + "start_activity_type", ColumnType.TEXT, "end_activity_type", ColumnType.TEXT, + "first_pt_boarding_stop", ColumnType.TEXT, "last_pt_egress_stop", ColumnType.TEXT)); + + // Map.of only has 10 argument max + columnTypes.put("traveled_distance", ColumnType.LONG); + columnTypes.put("euclidean_distance", ColumnType.LONG); + + return columnTypes; + } + @Override public Integer call() throws Exception { @@ -146,6 +159,43 @@ public Integer call() throws Exception { persons = persons.where(persons.textColumn("person").matchesRegex(matchId)); } +// filter persons according to person (attribute) filter + if (!personFilters.isEmpty()) { + IntSet generalFilteredRowIds = null; + for (Map.Entry entry : personFilters.entrySet()) { + if (!persons.containsColumn(entry.getKey())) { + log.warn("Persons table does not contain column for filter attribute {}. Filter on {} will not be applied.", entry.getKey(), entry.getValue()); + continue; + } + log.info("Using person filter for attribute {} and value {}", entry.getKey(), entry.getValue()); + + IntSet filteredRowIds = new IntOpenHashSet(); + + for (int i = 0; i < persons.rowCount(); i++) { + Row row = persons.row(i); + String value = row.getString(entry.getKey()); +// only add value once + if (value.equals(entry.getValue())) { + filteredRowIds.add(i); + } + } + + if (generalFilteredRowIds == null) { + // If generalFilteredRowIds is empty, add all elements from filteredRowIds to generalFilteredRowIds + generalFilteredRowIds = filteredRowIds; + } else { + // If generalFilteredRowIds is not empty, retain only the elements that are also in filteredRowIds + generalFilteredRowIds.retainAll(filteredRowIds); + } + } + + if (generalFilteredRowIds != null) { + persons = persons.where(Selection.with(generalFilteredRowIds.intStream().toArray())); + } + } + + log.info("Filtered {} out of {} persons", persons.rowCount(), total); + // Home filter by standard attribute if (shp.isDefined() && filter == LocationFilter.home) { Geometry geometry = shp.getGeometry(); @@ -166,18 +216,8 @@ public Integer call() throws Exception { log.info("Filtered {} out of {} persons", persons.rowCount(), total); - Map columnTypes = new HashMap<>(Map.of("person", ColumnType.TEXT, - "trav_time", ColumnType.STRING, "wait_time", ColumnType.STRING, "dep_time", ColumnType.STRING, - "longest_distance_mode", ColumnType.STRING, "main_mode", ColumnType.STRING, - "start_activity_type", ColumnType.TEXT, "end_activity_type", ColumnType.TEXT, - "first_pt_boarding_stop", ColumnType.TEXT, "last_pt_egress_stop", ColumnType.TEXT)); - - // Map.of only has 10 argument max - columnTypes.put("traveled_distance", ColumnType.LONG); - columnTypes.put("euclidean_distance", ColumnType.LONG); - Table trips = Table.read().csv(CsvReadOptions.builder(IOUtils.getBufferedReader(input.getPath("trips.csv"))) - .columnTypesPartial(columnTypes) + .columnTypesPartial(getColumnTypes()) .sample(false) .separator(CsvOptions.detectDelimiter(input.getPath("trips.csv"))).build()); @@ -271,6 +311,8 @@ public Integer call() throws Exception { writeTripDistribution(joined); + writeModeShift(joined); + return 0; } @@ -540,6 +582,34 @@ private void writeTripDistribution(Table trips) throws IOException { } } + private void writeModeShift(Table trips) throws IOException { + Path path; + try { + Path dir = Path.of(input.getPath("trips.csv")).getParent().resolve("ITERS").resolve("it.0"); + path = ApplicationUtils.matchInput("trips.csv", dir); + } catch (Exception e) { + log.error("Could not find trips from 0th iteration.", e); + return; + } + + Table originalTrips = Table.read().csv(CsvReadOptions.builder(IOUtils.getBufferedReader(path.toString())) + .columnTypesPartial(getColumnTypes()) + .sample(false) + .separator(CsvOptions.detectDelimiter(path.toString())).build()); + + // Use longest_distance_mode where main_mode is not present + originalTrips.stringColumn("main_mode") + .set(originalTrips.stringColumn("main_mode").isMissing(), + originalTrips.stringColumn("longest_distance_mode")); + + originalTrips.column("main_mode").setName("original_mode"); + + Table joined = new DataFrameJoiner(trips, "trip_id").inner(true, originalTrips); + Table aggr = joined.summarize("trip_id", count).by("original_mode", "main_mode"); + + aggr.write().csv(output.getPath("mode_shift.csv").toFile()); + } + /** * How shape file filtering should be applied. */ diff --git a/contribs/application/src/main/java/org/matsim/application/avro/CSVToAvroConverter.java b/contribs/application/src/main/java/org/matsim/application/avro/CSVToAvroConverter.java new file mode 100644 index 00000000000..7fc715f5d93 --- /dev/null +++ b/contribs/application/src/main/java/org/matsim/application/avro/CSVToAvroConverter.java @@ -0,0 +1,139 @@ +package org.matsim.application.avro; + +import it.unimi.dsi.fastutil.objects.Object2FloatAVLTreeMap; +import it.unimi.dsi.fastutil.objects.Object2FloatSortedMap; +import org.apache.avro.file.CodecFactory; +import org.apache.avro.file.DataFileWriter; +import org.apache.avro.io.DatumWriter; +import org.apache.avro.specific.SpecificDatumWriter; +import org.apache.commons.csv.CSVFormat; +import org.apache.commons.csv.CSVParser; +import org.apache.commons.csv.CSVRecord; +import org.matsim.core.utils.io.IOUtils; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.*; + +public class CSVToAvroConverter { + + public static void main(String[] args) throws IOException { + String projection = args.length > 2 ? args[2] : null; + String name = args.length > 3 ? args[3] : "Emissions"; + + XYTData avroData = readCSV(args[0], projection, name); + writeAvroFile(avroData, Path.of(args[1])); + } + + /** + * Reads a CSV file, processes its data, and returns the corresponding Avro object. + * + * @param csvFilePath the path to the CSV file + * @param projection the projection (CRS) + * @param name the name for the data series (defaults is "Emissions") + * @throws IOException if an error occurs during reading the file + */ + public static XYTData readCSV(String csvFilePath, String projection, String name) throws IOException { + List entries = new ArrayList<>(); + List xCoords = new ArrayList<>(); + List yCoords = new ArrayList<>(); + List timestamps = new ArrayList<>(); + Object2FloatSortedMap valuesMap = new Object2FloatAVLTreeMap<>(Comparator.comparing((XYT e) -> e.t) + .thenComparing(e -> e.x) + .thenComparing(e -> e.y)); + + try (CSVParser csvReader = new CSVParser(IOUtils.getBufferedReader(csvFilePath), CSVFormat.DEFAULT.builder() + .setCommentMarker('#').setSkipHeaderRecord(true).setHeader().build())) { + + String comment = csvReader.getHeaderComment(); + + if (comment != null && (projection == null || projection.isEmpty())) { + projection = comment; + } else if (projection == null) { + projection = ""; + } + + for (CSVRecord record : csvReader) { + try { + int time = (int) Double.parseDouble(record.get(0)); + float x = Float.parseFloat(record.get(1)); + float y = Float.parseFloat(record.get(2)); + float value = Float.parseFloat(record.get(3)); + + entries.add(new CSVEntries(time, x, y, value)); + + } catch (NumberFormatException e) { + System.out.println("Skipping invalid line: " + String.join(",", record)); + } + } + } + + // Sort entries by time -> x -> y + entries.sort(Comparator.comparing((CSVEntries e) -> e.time) + .thenComparing(e -> e.x) + .thenComparing(e -> e.y)); + + for (CSVEntries entry : entries) { + if (!xCoords.contains(entry.x)) { + xCoords.add(entry.x); + } + if (!yCoords.contains(entry.y)) { + yCoords.add(entry.y); + } + if (!timestamps.contains(entry.time)) { + timestamps.add(entry.time); + } + + valuesMap.put(new XYT(entry.x, entry.y, entry.time), entry.value); + } + + // Check if all combinations of x, y, and time exist + for (int time : timestamps) { + for (float x : xCoords) { + for (float y : yCoords) { + XYT key = new XYT(x, y, time); + if (!valuesMap.containsKey(key)) { + valuesMap.put(key, 0f); + } + } + } + } + + // Create Avro data object + XYTData avroData = new XYTData(); + avroData.setCrs(projection); + avroData.setXCoords(xCoords); + avroData.setYCoords(yCoords); + avroData.setTimestamps(timestamps); + + List valuesList = new ArrayList<>(valuesMap.values()); + Map> result = new HashMap<>(); + result.put(name != null && !name.isEmpty() ? name : "Emissions", valuesList); + + avroData.setData(result); + + return avroData; + } + + /** + * Writes the Avro data + * + * @param avroData the Avro data + * @param avroFile the path to the output Avro file + * @throws IOException if an error occurs during writing the file + */ + public static void writeAvroFile(XYTData avroData, Path avroFile) throws IOException { + DatumWriter datumWriter = new SpecificDatumWriter<>(XYTData.class); + try (DataFileWriter dataFileWriter = new DataFileWriter<>(datumWriter)) { + dataFileWriter.setCodec(CodecFactory.deflateCodec(9)); + dataFileWriter.create(XYTData.getClassSchema(), avroFile.toFile()); + dataFileWriter.append(avroData); + } + } + + private record CSVEntries(int time, float x, float y, float value) { + } + + private record XYT(float x, float y, float t) { + } +} diff --git a/contribs/application/src/main/java/org/matsim/application/options/ShpOptions.java b/contribs/application/src/main/java/org/matsim/application/options/ShpOptions.java index 985db84bba7..5d9f8ccec99 100644 --- a/contribs/application/src/main/java/org/matsim/application/options/ShpOptions.java +++ b/contribs/application/src/main/java/org/matsim/application/options/ShpOptions.java @@ -8,9 +8,12 @@ import org.geotools.api.feature.simple.SimpleFeatureType; import org.geotools.api.referencing.FactoryException; import org.geotools.api.referencing.crs.CoordinateReferenceSystem; -import org.geotools.data.*; +import org.geotools.api.referencing.operation.MathTransform; +import org.geotools.api.referencing.operation.TransformException; +import org.geotools.data.DefaultTransaction; import org.geotools.data.shapefile.ShapefileDataStore; import org.geotools.data.shapefile.ShapefileDataStoreFactory; +import org.geotools.geometry.jts.JTS; import org.geotools.geopkg.GeoPkgDataStoreFactory; import org.geotools.referencing.CRS; import org.locationtech.jts.geom.*; @@ -219,12 +222,30 @@ public Geometry getGeometry() { ); if (geometryCollection.isEmpty()) { - throw new IllegalStateException("There are noe geometries in the shape file."); + throw new IllegalStateException("There are no geometries in the shape file."); } return geometryCollection.union(); } + /** + * Return the union of all geometries in the shape file and project it to the target crs. + * @param toCRS target coordinate system + */ + public Geometry getGeometry(String toCRS) { + try { + CoordinateReferenceSystem sourceCRS = CRS.decode(detectCRS()); + CoordinateReferenceSystem targetCRS = CRS.decode(toCRS); + + MathTransform ct = CRS.findMathTransform(sourceCRS, targetCRS); + + return JTS.transform(getGeometry(), ct); + + } catch (TransformException | FactoryException e) { + throw new IllegalStateException("Could not transform coordinates of the provided shape", e); + } + } + /** * Creates an index to query features from this shape file. * diff --git a/contribs/application/src/main/java/org/matsim/application/prepare/population/CleanPopulation.java b/contribs/application/src/main/java/org/matsim/application/prepare/population/CleanPopulation.java index a729f5063d8..c9f46f11f64 100644 --- a/contribs/application/src/main/java/org/matsim/application/prepare/population/CleanPopulation.java +++ b/contribs/application/src/main/java/org/matsim/application/prepare/population/CleanPopulation.java @@ -6,6 +6,7 @@ import org.matsim.api.core.v01.population.*; import org.matsim.application.MATSimAppCommand; import org.matsim.core.population.PopulationUtils; +import org.matsim.core.population.algorithms.PersonAlgorithm; import org.matsim.core.population.algorithms.TripsToLegsAlgorithm; import org.matsim.core.router.RoutingModeMainModeIdentifier; import picocli.CommandLine; @@ -24,7 +25,7 @@ mixinStandardHelpOptions = true, showDefaultValues = true ) -public class CleanPopulation implements MATSimAppCommand { +public class CleanPopulation implements MATSimAppCommand, PersonAlgorithm { private static final Logger log = LogManager.getLogger(CleanPopulation.class); @@ -46,6 +47,10 @@ public class CleanPopulation implements MATSimAppCommand { @CommandLine.Option(names = "--output", description = "Output file name", required = true) private Path output; + // Using the analysis main mode identifier instead of the routing mode based one on purpose + // to be able to process older population files without any routing modes! + private final TripsToLegsAlgorithm trips2Legs = new TripsToLegsAlgorithm(new RoutingModeMainModeIdentifier()); + public static void main(String[] args) { System.exit(new CommandLine(new CleanPopulation()).execute(args)); } @@ -63,43 +68,64 @@ public Integer call() throws Exception { if (output.getParent() != null) Files.createDirectories(output.getParent()); - // Using the analysis main mode identifier instead of the routing mode based one on purpose - // to be able to process older population files without any routing modes! - TripsToLegsAlgorithm trips2Legs = new TripsToLegsAlgorithm(new RoutingModeMainModeIdentifier()); - for (Person person : population.getPersons().values()) { + run(person); + } + + PopulationUtils.writePopulation(population, output.toString()); + + return 0; + } + + @Override + public void run(Person person) { + if (rmUnselected) { + removeUnselectedPlans(person); + } - if (rmUnselected) { - Plan selected = person.getSelectedPlan(); - for (Plan plan : Lists.newArrayList(person.getPlans())) { - if (plan != selected) - person.removePlan(plan); + for (Plan plan : person.getPlans()) { + if (tripsToLegs) + trips2Legs.run(plan); + + for (PlanElement el : plan.getPlanElements()) { + if (rmRoutes) { + removeRouteFromLeg(el); } - } - for (Plan plan : person.getPlans()) { - if (tripsToLegs) - trips2Legs.run(plan); - - for (PlanElement el : plan.getPlanElements()) { - if (rmRoutes) { - if (el instanceof Leg) { - ((Leg) el).setRoute(null); - } - } - - if (rmActivityLocations) { - if (el instanceof Activity) { - ((Activity) el).setLinkId(null); - ((Activity) el).setFacilityId(null); - } - } + if (rmActivityLocations) { + removeActivityLocation(el); } } } + } - PopulationUtils.writePopulation(population, output.toString()); + /** + * Remove link and facility information from activity. + */ + public static void removeActivityLocation(PlanElement el) { + if (el instanceof Activity act) { + act.setLinkId(null); + act.setFacilityId(null); + } + } - return 0; + /** + * Remove route information from leg. + */ + public static void removeRouteFromLeg(PlanElement el) { + if (el instanceof Leg leg) { + leg.setRoute(null); + } + } + + /** + * Remove all unselected plans for given person. + */ + public static void removeUnselectedPlans(Person person) { + Plan selected = person.getSelectedPlan(); + for (Plan plan : Lists.newArrayList(person.getPlans())) { + if (plan != selected) + person.removePlan(plan); + } } -} \ No newline at end of file +} diff --git a/contribs/application/src/main/java/org/matsim/application/prepare/pt/AdjustSameDepartureTimes.java b/contribs/application/src/main/java/org/matsim/application/prepare/pt/AdjustSameDepartureTimes.java new file mode 100644 index 00000000000..4d8b9378815 --- /dev/null +++ b/contribs/application/src/main/java/org/matsim/application/prepare/pt/AdjustSameDepartureTimes.java @@ -0,0 +1,154 @@ +package org.matsim.application.prepare.pt; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.matsim.core.utils.geometry.CoordUtils; +import org.matsim.core.utils.misc.OptionalTime; +import org.matsim.pt.transitSchedule.api.*; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.function.Consumer; + +/** + * Some providers set the same departure and arrival times for multiple stops. + * This usually happens with on-demand buses, but can also happen on night buses where multiple stops can have a departure at the same minute. + * These departure times will lead to artifacts when using a pseudo network. + * The purpose of this class is to spread these departures more evently. + * However, in the case of on demand buses, the travel times will likely still be too optimistic. + */ +public class AdjustSameDepartureTimes implements Consumer { + + private static Logger log = LogManager.getLogger(AdjustSameDepartureTimes.class); + + private static OptionalTime add(OptionalTime x, double t) { + if (!x.isDefined()) { + return x; + } + return OptionalTime.defined(x.seconds() + t); + } + + @Override + public void accept(TransitSchedule schedule) { + for (TransitLine line : schedule.getTransitLines().values()) { + + List routes = new ArrayList<>(line.getRoutes().values()); + for (TransitRoute route : routes) { + List newStops = adjustDepartures(schedule.getFactory(), route); + + if (newStops == null) { + continue; + } + + log.info("Adjusted departures for route {} in line {}", route.getId(), line.getId()); + + line.removeRoute(route); + + TransitRoute newRoute = schedule.getFactory().createTransitRoute(route.getId(), route.getRoute(), newStops, route.getTransportMode()); + newRoute.setDescription(route.getDescription()); + for (Map.Entry e : route.getAttributes().getAsMap().entrySet()) { + newRoute.getAttributes().putAttribute(e.getKey(), e.getValue()); + } + route.getDepartures().values().forEach(newRoute::addDeparture); + + line.addRoute(newRoute); + } + } + + } + + private List adjustDepartures(TransitScheduleFactory f, TransitRoute route) { + + List stops = new ArrayList<>(route.getStops()); + + boolean adjusted = false; + + // Check if the times at the end of the schedule are the same + // These need to be calculated and can not be interpolated + // The arrival at the last stop is shifted by small travel time + if (stops.size() > 1) { + TransitRouteStop last = stops.getLast(); + TransitRouteStop secondLast = stops.get(stops.size() - 2); + + OptionalTime lastDep = last.getDepartureOffset().or(last.getArrivalOffset()); + OptionalTime secondLastDep = secondLast.getDepartureOffset().or(secondLast.getArrivalOffset()); + + if (lastDep.isDefined() && secondLastDep.isDefined() && lastDep.equals(secondLastDep)) { + // Calculate the time between the last two stops + double dist = Math.max(20, CoordUtils.calcEuclideanDistance(last.getStopFacility().getCoord(), secondLast.getStopFacility().getCoord())); + double time = dist / 10; // 10 m/s + + // Calculate the time for the last stop + TransitRouteStop newStop = f.createTransitRouteStop( + last.getStopFacility(), + add(last.getArrivalOffset(), time), + add(last.getDepartureOffset(), time) + ); + + newStop.setAwaitDepartureTime(last.isAwaitDepartureTime()); + newStop.setAllowAlighting(last.isAllowAlighting()); + newStop.setAllowBoarding(last.isAllowBoarding()); + + stops.set(stops.size() - 1, newStop); + adjusted = true; + } + } + + for (int i = 0; i < stops.size() - 1; ) { + + TransitRouteStop stop = stops.get(i); + OptionalTime dep = stop.getDepartureOffset().or(stop.getArrivalOffset()); + + if (!dep.isDefined()) { + i++; + continue; + } + + OptionalTime arr = null; + int j = i + 1; + for (; j < stops.size(); j++) { + TransitRouteStop nextStop = stops.get(j); + arr = nextStop.getArrivalOffset().or(nextStop.getDepartureOffset()); + if (!dep.equals(arr)) { + break; + } + } + + if (arr == null) { + i++; + continue; + } + + if (j > i + 1) { + double time = dep.seconds(); + double diff = (arr.seconds() - time) / (j - i); + + for (int k = i + 1; k < j; k++) { + TransitRouteStop stopToAdjust = stops.get(k); + int add = (int) (diff * (k - i)); + + TransitRouteStop newStop = f.createTransitRouteStop( + stopToAdjust.getStopFacility(), + add(stopToAdjust.getArrivalOffset(), add), + add(stopToAdjust.getDepartureOffset(), add) + ); + + newStop.setAwaitDepartureTime(stopToAdjust.isAwaitDepartureTime()); + newStop.setAllowAlighting(stopToAdjust.isAllowAlighting()); + newStop.setAllowBoarding(stopToAdjust.isAllowBoarding()); + + stops.set(k, newStop); + adjusted = true; + } + } + + i = j; + } + + if (adjusted) + return stops; + + return null; + } +} diff --git a/contribs/application/src/main/java/org/matsim/application/prepare/pt/CreateTransitScheduleFromGtfs.java b/contribs/application/src/main/java/org/matsim/application/prepare/pt/CreateTransitScheduleFromGtfs.java index 5038d1f046c..ddbe0e7868a 100644 --- a/contribs/application/src/main/java/org/matsim/application/prepare/pt/CreateTransitScheduleFromGtfs.java +++ b/contribs/application/src/main/java/org/matsim/application/prepare/pt/CreateTransitScheduleFromGtfs.java @@ -1,5 +1,6 @@ package org.matsim.application.prepare.pt; +import com.conveyal.gtfs.model.Route; import com.conveyal.gtfs.model.Stop; import org.apache.commons.io.FilenameUtils; import org.apache.logging.log4j.LogManager; @@ -31,10 +32,8 @@ import java.io.File; import java.nio.file.Path; import java.time.LocalDate; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +import java.util.*; +import java.util.function.Consumer; import java.util.function.Predicate; @@ -77,6 +76,15 @@ public class CreateTransitScheduleFromGtfs implements MATSimAppCommand { @CommandLine.Option(names = "--include-stops", description = "Fully qualified class name to a Predicate for filtering certain stops") private Class includeStops; + @CommandLine.Option(names = "--transform-stops", description = "Fully qualified class name to a Consumer for transforming stops before usage") + private Class transformStops; + + @CommandLine.Option(names = "--transform-routes", description = "Fully qualified class name to a Consumer for transforming routes before usage") + private Class transformRoutes; + + @CommandLine.Option(names = "--transform-schedule", description = "Fully qualified class name to a Consumer to be executed after the schedule was created", arity = "0..*", split = ",") + private List> transformSchedule; + @CommandLine.Option(names = "--merge-stops", description = "Whether stops should be merged by coordinate") private boolean mergeStops; @@ -134,6 +142,15 @@ public Integer call() throws Exception { log.info("Using prefix: {}", prefix); } + if (transformStops != null) { + converter.setTransformStop(createConsumer(transformStops, Stop.class)); + } + + if (transformRoutes != null) { + converter.setTransformRoute(createConsumer(transformRoutes, Route.class)); + } + + converter.build().convert(); i++; } @@ -144,6 +161,24 @@ public Integer call() throws Exception { TransitSchedulePostProcessTools.copyEarlyDeparturesToFollowingNight(scenario.getTransitSchedule(), 6 * 3600, "copied"); } + if (transformSchedule != null && !transformSchedule.isEmpty()) { + for (Class c : transformSchedule) { + Consumer f = createConsumer(c, TransitSchedule.class); + log.info("Applying {} to created schedule", c.getName()); + f.accept(scenario.getTransitSchedule()); + } + } + + for (TransitLine line : scenario.getTransitSchedule().getTransitLines().values()) { + List routes = new ArrayList<>(line.getRoutes().values()); + for (TransitRoute route : routes) { + if (route.getDepartures().isEmpty()) { + log.warn("Route {} in line {} with no departures removed.", route.getId(), line.getId()); + line.removeRoute(route); + } + } + } + Network network = NetworkUtils.readNetwork(networkFile); Scenario ptScenario = getScenarioWithPseudoPtNetworkAndTransitVehicles(network, scenario.getTransitSchedule(), "pt_"); @@ -151,11 +186,14 @@ public Integer call() throws Exception { if (validate) { //Check schedule and network TransitScheduleValidator.ValidationResult checkResult = TransitScheduleValidator.validateAll(ptScenario.getTransitSchedule(), ptScenario.getNetwork()); + List warnings = checkResult.getWarnings(); + if (!warnings.isEmpty()) + log.warn("TransitScheduleValidator warnings: {}", String.join("\n", warnings)); + if (checkResult.isValid()) { log.info("TransitSchedule and Network valid according to TransitScheduleValidator"); - log.warn("TransitScheduleValidator warnings: {}", checkResult.getWarnings()); } else { - log.error(checkResult.getErrors()); + log.error("TransitScheduleValidator errors: {}", String.join("\n", checkResult.getErrors())); throw new RuntimeException("TransitSchedule and/or Network invalid"); } } @@ -170,6 +208,12 @@ public Integer call() throws Exception { return 0; } + @SuppressWarnings({"unchecked", "unused"}) + private Consumer createConsumer(Class consumer, Class type) throws ReflectiveOperationException { + return (Consumer) consumer.getDeclaredConstructor().newInstance(); + } + + @SuppressWarnings("unchecked") private Predicate createFilter(int i) throws Exception { Predicate filter = (stop) -> true; diff --git a/contribs/application/src/main/java/org/matsim/application/prepare/scenario/CreateScenarioCutOut.java b/contribs/application/src/main/java/org/matsim/application/prepare/scenario/CreateScenarioCutOut.java new file mode 100644 index 00000000000..6559a9c5c97 --- /dev/null +++ b/contribs/application/src/main/java/org/matsim/application/prepare/scenario/CreateScenarioCutOut.java @@ -0,0 +1,634 @@ +package org.matsim.application.prepare.scenario; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.locationtech.jts.geom.Coordinate; +import org.locationtech.jts.geom.Geometry; +import org.locationtech.jts.geom.GeometryFactory; +import org.locationtech.jts.geom.LineString; +import org.matsim.api.core.v01.Coord; +import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.Scenario; +import org.matsim.api.core.v01.TransportMode; +import org.matsim.api.core.v01.network.Link; +import org.matsim.api.core.v01.network.Network; +import org.matsim.api.core.v01.network.Node; +import org.matsim.api.core.v01.population.*; +import org.matsim.application.MATSimAppCommand; +import org.matsim.application.options.CrsOptions; +import org.matsim.application.options.ShpOptions; +import org.matsim.core.api.experimental.events.EventsManager; +import org.matsim.core.config.Config; +import org.matsim.core.config.ConfigUtils; +import org.matsim.core.events.EventsUtils; +import org.matsim.core.network.NetworkChangeEvent; +import org.matsim.core.network.NetworkUtils; +import org.matsim.core.network.algorithms.MultimodalNetworkCleaner; +import org.matsim.core.network.algorithms.TransportModeNetworkFilter; +import org.matsim.core.network.io.NetworkChangeEventsWriter; +import org.matsim.core.population.PopulationUtils; +import org.matsim.core.population.algorithms.ParallelPersonAlgorithmUtils; +import org.matsim.core.population.algorithms.PersonAlgorithm; +import org.matsim.core.population.routes.NetworkRoute; +import org.matsim.core.router.TripStructureUtils; +import org.matsim.core.router.TripStructureUtils.Trip; +import org.matsim.core.router.costcalculators.OnlyTimeDependentTravelDisutility; +import org.matsim.core.router.speedy.SpeedyALTFactory; +import org.matsim.core.router.util.LeastCostPathCalculator; +import org.matsim.core.router.util.LeastCostPathCalculatorFactory; +import org.matsim.core.scenario.ScenarioUtils; +import org.matsim.core.trafficmonitoring.FreeSpeedTravelTime; +import org.matsim.core.trafficmonitoring.TravelTimeCalculator; +import org.matsim.core.utils.geometry.geotools.MGC; +import org.matsim.facilities.ActivityFacility; +import org.matsim.facilities.FacilitiesWriter; +import picocli.CommandLine; + +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Predicate; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * Cuts out a part of the Population and Network which is relevant inside the specified shape of the shapefile.

+ * How the network is cut out: + *
    + *
  • Keep all links in shape file
  • + *
  • Keep all links that are used by any agent in its route
  • + *
  • if an agent has not route, a shortest-path route is calculated and used instead
  • + *
  • This is done for all network modes
  • + *
+ *

+ * How the population is cut out: + *

    + *
  • All agents having any activity in the shape file are kept
  • + *
  • Agents traveling through the shape file are kept, this is determined by the route
  • + *
  • The buffer is not considered for the population cut out
  • + *
+ *

+ * How the network change events are generated: + *

    + *
  • Travel time is computed using the given events
  • + *
  • Travel times for all links outside the shape file + buffer will be fixed
  • + *
  • The capacity of these links will be set to infinity
  • + *
+ * + * Limitations:
+ * Cutting out agents and fixing the speed is a challenging problem, because we lose sensitivity to policy cases + * We can not use the speed limit and use the original capacity because this underestimates speed (because congestion can only decrease the speed) + * Therefore the capacity is set to infinity, but these road don't react to changes
+ *

+ * The cut-out will create a buffer area around the shape in which the speed is simulated with the original network, so that it is sensitive to changes + * Therefore, the buffer should not be too small + * One should be careful creating too small cut-outs because of the mentioned limitations. + * + * @return 0 if successful, 2 if CRS is null + */ +@CommandLine.Command(name = "scenario-cutout", description = "Cut out a scenario based on a shape file. Reduce population and network to the relevant area.") +public class CreateScenarioCutOut implements MATSimAppCommand, PersonAlgorithm { + + private static final Logger log = LogManager.getLogger(CreateScenarioCutOut.class); + + /** + * Maps mode to the {@link ThreadLocal} containing the router for the mode. This is a thread-local cache, so that we can use the same router for every thread. + */ + private final Map> mode2routerCache = new ConcurrentHashMap<>(); + + @CommandLine.Option(names = "--population", description = "Path to input population", required = true) + private String populationPath; + + @CommandLine.Option(names = "--network", description = "Path to network", required = true) + private String networkPath; + + @CommandLine.Option(names = "--facilities", description = "Path to facilities file. Only needed if there are agents with no coordinates or links", required = false) + private String facilityPath; + + @CommandLine.Option(names = "--events", description = "Input events used for travel time calculation. NOTE: Making a cutout without the events file will make the scenario inaccurate!", required = false) + private String eventPath; + + @CommandLine.Option(names = "--buffer", description = "Buffer around zones in meter", defaultValue = "5000") + private double buffer; + + @CommandLine.Option(names = "--output-network", description = "Path to output network", required = true) + private String outputNetwork; + + @CommandLine.Option(names = "--output-population", description = "Path to output population", required = true) + private String outputPopulation; + + @CommandLine.Option(names = "--output-facilities", description = "Path to output facilities (required if facilities were given).", required = false) + private String outputFacilities; + + @CommandLine.Option(names = "--output-network-change-events", description = "Path to network change event output", required = false) + private String outputEvents; + + @CommandLine.Option(names = "--network-change-events-interval", description = "Interval of NetworkChangesToBeApplied. Unit is seconds. Will be ignored if --output-network-change-events is undefined", defaultValue = "900", required = false) + private double changeEventsInterval; + + @CommandLine.Option(names = "--network-change-events-maxTime", description = "Interval of NetworkChangesToBeApplied. Unit is seconds. Will be ignored if --output-network-change-events is undefined", defaultValue = "86400", required = false) + private int changeEventsMaxTime; + + @CommandLine.Option(names = "--network-modes", description = "Modes to consider when cutting network", defaultValue = "car,bike", split = ",") + private Set modes; + + @CommandLine.Option(names = "--keep-modes", description = "Network modes of links that are always kept", defaultValue = TransportMode.pt, split = ",") + private Set keepModes; + + @CommandLine.Mixin + private CrsOptions crs; + + @CommandLine.Mixin + private ShpOptions shp; + + // External classes + private final GeometryFactory geoFactory = new GeometryFactory(); + private TravelTimeCalculator tt; + + // Variables used for processing + /** + * Map with mode-string as key and the mode-filtered Network as value. + */ + private final Map mode2modeOnlyNetwork = new HashMap<>(); + + /** + * Links that are inside the shapefile. + */ + private final Set> linksToKeep = ConcurrentHashMap.newKeySet(); + + /** + * Links that are outside the shapefile. + */ + private final Set> linksToDelete = ConcurrentHashMap.newKeySet(); + + /** + * Additional links to include (may be outside the shapefile). Links are marked like this, if they are used in a plan of an agent, that + * is relevant. + */ + private final Set> linksToInclude = ConcurrentHashMap.newKeySet(); + + /** + * Agents, that are not relevant: Not in the shapefile or buffer, no route through the shapefile or buffer. + */ + private final Set> personsToDelete = ConcurrentHashMap.newKeySet(); + + /** + * Save which facilities are within the shapefile, or belong to a link in the network, or are used by a person after filtering. + */ + private final Set> facilitiesToInclude = ConcurrentHashMap.newKeySet(); + + // Data inputs + /** + * Scenario with network, population and facilities. + */ + private Scenario scenario; + + /** + * Shapefile as a {@link Geometry}. + */ + private Geometry geom; + + /** + * Shapefile+buffer as a {@link Geometry}. + */ + private Geometry geomBuffer; + + private int emptyNetworkWarnings = 0; + private int noActCoordsWarnings = 0; + + public static void main(String[] args) { + new CreateScenarioCutOut().execute(args); + } + + @Override + public Integer call() throws Exception { + //Check CRS + if (crs.getInputCRS() == null) { + log.error("Input CRS must be specified"); + return 2; + } + + if (facilityPath != null && outputFacilities == null) { + log.error("Facilities were given as input, that means --output-facilities must be set."); + return 2; + } + + if (eventPath != null && outputEvents == null) { + log.error("Events were given as input, that means --output-network-change-events must be set."); + return 2; + } + + // Prepare required input-data + Config config = ConfigUtils.createConfig(); + config.global().setCoordinateSystem(crs.getInputCRS()); + config.plans().setInputFile(populationPath); + config.network().setInputFile(networkPath); + config.network().setTimeVariantNetwork(true); + if (facilityPath != null) { + config.facilities().setInputFile(facilityPath); + } + scenario = ScenarioUtils.loadScenario(config); + + geom = shp.getGeometry(crs.getInputCRS()); + geomBuffer = geom.buffer(buffer); + + for (String mode : modes) + mode2modeOnlyNetwork.putIfAbsent(mode, filterNetwork(scenario.getNetwork(), mode)); + + if (eventPath != null) { + TravelTimeCalculator.Builder builder = new TravelTimeCalculator.Builder(scenario.getNetwork()); + builder.setTimeslice(changeEventsInterval); + builder.setMaxTime(changeEventsMaxTime); + + EventsManager manager = EventsUtils.createEventsManager(); + + tt = builder.build(); + manager.addHandler(tt); + + manager.initProcessing(); + EventsUtils.readEvents(manager, eventPath); + manager.finishProcessing(); + } + + // Cut out the network: Filter for links inside the shapefile + for (Link link : scenario.getNetwork().getLinks().values()) { + if (geom.contains(MGC.coord2Point(link.getCoord())) + || geom.contains(MGC.coord2Point(link.getFromNode().getCoord())) + || geom.contains(MGC.coord2Point(link.getToNode().getCoord())) + || link.getAllowedModes().stream().anyMatch(keepModes::contains)) { + // keep the link + linksToKeep.add(link.getId()); + } else { + linksToDelete.add(link.getId()); + } + } + + log.info("Links in shape: {} out of {}", linksToKeep.size(), scenario.getNetwork().getLinks().size()); + + if (linksToKeep.isEmpty()) { + log.error("No links are in the resulting network. Check your input shape file and coordinate system"); + log.error("If using EPSG:4326 (WGS84), -Dorg.geotools.referencing.forceXY=true might help"); + return 1; + } + + // Cut out the population and mark needed network parts + ParallelPersonAlgorithmUtils.run(scenario.getPopulation(), Runtime.getRuntime().availableProcessors(), this); + + //Population + log.info("Persons in the original population: {}", scenario.getPopulation().getPersons().size()); + log.info("Persons to delete: {}", personsToDelete.size()); + for (Id personId : personsToDelete) { + scenario.getPopulation().removePerson(personId); + } + + log.info("Persons in the resulting scenario: {}", scenario.getPopulation().getPersons().size()); + + if (scenario.getPopulation().getPersons().isEmpty()) { + log.error("No persons are in the resulting population. Check if your input shape file and coordinate system is correct. Exiting ..."); + return 1; + } + + // Network + log.info("Additional links from routes to include: {}", linksToInclude.size()); + + log.info("number of links in original network: {}", scenario.getNetwork().getLinks().size()); + + for (Id linkId : linksToDelete) { + if (!linksToInclude.contains(linkId)) + scenario.getNetwork().removeLink(linkId); + } + + // clean the network + log.info("number of links before cleaning: {}", scenario.getNetwork().getLinks().size()); + log.info("number of nodes before cleaning: {}", scenario.getNetwork().getNodes().size()); + + MultimodalNetworkCleaner cleaner = new MultimodalNetworkCleaner(scenario.getNetwork()); + cleaner.removeNodesWithoutLinks(); + + for (String mode : modes) { + log.info("Cleaning mode {}", mode); + cleaner.run(Set.of(mode)); + } + + log.info("number of links after cleaning: {}", scenario.getNetwork().getLinks().size()); + log.info("number of nodes after cleaning: {}", scenario.getNetwork().getNodes().size()); + + ParallelPersonAlgorithmUtils.run(scenario.getPopulation(), Runtime.getRuntime().availableProcessors(), new CleanPersonLinkIds()); + + PopulationUtils.writePopulation(scenario.getPopulation(), outputPopulation); + + if (facilityPath != null) { + + log.info("number of facilities before filtering: {}", scenario.getActivityFacilities().getFacilities().size()); + + filterFacilities(); + + new FacilitiesWriter(scenario.getActivityFacilities()).write(outputFacilities); + log.info("number of facilities after filtering: {}", scenario.getActivityFacilities().getFacilities().size()); + } + + if (eventPath != null) { + List events = generateNetworkChangeEvents(changeEventsInterval); + new NetworkChangeEventsWriter().write(outputEvents, events); + } + + NetworkUtils.writeNetwork(scenario.getNetwork(), outputNetwork); + + return 0; + } + + // Helper-Functions + + /** + * Filters the network to the given mode. + */ + private Network filterNetwork(Network network, String mode) { + TransportModeNetworkFilter filter = new TransportModeNetworkFilter(network); + + Network carOnlyNetwork = NetworkUtils.createNetwork(); + filter.filter(carOnlyNetwork, Set.of(mode)); + return carOnlyNetwork; + } + + /** + * Filter facilities. + */ + private void filterFacilities() { + + for (ActivityFacility f : scenario.getActivityFacilities().getFacilities().values()) { + if (facilitiesToInclude.contains(f.getId())) + continue; + + if (f.getLinkId() != null && scenario.getNetwork().getLinks().containsKey(f.getLinkId())) { + facilitiesToInclude.add(f.getId()); + continue; + } + + // Expensive check last + if (f.getCoord() != null && geom.contains(MGC.coord2Point(f.getCoord()))) + facilitiesToInclude.add(f.getId()); + } + + Set> facilityIds = new HashSet<>(scenario.getActivityFacilities().getFacilities().keySet()); + for (Id id : facilityIds) { + if (!facilitiesToInclude.contains(id)) + scenario.getActivityFacilities().getFacilities().remove(id); + } +/* + scenario.getActivityFacilities().getFacilities().keySet() + .removeIf(Predicate.not(facilitiesToInclude::contains)); +*/ + } + + /** + * Creates a {@link LeastCostPathCalculator} for the given network and saves it in {@code mode2routerCache}. + * The network should be filtered to the expected mode using {@link CreateScenarioCutOut#filterNetwork}. + */ + private LeastCostPathCalculator createRouter(Network network, String mode) { + mode2routerCache.putIfAbsent(mode, new ThreadLocal<>()); + LeastCostPathCalculator c = mode2routerCache.get(mode).get(); + if (c == null) { + FreeSpeedTravelTime travelTime = new FreeSpeedTravelTime(); + LeastCostPathCalculatorFactory fastAStarLandmarksFactory = new SpeedyALTFactory(); + + OnlyTimeDependentTravelDisutility travelDisutility = new OnlyTimeDependentTravelDisutility(travelTime); + + c = fastAStarLandmarksFactory.createPathCalculator(network, travelDisutility, travelTime); + mode2routerCache.putIfAbsent(mode, new ThreadLocal<>()); + mode2routerCache.get(mode).set(c); + } + + return c; + } + + private Node getFromNode(Network network, Trip trip) { + if (network.getLinks().isEmpty()) { + if (emptyNetworkWarnings++ < 10) + log.warn("Tried to get a from-node on an empty network. Maybe you defined a wrong mode? Skipping ..."); + + return null; + } + + Map, ? extends Link> modeLinks = network.getLinks(); + if (trip.getOriginActivity().getLinkId() != null && modeLinks.get(trip.getOriginActivity().getLinkId()) != null) { + return modeLinks.get(trip.getOriginActivity().getLinkId()).getFromNode(); + } else { + return NetworkUtils.getNearestLink(network, getActivityCoord(trip.getOriginActivity())).getFromNode(); + } + } + + private Node getToNode(Network network, Trip trip) { + if (network.getLinks().isEmpty()) { + if (emptyNetworkWarnings++ < 10) + log.warn("Tried to get a to-node on an empty network. Maybe you defined a wrong mode? Skipping ..."); + + return null; + } + Map, ? extends Link> modeLinks = network.getLinks(); + if (trip.getDestinationActivity().getLinkId() != null && modeLinks.get(trip.getDestinationActivity().getLinkId()) != null) { + return modeLinks.get(trip.getDestinationActivity().getLinkId()).getToNode(); + } else { + return NetworkUtils.getNearestLink(network, getActivityCoord(trip.getDestinationActivity())).getToNode(); + } + } + + /** + * Routes a Path in the given network and mode. + */ + private LeastCostPathCalculator.Path getModeNetworkPath(Network network, String mode, Trip trip) { + LeastCostPathCalculator router = createRouter(network, mode); + + Node fromNode = getFromNode(network, trip); + Node toNode = getToNode(network, trip); + + if (fromNode == null || toNode == null) + return null; + + return router.calcLeastCostPath(fromNode, toNode, 0, null, null); + } + + /** + * Returns {@link Coord} of an activity, either from the activity itself or from the facility. + */ + private Coord getActivityCoord(Activity activity) { + if (scenario.getActivityFacilities() != null && activity.getFacilityId() != null && scenario.getActivityFacilities().getFacilities().containsKey(activity.getFacilityId())) + return scenario.getActivityFacilities().getFacilities().get(activity.getFacilityId()).getCoord(); + + return activity.getCoord(); + } + + /** + * Creates and applies the {@link NetworkChangeEvent}s to the network. It sets the capacity for all links outside the shapefile and bufferzone + * to infinite and reduces the freespeed of the links so that the agents behave somehow realistically outside the cutout-area. + * + * @param timeFrameLength interval length of time frames in seconds + * @return a list of the generated NetworkChangeEvents. Use is optional. + */ + private List generateNetworkChangeEvents(double timeFrameLength) { + List events = new LinkedList<>(); + + for (Link link : scenario.getNetwork().getLinks().values()) { + + // Don't generate events for links thar are in the shapefile + buffer + if (geomBuffer.contains(MGC.coord2Point(link.getCoord()))) + continue; + + // Setting capacity outside shapefile (and buffer) to infinite + link.setCapacity(Double.MAX_VALUE); + + // Do this for the whole simulation run + for (double time = 0; time < changeEventsMaxTime; time += timeFrameLength) { + + // Setting freespeed to the link average + double freespeed = link.getLength() / tt.getLinkTravelTimes().getLinkTravelTime(link, time, null, null); + NetworkChangeEvent event = new NetworkChangeEvent(time); + event.setFreespeedChange(new NetworkChangeEvent.ChangeValue(NetworkChangeEvent.ChangeType.ABSOLUTE_IN_SI_UNITS, freespeed)); + NetworkUtils.addNetworkChangeEvent(scenario.getNetwork(), event); + event.addLink(link); + events.add(event); + } + } + + return events; + } + + /** + * Parallelized Implementation of PersonAlgorithm for cutout. It checks whether this {@link Person} is relevant and if it is, it adds the + * {@link Link}s of the persons-route into {@code linksToInclude}. + * If this {@link Person} is not relevant, it is added into {@code personsToDelete}. + */ + @Override + public void run(Person person) { + boolean keepPerson = false; + + List trips = TripStructureUtils.getTrips(person.getSelectedPlan()); + + Set> linkIds = new HashSet<>(); + Set> facilityIds = new HashSet<>(); + + for (Trip trip : trips) { + Coord originCoord = getActivityCoord(trip.getOriginActivity()); + Coord destinationCoord = getActivityCoord(trip.getDestinationActivity()); + + if (originCoord == null || destinationCoord == null) { + if (noActCoordsWarnings++ < 10) + log.info("Activity coords of trip is null. Skipping Trip..."); + + continue; + } + + // keep all agents starting or ending in area + if (geom.contains(MGC.coord2Point(originCoord)) || geom.contains(MGC.coord2Point(destinationCoord))) { + keepPerson = true; + } + + LineString line = geoFactory.createLineString(new Coordinate[]{ + MGC.coord2Coordinate(originCoord), + MGC.coord2Coordinate(destinationCoord) + }); + + // also keep persons traveling through or close to area (beeline) + if (line.intersects(geom)) { + keepPerson = true; + } + + //Save route links + for (Leg leg : trip.getLegsOnly()) { + Route route = leg.getRoute(); + + // Need to search for routes in all plans, but probably these plans are not really different + // Need to route modes that are not present, e.g if there is a car plan, route bike as well + + // Store which modes needs to be routed + Set routingModes = new HashSet<>(modes); + + if (route instanceof NetworkRoute && !((NetworkRoute) route).getLinkIds().isEmpty()) { + // We have a NetworkRoute, thus we can just use it + linkIds.addAll(((NetworkRoute) route).getLinkIds()); + if (((NetworkRoute) route).getLinkIds().stream().anyMatch(linksToKeep::contains)) { + keepPerson = true; + } + + routingModes.remove(leg.getRoutingMode()); + } + + // Now compute routes for all other modes (all modes if no NetworkRoute is given) using shortest-path. + // Search/Generate the route for every mode + for (String mode : routingModes) { + LeastCostPathCalculator.Path path = getModeNetworkPath(mode2modeOnlyNetwork.get(mode), mode, trip); + if (path != null) { + // add all these links directly + path.links.stream().map(Link::getId).forEach(linkIds::add); + if (path.links.stream().map(Link::getId).anyMatch(linksToKeep::contains)) { + keepPerson = true; + } + } + // There is no additional link freespeed information, that we could save. So we are finished here + } + + if (trip.getOriginActivity().getFacilityId() != null) + facilityIds.add(trip.getOriginActivity().getFacilityId()); + + if (trip.getDestinationActivity().getFacilityId() != null) + facilityIds.add(trip.getDestinationActivity().getFacilityId()); + + if (trip.getOriginActivity().getLinkId() != null) { + linkIds.add(trip.getOriginActivity().getLinkId()); + } + + if (trip.getDestinationActivity().getLinkId() != null) { + linkIds.add(trip.getDestinationActivity().getLinkId()); + } + } + } + + //Check whether this person is relevant or not + if (keepPerson) { + linksToInclude.addAll(linkIds); + facilitiesToInclude.addAll(facilityIds); + } else { + personsToDelete.add(person.getId()); + } + + // Remove all unselected plans because these are not handled + person.getPlans().stream() + .filter(p -> p != person.getSelectedPlan()) + .forEach(person::removePlan); + } + + + private final class CleanPersonLinkIds implements PersonAlgorithm { + + + @Override + public void run(Person person) { + + Plan plan = person.getSelectedPlan(); + Network network = scenario.getNetwork(); + + for (Trip trip : TripStructureUtils.getTrips(plan)) { + // activity link ids are reset, if they are not retained in the cleaned network + if (trip.getOriginActivity().getLinkId() != null) { + if (!network.getLinks().containsKey(trip.getOriginActivity().getLinkId())) + trip.getOriginActivity().setLinkId(null); + } + + if (trip.getDestinationActivity().getLinkId() != null) { + if (!network.getLinks().containsKey(trip.getDestinationActivity().getLinkId())) + trip.getDestinationActivity().setLinkId(null); + } + } + + // Remove routes that contain now non-existing links + Set> linkIds = TripStructureUtils.getLegs(plan).stream() + .map(Leg::getRoute) + .filter(r -> r instanceof NetworkRoute) + .map(r -> (NetworkRoute) r) + .flatMap(r -> Stream.concat(Stream.of(r.getStartLinkId(), r.getEndLinkId()), r.getLinkIds().stream())) + .collect(Collectors.toSet()); + + if (!linkIds.stream().allMatch(l -> network.getLinks().containsKey(l))) + PopulationUtils.resetRoutes(person.getSelectedPlan()); + } + } + +} diff --git a/contribs/application/src/main/java/org/matsim/freightDemandGeneration/DemandReaderFromCSV.java b/contribs/application/src/main/java/org/matsim/freightDemandGeneration/DemandReaderFromCSV.java index 02ae5072583..e39eedd9ad4 100644 --- a/contribs/application/src/main/java/org/matsim/freightDemandGeneration/DemandReaderFromCSV.java +++ b/contribs/application/src/main/java/org/matsim/freightDemandGeneration/DemandReaderFromCSV.java @@ -550,6 +550,7 @@ static void createDemandForCarriers(Scenario scenario, ShpOptions.Index indexSha CoordinateTransformation crsTransformationNetworkAndShape) { for (DemandInformationElement newDemandInformationElement : demandInformation) { + log.info("Create demand for carrier {}", newDemandInformationElement.getCarrierName()); if (newDemandInformationElement.getTypeOfDemand().equals("service")) createServices(scenario, newDemandInformationElement, indexShape, population, combineSimilarJobs, crsTransformationNetworkAndShape); @@ -585,12 +586,16 @@ private static void createServices(Scenario scenario, DemandInformationElement n Integer numberOfServiceLocations = newDemandInformationElement.getNumberOfFirstJobElementLocations(); ArrayList usedServiceLocations = new ArrayList(); int numberOfLinksInNetwork = scenario.getNetwork().getLinks().size(); - HashMap, Person> possiblePersonsForService = new HashMap, Person>(); + HashMap, Person> possiblePersonsForService = new HashMap<>(); HashMap, HashMap> nearestLinkPerPerson = new HashMap<>(); // set number of jobs - if (shareOfPopulationWithThisService == null) + if (shareOfPopulationWithThisService == null) { numberOfJobs = newDemandInformationElement.getNumberOfJobs(); + if (population != null) + log.warn( + "You have a population but no share of the population for the demand. The number of jobs will be set to the number of jobs you set in the csv file. The population will not be used for the demand generation."); + } else if (population == null) throw new RuntimeException( "No population found although input parameter is set"); @@ -606,15 +611,14 @@ else if (population == null) possiblePersonsForService.putAll(population.getPersons()); int numberPossibleServices = (int) Math .round(shareOfPopulationWithThisService * possiblePersonsForService.size()); - if (sampleSizeInputPopulation == sampleTo) - numberOfJobs = (int) Math.round(shareOfPopulationWithThisService * possiblePersonsForService.size()); - else if (samplingOption.equals("changeNumberOfLocationsWithDemand")) - numberOfJobs = (int) Math.round((sampleTo / sampleSizeInputPopulation) - * (shareOfPopulationWithThisService * possiblePersonsForService.size())); - else if (samplingOption.equals("changeDemandOnLocation")) { - demandToDistribute = (int) Math.round((sampleTo / sampleSizeInputPopulation) * demandToDistribute); - numberOfJobs = (int) Math.round(shareOfPopulationWithThisService * possiblePersonsForService.size()); - } else + int sampledNumberPossibleServices = (int) Math.round((sampleTo / sampleSizeInputPopulation) * numberPossibleServices); + if (sampleSizeInputPopulation == sampleTo || samplingOption.equals("changeDemandOnLocation")) + numberOfJobs = numberPossibleServices; + else if (samplingOption.equals("changeNumberOfLocationsWithDemand")) { + numberOfJobs = sampledNumberPossibleServices; + numberPossibleServices = numberOfJobs; + } + else throw new RuntimeException( "Error with the sampling of the demand based on the population. Please check sampling sizes and sampling options!!"); if (numberPossibleServices != 0) @@ -773,16 +777,20 @@ private static void createShipments(Scenario scenario, DemandInformationElement String[] areasForDeliveryLocations = newDemandInformationElement.getAreasSecondJobElement(); String[] setLocationsOfPickup = newDemandInformationElement.getLocationsOfFirstJobElement(); String[] setLocationsOfDelivery = newDemandInformationElement.getLocationsOfSecondJobElement(); - ArrayList usedPickupLocations = new ArrayList(); - ArrayList usedDeliveryLocations = new ArrayList(); - HashMap, Person> possiblePersonsPickup = new HashMap, Person>(); - HashMap, Person> possiblePersonsDelivery = new HashMap, Person>(); + ArrayList usedPickupLocations = new ArrayList<>(); + ArrayList usedDeliveryLocations = new ArrayList<>(); + HashMap, Person> possiblePersonsPickup = new HashMap<>(); + HashMap, Person> possiblePersonsDelivery = new HashMap<>(); HashMap, HashMap> nearestLinkPerPersonPickup = new HashMap<>(); HashMap, HashMap> nearestLinkPerPersonDelivery = new HashMap<>(); // set number of jobs - if (shareOfPopulationWithThisPickup == null && shareOfPopulationWithThisDelivery == null) + if (shareOfPopulationWithThisPickup == null && shareOfPopulationWithThisDelivery == null){ + if (population != null) + log.warn( + "You have a population but no share of the population for the demand. The number of jobs will be set to the number of jobs you set in the csv file. The population will not be used for the demand generation."); numberOfJobs = newDemandInformationElement.getNumberOfJobs(); + } else if (population == null) throw new RuntimeException( "No population found although input parameter is set"); @@ -814,37 +822,24 @@ else if (population == null) int sampledNumberPossibleJobsPickup = (int)Math.round((sampleTo / sampleSizeInputPopulation) * numberPossibleJobsPickup); int sampledNumberPossibleJobsDelivery = (int) Math.round((sampleTo / sampleSizeInputPopulation) * numberPossibleJobsDelivery); if (numberPossibleJobsPickup > numberPossibleJobsDelivery) { - if (sampleSizeInputPopulation == sampleTo) { - numberOfJobs = (int) Math.round(shareOfPopulationWithThisPickup * numberPossibleJobsPickup); - numberPossibleJobsPickup = numberOfJobs; - if (shareOfPopulationWithThisDelivery != null) - numberPossibleJobsDelivery = (int) Math - .round(shareOfPopulationWithThisDelivery * numberPossibleJobsDelivery); + if (sampleSizeInputPopulation == sampleTo ||samplingOption.equals("changeDemandOnLocation")) { + numberOfJobs = numberPossibleJobsPickup; } else if (samplingOption.equals("changeNumberOfLocationsWithDemand")) { numberOfJobs = sampledNumberPossibleJobsPickup; numberPossibleJobsPickup = numberOfJobs; if (shareOfPopulationWithThisDelivery != null) numberPossibleJobsDelivery = sampledNumberPossibleJobsDelivery; - } else if (samplingOption.equals("changeDemandOnLocation")) { - demandToDistribute = (int) Math.round((sampleTo / sampleSizeInputPopulation) * demandToDistribute); - numberOfJobs = numberPossibleJobsPickup; } else throw new RuntimeException( "Error with the sampling of the demand based on the population. Please check sampling sizes and sampling options!!"); } else { - if (sampleSizeInputPopulation == sampleTo) { - numberOfJobs = (int) Math.round(shareOfPopulationWithThisDelivery * numberPossibleJobsDelivery); - numberPossibleJobsDelivery = numberOfJobs; - numberPossibleJobsPickup = (int) Math - .round(shareOfPopulationWithThisPickup * numberPossibleJobsPickup); + if (sampleSizeInputPopulation == sampleTo ||samplingOption.equals("changeDemandOnLocation")) { + numberOfJobs = numberPossibleJobsDelivery; } else if (samplingOption.equals("changeNumberOfLocationsWithDemand")) { numberOfJobs = sampledNumberPossibleJobsDelivery; numberPossibleJobsDelivery = numberOfJobs; if (shareOfPopulationWithThisDelivery != null) numberPossibleJobsPickup = sampledNumberPossibleJobsPickup; - } else if (samplingOption.equals("changeDemandOnLocation")) { - demandToDistribute = (int) Math.round((sampleTo / sampleSizeInputPopulation) * demandToDistribute); - numberOfJobs = numberPossibleJobsDelivery; } else throw new RuntimeException( "Error with the sampling of the demand based on the population. Please check sampling sizes and sampling options!!"); @@ -1289,6 +1284,7 @@ private static HashMap, Link> findAllPossibleLinks(Scenario scenario, Integer numberOfLocations, String[] areasForLocations, String[] setLocations, HashMap, Person> possiblePersons, HashMap, HashMap> nearestLinkPerPerson) { + log.info("Finding possible links for the demand in the selected areas {}", Arrays.toString(areasForLocations)); HashMap, Link> possibleLinks = new HashMap<>(); if (numberOfLocations == null) { for (Link link : scenario.getNetwork().getLinks().values()) @@ -1364,7 +1360,7 @@ private static Link findNextUsedLink(Scenario scenario, ShpOptions.Index indexSh private static HashMap, Person> findPossiblePersons(Population population, String[] areasForJobElementLocations, ShpOptions.Index indexShape, CoordinateTransformation crsTransformationNetworkAndShape) { - + log.info("Finding possible persons for the demand in the selected areas {}", Arrays.toString(areasForJobElementLocations)); HashMap, Person> possiblePersons = new HashMap<>(); for (Person person : population.getPersons().values()) { diff --git a/contribs/application/src/main/java/org/matsim/freightDemandGeneration/FreightDemandGeneration.java b/contribs/application/src/main/java/org/matsim/freightDemandGeneration/FreightDemandGeneration.java index 09ba9e75623..368dddaad69 100644 --- a/contribs/application/src/main/java/org/matsim/freightDemandGeneration/FreightDemandGeneration.java +++ b/contribs/application/src/main/java/org/matsim/freightDemandGeneration/FreightDemandGeneration.java @@ -374,13 +374,16 @@ private void createDemand(DemandGenerationOptions selectedDemandGenerationOption */ FreightDemandGenerationUtils.preparePopulation(population, sampleSizeInputPopulation, upSamplePopulationTo, "changeNumberOfLocationsWithDemand"); - case increaseDemandOnLocation -> + case increaseDemandOnLocation -> { /* * If the demand sample is higher than the population sample, the demand per * person will be increased. */ - FreightDemandGenerationUtils.preparePopulation(population, sampleSizeInputPopulation, - upSamplePopulationTo, "changeDemandOnLocation"); + log.warn("You have selected the option to increase the demand on the location. " + + "Because the simulation always uses the given demand the results are similar to the option with the same sample size."); + FreightDemandGenerationUtils.preparePopulation(population, sampleSizeInputPopulation, + upSamplePopulationTo, "changeDemandOnLocation"); + } case noPopulationSampling -> /* * If the demand sample is equal to the population sample, the demand is created diff --git a/contribs/application/src/test/java/org/matsim/application/analysis/population/TripAnalysisTest.java b/contribs/application/src/test/java/org/matsim/application/analysis/population/TripAnalysisTest.java new file mode 100644 index 00000000000..fac088ae04f --- /dev/null +++ b/contribs/application/src/test/java/org/matsim/application/analysis/population/TripAnalysisTest.java @@ -0,0 +1,131 @@ +package org.matsim.application.analysis.population; + +import org.apache.commons.csv.CSVFormat; +import org.apache.commons.csv.CSVPrinter; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.matsim.application.options.CsvOptions; +import org.matsim.core.utils.io.IOUtils; +import org.matsim.testcases.MatsimTestUtils; +import tech.tablesaw.api.ColumnType; +import tech.tablesaw.api.StringColumn; +import tech.tablesaw.api.Table; +import tech.tablesaw.io.csv.CsvReadOptions; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Map; + +class TripAnalysisTest { + @RegisterExtension + private final MatsimTestUtils utils = new MatsimTestUtils(); + private final CsvOptions csv = new CsvOptions(CSVFormat.Predefined.Default); + + @Test + void defaultParametersTest() throws IOException { + + writeInputCsvFiles(); + + new TripAnalysis().execute("--input-trips", Path.of(utils.getInputDirectory(), "trips.csv").toString(), + "--input-persons", Path.of(utils.getInputDirectory(), "persons.csv").toString(), + "--output-mode-share", Path.of(utils.getOutputDirectory(), "analysis", "population", "mode_share.csv").toString(), + "--output-mode-share-per-dist", Path.of(utils.getOutputDirectory(), "analysis", "population", "mode_share_per_dist.csv").toString(), + "--output-mode-users", Path.of(utils.getOutputDirectory(), "analysis", "population", "mode_users.csv").toString(), + "--output-trip-stats", Path.of(utils.getOutputDirectory(), "analysis", "population", "trip_stats.csv").toString(), + "--output-population-trip-stats", Path.of(utils.getOutputDirectory(), "analysis", "population", "population_trip_stats.csv").toString(), + "--output-trip-purposes-by-hour", Path.of(utils.getOutputDirectory(), "analysis", "population", "trip_purposes_by_hour.csv").toString(), + "--output-mode-share-distance-distribution", Path.of(utils.getOutputDirectory(), "analysis", "population", "mode_share_distance_distribution.csv").toString(), + "--output-mode-choices", Path.of(utils.getOutputDirectory(), "analysis", "population", "mode_choices.csv").toString(), + "--output-mode-choice-evaluation", Path.of(utils.getOutputDirectory(), "analysis", "population", "mode_choice_evaluation.csv").toString(), + "--output-mode-choice-evaluation-per-mode", Path.of(utils.getOutputDirectory(), "analysis", "population", "mode_choice_evaluation_per_mode.csv").toString(), + "--output-mode-confusion-matrix", Path.of(utils.getOutputDirectory(), "analysis", "population", "mode_confusion_matrix.csv").toString(), + "--output-mode-prediction-error", Path.of(utils.getOutputDirectory(), "analysis", "population", "mode_prediction_error.csv").toString()); + + Path out = Path.of(utils.getOutputDirectory(), "analysis", "population"); + + Assertions.assertThat(out) + .isDirectoryContaining("glob:**trip_stats.csv") + .isDirectoryContaining("glob:**mode_share.csv") + .isDirectoryContaining("glob:**mode_share_per_dist.csv") + .isDirectoryContaining("glob:**mode_users.csv") + .isDirectoryContaining("glob:**population_trip_stats.csv") + .isDirectoryContaining("glob:**trip_purposes_by_hour.csv") + .isDirectoryContaining("glob:**mode_share_distance_distribution.csv"); + + Path.of(utils.getInputDirectory()).toFile().delete(); + } + + @Test + void personFilterTest() throws IOException { + + writeInputCsvFiles(); + + new TripAnalysis().execute("--person-filter", "subpopulation=person", + "--input-trips", Path.of(utils.getInputDirectory(), "trips.csv").toString(), + "--input-persons", Path.of(utils.getInputDirectory(), "persons.csv").toString(), + "--output-mode-share", Path.of(utils.getOutputDirectory(), "analysis", "population", "mode_share.csv").toString(), + "--output-mode-share-per-dist", Path.of(utils.getOutputDirectory(), "analysis", "population", "mode_share_per_dist.csv").toString(), + "--output-mode-users", Path.of(utils.getOutputDirectory(), "analysis", "population", "mode_users.csv").toString(), + "--output-trip-stats", Path.of(utils.getOutputDirectory(), "analysis", "population", "trip_stats.csv").toString(), + "--output-population-trip-stats", Path.of(utils.getOutputDirectory(), "analysis", "population", "population_trip_stats.csv").toString(), + "--output-trip-purposes-by-hour", Path.of(utils.getOutputDirectory(), "analysis", "population", "trip_purposes_by_hour.csv").toString(), + "--output-mode-share-distance-distribution", Path.of(utils.getOutputDirectory(), "analysis", "population", "mode_share_distance_distribution.csv").toString(), + "--output-mode-choices", Path.of(utils.getOutputDirectory(), "analysis", "population", "mode_choices.csv").toString(), + "--output-mode-choice-evaluation", Path.of(utils.getOutputDirectory(), "analysis", "population", "mode_choice_evaluation.csv").toString(), + "--output-mode-choice-evaluation-per-mode", Path.of(utils.getOutputDirectory(), "analysis", "population", "mode_choice_evaluation_per_mode.csv").toString(), + "--output-mode-confusion-matrix", Path.of(utils.getOutputDirectory(), "analysis", "population", "mode_confusion_matrix.csv").toString(), + "--output-mode-prediction-error", Path.of(utils.getOutputDirectory(), "analysis", "population", "mode_prediction_error.csv").toString()); + + Path out = Path.of(utils.getOutputDirectory(), "analysis", "population"); + + Assertions.assertThat(out) + .isDirectoryContaining("glob:**trip_stats.csv") + .isDirectoryContaining("glob:**mode_share.csv") + .isDirectoryContaining("glob:**mode_share_per_dist.csv") + .isDirectoryContaining("glob:**mode_users.csv") + .isDirectoryContaining("glob:**population_trip_stats.csv") + .isDirectoryContaining("glob:**trip_purposes_by_hour.csv") + .isDirectoryContaining("glob:**mode_share_distance_distribution.csv"); + + Table modeShare = Table.read().csv(CsvReadOptions.builder(IOUtils.getBufferedReader(Path.of(utils.getOutputDirectory(), "analysis", "population", "mode_share.csv").toString())) + .columnTypesPartial(Map.of("person", ColumnType.TEXT)) + .sample(false) + .separator(CsvOptions.detectDelimiter(Path.of(utils.getOutputDirectory(), "analysis", "population", "mode_share.csv").toString())).build()); + + StringColumn mainMode = modeShare.stringColumn("main_mode"); + +// only 1 row with values + Assertions.assertThat(modeShare.rowCount()).isEqualTo(1); + // only mode car, no mode goods in mode share stats + Assertions.assertThat(mainMode.get(0)).isEqualTo("car"); + + Path.of(utils.getInputDirectory()).toFile().delete(); + } + + private void writeInputCsvFiles() throws IOException { + Path persons = Path.of(utils.getInputDirectory()).resolve("persons.csv"); + Files.createDirectories(persons.getParent()); + CSVPrinter printer = csv.createPrinter(persons); + +// print dummy persons + printer.printRecord("person", "executed_score", "first_act_x", "first_act_y", "first_act_type", "age", "carAvail", "home_x", "home_y", "householdIncome", "householdSize", + "income", "sex", "sim_ptAbo", "sim_regionType", "subpopulation", "purpose", "tourStartArea", "vehicleTypes"); + printer.printRecord("100", "-130.69951448065348", "369956.19", "5776578.61", "home_49200", "50", "always", "369956.19", "5776578.61", "5", "2", "1159.0", "f", "none", "124", "person", "", "", ""); + printer.printRecord("100_goodsTraffic", "-130.69951448065348", "369956.19", "5776578.61", "home_49200", "50", "always", "369956.19", "5776578.61", "5", "2", "1159.0", "f", "none", "124", "goodsTraffic", "", "", ""); + printer.close(); + +// print dummy trips + printer = csv.createPrinter(Path.of(utils.getInputDirectory(), "trips.csv")); + printer.printRecord("person", "trip_number", "trip_id", "dep_time", "trav_time", "wait_time", "traveled_distance", "euclidean_distance", "main_mode", "longest_distance_mode", + "modes", "start_activity_type", "end_activity_type", "start_facility_id", "start_link", "start_x", "start_y", "end_facility_id", "end_link", "end_x", "end_y", "first_pt_boarding_stop", "last_pt_egress_stop"); + printer.printRecord("100", "1", "100_1", "13:57:42", "00:34:07", "00:00:00", "53025", "34976", "car", "car", "walk-car-walk", "home_49200", "errands_3600", "null", "-199781090", + "369956.19", "5776578.61", "null", "152273276", "401592.51", "5761661.71", "", ""); + printer.printRecord("100", "2", "100_2", "15:42:50", "01:01:52", "00:00:00", "78917", "54643", "car", "car", "walk-car-walk", "errands_3600", "errands_4200", "null", "152273276", + "401592.51", "5761661.71", "null", "-366338372", "455444.34", "5752394.08", "", ""); + printer.printRecord("100_goodsTraffic", "1", "100_1", "13:57:42", "00:34:07", "00:00:00", "53025", "34976", "goods", "goods", "walk-goods-walk", "home_49200", "errands_3600", "null", "-199781090", + "369956.19", "5776578.61", "null", "152273276", "401592.51", "5761661.71", "", ""); + printer.close(); + } +} diff --git a/contribs/application/src/test/java/org/matsim/application/avro/CSVToAvroConverterTest.java b/contribs/application/src/test/java/org/matsim/application/avro/CSVToAvroConverterTest.java new file mode 100644 index 00000000000..d2e42c89258 --- /dev/null +++ b/contribs/application/src/test/java/org/matsim/application/avro/CSVToAvroConverterTest.java @@ -0,0 +1,85 @@ +package org.matsim.application.avro; + +import org.apache.avro.file.DataFileReader; +import org.apache.avro.specific.SpecificDatumReader; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.matsim.testcases.MatsimTestUtils; +import org.apache.commons.csv.CSVFormat; +import org.apache.commons.csv.CSVParser; +import org.apache.commons.csv.CSVRecord; +import org.matsim.core.utils.io.IOUtils; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static org.junit.jupiter.api.Assertions.*; + +class CSVToAvroConverterTest { + + @RegisterExtension + public final MatsimTestUtils utils = new MatsimTestUtils(); + + @Test + void conversion() throws IOException { + String input = utils.getInputDirectory() + "exampleCSV.csv"; + String output = utils.getOutputDirectory() + "exampleAvro.avro"; + + CSVToAvroConverter.main(new String[]{input, output}); + + // Verify the output Avro file exists + Path outputPath = Path.of(output); + assertTrue(Files.exists(outputPath), "The Avro output file should exist."); + + Set uniqueTimes = new HashSet<>(); + Set uniqueX = new HashSet<>(); + Set uniqueY = new HashSet<>(); + + try (CSVParser csvParser = new CSVParser(IOUtils.getBufferedReader(input), CSVFormat.DEFAULT.builder() + .setCommentMarker('#') + .setSkipHeaderRecord(true) + .setHeader("time", "x", "y", "value") + .build())) { + for (CSVRecord record : csvParser) { + uniqueTimes.add(Double.parseDouble(record.get("time"))); + uniqueX.add(Double.parseDouble(record.get("x"))); + uniqueY.add(Double.parseDouble(record.get("y"))); + } + } + + // Check if the avro file has the expected number of unique entries + int expectedTimeCount = uniqueTimes.size(); + int expectedXCount = uniqueX.size(); + int expectedYCount = uniqueY.size(); + int expectedEmissionsSize = expectedTimeCount * expectedXCount * expectedYCount; + + // Verify the avro data + SpecificDatumReader datumReader = new SpecificDatumReader<>(XYTData.class); + try (DataFileReader dataFileReader = new DataFileReader<>(new File(output), datumReader)) { + assertTrue(dataFileReader.hasNext(), "There should be at least one record in the Avro file."); + + XYTData avroData = dataFileReader.next(); + + // Verify the number of unique entries in the Avro file matches the CSV data + assertEquals(expectedTimeCount, avroData.getTimestamps().size(), "The number of unique time entries should match."); + assertEquals(expectedXCount, avroData.getXCoords().size(), "The number of unique x-coordinates should match."); + assertEquals(expectedYCount, avroData.getYCoords().size(), "The number of unique y-coordinates should match."); + + // Check if the data map has the expected number of entries + Map> emissionsData = avroData.getData(); + + for (Map.Entry> entry : emissionsData.entrySet()) { + assertNotNull(entry.getValue(), "The Emissions data should not be null."); + assertEquals(expectedEmissionsSize, entry.getValue().size(), "The size of the Emissions data should be timeCount * xCount * yCount."); + } + } + + Files.delete(outputPath); + } +} diff --git a/contribs/application/src/test/java/org/matsim/application/prepare/scenario/CreateScenarioCutOutTest.java b/contribs/application/src/test/java/org/matsim/application/prepare/scenario/CreateScenarioCutOutTest.java new file mode 100644 index 00000000000..9786a05ff00 --- /dev/null +++ b/contribs/application/src/test/java/org/matsim/application/prepare/scenario/CreateScenarioCutOutTest.java @@ -0,0 +1,229 @@ +package org.matsim.application.prepare.scenario; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.matsim.api.core.v01.Identifiable; +import org.matsim.api.core.v01.Scenario; +import org.matsim.api.core.v01.network.Network; +import org.matsim.core.config.Config; +import org.matsim.core.config.ConfigUtils; +import org.matsim.core.network.NetworkChangeEvent; +import org.matsim.core.network.NetworkUtils; +import org.matsim.core.network.io.NetworkChangeEventsParser; +import org.matsim.core.population.routes.PopulationComparison; +import org.matsim.core.scenario.ScenarioUtils; +import org.matsim.examples.ExamplesUtils; +import org.matsim.facilities.FacilitiesUtils; +import org.matsim.testcases.MatsimTestUtils; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.*; + +import static org.assertj.core.api.Assertions.assertThat; + +class CreateScenarioCutOutTest { + + @RegisterExtension + MatsimTestUtils utils = new MatsimTestUtils(); + + /** + * Test the cutout without facilities and without events. + */ + @Test + void testBasicCutout() { + // TODO Rueckfrage: Soll die cap auch auf inf gesetzt werden, wenn es keine Events gibt, die die freespeed anpassen? + new CreateScenarioCutOut().execute( + "--buffer", "100", + "--population", utils.getClassInputDirectory() + "plans_without_facilities.xml", + "--network", ExamplesUtils.getTestScenarioURL("chessboard") + "network.xml", + "--output-network", utils.getOutputDirectory() + "cut_network.xml", + "--output-population", utils.getOutputDirectory() + "cut_population.xml", + "--output-network-change-events", utils.getOutputDirectory() + "cut_change_events.xml", + "--input-crs", "EPSG:25832", + "--target-crs", "EPSG:25832", + "--shp", utils.getClassInputDirectory() + "chessboard-cutout.shp", + "--network-change-events-interval", "3600" + ); + + Scenario referenceScenario = getReferenceScenario(false, false); + Scenario outputScenario = getOutputScenario(false, false); + + // Network-Change event should only be generated, if an events file is given + assertThat(new File(utils.getOutputDirectory() + "cut_change_events.xml")) + .doesNotExist(); + assertThat(new File(utils.getOutputDirectory() + "cut_facilities.xml")) + .doesNotExist(); + + Assertions.assertTrue(NetworkUtils.compare(referenceScenario.getNetwork(), outputScenario.getNetwork()), "Network was not cut properly!"); + Assertions.assertSame(PopulationComparison.Result.equal, PopulationComparison.compare(referenceScenario.getPopulation(), outputScenario.getPopulation()), "Population was not cut properly!"); + } + + /** + * Test the cutout with facilities but without events. + */ + @Test + void testFacilitiesCutout() { + new CreateScenarioCutOut().execute( + "--buffer", "100", + "--population", ExamplesUtils.getTestScenarioURL("chessboard") + "plans.xml", + "--network", ExamplesUtils.getTestScenarioURL("chessboard") + "network.xml", + "--facilities", ExamplesUtils.getTestScenarioURL("chessboard") + "facilities.xml", + "--output-network", utils.getOutputDirectory() + "cut_network.xml", + "--output-population", utils.getOutputDirectory() + "cut_population.xml", + "--output-network-change-events", utils.getOutputDirectory() + "cut_change_events.xml", + "--output-facilities", utils.getOutputDirectory() + "cut_facilities.xml", + "--input-crs", "EPSG:25832", + "--target-crs", "EPSG:25832", + "--shp", utils.getClassInputDirectory() + "chessboard-cutout.shp", + "--network-change-events-interval", "3600" + ); + + Scenario referenceScenario = getReferenceScenario(false, true); + Scenario outputScenario = getOutputScenario(false, true); + + // Network-Change event should only be generated, if an events file is given + assertThat(new File(utils.getOutputDirectory() + "cut_change_events.xml")) + .doesNotExist(); + + Assertions.assertTrue(NetworkUtils.compare(referenceScenario.getNetwork(), outputScenario.getNetwork()), "Network was not cut properly!"); + Assertions.assertSame(PopulationComparison.Result.equal, PopulationComparison.compare(referenceScenario.getPopulation(), outputScenario.getPopulation()), "Population was not cut properly!"); + Assertions.assertTrue(outputScenario.getActivityFacilities().getFacilities().size() <= referenceScenario.getActivityFacilities().getFacilities().size()); + Assertions.assertTrue(outputScenario.getActivityFacilities().getFacilities().keySet().stream().allMatch(id -> referenceScenario.getActivityFacilities().getFacilities().containsKey(id))); + } + + /** + * Test the cutout without facilities but with events. + */ + @Test + void testEventsCutout() throws IOException { + new CreateScenarioCutOut().execute( + "--buffer", "100", + "--population", utils.getClassInputDirectory() + "plans_without_facilities.xml", + "--network", ExamplesUtils.getTestScenarioURL("chessboard") + "network.xml", + "--events", utils.getClassInputDirectory() + "events.xml.gz", + "--output-network", utils.getOutputDirectory() + "cut_network.xml", + "--output-population", utils.getOutputDirectory() + "cut_population.xml", + "--output-network-change-events", utils.getOutputDirectory() + "cut_change_events.xml", + "--input-crs", "EPSG:25832", + "--target-crs", "EPSG:25832", + "--shp", utils.getClassInputDirectory() + "chessboard-cutout.shp", + "--network-change-events-interval", "3600" + ); + + Scenario referenceScenario = getReferenceScenario(true, false); + Scenario outputScenario = getOutputScenario(true, false); + + assertThat(new File(utils.getOutputDirectory() + "cut_facilities.xml")) + .doesNotExist(); + + Assertions.assertTrue(NetworkUtils.compare(referenceScenario.getNetwork(), outputScenario.getNetwork()), "Network was not cut properly!"); + Assertions.assertTrue(checkIfNetworkChangeEventsAreSame(referenceScenario.getNetwork(), outputScenario.getNetwork()), "NetworkChangeEvents were not generated properly!"); + Assertions.assertSame(PopulationComparison.Result.equal, PopulationComparison.compare(referenceScenario.getPopulation(), outputScenario.getPopulation()), "Population was not cut properly!"); + } + + /** + * Test the cutout with facilities and events. + */ + @Test + void testFullCutOut() throws IOException { + new CreateScenarioCutOut().execute( + "--buffer", "100", + "--population", ExamplesUtils.getTestScenarioURL("chessboard") + "plans.xml", + "--network", ExamplesUtils.getTestScenarioURL("chessboard") + "network.xml", + "--events", utils.getClassInputDirectory() + "events.xml.gz", + "--facilities", ExamplesUtils.getTestScenarioURL("chessboard") + "facilities.xml", + "--output-network", utils.getOutputDirectory() + "cut_network.xml", + "--output-population", utils.getOutputDirectory() + "cut_population.xml", + "--output-network-change-events", utils.getOutputDirectory() + "cut_change_events.xml", + "--output-facilities", utils.getOutputDirectory() + "cut_facilities.xml", + "--input-crs", "EPSG:25832", + "--target-crs", "EPSG:25832", + "--shp", utils.getClassInputDirectory() + "chessboard-cutout.shp", + "--network-change-events-interval", "3600" + ); + + Scenario referenceScenario = getReferenceScenario(true, true); + Scenario outputScenario = getOutputScenario(true, true); + + Assertions.assertTrue(NetworkUtils.compare(referenceScenario.getNetwork(), outputScenario.getNetwork()), "Network was not cut properly!"); + Assertions.assertTrue(checkIfNetworkChangeEventsAreSame(referenceScenario.getNetwork(), outputScenario.getNetwork()), "NetworkChangeEvents were not generated properly!"); + Assertions.assertSame(PopulationComparison.Result.equal, PopulationComparison.compare(referenceScenario.getPopulation(), outputScenario.getPopulation()), "Population was not cut properly!"); + Assertions.assertTrue(outputScenario.getActivityFacilities().getFacilities().size() <= referenceScenario.getActivityFacilities().getFacilities().size()); + Assertions.assertTrue(outputScenario.getActivityFacilities().getFacilities().keySet().stream().allMatch(id -> referenceScenario.getActivityFacilities().getFacilities().containsKey(id))); + } + + /** + * Get the reference-output as a scenario + * + * @param withEvents If you executed the test with an input Events file, set this to true + */ + private Scenario getReferenceScenario(boolean withEvents, boolean withFacilities) { + String folder = withEvents ? "withEvents/" : "withoutEvents/"; + + Config referenceConfig = ConfigUtils.createConfig(); + referenceConfig.global().setCoordinateSystem("EPSG:25832"); + referenceConfig.network().setTimeVariantNetwork(true); + referenceConfig.network().setInputFile(utils.getClassInputDirectory() + folder + "cut_network.xml"); + if (withEvents) referenceConfig.network().setChangeEventsInputFile(utils.getClassInputDirectory() + folder + "cut_change_events.xml"); + referenceConfig.plans().setInputFile(utils.getClassInputDirectory() + folder + "cut_population.xml"); + if (withFacilities) referenceConfig.facilities().setInputFile(utils.getClassInputDirectory() + folder + "cut_facilities.xml"); + return ScenarioUtils.loadScenario(referenceConfig); + } + + /** + * Get the output as a scenario + */ + private Scenario getOutputScenario(boolean withEvents, boolean withFacilities) { + Config outputConfig = ConfigUtils.createConfig(); + outputConfig.global().setCoordinateSystem("EPSG:25832"); + outputConfig.network().setTimeVariantNetwork(true); + outputConfig.network().setInputFile(utils.getOutputDirectory() + "cut_network.xml"); + if (withEvents) outputConfig.network().setChangeEventsInputFile(utils.getOutputDirectory() + "cut_change_events.xml"); + outputConfig.plans().setInputFile(utils.getOutputDirectory() + "cut_population.xml"); + if (withFacilities) outputConfig.facilities().setInputFile(utils.getOutputDirectory() + "cut_facilities.xml"); + return ScenarioUtils.loadScenario(outputConfig); + } + + /** + * Checks if two Networks have the same NetworkChangeEvents by checking the ids. + */ + private boolean checkIfNetworkChangeEventsAreSame(Network firstNetwork, Network secondNetwork) throws IOException { + List firstList = new LinkedList<>(); + List secondList = new LinkedList<>(); + new NetworkChangeEventsParser(firstNetwork, firstList).parse(Files.newInputStream(Path.of(utils.getClassInputDirectory() + "withEvents/cut_change_events.xml"))); + new NetworkChangeEventsParser(secondNetwork, secondList).parse(Files.newInputStream(Path.of(utils.getOutputDirectory() + "cut_change_events.xml"))); + ; + + if (firstList.size() != secondList.size()) return false; + + // This loop is unefficient, but I did not found a better way, to compare the NetworkChangeEvents, as they have no deterministic order + int matches = 0; + for (NetworkChangeEvent firstEvent : firstList) { + // Find an event in the secondList, that matches this event + for (NetworkChangeEvent secondEvent : secondList) { + if (firstEvent.getStartTime() != secondEvent.getStartTime()) continue; + if (firstEvent.getFreespeedChange() != null && secondEvent.getFreespeedChange() != null && firstEvent.getFreespeedChange().getValue() != secondEvent.getFreespeedChange().getValue()) + continue; + if (firstEvent.getFlowCapacityChange() != null && secondEvent.getFlowCapacityChange() != null && firstEvent.getFlowCapacityChange().getValue() != secondEvent.getFlowCapacityChange().getValue()) + continue; + if (!equalsIds(firstEvent.getLinks(), secondEvent.getLinks())) continue; + + matches++; + break; + } + } + + return matches == firstList.size(); + } + + /** + * Checks if two List have the same elements by checking the ids. + */ + private boolean equalsIds(Collection> firstList, Collection> secondList) { + return new HashSet<>(firstList.stream().map(Identifiable::getId).toList()).equals(new HashSet<>(secondList.stream().map(Identifiable::getId).toList())); + } +} diff --git a/contribs/application/src/test/java/org/matsim/freightDemandGeneration/DemandReaderFromCSVTest.java b/contribs/application/src/test/java/org/matsim/freightDemandGeneration/DemandReaderFromCSVTest.java index 9d672b4a461..c27b251afc4 100644 --- a/contribs/application/src/test/java/org/matsim/freightDemandGeneration/DemandReaderFromCSVTest.java +++ b/contribs/application/src/test/java/org/matsim/freightDemandGeneration/DemandReaderFromCSVTest.java @@ -2,13 +2,11 @@ import java.io.IOException; import java.nio.file.Path; -import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; -import org.geotools.api.feature.simple.SimpleFeature; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; @@ -22,7 +20,6 @@ import org.matsim.freight.carriers.*; import org.matsim.core.config.Config; import org.matsim.core.config.ConfigUtils; -import org.matsim.core.network.NetworkUtils; import org.matsim.core.population.PopulationUtils; import org.matsim.core.scenario.ScenarioUtils; import org.matsim.freightDemandGeneration.CarrierReaderFromCSV.CarrierInformationElement; @@ -41,7 +38,7 @@ public class DemandReaderFromCSVTest { private MatsimTestUtils utils = new MatsimTestUtils(); @Test - void testLinkForPerson() throws IOException { + void testLinkForPerson() { Config config = ConfigUtils.createConfig(); config.network().setInputFile( "https://raw.githubusercontent.com/matsim-org/matsim-libs/master/examples/scenarios/freight-chessboard-9x9/grid9x9.xml"); @@ -61,13 +58,10 @@ void testLinkForPerson() throws IOException { Assertions.assertEquals("j(8,8)R",nearestLinkPerPerson.get(Id.createPersonId("person6")).values().iterator().next()); Assertions.assertEquals("i(5,9)R",nearestLinkPerPerson.get(Id.createPersonId("person7")).values().iterator().next()); Assertions.assertEquals("i(9,5)R",nearestLinkPerPerson.get(Id.createPersonId("person8")).values().iterator().next()); - - - } @Test - void demandCreation() throws IOException { + void demandCreationWithSampleWithChangeNumberOfLocations() throws IOException { // read inputs Config config = ConfigUtils.createConfig(); config.network().setInputFile( @@ -82,126 +76,21 @@ void demandCreation() throws IOException { ShpOptions shp = new ShpOptions(shapeFilePath, "WGS84", null); String shapeCategory = "Ortsteil"; ShpOptions.Index indexShape = shp.createIndex("Ortsteil"); - Collection polygonsInShape = shp.readFeatures(); String populationLocation = utils.getPackageInputDirectory() + "testPopulation.xml"; Population population = PopulationUtils.readPopulation(populationLocation); FreightDemandGenerationUtils.preparePopulation(population, 0.5, 1.0, "changeNumberOfLocationsWithDemand"); // run methods - Set allNewCarrierInformation = CarrierReaderFromCSV - .readCarrierInformation(carrierCSVLocation); - CarrierReaderFromCSV.createNewCarrierAndAddVehicleTypes(scenario, allNewCarrierInformation, freightCarriersConfigGroup, - indexShape, 1, null); - Set demandInformation = DemandReaderFromCSV.readDemandInformation(demandCSVLocation); - DemandReaderFromCSV.checkNewDemand(scenario, demandInformation, indexShape, shapeCategory); - DemandReaderFromCSV.createDemandForCarriers(scenario, indexShape, demandInformation, population, false, - null); - Assertions.assertEquals(3, CarriersUtils.getCarriers(scenario).getCarriers().size()); - Assertions.assertTrue( - CarriersUtils.getCarriers(scenario).getCarriers().containsKey(Id.create("testCarrier1", Carrier.class))); - Assertions.assertTrue( - CarriersUtils.getCarriers(scenario).getCarriers().containsKey(Id.create("testCarrier2", Carrier.class))); - Assertions.assertTrue( - CarriersUtils.getCarriers(scenario).getCarriers().containsKey(Id.create("testCarrier3", Carrier.class))); + createDemandAndCheckCarrier(carrierCSVLocation, scenario, freightCarriersConfigGroup, indexShape, demandCSVLocation, shapeCategory, + population); - // check carrier 1 - Network network = NetworkUtils.readNetwork( - "https://raw.githubusercontent.com/matsim-org/matsim-libs/master/examples/scenarios/freight-chessboard-9x9/grid9x9.xml"); - Carrier testCarrier1 = CarriersUtils.getCarriers(scenario).getCarriers() - .get(Id.create("testCarrier1", Carrier.class)); - Assertions.assertEquals(14, testCarrier1.getServices().size()); - Assertions.assertEquals(0, testCarrier1.getShipments().size()); - Object2IntMap countServicesWithCertainDemand = new Object2IntOpenHashMap<>(); - Map> locationsPerServiceElement = new HashMap<>(); - int countDemand = 0; - for (CarrierService service : testCarrier1.getServices().values()) { - countServicesWithCertainDemand.merge((Integer) service.getCapacityDemand(), 1, Integer::sum); - countDemand = countDemand + service.getCapacityDemand(); - if (service.getCapacityDemand() == 0) { - Assertions.assertEquals(180, service.getServiceDuration(), MatsimTestUtils.EPSILON); - Assertions.assertEquals(TimeWindow.newInstance(3000, 13000), service.getServiceStartTimeWindow()); - locationsPerServiceElement.computeIfAbsent("serviceElement1", (k) -> new HashSet<>()) - .add(service.getLocationLinkId().toString()); - } else if (service.getCapacityDemand() == 1) { - Assertions.assertEquals(100, service.getServiceDuration(), MatsimTestUtils.EPSILON); - Assertions.assertEquals(TimeWindow.newInstance(5000, 20000), service.getServiceStartTimeWindow()); - locationsPerServiceElement.computeIfAbsent("serviceElement2", (k) -> new HashSet<>()) - .add(service.getLocationLinkId().toString()); - } else if (service.getCapacityDemand() == 2) { - Assertions.assertEquals(200, service.getServiceDuration(), MatsimTestUtils.EPSILON); - Assertions.assertEquals(TimeWindow.newInstance(5000, 20000), service.getServiceStartTimeWindow()); - locationsPerServiceElement.computeIfAbsent("serviceElement2", (k) -> new HashSet<>()) - .add(service.getLocationLinkId().toString()); - } else - Assertions.fail("Service has a wrong demand."); - } - Assertions.assertEquals(12, countDemand); - Assertions.assertEquals(4, countServicesWithCertainDemand.getInt(0)); - Assertions.assertEquals(8, countServicesWithCertainDemand.getInt(1)); - Assertions.assertEquals(2, countServicesWithCertainDemand.getInt(2)); - Assertions.assertEquals(4, locationsPerServiceElement.get("serviceElement1").size()); - for (String locationsOfServiceElement : locationsPerServiceElement.get("serviceElement1")) { - Link link = network.getLinks().get(Id.createLinkId(locationsOfServiceElement)); - Assertions.assertTrue( - FreightDemandGenerationUtils.checkPositionInShape(link, null, indexShape, null, null)); - Assertions.assertFalse(FreightDemandGenerationUtils.checkPositionInShape(link, null, indexShape, - new String[] { "area1" }, null)); - Assertions.assertTrue(FreightDemandGenerationUtils.checkPositionInShape(link, null, indexShape, - new String[] { "area2" }, null)); - } - Assertions.assertEquals(4, locationsPerServiceElement.get("serviceElement2").size()); - Assertions.assertTrue(locationsPerServiceElement.get("serviceElement2").contains("i(2,0)")); + Network network = scenario.getNetwork(); - // check carrier 2 - Carrier testCarrier2 = CarriersUtils.getCarriers(scenario).getCarriers() - .get(Id.create("testCarrier2", Carrier.class)); - Assertions.assertEquals(0, testCarrier2.getServices().size()); - Assertions.assertEquals(11, testCarrier2.getShipments().size()); - Object2IntMap countShipmentsWithCertainDemand = new Object2IntOpenHashMap<>(); - Map> locationsPerShipmentElement = new HashMap<>(); - countDemand = 0; - for (CarrierShipment shipment : testCarrier2.getShipments().values()) { - countShipmentsWithCertainDemand.merge((Integer) shipment.getSize(), 1, Integer::sum); - countDemand = countDemand + shipment.getSize(); - if (shipment.getSize() == 0) { - Assertions.assertEquals(300, shipment.getPickupServiceTime(), MatsimTestUtils.EPSILON); - Assertions.assertEquals(350, shipment.getDeliveryServiceTime(), MatsimTestUtils.EPSILON); - Assertions.assertEquals(TimeWindow.newInstance(10000, 45000), shipment.getPickupTimeWindow()); - Assertions.assertEquals(TimeWindow.newInstance(11000, 44000), shipment.getDeliveryTimeWindow()); - locationsPerShipmentElement.computeIfAbsent("ShipmenElement1_pickup", (k) -> new HashSet<>()) - .add(shipment.getFrom().toString()); - locationsPerShipmentElement.computeIfAbsent("ShipmenElement1_delivery", (k) -> new HashSet<>()) - .add(shipment.getTo().toString()); - } else if (shipment.getSize() == 2) { - Assertions.assertEquals(400, shipment.getPickupServiceTime(), MatsimTestUtils.EPSILON); - Assertions.assertEquals(400, shipment.getDeliveryServiceTime(), MatsimTestUtils.EPSILON); - Assertions.assertEquals(TimeWindow.newInstance(11000, 44000), shipment.getPickupTimeWindow()); - Assertions.assertEquals(TimeWindow.newInstance(20000, 40000), shipment.getDeliveryTimeWindow()); - locationsPerShipmentElement.computeIfAbsent("ShipmenElement2_pickup", (k) -> new HashSet<>()) - .add(shipment.getFrom().toString()); - locationsPerShipmentElement.computeIfAbsent("ShipmenElement2_delivery", (k) -> new HashSet<>()) - .add(shipment.getTo().toString()); - } else if (shipment.getSize() == 3) { - Assertions.assertEquals(600, shipment.getPickupServiceTime(), MatsimTestUtils.EPSILON); - Assertions.assertEquals(600, shipment.getDeliveryServiceTime(), MatsimTestUtils.EPSILON); - Assertions.assertEquals(TimeWindow.newInstance(11000, 44000), shipment.getPickupTimeWindow()); - Assertions.assertEquals(TimeWindow.newInstance(20000, 40000), shipment.getDeliveryTimeWindow()); - locationsPerShipmentElement.computeIfAbsent("ShipmenElement2_pickup", (k) -> new HashSet<>()) - .add(shipment.getFrom().toString()); - locationsPerShipmentElement.computeIfAbsent("ShipmenElement2_delivery", (k) -> new HashSet<>()) - .add(shipment.getTo().toString()); - } else - Assertions.fail("Shipment has an unexpected demand."); - } - Assertions.assertEquals(15, countDemand); - Assertions.assertEquals(4, countShipmentsWithCertainDemand.getInt(0)); - Assertions.assertEquals(6, countShipmentsWithCertainDemand.getInt(2)); - Assertions.assertEquals(1, countShipmentsWithCertainDemand.getInt(3)); - Assertions.assertEquals(4, locationsPerShipmentElement.get("ShipmenElement1_pickup").size()); - Assertions.assertEquals(1, locationsPerShipmentElement.get("ShipmenElement1_delivery").size()); - Assertions.assertTrue(locationsPerShipmentElement.get("ShipmenElement1_delivery").contains("i(2,0)")); - Assertions.assertEquals(1, locationsPerShipmentElement.get("ShipmenElement2_pickup").size()); - Assertions.assertEquals(2, locationsPerShipmentElement.get("ShipmenElement2_delivery").size()); + checkCarrier1and2(scenario, network, indexShape); + + Object2IntMap countShipmentsWithCertainDemand; + Map> locationsPerShipmentElement; + int countDemand; // check carrier 3 Carrier testCarrier3 = CarriersUtils.getCarriers(scenario).getCarriers() @@ -219,16 +108,16 @@ void demandCreation() throws IOException { Assertions.assertEquals(1250, shipment.getDeliveryServiceTime(), MatsimTestUtils.EPSILON); Assertions.assertEquals(TimeWindow.newInstance(8000, 50000), shipment.getPickupTimeWindow()); Assertions.assertEquals(TimeWindow.newInstance(10000, 60000), shipment.getDeliveryTimeWindow()); - locationsPerShipmentElement.computeIfAbsent("ShipmenElement1_pickup", (k) -> new HashSet<>()) + locationsPerShipmentElement.computeIfAbsent("ShipmentElement1_pickup", (k) -> new HashSet<>()) .add(shipment.getFrom().toString()); - locationsPerShipmentElement.computeIfAbsent("ShipmenElement1_delivery", (k) -> new HashSet<>()) + locationsPerShipmentElement.computeIfAbsent("ShipmentElement1_delivery", (k) -> new HashSet<>()) .add(shipment.getTo().toString()); } Assertions.assertEquals(20, countDemand); Assertions.assertEquals(4, countShipmentsWithCertainDemand.getInt(5)); - Assertions.assertEquals(2, locationsPerShipmentElement.get("ShipmenElement1_pickup").size()); - Assertions.assertEquals(4, locationsPerShipmentElement.get("ShipmenElement1_delivery").size()); - for (String locationsOfShipmentElement : locationsPerShipmentElement.get("ShipmenElement1_delivery")) { + Assertions.assertEquals(2, locationsPerShipmentElement.get("ShipmentElement1_pickup").size()); + Assertions.assertEquals(4, locationsPerShipmentElement.get("ShipmentElement1_delivery").size()); + for (String locationsOfShipmentElement : locationsPerShipmentElement.get("ShipmentElement1_delivery")) { Link link = network.getLinks().get(Id.createLinkId(locationsOfShipmentElement)); Assertions.assertTrue( FreightDemandGenerationUtils.checkPositionInShape(link, null, indexShape, null, null)); @@ -239,6 +128,140 @@ void demandCreation() throws IOException { } } + @Test + void demandCreationWithSampleWithDemandOnLocation() throws IOException { + // read inputs + Config config = ConfigUtils.createConfig(); + config.network().setInputFile( + "https://raw.githubusercontent.com/matsim-org/matsim-libs/master/examples/scenarios/freight-chessboard-9x9/grid9x9.xml"); + Scenario scenario = ScenarioUtils.loadScenario(config); + FreightCarriersConfigGroup freightCarriersConfigGroup = ConfigUtils.addOrGetModule(scenario.getConfig(), + FreightCarriersConfigGroup.class); + freightCarriersConfigGroup.setCarriersVehicleTypesFile(utils.getPackageInputDirectory() + "testVehicleTypes.xml"); + Path carrierCSVLocation = Path.of(utils.getPackageInputDirectory() + "testCarrierCSV.csv"); + Path demandCSVLocation = Path.of(utils.getPackageInputDirectory() + "testDemandCSV.csv"); + Path shapeFilePath = Path.of(utils.getPackageInputDirectory() + "testShape/testShape.shp"); + ShpOptions shp = new ShpOptions(shapeFilePath, "WGS84", null); + String shapeCategory = "Ortsteil"; + ShpOptions.Index indexShape = shp.createIndex("Ortsteil"); + String populationLocation = utils.getPackageInputDirectory() + "testPopulation.xml"; + Population population = PopulationUtils.readPopulation(populationLocation); + FreightDemandGenerationUtils.preparePopulation(population, 0.5, 1.0, "changeDemandOnLocation"); + + createDemandAndCheckCarrier(carrierCSVLocation, scenario, freightCarriersConfigGroup, indexShape, demandCSVLocation, shapeCategory, population); + + // check carrier 1 + Network network = scenario.getNetwork(); + + checkCarrier1and2(scenario, network, indexShape); + int countDemand; + Object2IntMap countShipmentsWithCertainDemand; + Map> locationsPerShipmentElement; + + // check carrier 3 + Carrier testCarrier3 = CarriersUtils.getCarriers(scenario).getCarriers() + .get(Id.create("testCarrier3", Carrier.class)); + Assertions.assertEquals(0, testCarrier3.getServices().size()); + Assertions.assertEquals(2, testCarrier3.getShipments().size()); + countShipmentsWithCertainDemand = new Object2IntOpenHashMap<>(); + locationsPerShipmentElement = new HashMap<>(); + countDemand = 0; + for (CarrierShipment shipment : testCarrier3.getShipments().values()) { + countShipmentsWithCertainDemand.merge((Integer) shipment.getSize(), 1, Integer::sum); + countDemand = countDemand + shipment.getSize(); + Assertions.assertEquals(10, shipment.getSize()); + Assertions.assertEquals(4000, shipment.getPickupServiceTime(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(2500, shipment.getDeliveryServiceTime(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(TimeWindow.newInstance(8000, 50000), shipment.getPickupTimeWindow()); + Assertions.assertEquals(TimeWindow.newInstance(10000, 60000), shipment.getDeliveryTimeWindow()); + locationsPerShipmentElement.computeIfAbsent("ShipmentElement1_pickup", (k) -> new HashSet<>()) + .add(shipment.getFrom().toString()); + locationsPerShipmentElement.computeIfAbsent("ShipmentElement1_delivery", (k) -> new HashSet<>()) + .add(shipment.getTo().toString()); + } + Assertions.assertEquals(20, countDemand); + Assertions.assertEquals(2, countShipmentsWithCertainDemand.getInt(10)); + Assertions.assertEquals(1, locationsPerShipmentElement.get("ShipmentElement1_pickup").size()); + Assertions.assertEquals(2, locationsPerShipmentElement.get("ShipmentElement1_delivery").size()); + for (String locationsOfShipmentElement : locationsPerShipmentElement.get("ShipmentElement1_delivery")) { + Link link = network.getLinks().get(Id.createLinkId(locationsOfShipmentElement)); + Assertions.assertTrue( + FreightDemandGenerationUtils.checkPositionInShape(link, null, indexShape, null, null)); + Assertions.assertTrue(FreightDemandGenerationUtils.checkPositionInShape(link, null, indexShape, + new String[] { "area1" }, null)); + Assertions.assertFalse(FreightDemandGenerationUtils.checkPositionInShape(link, null, indexShape, + new String[] { "area2" }, null)); + } + } + + @Test + void demandCreationNoSampling() throws IOException { + // read inputs + Config config = ConfigUtils.createConfig(); + config.network().setInputFile( + "https://raw.githubusercontent.com/matsim-org/matsim-libs/master/examples/scenarios/freight-chessboard-9x9/grid9x9.xml"); + Scenario scenario = ScenarioUtils.loadScenario(config); + FreightCarriersConfigGroup freightCarriersConfigGroup = ConfigUtils.addOrGetModule(scenario.getConfig(), + FreightCarriersConfigGroup.class); + freightCarriersConfigGroup.setCarriersVehicleTypesFile(utils.getPackageInputDirectory() + "testVehicleTypes.xml"); + Path carrierCSVLocation = Path.of(utils.getPackageInputDirectory() + "testCarrierCSV.csv"); + Path demandCSVLocation = Path.of(utils.getPackageInputDirectory() + "testDemandCSV.csv"); + Path shapeFilePath = Path.of(utils.getPackageInputDirectory() + "testShape/testShape.shp"); + ShpOptions shp = new ShpOptions(shapeFilePath, "WGS84", null); + String shapeCategory = "Ortsteil"; + ShpOptions.Index indexShape = shp.createIndex("Ortsteil"); + String populationLocation = utils.getPackageInputDirectory() + "testPopulation.xml"; + Population population = PopulationUtils.readPopulation(populationLocation); + FreightDemandGenerationUtils.preparePopulation(population, 0.5, 0.5, "changeDemandOnLocation"); + + // run methods + createDemandAndCheckCarrier(carrierCSVLocation, scenario, freightCarriersConfigGroup, indexShape, demandCSVLocation, shapeCategory, + population); + + // check carrier 1 + Network network = scenario.getNetwork(); + + checkCarrier1and2(scenario, network, indexShape); + Object2IntMap countShipmentsWithCertainDemand; + Map> locationsPerShipmentElement; + int countDemand; + + // check carrier 3 + Carrier testCarrier3 = CarriersUtils.getCarriers(scenario).getCarriers() + .get(Id.create("testCarrier3", Carrier.class)); + Assertions.assertEquals(0, testCarrier3.getServices().size()); + Assertions.assertEquals(2, testCarrier3.getShipments().size()); + countShipmentsWithCertainDemand = new Object2IntOpenHashMap<>(); + locationsPerShipmentElement = new HashMap<>(); + countDemand = 0; + for (CarrierShipment shipment : testCarrier3.getShipments().values()) { + countShipmentsWithCertainDemand.merge((Integer) shipment.getSize(), 1, Integer::sum); + countDemand = countDemand + shipment.getSize(); + Assertions.assertEquals(10, shipment.getSize()); + Assertions.assertEquals(4000, shipment.getPickupServiceTime(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(2500, shipment.getDeliveryServiceTime(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(TimeWindow.newInstance(8000, 50000), shipment.getPickupTimeWindow()); + Assertions.assertEquals(TimeWindow.newInstance(10000, 60000), shipment.getDeliveryTimeWindow()); + locationsPerShipmentElement.computeIfAbsent("ShipmentElement1_pickup", (k) -> new HashSet<>()) + .add(shipment.getFrom().toString()); + locationsPerShipmentElement.computeIfAbsent("ShipmentElement1_delivery", (k) -> new HashSet<>()) + .add(shipment.getTo().toString()); + } + Assertions.assertEquals(20, countDemand); + Assertions.assertEquals(2, countShipmentsWithCertainDemand.getInt(10)); + Assertions.assertEquals(1, locationsPerShipmentElement.get("ShipmentElement1_pickup").size()); + Assertions.assertEquals(2, locationsPerShipmentElement.get("ShipmentElement1_delivery").size()); + for (String locationsOfShipmentElement : locationsPerShipmentElement.get("ShipmentElement1_delivery")) { + Link link = network.getLinks().get(Id.createLinkId(locationsOfShipmentElement)); + Assertions.assertTrue( + FreightDemandGenerationUtils.checkPositionInShape(link, null, indexShape, null, null)); + Assertions.assertTrue(FreightDemandGenerationUtils.checkPositionInShape(link, null, indexShape, + new String[] { "area1" }, null)); + Assertions.assertFalse(FreightDemandGenerationUtils.checkPositionInShape(link, null, indexShape, + new String[] { "area2" }, null)); + } + } + @Test void csvDemandReader() throws IOException { @@ -295,7 +318,7 @@ void csvDemandReader() throws IOException { Assertions.assertNull(demandInformationElement.getAreasSecondJobElement()); Assertions.assertEquals(1, (int) demandInformationElement.getNumberOfSecondJobElementLocations()); Assertions.assertEquals(1, demandInformationElement.getLocationsOfSecondJobElement().length); - Assertions.assertTrue(demandInformationElement.getLocationsOfSecondJobElement()[0].equals("i(2,0)")); + Assertions.assertEquals("i(2,0)", demandInformationElement.getLocationsOfSecondJobElement()[0]); Assertions.assertEquals(350, (int) demandInformationElement.getSecondJobElementTimePerUnit()); Assertions.assertEquals(TimeWindow.newInstance(11000, 44000), demandInformationElement.getSecondJobElementTimeWindow()); @@ -341,4 +364,131 @@ void csvDemandReader() throws IOException { Assertions.fail("No expected demandInformationElement found"); } } + + private static void createDemandAndCheckCarrier(Path carrierCSVLocation, Scenario scenario, FreightCarriersConfigGroup freightCarriersConfigGroup, + ShpOptions.Index indexShape, Path demandCSVLocation, String shapeCategory, + Population population) throws IOException { + // run methods + Set allNewCarrierInformation = CarrierReaderFromCSV + .readCarrierInformation(carrierCSVLocation); + CarrierReaderFromCSV.createNewCarrierAndAddVehicleTypes(scenario, allNewCarrierInformation, freightCarriersConfigGroup, + indexShape, 1, null); + Set demandInformation = DemandReaderFromCSV.readDemandInformation(demandCSVLocation); + DemandReaderFromCSV.checkNewDemand(scenario, demandInformation, indexShape, shapeCategory); + DemandReaderFromCSV.createDemandForCarriers(scenario, indexShape, demandInformation, population, false, + null); + Assertions.assertEquals(3, CarriersUtils.getCarriers(scenario).getCarriers().size()); + Assertions.assertTrue( + CarriersUtils.getCarriers(scenario).getCarriers().containsKey(Id.create("testCarrier1", Carrier.class))); + Assertions.assertTrue( + CarriersUtils.getCarriers(scenario).getCarriers().containsKey(Id.create("testCarrier2", Carrier.class))); + Assertions.assertTrue( + CarriersUtils.getCarriers(scenario).getCarriers().containsKey(Id.create("testCarrier3", Carrier.class))); + } + + /** + * These results should be the same for these carriers. + * The difference is only based on the population sample methods for carrier3, because a shareOfThePopulation is used. + * + * @param scenario the scenario + * @param network the network + * @param indexShape the index of the shape + */ + private static void checkCarrier1and2(Scenario scenario, Network network, ShpOptions.Index indexShape) { + Carrier testCarrier1 = CarriersUtils.getCarriers(scenario).getCarriers() + .get(Id.create("testCarrier1", Carrier.class)); + Assertions.assertEquals(14, testCarrier1.getServices().size()); + Assertions.assertEquals(0, testCarrier1.getShipments().size()); + Object2IntMap countServicesWithCertainDemand = new Object2IntOpenHashMap<>(); + Map> locationsPerServiceElement = new HashMap<>(); + int countDemand = 0; + for (CarrierService service : testCarrier1.getServices().values()) { + countServicesWithCertainDemand.merge((Integer) service.getCapacityDemand(), 1, Integer::sum); + countDemand = countDemand + service.getCapacityDemand(); + if (service.getCapacityDemand() == 0) { + Assertions.assertEquals(180, service.getServiceDuration(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(TimeWindow.newInstance(3000, 13000), service.getServiceStartTimeWindow()); + locationsPerServiceElement.computeIfAbsent("serviceElement1", (k) -> new HashSet<>()) + .add(service.getLocationLinkId().toString()); + } else if (service.getCapacityDemand() == 1) { + Assertions.assertEquals(100, service.getServiceDuration(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(TimeWindow.newInstance(5000, 20000), service.getServiceStartTimeWindow()); + locationsPerServiceElement.computeIfAbsent("serviceElement2", (k) -> new HashSet<>()) + .add(service.getLocationLinkId().toString()); + } else if (service.getCapacityDemand() == 2) { + Assertions.assertEquals(200, service.getServiceDuration(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(TimeWindow.newInstance(5000, 20000), service.getServiceStartTimeWindow()); + locationsPerServiceElement.computeIfAbsent("serviceElement2", (k) -> new HashSet<>()) + .add(service.getLocationLinkId().toString()); + } else + Assertions.fail("Service has a wrong demand."); + } + Assertions.assertEquals(12, countDemand); + Assertions.assertEquals(4, countServicesWithCertainDemand.getInt(0)); + Assertions.assertEquals(8, countServicesWithCertainDemand.getInt(1)); + Assertions.assertEquals(2, countServicesWithCertainDemand.getInt(2)); + Assertions.assertEquals(4, locationsPerServiceElement.get("serviceElement1").size()); + for (String locationsOfServiceElement : locationsPerServiceElement.get("serviceElement1")) { + Link link = network.getLinks().get(Id.createLinkId(locationsOfServiceElement)); + Assertions.assertTrue( + FreightDemandGenerationUtils.checkPositionInShape(link, null, indexShape, null, null)); + Assertions.assertFalse(FreightDemandGenerationUtils.checkPositionInShape(link, null, indexShape, + new String[] { "area1" }, null)); + Assertions.assertTrue(FreightDemandGenerationUtils.checkPositionInShape(link, null, indexShape, + new String[] { "area2" }, null)); + } + Assertions.assertEquals(4, locationsPerServiceElement.get("serviceElement2").size()); + Assertions.assertTrue(locationsPerServiceElement.get("serviceElement2").contains("i(2,0)")); + + // check carrier 2 + Carrier testCarrier2 = CarriersUtils.getCarriers(scenario).getCarriers() + .get(Id.create("testCarrier2", Carrier.class)); + Assertions.assertEquals(0, testCarrier2.getServices().size()); + Assertions.assertEquals(11, testCarrier2.getShipments().size()); + Object2IntMap countShipmentsWithCertainDemand = new Object2IntOpenHashMap<>(); + Map> locationsPerShipmentElement = new HashMap<>(); + countDemand = 0; + for (CarrierShipment shipment : testCarrier2.getShipments().values()) { + countShipmentsWithCertainDemand.merge((Integer) shipment.getSize(), 1, Integer::sum); + countDemand = countDemand + shipment.getSize(); + if (shipment.getSize() == 0) { + Assertions.assertEquals(300, shipment.getPickupServiceTime(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(350, shipment.getDeliveryServiceTime(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(TimeWindow.newInstance(10000, 45000), shipment.getPickupTimeWindow()); + Assertions.assertEquals(TimeWindow.newInstance(11000, 44000), shipment.getDeliveryTimeWindow()); + locationsPerShipmentElement.computeIfAbsent("ShipmentElement1_pickup", (k) -> new HashSet<>()) + .add(shipment.getFrom().toString()); + locationsPerShipmentElement.computeIfAbsent("ShipmentElement1_delivery", (k) -> new HashSet<>()) + .add(shipment.getTo().toString()); + } else if (shipment.getSize() == 2) { + Assertions.assertEquals(400, shipment.getPickupServiceTime(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(400, shipment.getDeliveryServiceTime(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(TimeWindow.newInstance(11000, 44000), shipment.getPickupTimeWindow()); + Assertions.assertEquals(TimeWindow.newInstance(20000, 40000), shipment.getDeliveryTimeWindow()); + locationsPerShipmentElement.computeIfAbsent("ShipmentElement2_pickup", (k) -> new HashSet<>()) + .add(shipment.getFrom().toString()); + locationsPerShipmentElement.computeIfAbsent("ShipmentElement2_delivery", (k) -> new HashSet<>()) + .add(shipment.getTo().toString()); + } else if (shipment.getSize() == 3) { + Assertions.assertEquals(600, shipment.getPickupServiceTime(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(600, shipment.getDeliveryServiceTime(), MatsimTestUtils.EPSILON); + Assertions.assertEquals(TimeWindow.newInstance(11000, 44000), shipment.getPickupTimeWindow()); + Assertions.assertEquals(TimeWindow.newInstance(20000, 40000), shipment.getDeliveryTimeWindow()); + locationsPerShipmentElement.computeIfAbsent("ShipmentElement2_pickup", (k) -> new HashSet<>()) + .add(shipment.getFrom().toString()); + locationsPerShipmentElement.computeIfAbsent("ShipmentElement2_delivery", (k) -> new HashSet<>()) + .add(shipment.getTo().toString()); + } else + Assertions.fail("Shipment has an unexpected demand."); + } + Assertions.assertEquals(15, countDemand); + Assertions.assertEquals(4, countShipmentsWithCertainDemand.getInt(0)); + Assertions.assertEquals(6, countShipmentsWithCertainDemand.getInt(2)); + Assertions.assertEquals(1, countShipmentsWithCertainDemand.getInt(3)); + Assertions.assertEquals(4, locationsPerShipmentElement.get("ShipmentElement1_pickup").size()); + Assertions.assertEquals(1, locationsPerShipmentElement.get("ShipmentElement1_delivery").size()); + Assertions.assertTrue(locationsPerShipmentElement.get("ShipmentElement1_delivery").contains("i(2,0)")); + Assertions.assertEquals(1, locationsPerShipmentElement.get("ShipmentElement2_pickup").size()); + Assertions.assertEquals(2, locationsPerShipmentElement.get("ShipmentElement2_delivery").size()); + } } diff --git a/contribs/application/test/input/org/matsim/application/avro/CSVToAvroConverterTest/conversion/exampleCSV.csv b/contribs/application/test/input/org/matsim/application/avro/CSVToAvroConverterTest/conversion/exampleCSV.csv new file mode 100755 index 00000000000..2d2e7edf390 --- /dev/null +++ b/contribs/application/test/input/org/matsim/application/avro/CSVToAvroConverterTest/conversion/exampleCSV.csv @@ -0,0 +1,1000 @@ +# EPSG:25832 +time,x,y,value +32400.0,648945.53,5456036.22,0.0 +75600.0,771945.53,5437786.22,1.232917389748582E-14 +126000.0,693445.53,5503036.22,0.0 +118800.0,647445.53,5391036.22,0.0 +14400.0,654195.53,5404286.22,2.5288708184179678E-19 +32400.0,726945.53,5426786.22,0.02577319063094685 +32400.0,637195.53,5398536.22,4.1998834179801743E-7 +57600.0,760695.53,5501036.22,0.0 +61200.0,728195.53,5369036.22,3.220922360871546E-8 +86400.0,647445.53,5458036.22,7.703710249622029E-17 +118800.0,667445.53,5437036.22,6.924712260725536E-6 +68400.0,725445.53,5405536.22,3.675837435396217E-4 +50400.0,683445.53,5506786.22,3.3186379281710923E-7 +93600.0,728695.53,5358536.22,2.3544728470023535E-8 +10800.0,760945.53,5380786.22,0.0 +122400.0,770695.53,5332536.22,0.0 +118800.0,728445.53,5500536.22,9.318650701645737E-5 +57600.0,647195.53,5470786.22,3.827718537215421E-9 +28800.0,648695.53,5424536.22,1.2083875967864239E-4 +93600.0,770445.53,5330286.22,0.0 +97200.0,725695.53,5411036.22,1.394421289790232E-5 +43200.0,631945.53,5321036.22,0.0024186498374828645 +18000.0,788445.53,5421286.22,1.384736918844948E-5 +39600.0,637695.53,5444036.22,3.3597084738402057E-25 +126000.0,744195.53,5368536.22,1.4833791879054379E-9 +64800.0,728445.53,5363786.22,1.3620862620927954E-6 +115200.0,754695.53,5452786.22,1.0870094570770482E-8 +111600.0,667195.53,5387536.22,1.364615310964844E-22 +39600.0,666695.53,5463536.22,9.797806120569641E-9 +18000.0,637695.53,5338286.22,0.0018455584671993514 +75600.0,728195.53,5337536.22,0.0 +25200.0,760445.53,5338036.22,3.5805412234133383E-19 +14400.0,683445.53,5480536.22,1.7945441124764703E-12 +54000.0,771695.53,5447536.22,6.973936391771469E-13 +46800.0,787195.53,5427286.22,2.1205296192216874E-10 +39600.0,725195.53,5443286.22,0.008056646034027044 +72000.0,682445.53,5420036.22,6.204503073487877E-4 +122400.0,647695.53,5463286.22,0.0 +54000.0,667445.53,5327036.22,1.283526885926943E-4 +0.0,717445.53,5487536.22,4.052968971908666E-13 +25200.0,698945.53,5398036.22,0.002391896004911412 +93600.0,745195.53,5391286.22,8.604917063886524E-4 +3600.0,700195.53,5330536.22,1.4971437109495422E-8 +10800.0,698695.53,5489536.22,0.0 +122400.0,725945.53,5429286.22,3.539464191481934E-4 +25200.0,683695.53,5440536.22,3.243976894132273E-12 +100800.0,789945.53,5473286.22,0.0 +21600.0,760445.53,5365286.22,1.264888754701643E-6 +90000.0,710195.53,5407286.22,8.811533626744448E-4 +86400.0,682695.53,5443286.22,2.5335972093246075E-11 +21600.0,761695.53,5446536.22,3.1182811248223256E-11 +72000.0,647945.53,5362036.22,0.0032359032476262663 +21600.0,788445.53,5377286.22,0.0 +72000.0,682695.53,5487286.22,0.0 +122400.0,789945.53,5437786.22,0.0 +10800.0,788195.53,5451786.22,0.0 +28800.0,744695.53,5487786.22,0.0012788998123037098 +118800.0,682695.53,5375786.22,7.656007159970624E-7 +0.0,640945.53,5392536.22,2.1538815017824573E-8 +100800.0,667445.53,5476786.22,2.5918212094227643E-5 +36000.0,786695.53,5392036.22,0.0 +104400.0,650445.53,5373286.22,0.0 +82800.0,760695.53,5425536.22,5.098286614069713E-6 +61200.0,760695.53,5484036.22,0.0 +72000.0,637945.53,5386536.22,2.2542420811053447E-6 +57600.0,725695.53,5503786.22,0.0022794795669787726 +28800.0,683945.53,5473036.22,0.0 +64800.0,743695.53,5366036.22,8.172065350002966E-14 +25200.0,786445.53,5413786.22,7.56573160139707E-4 +75600.0,647445.53,5480536.22,0.002667712454578127 +82800.0,745445.53,5480286.22,2.8719580850903795E-8 +21600.0,726445.53,5376286.22,1.70655524963423E-4 +118800.0,789945.53,5426286.22,0.0 +64800.0,710195.53,5456286.22,0.0 +25200.0,666945.53,5355286.22,1.1203994089590187E-9 +61200.0,665695.53,5352036.22,1.9111856046917405E-4 +46800.0,710445.53,5346286.22,1.1016103441208955E-5 +104400.0,647445.53,5418786.22,0.0 +10800.0,663695.53,5502786.22,0.0 +68400.0,637945.53,5391786.22,2.582346266134949E-7 +72000.0,771945.53,5445036.22,0.0 +54000.0,682945.53,5341536.22,0.0017490486741334166 +90000.0,647445.53,5462786.22,0.0 +14400.0,726945.53,5331536.22,0.0 +82800.0,789695.53,5446786.22,0.0 +86400.0,790445.53,5366536.22,1.348615054448121E-9 +72000.0,760195.53,5387536.22,0.0 +100800.0,710445.53,5441536.22,0.0015604665443077082 +104400.0,682945.53,5488036.22,0.0 +0.0,674445.53,5500286.22,0.0 +7200.0,653945.53,5464286.22,0.0 +122400.0,666195.53,5350786.22,1.72057939471335E-5 +61200.0,666945.53,5435286.22,5.534011155761789E-6 +57600.0,666695.53,5376536.22,8.877625097741535E-4 +111600.0,770195.53,5474036.22,0.0 +126000.0,745445.53,5392286.22,2.362330944018771E-5 +111600.0,666195.53,5373536.22,4.91794888230505E-7 +75600.0,725445.53,5382286.22,2.0716389740725109E-4 +68400.0,754945.53,5357536.22,7.453860495021012E-13 +7200.0,760945.53,5464036.22,7.477490291198621E-7 +122400.0,682695.53,5383286.22,3.2029408540309514E-5 +14400.0,637445.53,5372286.22,0.0 +90000.0,708945.53,5326036.22,1.0553331272396719E-19 +111600.0,631945.53,5398036.22,3.755899000400293E-11 +32400.0,786945.53,5476536.22,0.0 +75600.0,666945.53,5396286.22,2.075506966401299E-4 +43200.0,787445.53,5502536.22,0.0 +32400.0,667195.53,5352286.22,2.492343908610874E-5 +36000.0,789695.53,5346536.22,5.826858858773919E-10 +7200.0,653445.53,5401786.22,2.758185743098009E-9 +97200.0,725945.53,5480286.22,8.712360084152933E-10 +111600.0,647445.53,5412286.22,0.0 +82800.0,726945.53,5505286.22,0.006015170431449966 +50400.0,648945.53,5388536.22,0.0 +126000.0,630945.53,5356286.22,0.0 +32400.0,637445.53,5467536.22,0.0 +104400.0,708695.53,5489286.22,0.0 +57600.0,632445.53,5332036.22,2.1037905188525125E-8 +108000.0,789945.53,5456536.22,0.0 +14400.0,726195.53,5390536.22,7.83713044064965E-4 +10800.0,653945.53,5392536.22,4.378789305275177E-18 +28800.0,637695.53,5498536.22,4.246552386136198E-4 +111600.0,632445.53,5460286.22,2.0947804229909534E-7 +111600.0,754695.53,5459536.22,1.3666869405278142E-8 +43200.0,725445.53,5501536.22,0.0010899483919287211 +108000.0,743945.53,5345786.22,0.0 +75600.0,710195.53,5434536.22,0.0011319500762417304 +100800.0,631945.53,5420536.22,0.0 +93600.0,790445.53,5360286.22,0.0 +118800.0,728445.53,5504286.22,1.256495806040252E-4 +75600.0,789695.53,5457786.22,0.0 +39600.0,789695.53,5329786.22,9.822345711036667E-27 +104400.0,728695.53,5348536.22,0.0 +3600.0,742945.53,5504536.22,0.0 +21600.0,636945.53,5424536.22,0.0 +21600.0,742195.53,5457786.22,2.0837665095988055E-6 +64800.0,631945.53,5492286.22,0.0 +75600.0,760445.53,5390036.22,2.407904970754908E-21 +115200.0,725945.53,5423286.22,4.177729853939279E-4 +46800.0,648945.53,5399286.22,3.0265931841982404E-5 +50400.0,682195.53,5427536.22,3.217647597288719E-4 +7200.0,715695.53,5471286.22,0.0 +46800.0,760445.53,5481786.22,0.0 +100800.0,789945.53,5467036.22,0.0 +68400.0,790195.53,5342786.22,0.0 +21600.0,760195.53,5364036.22,8.091388069362037E-5 +64800.0,744945.53,5390036.22,0.00169498417455375 +43200.0,725945.53,5361036.22,1.1399538236643093E-7 +46800.0,787445.53,5496286.22,0.0 +72000.0,790195.53,5339036.22,0.0 +57600.0,710195.53,5483536.22,3.803926771001606E-9 +10800.0,776195.53,5393536.22,3.1259963618356163E-6 +43200.0,744945.53,5478036.22,2.3039412030609397E-17 +10800.0,699195.53,5353286.22,6.302518628013936E-5 +82800.0,665945.53,5363286.22,0.0 +79200.0,632695.53,5328036.22,9.75576338162119E-8 +82800.0,667195.53,5444536.22,0.0010704209411575229 +21600.0,666945.53,5366286.22,0.0 +39600.0,710445.53,5373536.22,1.1328966659453571E-8 +36000.0,664445.53,5395036.22,5.128814118801484E-7 +21600.0,648445.53,5417036.22,0.0 +93600.0,682445.53,5380036.22,7.849379677938453E-5 +126000.0,770195.53,5449286.22,0.0 +43200.0,726945.53,5379286.22,0.0017347506924268636 +64800.0,789695.53,5488536.22,0.0 +104400.0,745445.53,5437786.22,2.705745098669176E-16 +126000.0,708695.53,5454536.22,8.326507074694347E-17 +43200.0,637695.53,5431036.22,1.1613097818069644E-14 +14400.0,699945.53,5506786.22,0.0 +126000.0,755195.53,5497286.22,0.0 +82800.0,770445.53,5346536.22,0.0016973381253060475 +32400.0,726945.53,5430536.22,0.013151997768523504 +72000.0,632695.53,5355286.22,4.872215334667197E-5 +28800.0,760695.53,5371786.22,0.0019033375196090964 +118800.0,728945.53,5372536.22,7.156436742201306E-23 +43200.0,647445.53,5328786.22,1.2951662937858896E-8 +100800.0,632445.53,5482786.22,8.755651909083866E-5 +0.0,717195.53,5410286.22,0.0015722962184891239 +104400.0,667195.53,5394286.22,1.2688522119124712E-10 +57600.0,647695.53,5334286.22,0.0 +3600.0,777945.53,5495536.22,0.0 +14400.0,648195.53,5493286.22,1.1265903716605813E-9 +21600.0,638445.53,5505036.22,1.784200790558263E-7 +115200.0,667195.53,5379536.22,1.4940663216932168E-5 +43200.0,744695.53,5413036.22,0.0 +111600.0,755445.53,5332786.22,0.0 +126000.0,754695.53,5434786.22,3.120028509173332E-11 +39600.0,709695.53,5432536.22,1.1322826181922748E-4 +25200.0,649195.53,5332786.22,0.0 +68400.0,708945.53,5372036.22,3.306479915820767E-11 +54000.0,682945.53,5345286.22,0.001731388194963168 +28800.0,726695.53,5382786.22,0.003172205038090179 +82800.0,632695.53,5324786.22,3.17899685580897E-5 +90000.0,693445.53,5324286.22,5.145095146822457E-5 +39600.0,648945.53,5427036.22,0.004729345391440732 +108000.0,770695.53,5357286.22,0.0 +72000.0,647445.53,5490036.22,4.809778628440698E-4 +18000.0,648945.53,5321036.22,4.9037347024546E-12 +32400.0,699195.53,5399286.22,1.237323629630324E-4 +57600.0,745195.53,5474536.22,0.0 +115200.0,647445.53,5400536.22,2.6662147178093192E-9 +10800.0,787945.53,5383036.22,0.0 +115200.0,708695.53,5470286.22,6.587716137242722E-16 +93600.0,665945.53,5341786.22,2.2379624333314503E-7 +0.0,763695.53,5469286.22,6.188764691032071E-4 +97200.0,632195.53,5484536.22,1.6133528248147425E-4 +82800.0,789695.53,5443036.22,0.0 +36000.0,709695.53,5443036.22,0.00224129299599732 +100800.0,754695.53,5483786.22,0.0 +93600.0,760695.53,5409286.22,0.0 +54000.0,637945.53,5445286.22,3.125352759309182E-22 +79200.0,754945.53,5331286.22,0.0 +39600.0,760195.53,5497786.22,0.0 +72000.0,760695.53,5454036.22,1.996420136579322E-6 +28800.0,647195.53,5335786.22,0.0 +25200.0,742195.53,5434286.22,1.1263176054923073E-4 +7200.0,787945.53,5463286.22,0.0 +7200.0,787695.53,5404536.22,1.6840459795765696E-5 +68400.0,728445.53,5355786.22,3.6289186866362678E-6 +90000.0,745445.53,5465536.22,0.0 +79200.0,710195.53,5425036.22,0.0032643015802136708 +104400.0,631945.53,5411036.22,0.0 +75600.0,771695.53,5379036.22,5.528454894582679E-11 +104400.0,754695.53,5472286.22,0.0 +68400.0,771695.53,5395786.22,0.0040217071124737675 +100800.0,682695.53,5430286.22,1.8389858432659195E-5 +14400.0,726445.53,5459536.22,0.009347576844583485 +3600.0,680195.53,5486036.22,0.0 +122400.0,650445.53,5338036.22,0.0 +43200.0,786945.53,5427786.22,4.7187646843816215E-11 +115200.0,743445.53,5463786.22,0.0 +75600.0,760195.53,5380286.22,0.0 +75600.0,728445.53,5338786.22,3.2928204667975456E-25 +0.0,639695.53,5323536.22,4.7650161723803145E-7 +57600.0,787445.53,5437286.22,7.324873723436125E-8 +28800.0,648945.53,5481286.22,2.384085011489151E-4 +36000.0,787195.53,5458786.22,0.0 +0.0,674195.53,5445536.22,9.889581477817966E-15 +21600.0,771195.53,5480536.22,0.0 +64800.0,754945.53,5365536.22,0.002039955585829622 +90000.0,745195.53,5400786.22,0.0 +79200.0,745195.53,5422786.22,4.2679583236141074E-15 +122400.0,631945.53,5379786.22,0.0 +50400.0,760195.53,5463536.22,1.8700167398507355E-8 +68400.0,665695.53,5326036.22,4.399292880310784E-6 +50400.0,682445.53,5496536.22,0.0 +28800.0,637195.53,5423786.22,0.0 +46800.0,759945.53,5407036.22,0.0 +3600.0,638445.53,5331286.22,5.413266505499651E-5 +79200.0,647445.53,5473036.22,4.922298007484491E-6 +54000.0,637695.53,5380286.22,2.587864601353453E-6 +118800.0,743445.53,5452286.22,2.249498629203732E-7 +36000.0,682695.53,5352286.22,4.412993972805259E-16 +14400.0,744695.53,5352786.22,0.0 +50400.0,667445.53,5341786.22,2.888704287911911E-5 +46800.0,744945.53,5471786.22,0.0 +43200.0,709945.53,5474536.22,2.7566024364420876E-4 +39600.0,637445.53,5438286.22,0.001882703968844815 +82800.0,666945.53,5381536.22,9.114024622411893E-4 +82800.0,745195.53,5411286.22,0.0 +90000.0,667445.53,5497286.22,0.0 +122400.0,755445.53,5321786.22,4.833582381448485E-5 +39600.0,744695.53,5424036.22,2.3728649398982115E-10 +126000.0,682695.53,5381786.22,2.875960024139177E-6 +36000.0,744695.53,5440786.22,0.0 +50400.0,725945.53,5337536.22,2.7440768690258717E-4 +28800.0,725695.53,5368786.22,1.1877570569722132E-23 +43200.0,648945.53,5409536.22,0.0 +3600.0,635445.53,5376786.22,0.0 +32400.0,771195.53,5392536.22,5.192142604681163E-5 +82800.0,682445.53,5395786.22,0.002702586543763844 +90000.0,725945.53,5493036.22,0.0010439069183325587 +82800.0,682695.53,5463036.22,1.2330142476057988E-4 +108000.0,743445.53,5473786.22,0.0 +82800.0,725695.53,5434536.22,0.015554835748620382 +32400.0,667195.53,5356036.22,3.5660900669030516E-13 +32400.0,664195.53,5412036.22,2.8536280001337385E-4 +72000.0,725695.53,5456786.22,0.0016877412890636972 +28800.0,699195.53,5426536.22,0.003360370765514746 +57600.0,666945.53,5439536.22,0.003527705583873496 +54000.0,649195.53,5432536.22,2.231198732094981E-6 +32400.0,725195.53,5475536.22,1.226097306917035E-6 +79200.0,667195.53,5454036.22,3.9224116347950855E-11 +68400.0,647195.53,5438536.22,2.7174092505029054E-6 +104400.0,755445.53,5354036.22,0.0 +0.0,736945.53,5462036.22,9.700691855097171E-5 +0.0,735445.53,5322036.22,0.0 +75600.0,790195.53,5329786.22,0.0 +57600.0,725445.53,5445036.22,0.013486738937966652 +3600.0,758695.53,5323536.22,3.871215686363705E-4 +14400.0,636945.53,5500536.22,3.902243326256835E-4 +7200.0,680695.53,5414786.22,0.0031443524491691762 +7200.0,680945.53,5474036.22,1.5222929585878438E-19 +111600.0,770695.53,5345786.22,0.0 +21600.0,683695.53,5465786.22,0.0018974088235183164 +79200.0,682695.53,5468286.22,5.9958870364689254E-5 +10800.0,726695.53,5324786.22,2.5427683311993274E-18 +50400.0,637445.53,5404286.22,2.1253431599485543E-11 +61200.0,649195.53,5414786.22,0.0 +3600.0,653945.53,5345786.22,0.0 +7200.0,699945.53,5388286.22,0.0016526452425193819 +14400.0,698945.53,5503036.22,0.0 +126000.0,632695.53,5503786.22,0.0 +46800.0,648945.53,5403036.22,0.0 +108000.0,682695.53,5413536.22,1.5118565350287359E-6 +111600.0,789695.53,5384036.22,0.0 +111600.0,631945.53,5385786.22,0.0 +86400.0,728695.53,5366786.22,3.7537052350335664E-6 +97200.0,631945.53,5429786.22,0.0 +61200.0,745195.53,5478286.22,3.213040928756448E-15 +39600.0,787195.53,5452036.22,0.0 +46800.0,632195.53,5369286.22,1.0262487474357178E-15 +50400.0,744695.53,5389786.22,0.0015110312745235646 +97200.0,682945.53,5502786.22,1.4695140240538105E-17 +18000.0,637445.53,5332536.22,9.526541008869182E-4 +46800.0,786945.53,5421536.22,2.5672188521777682E-8 +90000.0,790445.53,5369786.22,5.309426493120606E-5 +43200.0,789945.53,5365786.22,1.5907945436135143E-12 +126000.0,682945.53,5432536.22,3.8697056201169244E-4 +61200.0,787445.53,5431036.22,2.2218420009429723E-9 +64800.0,666945.53,5416286.22,3.3796176056792366E-6 +25200.0,771195.53,5457286.22,4.929229458100236E-4 +50400.0,708695.53,5368036.22,1.0760203249223932E-7 +72000.0,787445.53,5394536.22,0.0 +7200.0,665195.53,5394786.22,2.936178859421174E-7 +39600.0,744945.53,5482786.22,1.895678718224306E-4 +104400.0,743945.53,5357286.22,0.0 +36000.0,631945.53,5357286.22,5.407585851137132E-4 +14400.0,759945.53,5373786.22,3.463798446444312E-5 +97200.0,743445.53,5498036.22,0.0 +21600.0,648195.53,5409286.22,0.0 +3600.0,715695.53,5336286.22,0.0 +97200.0,667195.53,5407036.22,1.838884331371289E-10 +50400.0,786945.53,5404536.22,1.2379921403403915E-6 +64800.0,771945.53,5460536.22,7.472146572399293E-4 +82800.0,710445.53,5480536.22,7.178184258269999E-5 +25200.0,786695.53,5478786.22,0.0 +10800.0,715695.53,5396536.22,0.0043784991223905214 +111600.0,682695.53,5393786.22,5.165760522561431E-5 +68400.0,649195.53,5376536.22,0.0 +115200.0,770695.53,5335036.22,0.0 +126000.0,728445.53,5502286.22,1.731671001912405E-12 +7200.0,778195.53,5417036.22,3.268498553937811E-11 +118800.0,682945.53,5443036.22,0.0 +28800.0,742195.53,5401536.22,2.5702663937604323E-26 +100800.0,709195.53,5366786.22,1.2765705443307971E-8 +50400.0,709945.53,5451286.22,2.3497922311377892E-8 +97200.0,682695.53,5437786.22,1.6722722522856405E-7 +43200.0,744945.53,5465786.22,2.1837781593367917E-14 +3600.0,699695.53,5462536.22,0.0 +104400.0,647695.53,5483786.22,1.0678349885646622E-7 +126000.0,710445.53,5393036.22,2.8855544826365657E-4 +18000.0,638945.53,5413286.22,0.0 +18000.0,742195.53,5489536.22,0.0028845933702770993 +100800.0,790445.53,5341286.22,0.0 +32400.0,786695.53,5409786.22,2.2857051710765733E-4 +57600.0,771945.53,5487786.22,0.0 +79200.0,755195.53,5339036.22,0.0 +0.0,720195.53,5358536.22,0.0 +18000.0,682195.53,5363786.22,0.0 +115200.0,789695.53,5381036.22,0.0 +68400.0,665695.53,5338286.22,5.858295368630776E-4 +93600.0,745445.53,5458286.22,0.0 +46800.0,709945.53,5478286.22,4.336638424063236E-4 +93600.0,665945.53,5345536.22,2.0030685877886902E-22 +10800.0,771195.53,5362036.22,7.205191240192676E-13 +25200.0,649195.53,5320536.22,5.945609969053481E-13 +111600.0,789945.53,5442786.22,0.0 +118800.0,708695.53,5460786.22,0.0 +18000.0,698945.53,5461286.22,0.0 +18000.0,663945.53,5464036.22,1.0846469955067284E-7 +25200.0,683445.53,5375536.22,7.438645754382642E-5 +43200.0,682195.53,5452786.22,3.981778025806807E-9 +39600.0,648945.53,5430786.22,2.6999851954038405E-4 +118800.0,754695.53,5441036.22,0.0 +75600.0,667195.53,5461286.22,0.0 +68400.0,647445.53,5499286.22,4.182653519106232E-5 +28800.0,771445.53,5489036.22,0.0 +79200.0,787445.53,5377536.22,0.0 +10800.0,786695.53,5367286.22,1.1383805608944162E-7 +61200.0,709945.53,5408036.22,0.013290587081964702 +14400.0,741945.53,5477786.22,0.0 +115200.0,665695.53,5493286.22,4.543039529519219E-8 +43200.0,744695.53,5400786.22,0.0 +10800.0,742195.53,5333036.22,9.003088338061256E-11 +10800.0,664445.53,5366036.22,0.0 +14400.0,761445.53,5454286.22,7.966940477804451E-6 +61200.0,725445.53,5438786.22,0.024250611890346264 +126000.0,665695.53,5479536.22,4.206071114591889E-17 +18000.0,744695.53,5322286.22,6.004593570288576E-10 +14400.0,636945.53,5504286.22,4.494430242506685E-5 +7200.0,638195.53,5382786.22,5.5239505893972375E-6 +50400.0,787445.53,5466786.22,0.0 +39600.0,682695.53,5345536.22,0.0012985149477684446 +61200.0,647695.53,5332036.22,0.0 +46800.0,637945.53,5477036.22,2.4071863898416648E-15 +50400.0,743445.53,5361536.22,0.0 +18000.0,683445.53,5446786.22,3.5150159247508354E-12 +61200.0,710195.53,5475286.22,7.856623927746471E-5 +46800.0,771695.53,5466536.22,1.2138888794870474E-7 +86400.0,770445.53,5332286.22,5.384645359939872E-13 +10800.0,638695.53,5453536.22,1.6460363137321013E-4 +46800.0,709695.53,5413286.22,0.004447369492917675 +28800.0,666945.53,5321036.22,5.108237057951959E-11 +57600.0,754695.53,5332036.22,0.0 +122400.0,728195.53,5504036.22,5.5001558972751275E-5 +18000.0,709695.53,5324536.22,0.0 +0.0,736695.53,5391036.22,2.6920152232450407E-4 +36000.0,745445.53,5369536.22,8.130468110764764E-5 +50400.0,725445.53,5465536.22,7.341060045809257E-6 +68400.0,755195.53,5363286.22,2.458194195462097E-4 +93600.0,754695.53,5498536.22,0.0 +54000.0,787195.53,5385036.22,0.0 +64800.0,745195.53,5455036.22,8.235232181833821E-4 +90000.0,665945.53,5353286.22,2.555687809079443E-5 +32400.0,648695.53,5393036.22,9.436286760413617E-9 +50400.0,632195.53,5362786.22,3.732546867441682E-4 +43200.0,787195.53,5429286.22,1.5270358433229932E-9 +36000.0,682695.53,5356036.22,0.0 +54000.0,666945.53,5463286.22,5.806329013211245E-9 +32400.0,709695.53,5465786.22,0.0 +54000.0,666695.53,5404536.22,2.2461372813846518E-4 +46800.0,637445.53,5414536.22,4.4421801666375997E-5 +122400.0,708695.53,5468286.22,0.0 +97200.0,693695.53,5359786.22,6.166620633164017E-5 +86400.0,745195.53,5393286.22,3.1171109130419613E-4 +43200.0,710445.53,5354536.22,1.8399092690044942E-6 +118800.0,770695.53,5331536.22,0.0 +50400.0,647695.53,5366536.22,3.5087809922118433E-9 +36000.0,664195.53,5397786.22,0.0021316137587873646 +50400.0,725195.53,5400786.22,2.6601875487083395E-4 +93600.0,682695.53,5445036.22,0.0 +79200.0,647945.53,5336786.22,0.0 +21600.0,725445.53,5370286.22,5.1438818639222313E-14 +54000.0,636945.53,5505036.22,1.821407317273941E-5 +61200.0,744945.53,5399036.22,0.0 +36000.0,648945.53,5452286.22,8.742889738796792E-7 +14400.0,776945.53,5468786.22,2.3640508986600065E-9 +79200.0,728445.53,5331536.22,5.115341204551519E-8 +93600.0,631945.53,5439286.22,2.14338626601389E-4 +39600.0,786945.53,5442536.22,7.3640409637327764E-6 +100800.0,709195.53,5360536.22,8.826614670540042E-7 +122400.0,667445.53,5425536.22,0.0 +25200.0,664195.53,5470036.22,4.615405790861533E-5 +7200.0,788445.53,5327036.22,1.2273043029153317E-10 +21600.0,771695.53,5354286.22,2.202838441573357E-7 +21600.0,699195.53,5484536.22,2.017042976852685E-5 +7200.0,665445.53,5463786.22,4.000304505858808E-14 +43200.0,666945.53,5497536.22,1.3028375698636578E-8 +36000.0,771195.53,5389786.22,2.4264602041991147E-5 +68400.0,745195.53,5443286.22,0.0 +32400.0,744695.53,5456286.22,5.799111697540393E-4 +57600.0,770195.53,5346536.22,0.0024549117729529683 +61200.0,789695.53,5497536.22,0.0 +68400.0,682445.53,5427536.22,2.1989946883207976E-4 +18000.0,761695.53,5476536.22,1.037471302528467E-9 +28800.0,787195.53,5499536.22,0.0 +43200.0,710445.53,5348286.22,1.824388839062635E-5 +43200.0,745445.53,5346036.22,6.17430630770012E-5 +75600.0,647195.53,5409286.22,0.0 +90000.0,667195.53,5436536.22,7.123340879041073E-5 +108000.0,725695.53,5382536.22,3.470500389562014E-5 +7200.0,715445.53,5406286.22,2.1743719548632793E-4 +7200.0,680945.53,5477786.22,0.0 +82800.0,754945.53,5323786.22,5.049720456600422E-4 +115200.0,647695.53,5465536.22,0.0 +10800.0,788195.53,5448036.22,0.0 +25200.0,698945.53,5394286.22,0.005360072885995025 +3600.0,742695.53,5431536.22,2.174849982233723E-4 +108000.0,647445.53,5409286.22,0.0 +39600.0,637945.53,5504786.22,1.9235077374988506E-6 +79200.0,665945.53,5366536.22,0.0 +64800.0,637945.53,5398786.22,6.123683695544214E-7 +0.0,736945.53,5449786.22,6.7452204257929636E-6 +108000.0,682945.53,5476536.22,0.0 +100800.0,725695.53,5393036.22,3.931540106129208E-8 +3600.0,760945.53,5332786.22,1.7453853325663566E-11 +28800.0,726945.53,5450036.22,0.019206105765447172 +115200.0,682695.53,5385286.22,5.378259831898873E-10 +64800.0,787445.53,5407786.22,1.1988914226479576E-4 +64800.0,666945.53,5420036.22,4.287758416171956E-12 +86400.0,631945.53,5439536.22,8.545476134416887E-4 +97200.0,743945.53,5370036.22,0.0 +86400.0,771945.53,5413036.22,5.060954926097419E-9 +61200.0,665695.53,5364286.22,0.0 +43200.0,709695.53,5407286.22,0.008202785960046215 +7200.0,698945.53,5368036.22,1.2754874763797484E-22 +82800.0,708945.53,5336536.22,2.341346096041145E-9 +79200.0,743695.53,5333786.22,6.853058489180706E-20 +32400.0,631945.53,5361036.22,1.7440269015722354E-6 +72000.0,771695.53,5382036.22,2.324706590212936E-10 +68400.0,771945.53,5452536.22,3.4904162155379474E-6 +50400.0,760445.53,5456536.22,0.0021738979286748264 +100800.0,682945.53,5487036.22,0.0 +90000.0,755195.53,5320786.22,0.0 +64800.0,649195.53,5396036.22,0.0013836342071890586 +50400.0,632195.53,5356536.22,2.2371671391556753E-4 +93600.0,632445.53,5501536.22,1.6681531437614066E-8 +21600.0,786445.53,5437286.22,2.811676799492209E-7 +64800.0,667195.53,5487286.22,9.431899742671508E-4 +64800.0,665695.53,5347286.22,1.5118738452139117E-8 +100800.0,665945.53,5332786.22,5.878839671949103E-8 +7200.0,743195.53,5424036.22,5.453501239025885E-12 +18000.0,725195.53,5333286.22,2.1793857695039325E-14 +7200.0,653695.53,5401286.22,1.2234390439600436E-7 +10800.0,637195.53,5360536.22,3.061550319189858E-4 +21600.0,741945.53,5403036.22,8.479801806390506E-12 +126000.0,725945.53,5419786.22,7.364102907967158E-4 +118800.0,728195.53,5503036.22,1.7708078714673641E-4 +104400.0,760695.53,5395536.22,0.0 +46800.0,647445.53,5330786.22,2.014403420346911E-17 +122400.0,632195.53,5444786.22,2.98262850425734E-15 +100800.0,693695.53,5350286.22,1.164670947445251E-5 +43200.0,760445.53,5483786.22,0.0 +86400.0,682695.53,5455536.22,4.6309344296474603E-10 +32400.0,786695.53,5413536.22,7.223148258884215E-4 +115200.0,770695.53,5338786.22,0.0 +79200.0,760445.53,5378536.22,0.0 +79200.0,789695.53,5448286.22,0.0 +39600.0,726945.53,5398286.22,5.6447909760109386E-5 +104400.0,743445.53,5493536.22,3.668607596161156E-10 +68400.0,693445.53,5349536.22,0.0012111796047769934 +104400.0,665945.53,5321286.22,0.0 +93600.0,745445.53,5462036.22,0.0 +82800.0,647945.53,5327286.22,3.486421031297122E-5 +108000.0,650445.53,5363786.22,5.525393603483974E-6 +126000.0,647445.53,5388786.22,0.0 +75600.0,745445.53,5501536.22,0.0 +100800.0,728695.53,5347536.22,0.0 +97200.0,760695.53,5406036.22,0.0 +7200.0,726445.53,5328286.22,0.0 +32400.0,771945.53,5325536.22,0.0 +118800.0,770195.53,5451286.22,1.7058361410248424E-19 +32400.0,741695.53,5506036.22,0.0 +39600.0,786945.53,5446286.22,5.9146666734073886E-15 +72000.0,760445.53,5389036.22,0.0 +100800.0,745445.53,5445036.22,0.0 +115200.0,789945.53,5444036.22,0.0 +93600.0,710445.53,5464786.22,0.0 +104400.0,789945.53,5466036.22,0.0 +21600.0,699195.53,5488286.22,3.4051460339498796E-5 +118800.0,755195.53,5499286.22,0.0 +79200.0,710445.53,5492036.22,1.9874421988806058E-4 +3600.0,670695.53,5378536.22,1.0765286575877429E-6 +104400.0,760695.53,5389286.22,0.0 +104400.0,725945.53,5457036.22,1.205638918070742E-4 +18000.0,777195.53,5495286.22,0.0 +97200.0,754695.53,5491286.22,0.0 +0.0,701945.53,5393286.22,0.0019846050787021585 +25200.0,683695.53,5446536.22,2.6081919722443583E-13 +0.0,657445.53,5342036.22,0.0 +3600.0,679945.53,5421036.22,0.0012212551585020356 +93600.0,789945.53,5496536.22,0.0 +111600.0,709195.53,5342536.22,3.1232299503084633E-28 +28800.0,771945.53,5352786.22,1.5796645703635318E-4 +104400.0,770195.53,5494786.22,0.0 +118800.0,632445.53,5447286.22,0.0 +75600.0,755195.53,5348536.22,0.0 +90000.0,647445.53,5450536.22,0.0 +100800.0,745195.53,5380286.22,0.0 +61200.0,708695.53,5339036.22,4.0749717070670595E-5 +18000.0,786945.53,5340786.22,4.221719071268786E-8 +64800.0,682695.53,5501536.22,2.0669350573360615E-16 +68400.0,710195.53,5449286.22,6.956907365907471E-6 +118800.0,647695.53,5456036.22,0.0 +68400.0,666945.53,5401036.22,3.172981390386548E-4 +28800.0,637445.53,5490786.22,2.3764513867145597E-7 +111600.0,770195.53,5477786.22,0.0 +111600.0,743445.53,5470286.22,0.0 +64800.0,787445.53,5401536.22,8.011938117571493E-15 +3600.0,776195.53,5345786.22,4.595994914988141E-14 +72000.0,728445.53,5346286.22,2.3258683301353653E-6 +7200.0,741945.53,5342786.22,7.624404247550742E-16 +115200.0,710445.53,5421536.22,1.320294080659499E-4 +28800.0,786945.53,5500036.22,0.0 +68400.0,725695.53,5470536.22,8.151370479954834E-4 +104400.0,789695.53,5401036.22,0.0 +57600.0,665695.53,5358286.22,2.945727967884297E-16 +86400.0,665945.53,5343786.22,4.063735752454977E-12 +64800.0,725695.53,5476286.22,1.4948718984344204E-5 +39600.0,771695.53,5498536.22,0.0 +10800.0,665445.53,5388536.22,0.0 +36000.0,637695.53,5450536.22,6.136306845555985E-9 +68400.0,632695.53,5362786.22,2.5050309240800265E-4 +68400.0,755195.53,5351036.22,1.0381328222949606E-4 +115200.0,632195.53,5455536.22,0.0 +108000.0,790445.53,5328536.22,0.0 +7200.0,638195.53,5397536.22,1.0794287565880763E-4 +122400.0,745445.53,5401786.22,0.0 +50400.0,709695.53,5384036.22,5.023348580380571E-4 +57600.0,647695.53,5347036.22,1.992499969088999E-5 +57600.0,709945.53,5422786.22,0.03142317411319116 +14400.0,698695.53,5435786.22,5.89301171159115E-7 +10800.0,777195.53,5328036.22,6.053045500545568E-8 +111600.0,743945.53,5338286.22,0.0 +104400.0,770195.53,5496786.22,0.0 +79200.0,665945.53,5370786.22,4.404804146985026E-9 +61200.0,760195.53,5422036.22,5.205718290775661E-5 +36000.0,771195.53,5377036.22,7.719306552323939E-12 +75600.0,754945.53,5347036.22,0.0 +115200.0,725945.53,5435536.22,4.2180425370251745E-4 +36000.0,664195.53,5385536.22,3.553940201334541E-18 +57600.0,637945.53,5430286.22,8.121610053646475E-13 +82800.0,771945.53,5420786.22,7.104600856420152E-12 +72000.0,647445.53,5502286.22,0.0010757500787333802 +122400.0,770195.53,5456786.22,8.857685918166214E-6 +100800.0,771945.53,5389786.22,0.0 +93600.0,631945.53,5427036.22,0.0 +122400.0,709195.53,5332036.22,0.0 +86400.0,631945.53,5443786.22,1.2260823067287289E-5 +93600.0,667195.53,5418536.22,2.230145232634944E-10 +64800.0,728195.53,5352286.22,9.153932673309549E-9 +36000.0,709695.53,5455286.22,1.2915993264310851E-26 +100800.0,760695.53,5394536.22,0.0 +126000.0,666195.53,5337036.22,0.0 +111600.0,788695.53,5368036.22,0.0 +7200.0,758445.53,5375286.22,8.155778641584691E-8 +18000.0,666695.53,5341286.22,5.6991182356128275E-5 +68400.0,760695.53,5469786.22,5.419242697591061E-4 +86400.0,682445.53,5376286.22,1.4727491926269225E-5 +57600.0,744945.53,5413286.22,0.0 +108000.0,667445.53,5449786.22,3.140444424988411E-8 +68400.0,744945.53,5382036.22,0.0 +25200.0,741945.53,5379786.22,1.5541347858088108E-12 +93600.0,743695.53,5320786.22,0.0 +43200.0,745445.53,5333286.22,1.5106563013707876E-19 +72000.0,745445.53,5500786.22,0.0 +68400.0,728195.53,5348036.22,2.489053972548572E-13 +118800.0,728945.53,5359786.22,0.0 +21600.0,786695.53,5498036.22,0.0 +0.0,717195.53,5422536.22,0.001968501830966975 +14400.0,744695.53,5365036.22,9.1221585815667E-14 +61200.0,708695.53,5333286.22,1.613720263419671E-7 +50400.0,666945.53,5478036.22,6.800013930923147E-5 +93600.0,710445.53,5469036.22,0.0 +28800.0,664195.53,5431536.22,0.0 +3600.0,664695.53,5403786.22,5.414235356677049E-17 +54000.0,759945.53,5375286.22,1.2335699703152942E-7 +54000.0,725945.53,5322786.22,2.108024553706377E-22 +21600.0,649195.53,5356036.22,1.4585370636257553E-6 +57600.0,682195.53,5391036.22,0.008031614662020427 +14400.0,638945.53,5449036.22,0.0 +54000.0,637445.53,5378786.22,3.1977372804437525E-6 +90000.0,667195.53,5426036.22,0.0 +43200.0,683945.53,5393786.22,0.005158638296620154 +36000.0,648945.53,5439536.22,1.4751412009472663E-24 +43200.0,789945.53,5367786.22,1.162562113100304E-6 +0.0,752445.53,5478286.22,4.965550035675677E-4 +72000.0,755195.53,5347536.22,2.763949885191577E-6 +0.0,717695.53,5484786.22,1.4790921505120023E-14 +97200.0,755445.53,5364536.22,0.0 +32400.0,664445.53,5409786.22,3.773436824829316E-8 +108000.0,760695.53,5377536.22,0.0 +64800.0,682445.53,5438536.22,1.0947948693660418E-4 +68400.0,632695.53,5356536.22,1.4328509689373646E-4 +90000.0,771945.53,5414036.22,3.487755148030314E-10 +104400.0,632445.53,5466786.22,0.0 +21600.0,726695.53,5443286.22,0.01957679831774666 +79200.0,693445.53,5325286.22,2.2256640218084308E-5 +64800.0,667195.53,5475036.22,0.002053925065957947 +64800.0,665695.53,5335036.22,4.99936018072682E-4 +68400.0,666945.53,5413286.22,0.006423852268070652 +0.0,639195.53,5454036.22,0.0 +3600.0,777695.53,5426536.22,0.0 +100800.0,665945.53,5320536.22,1.8956109001371514E-26 +50400.0,666695.53,5413036.22,0.008425189649183108 +86400.0,771945.53,5400786.22,0.0019364594355473306 +18000.0,725195.53,5337536.22,5.077429554247418E-8 +104400.0,709195.53,5365286.22,1.971093202028539E-5 +79200.0,743695.53,5348536.22,2.511558568108595E-4 +122400.0,632195.53,5432536.22,6.664990850142437E-23 +36000.0,771945.53,5322286.22,0.0 +72000.0,745195.53,5435536.22,3.4499466422824247E-6 +97200.0,771945.53,5397286.22,1.5992307436075716E-8 +50400.0,682945.53,5352036.22,3.4729166308124266E-14 +7200.0,758695.53,5442536.22,0.0 +68400.0,725695.53,5466286.22,6.934572412456316E-6 +82800.0,647945.53,5339536.22,0.0 +10800.0,761195.53,5442036.22,1.2047794421306353E-11 +64800.0,790195.53,5354536.22,5.3979245972548854E-5 +126000.0,650445.53,5328786.22,2.0150441215159144E-7 +68400.0,649195.53,5389286.22,0.0 +93600.0,632195.53,5504286.22,5.465855407693498E-6 +68400.0,771695.53,5383536.22,9.533855640440829E-9 +68400.0,789695.53,5474786.22,0.0 +21600.0,771695.53,5352536.22,3.7629826697315534E-4 +39600.0,631945.53,5331786.22,3.0371421146278063E-10 +32400.0,759945.53,5465036.22,2.7125012385296393E-9 +36000.0,637445.53,5451036.22,1.034813642070404E-7 +111600.0,665695.53,5497536.22,7.323069341443739E-13 +126000.0,632445.53,5432786.22,0.0 +79200.0,745445.53,5494036.22,7.410714550908904E-19 +118800.0,631945.53,5381036.22,3.25301881862037E-11 +97200.0,745195.53,5387536.22,1.5130766176155414E-8 +14400.0,683195.53,5409286.22,0.002933590687292336 +54000.0,632195.53,5337286.22,8.720020041469597E-11 +97200.0,790445.53,5354536.22,0.0 +64800.0,647195.53,5447536.22,7.002685516230312E-6 +46800.0,745445.53,5327036.22,3.5342391172279097E-4 +43200.0,771695.53,5485536.22,0.0 +21600.0,776945.53,5398036.22,1.7414773696481112E-12 +10800.0,742195.53,5335036.22,4.473475849820338E-15 +54000.0,760195.53,5442536.22,0.0 +36000.0,667195.53,5333786.22,1.8378830419227057E-7 +68400.0,760195.53,5395036.22,0.002394924993478955 +3600.0,758195.53,5454036.22,3.7085783812714937E-6 +104400.0,790445.53,5337786.22,0.0 +54000.0,786945.53,5389786.22,0.0 +82800.0,647195.53,5398536.22,4.3871886817178516E-4 +43200.0,760195.53,5486786.22,0.0 +90000.0,728695.53,5368036.22,0.0 +21600.0,761695.53,5440536.22,2.989641709806988E-10 +43200.0,725195.53,5436536.22,0.026108207501357967 +118800.0,743945.53,5324036.22,1.1742334146538584E-7 +0.0,752195.53,5413536.22,0.0 +14400.0,776695.53,5412036.22,2.5613840716035906E-8 +46800.0,771445.53,5412036.22,4.375598890542089E-7 +97200.0,667445.53,5476036.22,2.5796454457598176E-4 +21600.0,664445.53,5501036.22,1.737540279194381E-7 +90000.0,789945.53,5497786.22,0.0 +39600.0,744945.53,5495536.22,4.4253224802703396E-18 +68400.0,710195.53,5453536.22,1.3942143102222911E-14 +97200.0,728695.53,5351036.22,0.0 +64800.0,771945.53,5456286.22,2.1865847234250175E-4 +7200.0,683445.53,5362036.22,0.0 +25200.0,786445.53,5407786.22,8.026065519684602E-4 +43200.0,787195.53,5431286.22,1.5827825386308613E-9 +54000.0,710195.53,5503286.22,0.0 +54000.0,708695.53,5363286.22,0.0011057305764294813 +18000.0,648445.53,5461286.22,6.219269076469283E-8 +25200.0,637195.53,5458036.22,4.0837996867287504E-5 +54000.0,745195.53,5501036.22,0.0 +118800.0,630945.53,5364786.22,0.0 +118800.0,710445.53,5414036.22,8.565587556673108E-5 +46800.0,771695.53,5479286.22,0.0 +64800.0,760195.53,5398786.22,2.4202639136998005E-5 +3600.0,699445.53,5391536.22,0.006387018816369767 +126000.0,647695.53,5443536.22,0.0 +126000.0,790195.53,5495286.22,0.0 +61200.0,725445.53,5424036.22,0.03977945637981644 +118800.0,682945.53,5447286.22,0.0 +122400.0,693695.53,5321786.22,1.7788813709284076E-11 +21600.0,761695.53,5434286.22,4.967569676704496E-9 +54000.0,636945.53,5507036.22,2.2237431791522308E-7 +39600.0,682195.53,5465286.22,0.004399412228014982 +104400.0,771445.53,5506286.22,0.0 +126000.0,632695.53,5491536.22,0.0 +21600.0,787945.53,5505286.22,0.0 +18000.0,761445.53,5411536.22,4.225584747287105E-16 +100800.0,647695.53,5501536.22,1.404556870753675E-4 +64800.0,728195.53,5356036.22,7.542905197769989E-7 +97200.0,631945.53,5417536.22,0.0 +18000.0,777195.53,5482536.22,0.0 +57600.0,760195.53,5426536.22,1.3099060200611276E-4 +25200.0,683445.53,5387786.22,2.8538261992927197E-5 +97200.0,682945.53,5490536.22,0.0 +57600.0,632195.53,5320536.22,9.549522486160181E-4 +3600.0,680445.53,5487536.22,0.0 +115200.0,788695.53,5358536.22,0.0 +3600.0,777695.53,5430286.22,0.0 +7200.0,665195.53,5390536.22,0.0 +64800.0,728445.53,5351536.22,4.717398306292798E-9 +118800.0,754695.53,5445286.22,0.0 +72000.0,631945.53,5475786.22,0.0 +54000.0,725445.53,5450786.22,0.004331652944162356 +72000.0,745445.53,5504536.22,0.0 +7200.0,758695.53,5446286.22,0.0 +118800.0,682195.53,5506286.22,0.0 +21600.0,648695.53,5484036.22,3.591448861768275E-8 +3600.0,715695.53,5348536.22,1.75241866397327E-7 +86400.0,725695.53,5428786.22,0.010665336472864304 +46800.0,725445.53,5494786.22,0.008788388282194182 +3600.0,679945.53,5419036.22,8.784841176589378E-4 +54000.0,771695.53,5434786.22,7.8268207262538E-15 +36000.0,647445.53,5367286.22,1.4395826140819222E-11 +61200.0,743445.53,5330536.22,4.0275977692257783E-7 +104400.0,710195.53,5375536.22,1.1978440735699808E-9 +111600.0,790445.53,5323036.22,0.0 +75600.0,725445.53,5395036.22,2.477978385206145E-4 +61200.0,709945.53,5420786.22,0.018590116516667178 +14400.0,648945.53,5364786.22,5.349735274331209E-5 +36000.0,726945.53,5407286.22,7.467962566033564E-4 +90000.0,771945.53,5410286.22,8.773199977505344E-9 +108000.0,728695.53,5339036.22,0.0 +18000.0,709695.53,5320286.22,0.0 +32400.0,683695.53,5384786.22,5.925694861177396E-5 +90000.0,760695.53,5415036.22,5.272977891312005E-7 +79200.0,647945.53,5349036.22,0.0 +90000.0,682445.53,5385786.22,8.037768596149742E-5 +108000.0,745445.53,5426536.22,1.8093869178094046E-12 +122400.0,788695.53,5352286.22,0.0 +57600.0,743445.53,5341036.22,0.0 +32400.0,664445.53,5413536.22,0.005133115971381221 +36000.0,760695.53,5331286.22,3.2888269852934825E-13 +100800.0,667445.53,5464536.22,0.0 +43200.0,637445.53,5427536.22,9.02596555461348E-12 +7200.0,648445.53,5366036.22,2.718411208814402E-8 +43200.0,771445.53,5422536.22,3.38036636407078E-7 +54000.0,760195.53,5446286.22,0.0 +118800.0,789945.53,5438536.22,0.0 +72000.0,743695.53,5363286.22,0.0 +118800.0,693945.53,5369286.22,3.4630286639059234E-6 +0.0,659195.53,5493536.22,0.0 +54000.0,789945.53,5338036.22,0.0 +50400.0,789945.53,5354786.22,3.534158477470178E-5 +25200.0,786445.53,5401536.22,3.5940551578523725E-16 +43200.0,682695.53,5324786.22,0.0019200549864494792 +111600.0,710445.53,5417286.22,4.2501178858933976E-5 +111600.0,745445.53,5415036.22,0.0 +61200.0,744945.53,5411286.22,0.0 +28800.0,786695.53,5432786.22,2.87856294506639E-12 +100800.0,743445.53,5490786.22,0.0 +14400.0,741945.53,5473536.22,0.0 +7200.0,741445.53,5474786.22,0.0 +32400.0,666695.53,5496786.22,6.357628443353903E-8 +46800.0,637445.53,5410786.22,1.5799167137591632E-7 +97200.0,745195.53,5383786.22,0.0 +25200.0,666945.53,5343036.22,1.3469622859126334E-8 +115200.0,665695.53,5489036.22,3.1258827572125807E-6 +86400.0,667445.53,5491786.22,4.951099188738647E-4 +54000.0,760445.53,5441786.22,0.0 +25200.0,648195.53,5398286.22,0.0010125173099363842 +68400.0,647445.53,5503536.22,0.0027907538590837967 +25200.0,760195.53,5340786.22,0.0 +25200.0,682445.53,5373786.22,6.642504331210261E-6 +10800.0,654195.53,5463786.22,2.49696773205417E-13 +25200.0,726695.53,5430286.22,0.010567058491156234 +79200.0,647195.53,5408036.22,0.0 +0.0,778945.53,5410286.22,6.748861877979575E-4 +21600.0,683445.53,5398786.22,0.01335034287064519 +75600.0,682695.53,5479786.22,0.0 +54000.0,709695.53,5381536.22,5.169019903995503E-4 +118800.0,708695.53,5459036.22,0.0 +28800.0,710195.53,5365036.22,6.215443465720615E-4 +82800.0,667195.53,5432286.22,2.4149191885133423E-10 +39600.0,709945.53,5501536.22,6.680605571267877E-4 +25200.0,648445.53,5393786.22,1.4702521038578647E-6 +97200.0,632195.53,5494786.22,0.0 +86400.0,647195.53,5391036.22,0.0 +10800.0,761195.53,5445786.22,3.6034437705532865E-13 +57600.0,771695.53,5429036.22,5.157401923941465E-6 +93600.0,632195.53,5492036.22,0.0 +32400.0,667195.53,5356536.22,5.429069513971224E-15 +0.0,639195.53,5441786.22,0.0 +57600.0,649195.53,5415536.22,0.0 +28800.0,709695.53,5489036.22,2.9776196644432916E-6 +75600.0,632695.53,5337286.22,6.753087188682807E-9 +97200.0,647445.53,5444036.22,0.0 +57600.0,760195.53,5430286.22,3.354309177683619E-4 +118800.0,665695.53,5485786.22,1.1430938712768165E-19 +86400.0,760695.53,5419786.22,2.544022435908504E-4 +93600.0,725695.53,5422536.22,0.0018643432592562975 +43200.0,725445.53,5488786.22,9.583055297205931E-6 +100800.0,632195.53,5475036.22,0.0 +97200.0,632445.53,5492286.22,0.0 +21600.0,787445.53,5367536.22,1.5669037791093882E-16 +46800.0,637695.53,5408036.22,8.252244465372511E-10 +25200.0,742195.53,5444786.22,8.257593138107699E-11 +25200.0,664445.53,5477786.22,0.0010787608748686224 +75600.0,760445.53,5377286.22,0.0 +82800.0,728445.53,5324036.22,0.0 +39600.0,745445.53,5359036.22,1.3148789760733826E-16 +25200.0,761695.53,5421286.22,8.499398426183961E-6 +108000.0,632445.53,5469786.22,0.0 +108000.0,770195.53,5485286.22,0.0 +50400.0,637695.53,5391036.22,3.195607068637423E-7 +39600.0,759945.53,5434786.22,3.819386065095058E-18 +68400.0,708945.53,5368286.22,1.3692038415351366E-8 +126000.0,693945.53,5371036.22,1.4662093758831516E-6 +61200.0,667195.53,5500286.22,1.8100181453136827E-12 +21600.0,776945.53,5385786.22,2.794505152843165E-4 +86400.0,745445.53,5464536.22,1.1657986636138147E-9 +126000.0,770695.53,5321036.22,0.0 +79200.0,631945.53,5463036.22,0.0 +39600.0,710445.53,5360786.22,6.130368137469873E-4 +21600.0,664195.53,5493286.22,4.552218255363047E-10 +21600.0,663945.53,5426536.22,0.0 +104400.0,771945.53,5378286.22,0.0 +54000.0,682445.53,5473286.22,6.124694936175673E-7 +14400.0,761195.53,5385536.22,0.0 +115200.0,632445.53,5452786.22,0.0 +86400.0,647945.53,5326036.22,4.621917504063898E-5 +115200.0,630945.53,5366036.22,4.777858847718174E-6 +43200.0,760445.53,5496536.22,0.0 +21600.0,760195.53,5351786.22,5.7697141635310834E-8 +90000.0,745445.53,5477786.22,7.08043998769103E-19 +126000.0,755695.53,5369286.22,6.925050487517651E-7 +75600.0,708945.53,5351286.22,9.610789374385755E-9 +108000.0,745445.53,5430286.22,2.160150102956168E-9 +108000.0,710445.53,5433036.22,8.873912805322081E-14 +18000.0,648445.53,5449036.22,2.5344543803654593E-5 +14400.0,776695.53,5399786.22,2.5786847462619035E-10 +36000.0,787195.53,5463036.22,0.0 +90000.0,760695.53,5427286.22,3.512146754164756E-4 +21600.0,744945.53,5343036.22,0.0 +108000.0,759945.53,5506536.22,0.0 +32400.0,637195.53,5400536.22,2.574922273317259E-13 +104400.0,743445.53,5481286.22,0.0 +75600.0,728445.53,5335036.22,4.1524977109687874E-15 +68400.0,754945.53,5355536.22,3.5197883952037155E-16 +46800.0,760195.53,5484786.22,0.0 +32400.0,771945.53,5337786.22,7.121274471169096E-9 +32400.0,699195.53,5403036.22,0.010320312651680019 +104400.0,682695.53,5420786.22,2.7857674499930865E-5 +122400.0,665695.53,5482786.22,8.227941229908216E-10 +111600.0,647695.53,5466786.22,1.2291683459281997E-10 +0.0,674195.53,5433286.22,2.2888542692541078E-5 +50400.0,667445.53,5346036.22,2.621322774217271E-8 +43200.0,771445.53,5410286.22,4.203213624669235E-7 +21600.0,771195.53,5484786.22,0.0 +75600.0,693445.53,5336786.22,9.888265151963402E-4 +64800.0,693445.53,5358536.22,0.018005425261264873 +36000.0,744695.53,5445036.22,0.0 +0.0,659195.53,5481286.22,0.0 +82800.0,770445.53,5336036.22,1.1412308620109652E-7 +46800.0,787445.53,5483536.22,0.0 +122400.0,745445.53,5403536.22,0.0 +115200.0,770195.53,5469286.22,0.0 +28800.0,777195.53,5392286.22,9.769312788228006E-9 +10800.0,787945.53,5386786.22,0.0 +50400.0,743445.53,5372286.22,0.0012279895031403387 +7200.0,741945.53,5355036.22,0.0 +3600.0,741445.53,5356286.22,0.0 +10800.0,638445.53,5386536.22,4.219762305638215E-8 +43200.0,667445.53,5373286.22,1.829101226384098E-8 +86400.0,665945.53,5356036.22,1.0157281112879142E-10 +43200.0,648945.53,5413786.22,0.0 +93600.0,760695.53,5413536.22,3.128748844118135E-11 +0.0,658695.53,5418786.22,1.3654394365461458E-4 +57600.0,682445.53,5458036.22,2.990246085885282E-10 +46800.0,725445.53,5482536.22,3.6540028797324095E-4 +61200.0,771695.53,5422786.22,1.1243390369291195E-6 +32400.0,647195.53,5322786.22,2.942939364548748E-5 +122400.0,788695.53,5356036.22,0.0 +64800.0,709945.53,5391286.22,0.003044277830750037 +50400.0,771445.53,5382536.22,2.0306083727304698E-10 +61200.0,647195.53,5456286.22,1.1482494090290067E-14 +57600.0,649195.53,5419286.22,1.8160131623276394E-18 +36000.0,637695.53,5462786.22,1.3332793508106692E-4 +75600.0,760195.53,5376036.22,2.022632866238985E-10 +32400.0,683945.53,5447786.22,6.8429009234235055E-15 +46800.0,649195.53,5464286.22,4.635861967086022E-4 +122400.0,632445.53,5446286.22,1.0453449503390243E-19 +122400.0,682945.53,5440036.22,3.78606852467104E-12 +10800.0,648695.53,5365536.22,4.542339483439285E-6 +108000.0,632195.53,5468536.22,0.0 +10800.0,726195.53,5452786.22,0.007180149057002687 +10800.0,683695.53,5347286.22,0.00230753038681642 +21600.0,787445.53,5371286.22,1.5729303321059624E-15 +72000.0,754945.53,5346036.22,2.731351618716551E-9 +25200.0,663945.53,5403036.22,2.0616373713848893E-7 +86400.0,743695.53,5322786.22,4.4716946070191154E-10 +14400.0,698695.53,5432036.22,1.2840847272877054E-4 +79200.0,708945.53,5347786.22,9.926167819046839E-9 +111600.0,710445.53,5429536.22,4.635785462631024E-12 +21600.0,698945.53,5417536.22,8.996267548226817E-4 +39600.0,664195.53,5381036.22,1.2551556452621593E-5 +108000.0,728695.53,5326786.22,0.0 +72000.0,743695.53,5351036.22,7.711978217055237E-6 +118800.0,709195.53,5331036.22,1.6518170649493922E-5 +104400.0,667445.53,5465536.22,3.213003996742917E-12 +97200.0,710445.53,5457286.22,0.0 +93600.0,728695.53,5370786.22,1.998680333000411E-10 +50400.0,789945.53,5342536.22,0.0 +3600.0,680195.53,5473786.22,3.458916556898183E-7 +111600.0,728695.53,5323286.22,0.0 +111600.0,725695.53,5379286.22,3.3918699788273704E-5 +118800.0,790195.53,5501536.22,0.0 +61200.0,790195.53,5373536.22,1.4113953288418397E-6 +104400.0,693695.53,5342786.22,2.232696605007492E-4 +75600.0,665695.53,5321536.22,0.0 +108000.0,667445.53,5462036.22,1.571825374178677E-11 +79200.0,790195.53,5320536.22,8.337952441940285E-6 +32400.0,666695.53,5484536.22,1.2095572140131744E-4 +3600.0,776445.53,5353536.22,1.2983969091502E-4 +72000.0,728195.53,5336786.22,0.0 +28800.0,648945.53,5496036.22,2.3449097423890485E-11 +21600.0,637195.53,5483286.22,0.0020590068316833653 +93600.0,667195.53,5430786.22,2.0705858248079036E-15 +10800.0,741695.53,5467036.22,0.0 +3600.0,665445.53,5341036.22,4.3270754022743655E-5 +21600.0,663945.53,5430286.22,0.0 +111600.0,682695.53,5406036.22,4.8383605319359674E-5 +25200.0,648195.53,5386036.22,0.0 +18000.0,636945.53,5460536.22,5.700648829469989E-7 +61200.0,725695.53,5489036.22,4.3630559639846245E-5 +46800.0,683945.53,5395536.22,0.0073430779428884044 +0.0,781945.53,5358536.22,3.834491746528641E-14 +111600.0,667195.53,5375286.22,1.2638575193424095E-6 +18000.0,648195.53,5447786.22,9.602245852721577E-5 +122400.0,650445.53,5336286.22,0.0 +39600.0,786695.53,5377286.22,0.0 +75600.0,728195.53,5325286.22,2.79922301048081E-14 +115200.0,647445.53,5398536.22,1.7946988393066696E-5 +97200.0,667195.53,5419286.22,1.7756011044230733E-18 +57600.0,665695.53,5370536.22,4.707748420713364E-9 +0.0,763445.53,5400536.22,3.0057256295695725E-6 +32400.0,682195.53,5498536.22,1.8223163373885304E-23 \ No newline at end of file diff --git a/contribs/application/test/input/org/matsim/application/prepare/scenario/CreateScenarioCutOutTest/chessboard-cutout.cpg b/contribs/application/test/input/org/matsim/application/prepare/scenario/CreateScenarioCutOutTest/chessboard-cutout.cpg new file mode 100644 index 00000000000..3ad133c048f --- /dev/null +++ b/contribs/application/test/input/org/matsim/application/prepare/scenario/CreateScenarioCutOutTest/chessboard-cutout.cpg @@ -0,0 +1 @@ +UTF-8 \ No newline at end of file diff --git a/contribs/application/test/input/org/matsim/application/prepare/scenario/CreateScenarioCutOutTest/chessboard-cutout.dbf b/contribs/application/test/input/org/matsim/application/prepare/scenario/CreateScenarioCutOutTest/chessboard-cutout.dbf new file mode 100644 index 00000000000..80870575b3e Binary files /dev/null and b/contribs/application/test/input/org/matsim/application/prepare/scenario/CreateScenarioCutOutTest/chessboard-cutout.dbf differ diff --git a/contribs/application/test/input/org/matsim/application/prepare/scenario/CreateScenarioCutOutTest/chessboard-cutout.prj b/contribs/application/test/input/org/matsim/application/prepare/scenario/CreateScenarioCutOutTest/chessboard-cutout.prj new file mode 100644 index 00000000000..bd846aeb220 --- /dev/null +++ b/contribs/application/test/input/org/matsim/application/prepare/scenario/CreateScenarioCutOutTest/chessboard-cutout.prj @@ -0,0 +1 @@ +PROJCS["ETRS_1989_UTM_Zone_32N",GEOGCS["GCS_ETRS_1989",DATUM["D_ETRS_1989",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",9.0],PARAMETER["Scale_Factor",0.9996],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]] \ No newline at end of file diff --git a/contribs/application/test/input/org/matsim/application/prepare/scenario/CreateScenarioCutOutTest/chessboard-cutout.qix b/contribs/application/test/input/org/matsim/application/prepare/scenario/CreateScenarioCutOutTest/chessboard-cutout.qix new file mode 100644 index 00000000000..2055d185d42 Binary files /dev/null and b/contribs/application/test/input/org/matsim/application/prepare/scenario/CreateScenarioCutOutTest/chessboard-cutout.qix differ diff --git a/contribs/application/test/input/org/matsim/application/prepare/scenario/CreateScenarioCutOutTest/chessboard-cutout.shp b/contribs/application/test/input/org/matsim/application/prepare/scenario/CreateScenarioCutOutTest/chessboard-cutout.shp new file mode 100644 index 00000000000..71694c2acba Binary files /dev/null and b/contribs/application/test/input/org/matsim/application/prepare/scenario/CreateScenarioCutOutTest/chessboard-cutout.shp differ diff --git a/contribs/application/test/input/org/matsim/application/prepare/scenario/CreateScenarioCutOutTest/chessboard-cutout.shx b/contribs/application/test/input/org/matsim/application/prepare/scenario/CreateScenarioCutOutTest/chessboard-cutout.shx new file mode 100644 index 00000000000..0c04b8e2253 Binary files /dev/null and b/contribs/application/test/input/org/matsim/application/prepare/scenario/CreateScenarioCutOutTest/chessboard-cutout.shx differ diff --git a/contribs/application/test/input/org/matsim/application/prepare/scenario/CreateScenarioCutOutTest/events.xml.gz b/contribs/application/test/input/org/matsim/application/prepare/scenario/CreateScenarioCutOutTest/events.xml.gz new file mode 100644 index 00000000000..33baff0c786 Binary files /dev/null and b/contribs/application/test/input/org/matsim/application/prepare/scenario/CreateScenarioCutOutTest/events.xml.gz differ diff --git a/contribs/application/test/input/org/matsim/application/prepare/scenario/CreateScenarioCutOutTest/plans_without_facilities.xml b/contribs/application/test/input/org/matsim/application/prepare/scenario/CreateScenarioCutOutTest/plans_without_facilities.xml new file mode 100644 index 00000000000..43b065d3090 --- /dev/null +++ b/contribs/application/test/input/org/matsim/application/prepare/scenario/CreateScenarioCutOutTest/plans_without_facilities.xml @@ -0,0 +1,6119 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/contribs/application/test/input/org/matsim/application/prepare/scenario/CreateScenarioCutOutTest/withEvents/cut_change_events.xml b/contribs/application/test/input/org/matsim/application/prepare/scenario/CreateScenarioCutOutTest/withEvents/cut_change_events.xml new file mode 100644 index 00000000000..7f5645d4767 --- /dev/null +++ b/contribs/application/test/input/org/matsim/application/prepare/scenario/CreateScenarioCutOutTest/withEvents/cut_change_events.xml @@ -0,0 +1,20284 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/contribs/application/test/input/org/matsim/application/prepare/scenario/CreateScenarioCutOutTest/withEvents/cut_facilities.xml b/contribs/application/test/input/org/matsim/application/prepare/scenario/CreateScenarioCutOutTest/withEvents/cut_facilities.xml new file mode 100644 index 00000000000..a0c594d3192 --- /dev/null +++ b/contribs/application/test/input/org/matsim/application/prepare/scenario/CreateScenarioCutOutTest/withEvents/cut_facilities.xml @@ -0,0 +1,255 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/contribs/application/test/input/org/matsim/application/prepare/scenario/CreateScenarioCutOutTest/withEvents/cut_network.xml b/contribs/application/test/input/org/matsim/application/prepare/scenario/CreateScenarioCutOutTest/withEvents/cut_network.xml new file mode 100644 index 00000000000..4c70637cf82 --- /dev/null +++ b/contribs/application/test/input/org/matsim/application/prepare/scenario/CreateScenarioCutOutTest/withEvents/cut_network.xml @@ -0,0 +1,1258 @@ + + + + + + EPSG:25832 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + 1 + + + + + 10 + 1 + + + + + 100 + 1 + + + + + 101 + 1 + + + + + 102 + 1 + + + + + 103 + 1 + + + + + 104 + 1 + + + + + 105 + 1 + + + + + 106 + 1 + + + + + 107 + 1 + + + + + 108 + 1 + + + + + 109 + 1 + + + + + 11 + 1 + + + + + 110 + 1 + + + + + 111 + 1 + + + + + 112 + 1 + + + + + 113 + 1 + + + + + 114 + 1 + + + + + 115 + 1 + + + + + 116 + 1 + + + + + 117 + 1 + + + + + 118 + 1 + + + + + 119 + 1 + + + + + 12 + 1 + + + + + 120 + 1 + + + + + 121 + 1 + + + + + 127 + 1 + + + + + 128 + 1 + + + + + 129 + 1 + + + + + 13 + 1 + + + + + 130 + 1 + + + + + 131 + 1 + + + + + 132 + 1 + + + + + 134 + 1 + + + + + 135 + 1 + + + + + 136 + 1 + + + + + 137 + 1 + + + + + 138 + 1 + + + + + 139 + 1 + + + + + 14 + 1 + + + + + 140 + 1 + + + + + 141 + 1 + + + + + 142 + 1 + + + + + 143 + 1 + + + + + 144 + 1 + + + + + 145 + 1 + + + + + 146 + 1 + + + + + 147 + 1 + + + + + 148 + 1 + + + + + 149 + 1 + + + + + 15 + 1 + + + + + 150 + 1 + + + + + 151 + 1 + + + + + 152 + 1 + + + + + 153 + 1 + + + + + 154 + 1 + + + + + 155 + 1 + + + + + 156 + 1 + + + + + 157 + 1 + + + + + 158 + 1 + + + + + 159 + 1 + + + + + 16 + 1 + + + + + 160 + 1 + + + + + 161 + 1 + + + + + 162 + 1 + + + + + 163 + 1 + + + + + 165 + 1 + + + + + 166 + 1 + + + + + 167 + 1 + + + + + 168 + 1 + + + + + 169 + 1 + + + + + 17 + 1 + + + + + 170 + 1 + + + + + 171 + 1 + + + + + 172 + 1 + + + + + 173 + 1 + + + + + 174 + 1 + + + + + 175 + 1 + + + + + 176 + 1 + + + + + 177 + 1 + + + + + 178 + 1 + + + + + 179 + 1 + + + + + 18 + 1 + + + + + 180 + 1 + + + + + 19 + 1 + + + + + 2 + 1 + + + + + 20 + 1 + + + + + 21 + 1 + + + + + 22 + 1 + + + + + 23 + 1 + + + + + 24 + 1 + + + + + 25 + 1 + + + + + 26 + 1 + + + + + 27 + 1 + + + + + 28 + 1 + + + + + 29 + 1 + + + + + 3 + 1 + + + + + 30 + 1 + + + + + 31 + 1 + + + + + 32 + 1 + + + + + 33 + 1 + + + + + 34 + 1 + + + + + 35 + 1 + + + + + 36 + 1 + + + + + 37 + 1 + + + + + 38 + 1 + + + + + 39 + 1 + + + + + 4 + 1 + + + + + 40 + 1 + + + + + 41 + 1 + + + + + 42 + 1 + + + + + 43 + 1 + + + + + 44 + 1 + + + + + 45 + 1 + + + + + 46 + 1 + + + + + 47 + 1 + + + + + 48 + 1 + + + + + 49 + 1 + + + + + 5 + 1 + + + + + 50 + 1 + + + + + 51 + 1 + + + + + 52 + 1 + + + + + 53 + 1 + + + + + 54 + 1 + + + + + 55 + 1 + + + + + 56 + 1 + + + + + 57 + 1 + + + + + 58 + 1 + + + + + 59 + 1 + + + + + 6 + 1 + + + + + 60 + 1 + + + + + 61 + 1 + + + + + 62 + 1 + + + + + 63 + 1 + + + + + 64 + 1 + + + + + 65 + 1 + + + + + 66 + 1 + + + + + 67 + 1 + + + + + 68 + 1 + + + + + 69 + 1 + + + + + 7 + 1 + + + + + 70 + 1 + + + + + 71 + 1 + + + + + 72 + 1 + + + + + 73 + 1 + + + + + 74 + 1 + + + + + 75 + 1 + + + + + 76 + 1 + + + + + 77 + 1 + + + + + 78 + 1 + + + + + 79 + 1 + + + + + 8 + 1 + + + + + 80 + 1 + + + + + 81 + 1 + + + + + 82 + 1 + + + + + 83 + 1 + + + + + 84 + 1 + + + + + 85 + 1 + + + + + 86 + 1 + + + + + 87 + 1 + + + + + 88 + 1 + + + + + 89 + 1 + + + + + 9 + 1 + + + + + 90 + 1 + + + + + 91 + 1 + + + + + 92 + 1 + + + + + 93 + 1 + + + + + 94 + 1 + + + + + 95 + 1 + + + + + 96 + 1 + + + + + 97 + 1 + + + + + 98 + 1 + + + + + 99 + 1 + + + + + + + diff --git a/contribs/application/test/input/org/matsim/application/prepare/scenario/CreateScenarioCutOutTest/withEvents/cut_population.xml b/contribs/application/test/input/org/matsim/application/prepare/scenario/CreateScenarioCutOutTest/withEvents/cut_population.xml new file mode 100644 index 00000000000..b8cdc8c384b --- /dev/null +++ b/contribs/application/test/input/org/matsim/application/prepare/scenario/CreateScenarioCutOutTest/withEvents/cut_population.xml @@ -0,0 +1,2588 @@ + + + + + + + EPSG:25832 + + + + + + + + 30 + + + + + + + + + + + + + + + + + + + + + + + + + 37 + + + + + + + + + + + + + + + + + + + + + + + + + 56 + + + + + + + + + + + + + + + + + + + + + + + + + 74 + + + + + + + + + + + + + + + + + + + + + + + + + 67 + + + + + + + + + + + + + + + + + + + + + + + + + 38 + + + + + + + + + + + + + + + + + + + + + + + + + 63 + + + + + + + + + + + + + + + + + + + + + + + + + 9 + + + + + + + + + + + + + + + + + + + + + + + + + 66 + + + + + + + + + + + + + + + + + + + + + + + + + 45 + + + + + + + + + + + + + + + + + + + + + + + + + 76 + + + + + + + + + + + + + + + + + + + + + + + + + 26 + + + + + + + + + + + + + + + + + + + + + + + + + 8 + + + + + + + + + + + + + + + + + + + + + + + + + 31 + + + + + + + + + + + + + + + + + + + + + + + + + 27 + + + + + + + + + + + + + + + + + + + + + + + + + 86 + + + + + + + + + + + + + + + + + + + + + + + + + 97 + + + + + + + + + + + + + + + + + + + + + + + + + 50 + + + + + + + + + + + + + + + + + + + + + + + + + 92 + + + + + + + + + + + + + + + + + + + + + + + + + 44 + + + + + + + + + + + + + + + + + + + + + + + + + 58 + + + + + + + + + + + + + + + + + + + + + + + + + 10 + + + + + + + + + + + + + + + + + + + + + + + + + 72 + + + + + + + + + + + + + + + + + + + + + + + + + 45 + + + + + + + + + + + + + + + + + + + + + + + + + 9 + + + + + + + + + + + + + + + + + + + + + + + + + 93 + + + + + + + + + + + + + + + + + + + + + + + + + 94 + + + + + + + + + + + + + + + + + + + + + + + + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + 56 + + + + + + + + + + + + + + + + + + + + + + + + + 58 + + + + + + + + + + + + + + + + + + + + + + + + + 11 + + + + + + + + + + + + + + + + + + + + + + + + + 4 + + + + + + + + + + + + + + + + + + + + + + + + + 25 + + + + + + + + + + + + + + + + + + + + + + + + + 12 + + + + + + + + + + + + + + + + + + + + + + + + + 72 + + + + + + + + + + + + + + + + + + + + + + + + + 63 + + + + + + + + + + + + + + + + + + + + + + + + + 32 + + + + + + + + + + + + + + + + + + + + + + + + + 84 + + + + + + + + + + + + + + + + + + + + + + + + + 60 + + + + + + + + + + + + + + + + + + + + + + + + + 92 + + + + + + + + + + + + + + + + + + + + + + + + + 61 + + + + + + + + + + + + + + + + + + + + + + + + + 39 + + + + + + + + + + + + + + + + + + + + + + + + + 55 + + + + + + + + + + + + + + + + + + + + + + + + + 81 + + + + + + + + + + + + + + + + + + + + + + + + + 37 + + + + + + + + + + + + + + + + + + + + + + + + + 73 + + + + + + + + + + + + + + + + + + + + + + + + + 72 + + + + + + + + + + + + + + + + + + + + + + + + + 8 + + + + + + + + + + + + + + + + + + + + + + + + + 80 + + + + + + + + + + + + + + + + + + + + + + + + + 5 + + + + + + + + + + + + + + + + + + + + + + + + + 88 + + + + + + + + + + + + + + + + + + + + + + + + + 61 + + + + + + + + + + + + + + + + + + + + + + + + + 57 + + + + + + + + + + + + + + + + + + + + + + + + + 38 + + + + + + + + + + + + + + + + + + + + + + + + + 22 + + + + + + + + + + + + + + + + + + + + + + + + + 92 + + + + + + + + + + + + + + + + + + + + + + + + + 74 + + + + + + + + + + + + + + + + + + + + + + + + + 76 + + + + + + + + + + + + + + + + + + + + + + + + + 80 + + + + + + + + + + + + + + + + + + + + + + + + + 37 + + + + + + + + + + + + + + + + + + + + + + + + + 11 + + + + + + + + + + + + + + + + + + + + + + + + + 41 + + + + + + + + + + + + + + + + + + + + + + + + + 76 + + + + + + + + + + + + + + + + + + + + + + + + + 23 + + + + + + + + + + + + + + + + + + + + + + + + + 84 + + + + + + + + + + + + + + + + + + + + + + + + + 36 + + + + + + + + + + + + + + + + + + + + + + + + + 2 + + + + + + + + + + + + + + + + + + + + + + + + + 23 + + + + + + + + + + + + + + + + + + + + + + + + + 58 + + + + + + + + + + + + + + + + + + + + + + + + + 55 + + + + + + + + + + + + + + + + + + + + + + + + + 40 + + + + + + + + + + + + + + + + + + + + + + + + + 64 + + + + + + + + + + + + + + + + + + + + + + + + + 5 + + + + + + + + + + + + + + + + + + + + + + + + + 43 + + + + + + + + + + + + + + + + + + + + + + + + + 87 + + + + + + + + + + + + + + + + + + + + + + + + + 88 + + + + + + + + + + + + + + + + + + + + + + + + + 92 + + + + + + + + + + + + + + + + + + + + + + + + + 77 + + + + + + + + + + + + + + + + + + + + + + + + + 15 + + + + + + + + + + + + + + + + + + + + + + + + + 8 + + + + + + + + + + + + + + + + + + + + + + + + + 59 + + + + + + + + + + + + + + + + + + + + + + + + + 39 + + + + + + + + + + + + + + + + + + + + + + + + + 64 + + + + + + + + + + + + + + + + + + + + + + + + + 69 + + + + + + + + + + + + + + + + + + + + + + + + + 26 + + + + + + + + + + + + + + + + + + + + + + + + + 76 + + + + + + + + + + + + + + + + + + + + + + + + + 47 + + + + + + + + + + + + + + + + + + + + + + + + + 30 + + + + + + + + + + + + + + + + + + + + + + + + + 34 + + + + + + + + + + + + + + + + + + + + + + + + + 43 + + + + + + + + + + + + + + + + + + + + + + + + + 30 + + + + + + + + + + + + + + + + + + + + + + + + + 37 + + + + + + + + + + + + + + + + + + + + + + + + + 38 + + + + + + + + + + + + + + + + + + + + + + + + + 45 + + + + + + + + + + + + + + + + + + + + + + + + + 68 + + + + + + + + + + + + + + + + + + + + + + + + + 35 + + + + + + + + + + + + + + + + + + + + + + + + + 12 + + + + + + + + + + + + + + + + + + + + + + + + + 20 + + + + + + + + + + + + + + + + + + + + + + + + + 33 + + + + + + + + + + + + + + + + + + + + + + + + + 24 + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + + + + + + + + + + + + + + + + + + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + 26 + + + + + + + + + + + + + + + + + + + + + + + diff --git a/contribs/application/test/input/org/matsim/application/prepare/scenario/CreateScenarioCutOutTest/withoutEvents/cut_facilities.xml b/contribs/application/test/input/org/matsim/application/prepare/scenario/CreateScenarioCutOutTest/withoutEvents/cut_facilities.xml new file mode 100644 index 00000000000..a0c594d3192 --- /dev/null +++ b/contribs/application/test/input/org/matsim/application/prepare/scenario/CreateScenarioCutOutTest/withoutEvents/cut_facilities.xml @@ -0,0 +1,255 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/contribs/application/test/input/org/matsim/application/prepare/scenario/CreateScenarioCutOutTest/withoutEvents/cut_network.xml b/contribs/application/test/input/org/matsim/application/prepare/scenario/CreateScenarioCutOutTest/withoutEvents/cut_network.xml new file mode 100644 index 00000000000..b5c2b9a3cbc --- /dev/null +++ b/contribs/application/test/input/org/matsim/application/prepare/scenario/CreateScenarioCutOutTest/withoutEvents/cut_network.xml @@ -0,0 +1,1258 @@ + + + + + + EPSG:25832 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + 1 + + + + + 10 + 1 + + + + + 100 + 1 + + + + + 101 + 1 + + + + + 102 + 1 + + + + + 103 + 1 + + + + + 104 + 1 + + + + + 105 + 1 + + + + + 106 + 1 + + + + + 107 + 1 + + + + + 108 + 1 + + + + + 109 + 1 + + + + + 11 + 1 + + + + + 110 + 1 + + + + + 111 + 1 + + + + + 112 + 1 + + + + + 113 + 1 + + + + + 114 + 1 + + + + + 115 + 1 + + + + + 116 + 1 + + + + + 117 + 1 + + + + + 118 + 1 + + + + + 119 + 1 + + + + + 12 + 1 + + + + + 120 + 1 + + + + + 121 + 1 + + + + + 127 + 1 + + + + + 128 + 1 + + + + + 129 + 1 + + + + + 13 + 1 + + + + + 130 + 1 + + + + + 131 + 1 + + + + + 132 + 1 + + + + + 134 + 1 + + + + + 135 + 1 + + + + + 136 + 1 + + + + + 137 + 1 + + + + + 138 + 1 + + + + + 139 + 1 + + + + + 14 + 1 + + + + + 140 + 1 + + + + + 141 + 1 + + + + + 142 + 1 + + + + + 143 + 1 + + + + + 144 + 1 + + + + + 145 + 1 + + + + + 146 + 1 + + + + + 147 + 1 + + + + + 148 + 1 + + + + + 149 + 1 + + + + + 15 + 1 + + + + + 150 + 1 + + + + + 151 + 1 + + + + + 152 + 1 + + + + + 153 + 1 + + + + + 154 + 1 + + + + + 155 + 1 + + + + + 156 + 1 + + + + + 157 + 1 + + + + + 158 + 1 + + + + + 159 + 1 + + + + + 16 + 1 + + + + + 160 + 1 + + + + + 161 + 1 + + + + + 162 + 1 + + + + + 163 + 1 + + + + + 165 + 1 + + + + + 166 + 1 + + + + + 167 + 1 + + + + + 168 + 1 + + + + + 169 + 1 + + + + + 17 + 1 + + + + + 170 + 1 + + + + + 171 + 1 + + + + + 172 + 1 + + + + + 173 + 1 + + + + + 174 + 1 + + + + + 175 + 1 + + + + + 176 + 1 + + + + + 177 + 1 + + + + + 178 + 1 + + + + + 179 + 1 + + + + + 18 + 1 + + + + + 180 + 1 + + + + + 19 + 1 + + + + + 2 + 1 + + + + + 20 + 1 + + + + + 21 + 1 + + + + + 22 + 1 + + + + + 23 + 1 + + + + + 24 + 1 + + + + + 25 + 1 + + + + + 26 + 1 + + + + + 27 + 1 + + + + + 28 + 1 + + + + + 29 + 1 + + + + + 3 + 1 + + + + + 30 + 1 + + + + + 31 + 1 + + + + + 32 + 1 + + + + + 33 + 1 + + + + + 34 + 1 + + + + + 35 + 1 + + + + + 36 + 1 + + + + + 37 + 1 + + + + + 38 + 1 + + + + + 39 + 1 + + + + + 4 + 1 + + + + + 40 + 1 + + + + + 41 + 1 + + + + + 42 + 1 + + + + + 43 + 1 + + + + + 44 + 1 + + + + + 45 + 1 + + + + + 46 + 1 + + + + + 47 + 1 + + + + + 48 + 1 + + + + + 49 + 1 + + + + + 5 + 1 + + + + + 50 + 1 + + + + + 51 + 1 + + + + + 52 + 1 + + + + + 53 + 1 + + + + + 54 + 1 + + + + + 55 + 1 + + + + + 56 + 1 + + + + + 57 + 1 + + + + + 58 + 1 + + + + + 59 + 1 + + + + + 6 + 1 + + + + + 60 + 1 + + + + + 61 + 1 + + + + + 62 + 1 + + + + + 63 + 1 + + + + + 64 + 1 + + + + + 65 + 1 + + + + + 66 + 1 + + + + + 67 + 1 + + + + + 68 + 1 + + + + + 69 + 1 + + + + + 7 + 1 + + + + + 70 + 1 + + + + + 71 + 1 + + + + + 72 + 1 + + + + + 73 + 1 + + + + + 74 + 1 + + + + + 75 + 1 + + + + + 76 + 1 + + + + + 77 + 1 + + + + + 78 + 1 + + + + + 79 + 1 + + + + + 8 + 1 + + + + + 80 + 1 + + + + + 81 + 1 + + + + + 82 + 1 + + + + + 83 + 1 + + + + + 84 + 1 + + + + + 85 + 1 + + + + + 86 + 1 + + + + + 87 + 1 + + + + + 88 + 1 + + + + + 89 + 1 + + + + + 9 + 1 + + + + + 90 + 1 + + + + + 91 + 1 + + + + + 92 + 1 + + + + + 93 + 1 + + + + + 94 + 1 + + + + + 95 + 1 + + + + + 96 + 1 + + + + + 97 + 1 + + + + + 98 + 1 + + + + + 99 + 1 + + + + + + + diff --git a/contribs/application/test/input/org/matsim/application/prepare/scenario/CreateScenarioCutOutTest/withoutEvents/cut_population.xml b/contribs/application/test/input/org/matsim/application/prepare/scenario/CreateScenarioCutOutTest/withoutEvents/cut_population.xml new file mode 100644 index 00000000000..b8cdc8c384b --- /dev/null +++ b/contribs/application/test/input/org/matsim/application/prepare/scenario/CreateScenarioCutOutTest/withoutEvents/cut_population.xml @@ -0,0 +1,2588 @@ + + + + + + + EPSG:25832 + + + + + + + + 30 + + + + + + + + + + + + + + + + + + + + + + + + + 37 + + + + + + + + + + + + + + + + + + + + + + + + + 56 + + + + + + + + + + + + + + + + + + + + + + + + + 74 + + + + + + + + + + + + + + + + + + + + + + + + + 67 + + + + + + + + + + + + + + + + + + + + + + + + + 38 + + + + + + + + + + + + + + + + + + + + + + + + + 63 + + + + + + + + + + + + + + + + + + + + + + + + + 9 + + + + + + + + + + + + + + + + + + + + + + + + + 66 + + + + + + + + + + + + + + + + + + + + + + + + + 45 + + + + + + + + + + + + + + + + + + + + + + + + + 76 + + + + + + + + + + + + + + + + + + + + + + + + + 26 + + + + + + + + + + + + + + + + + + + + + + + + + 8 + + + + + + + + + + + + + + + + + + + + + + + + + 31 + + + + + + + + + + + + + + + + + + + + + + + + + 27 + + + + + + + + + + + + + + + + + + + + + + + + + 86 + + + + + + + + + + + + + + + + + + + + + + + + + 97 + + + + + + + + + + + + + + + + + + + + + + + + + 50 + + + + + + + + + + + + + + + + + + + + + + + + + 92 + + + + + + + + + + + + + + + + + + + + + + + + + 44 + + + + + + + + + + + + + + + + + + + + + + + + + 58 + + + + + + + + + + + + + + + + + + + + + + + + + 10 + + + + + + + + + + + + + + + + + + + + + + + + + 72 + + + + + + + + + + + + + + + + + + + + + + + + + 45 + + + + + + + + + + + + + + + + + + + + + + + + + 9 + + + + + + + + + + + + + + + + + + + + + + + + + 93 + + + + + + + + + + + + + + + + + + + + + + + + + 94 + + + + + + + + + + + + + + + + + + + + + + + + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + 56 + + + + + + + + + + + + + + + + + + + + + + + + + 58 + + + + + + + + + + + + + + + + + + + + + + + + + 11 + + + + + + + + + + + + + + + + + + + + + + + + + 4 + + + + + + + + + + + + + + + + + + + + + + + + + 25 + + + + + + + + + + + + + + + + + + + + + + + + + 12 + + + + + + + + + + + + + + + + + + + + + + + + + 72 + + + + + + + + + + + + + + + + + + + + + + + + + 63 + + + + + + + + + + + + + + + + + + + + + + + + + 32 + + + + + + + + + + + + + + + + + + + + + + + + + 84 + + + + + + + + + + + + + + + + + + + + + + + + + 60 + + + + + + + + + + + + + + + + + + + + + + + + + 92 + + + + + + + + + + + + + + + + + + + + + + + + + 61 + + + + + + + + + + + + + + + + + + + + + + + + + 39 + + + + + + + + + + + + + + + + + + + + + + + + + 55 + + + + + + + + + + + + + + + + + + + + + + + + + 81 + + + + + + + + + + + + + + + + + + + + + + + + + 37 + + + + + + + + + + + + + + + + + + + + + + + + + 73 + + + + + + + + + + + + + + + + + + + + + + + + + 72 + + + + + + + + + + + + + + + + + + + + + + + + + 8 + + + + + + + + + + + + + + + + + + + + + + + + + 80 + + + + + + + + + + + + + + + + + + + + + + + + + 5 + + + + + + + + + + + + + + + + + + + + + + + + + 88 + + + + + + + + + + + + + + + + + + + + + + + + + 61 + + + + + + + + + + + + + + + + + + + + + + + + + 57 + + + + + + + + + + + + + + + + + + + + + + + + + 38 + + + + + + + + + + + + + + + + + + + + + + + + + 22 + + + + + + + + + + + + + + + + + + + + + + + + + 92 + + + + + + + + + + + + + + + + + + + + + + + + + 74 + + + + + + + + + + + + + + + + + + + + + + + + + 76 + + + + + + + + + + + + + + + + + + + + + + + + + 80 + + + + + + + + + + + + + + + + + + + + + + + + + 37 + + + + + + + + + + + + + + + + + + + + + + + + + 11 + + + + + + + + + + + + + + + + + + + + + + + + + 41 + + + + + + + + + + + + + + + + + + + + + + + + + 76 + + + + + + + + + + + + + + + + + + + + + + + + + 23 + + + + + + + + + + + + + + + + + + + + + + + + + 84 + + + + + + + + + + + + + + + + + + + + + + + + + 36 + + + + + + + + + + + + + + + + + + + + + + + + + 2 + + + + + + + + + + + + + + + + + + + + + + + + + 23 + + + + + + + + + + + + + + + + + + + + + + + + + 58 + + + + + + + + + + + + + + + + + + + + + + + + + 55 + + + + + + + + + + + + + + + + + + + + + + + + + 40 + + + + + + + + + + + + + + + + + + + + + + + + + 64 + + + + + + + + + + + + + + + + + + + + + + + + + 5 + + + + + + + + + + + + + + + + + + + + + + + + + 43 + + + + + + + + + + + + + + + + + + + + + + + + + 87 + + + + + + + + + + + + + + + + + + + + + + + + + 88 + + + + + + + + + + + + + + + + + + + + + + + + + 92 + + + + + + + + + + + + + + + + + + + + + + + + + 77 + + + + + + + + + + + + + + + + + + + + + + + + + 15 + + + + + + + + + + + + + + + + + + + + + + + + + 8 + + + + + + + + + + + + + + + + + + + + + + + + + 59 + + + + + + + + + + + + + + + + + + + + + + + + + 39 + + + + + + + + + + + + + + + + + + + + + + + + + 64 + + + + + + + + + + + + + + + + + + + + + + + + + 69 + + + + + + + + + + + + + + + + + + + + + + + + + 26 + + + + + + + + + + + + + + + + + + + + + + + + + 76 + + + + + + + + + + + + + + + + + + + + + + + + + 47 + + + + + + + + + + + + + + + + + + + + + + + + + 30 + + + + + + + + + + + + + + + + + + + + + + + + + 34 + + + + + + + + + + + + + + + + + + + + + + + + + 43 + + + + + + + + + + + + + + + + + + + + + + + + + 30 + + + + + + + + + + + + + + + + + + + + + + + + + 37 + + + + + + + + + + + + + + + + + + + + + + + + + 38 + + + + + + + + + + + + + + + + + + + + + + + + + 45 + + + + + + + + + + + + + + + + + + + + + + + + + 68 + + + + + + + + + + + + + + + + + + + + + + + + + 35 + + + + + + + + + + + + + + + + + + + + + + + + + 12 + + + + + + + + + + + + + + + + + + + + + + + + + 20 + + + + + + + + + + + + + + + + + + + + + + + + + 33 + + + + + + + + + + + + + + + + + + + + + + + + + 24 + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + + + + + + + + + + + + + + + + + + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + 26 + + + + + + + + + + + + + + + + + + + + + + + diff --git a/contribs/cadytsIntegration/src/main/java/org/matsim/contrib/cadyts/car/PlansTranslatorBasedOnEvents.java b/contribs/cadytsIntegration/src/main/java/org/matsim/contrib/cadyts/car/PlansTranslatorBasedOnEvents.java index 90327b37b1e..1a325f8b4fe 100644 --- a/contribs/cadytsIntegration/src/main/java/org/matsim/contrib/cadyts/car/PlansTranslatorBasedOnEvents.java +++ b/contribs/cadytsIntegration/src/main/java/org/matsim/contrib/cadyts/car/PlansTranslatorBasedOnEvents.java @@ -59,8 +59,6 @@ public final class PlansTranslatorBasedOnEvents implements PlansTranslator private int iteration = -1; - // this is _only_ there for output: - Set plansEverSeen = new HashSet<>(); private static final String STR_PLANSTEPFACTORY = "planStepFactory"; private static final String STR_ITERATION = "iteration"; @@ -167,9 +165,6 @@ private PlanBuilder getPlanStepFactoryForPlan(final Plan selectedPlan) { // construct a new PlanBulder and attach it to the plan: planStepFactory = new PlanBuilder(); selectedPlan.getCustomAttributes().put(STR_PLANSTEPFACTORY, planStepFactory); - - // memorize the plan as being seen: - this.plansEverSeen.add(selectedPlan); } return planStepFactory; diff --git a/contribs/commercialTrafficApplications/src/main/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/TourPlanning.java b/contribs/commercialTrafficApplications/src/main/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/TourPlanning.java index 2c1e9d82e2e..3abe204e4ba 100644 --- a/contribs/commercialTrafficApplications/src/main/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/TourPlanning.java +++ b/contribs/commercialTrafficApplications/src/main/java/org/matsim/contrib/commercialTrafficApplications/jointDemand/TourPlanning.java @@ -176,6 +176,7 @@ static void runTourPlanningForCarriers(Carriers carriers, Scenario scenario, VRP // plans log.info("routing for carrier " + carrier.getId() + " finished. Tour planning plus routing took " + (System.currentTimeMillis() - start) / 1000 + " seconds."); + carrier.addPlan(carrierPlan); carrier.setSelectedPlan(carrierPlan); })).get(); ; diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/DrtWithExtensionsConfigGroup.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/DrtWithExtensionsConfigGroup.java index 0db7bda1d6a..030df0edc4a 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/DrtWithExtensionsConfigGroup.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/DrtWithExtensionsConfigGroup.java @@ -20,16 +20,20 @@ package org.matsim.contrib.drt.extension; import java.util.Optional; +import java.util.function.Supplier; import javax.annotation.Nullable; import org.matsim.contrib.drt.extension.companions.DrtCompanionParams; +import org.matsim.contrib.drt.extension.services.services.params.DrtServicesParams; import org.matsim.contrib.drt.extension.operations.DrtOperationsParams; +import org.matsim.contrib.drt.optimizer.constraints.DefaultDrtOptimizationConstraintsSet; +import org.matsim.contrib.drt.optimizer.constraints.DrtOptimizationConstraintsSet; import org.matsim.contrib.drt.run.DrtConfigGroup; /** * @author Steffen Axer - * + *

* This class summarizes all optional drt parametersets and should be used while creating MultiModeDrtConfigGroup instances */ public class DrtWithExtensionsConfigGroup extends DrtConfigGroup { @@ -40,14 +44,26 @@ public class DrtWithExtensionsConfigGroup extends DrtConfigGroup { @Nullable private DrtOperationsParams drtOperationsParams; + @Nullable + private DrtServicesParams drtServicesParams; + public DrtWithExtensionsConfigGroup() { + this(DefaultDrtOptimizationConstraintsSet::new); + } + + public DrtWithExtensionsConfigGroup(Supplier drtOptimizationConstraintsSetSupplier) { + super(drtOptimizationConstraintsSetSupplier); // Optional addDefinition(DrtCompanionParams.SET_NAME, DrtCompanionParams::new, () -> drtCompanionParams, - params -> drtCompanionParams = (DrtCompanionParams) params); + params -> drtCompanionParams = (DrtCompanionParams) params); // Optional addDefinition(DrtOperationsParams.SET_NAME, DrtOperationsParams::new, () -> drtOperationsParams, - params -> drtOperationsParams = (DrtOperationsParams) params); + params -> drtOperationsParams = (DrtOperationsParams) params); + + // Optional + addDefinition(DrtServicesParams.SET_TYPE, DrtServicesParams::new, () -> drtServicesParams, + params -> drtServicesParams = (DrtServicesParams) params); } public Optional getDrtCompanionParams() { @@ -57,5 +73,9 @@ public Optional getDrtCompanionParams() { public Optional getDrtOperationsParams() { return Optional.ofNullable(drtOperationsParams); } - + + public Optional getServicesParams() { + return Optional.ofNullable(drtServicesParams); + } + } diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/preplanned/optimizer/PreplannedDrtOptimizer.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/preplanned/optimizer/PreplannedDrtOptimizer.java index fd0f6672826..5e47c385106 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/preplanned/optimizer/PreplannedDrtOptimizer.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/preplanned/optimizer/PreplannedDrtOptimizer.java @@ -77,7 +77,7 @@ public PreplannedDrtOptimizer(DrtConfigGroup drtCfg, PreplannedSchedules preplan TravelTime travelTime, TravelDisutility travelDisutility, MobsimTimer timer, DrtTaskFactory taskFactory, EventsManager eventsManager, Fleet fleet, ScheduleTimingUpdater scheduleTimingUpdater) { Preconditions.checkArgument( - fleet.getVehicles().keySet().equals(preplannedSchedules.vehicleToPreplannedStops.keySet()), + fleet.getVehicles().keySet().containsAll(preplannedSchedules.vehicleToPreplannedStops.keySet()), "Some schedules are preplanned for vehicles outside the fleet"); this.mode = drtCfg.getMode(); diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/analysis/DrtServiceProfileCalculator.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/analysis/DrtServiceProfileCalculator.java new file mode 100644 index 00000000000..4d6e116c5a6 --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/analysis/DrtServiceProfileCalculator.java @@ -0,0 +1,145 @@ +/* + * *********************************************************************** * + * project: org.matsim.* + * *********************************************************************** * + * * + * copyright : (C) 2024 by the members listed in the COPYING, * + * LICENSE and WARRANTY file. * + * email : info at matsim dot org * + * * + * *********************************************************************** * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * See also COPYING, LICENSE and WARRANTY file * + * * + * *********************************************************************** * + */ +package org.matsim.contrib.drt.extension.services.analysis; + +import com.google.common.base.Verify; +import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.IdMap; +import org.matsim.contrib.common.timeprofile.TimeDiscretizer; +import org.matsim.contrib.drt.extension.services.events.DrtServiceEndedEvent; +import org.matsim.contrib.drt.extension.services.events.DrtServiceEndedEventHandler; +import org.matsim.contrib.drt.extension.services.events.DrtServiceStartedEvent; +import org.matsim.contrib.drt.extension.services.events.DrtServiceStartedEventHandler; +import org.matsim.contrib.drt.extension.services.schedule.DrtService; +import org.matsim.contrib.dvrp.fleet.DvrpVehicleSpecification; +import org.matsim.contrib.dvrp.fleet.FleetSpecification; +import org.matsim.core.config.groups.QSimConfigGroup; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author steffenaxer + */ +public class DrtServiceProfileCalculator implements DrtServiceEndedEventHandler, + DrtServiceStartedEventHandler { + + private final TimeDiscretizer timeDiscretizer; + + private Map serviceProfile; + + private final Map, DrtServiceStartedEvent> vehicleServices = new IdMap<>(DrtService.class); + + private final double analysisEndTime; + + private final String dvrpMode; + + private boolean wasConsolidatedInThisIteration = false; + + public DrtServiceProfileCalculator(String dvrpMode, FleetSpecification fleet, int timeInterval, + QSimConfigGroup qsimConfig) { + this.dvrpMode = dvrpMode; + double qsimEndTime = qsimConfig.getEndTime().orElse(0); + double maxServiceEndTime = fleet.getVehicleSpecifications() + .values() + .stream() + .mapToDouble(DvrpVehicleSpecification::getServiceEndTime) + .max() + .orElse(0); + analysisEndTime = Math.max(qsimEndTime, maxServiceEndTime); + timeDiscretizer = new TimeDiscretizer((int)Math.ceil(analysisEndTime), timeInterval); + } + + + public TimeDiscretizer getTimeDiscretizer() { + return timeDiscretizer; + } + + public Map getProfile() + { + this.consolidate(); + return this.serviceProfile; + } + + private void consolidate() { + if (!wasConsolidatedInThisIteration) { + serviceProfile.values().forEach(this::normalizeProfile); + wasConsolidatedInThisIteration = true; + } + } + + private void normalizeProfile(double[] profile) { + for (int i = 0; i < profile.length; i++) { + profile[i] /= timeDiscretizer.getTimeInterval(); + } + } + + private void increment(String serviceType,double beginTime, double endTime) { + Verify.verify(serviceType != null); + + double[] profile = serviceProfile.computeIfAbsent(serviceType, + v -> new double[timeDiscretizer.getIntervalCount()]); + increment(profile, Math.min(beginTime, endTime), endTime); + } + + private void increment(double[] values, double beginTime, double endTime) { + if (beginTime == endTime && beginTime >= analysisEndTime) { + return; + } + endTime = Math.min(endTime, analysisEndTime); + + double timeInterval = timeDiscretizer.getTimeInterval(); + int fromIdx = timeDiscretizer.getIdx(beginTime); + int toIdx = timeDiscretizer.getIdx(endTime); + + for (int i = fromIdx; i < toIdx; i++) { + values[i] += timeInterval; + } + } + + + /* Event handling starts here */ + + @Override + public void handleEvent(DrtServiceEndedEvent event) { + if (!event.getMode().equals(dvrpMode)) { + return; + } + + DrtServiceStartedEvent serviceStartedEvent = this.vehicleServices.remove(event.getDrtServiceId()); + increment(serviceStartedEvent.getServiceType(), serviceStartedEvent.getTime(), event.getTime()); + } + + @Override + public void handleEvent(DrtServiceStartedEvent event) { + if (!event.getMode().equals(dvrpMode)) { + return; + } + + this.vehicleServices.putIfAbsent(event.getDrtServiceId(), event); + } + + @Override + public void reset(int iteration) { + vehicleServices.clear(); + serviceProfile = new HashMap<>(); + wasConsolidatedInThisIteration = false; + } +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/analysis/DrtServiceProfileView.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/analysis/DrtServiceProfileView.java new file mode 100644 index 00000000000..567b09e4bac --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/analysis/DrtServiceProfileView.java @@ -0,0 +1,59 @@ + +/* + * *********************************************************************** * + * project: org.matsim.* + * *********************************************************************** * + * * + * copyright : (C) 2024 by the members listed in the COPYING, * + * LICENSE and WARRANTY file. * + * email : info at matsim dot org * + * * + * *********************************************************************** * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * See also COPYING, LICENSE and WARRANTY file * + * * + * *********************************************************************** * + */ +package org.matsim.contrib.drt.extension.services.analysis; + +import static java.util.Map.Entry; + +import java.awt.Paint; +import java.util.Collections; +import java.util.Map; + +import org.matsim.contrib.common.timeprofile.ProfileWriter; +import org.matsim.contrib.dvrp.schedule.Task; + +import com.google.common.collect.ImmutableMap; + +public class DrtServiceProfileView implements ProfileWriter.ProfileView { + + private final DrtServiceProfileCalculator calculator; + + public DrtServiceProfileView(DrtServiceProfileCalculator calculator) { + this.calculator = calculator; + } + + @Override + public ImmutableMap profiles() { + return calculator.getProfile() + .entrySet() + .stream() + .collect(ImmutableMap.toImmutableMap(Entry::getKey, Entry::getValue)); + } + + @Override + public Map seriesPaints() { + return Collections.emptyMap(); + } + + @Override + public double[] times() { + return calculator.getTimeDiscretizer().getTimes(); + } +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/analysis/ServiceAnalysisModule.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/analysis/ServiceAnalysisModule.java new file mode 100644 index 00000000000..55740e7b6be --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/analysis/ServiceAnalysisModule.java @@ -0,0 +1,61 @@ +/* + * *********************************************************************** * + * project: org.matsim.* + * *********************************************************************** * + * * + * copyright : (C) 2024 by the members listed in the COPYING, * + * LICENSE and WARRANTY file. * + * email : info at matsim dot org * + * * + * *********************************************************************** * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * See also COPYING, LICENSE and WARRANTY file * + * * + * *********************************************************************** * + */ +package org.matsim.contrib.drt.extension.services.analysis; + + +import org.matsim.contrib.common.timeprofile.ProfileWriter; +import org.matsim.contrib.drt.extension.services.analysis.DrtServiceProfileCalculator; +import org.matsim.contrib.drt.extension.services.analysis.DrtServiceProfileView; +import org.matsim.contrib.drt.extension.services.tasks.DefaultStackableTasksImpl; +import org.matsim.contrib.drt.extension.services.tasks.StackableTasks; +import org.matsim.contrib.drt.run.DrtConfigGroup; +import org.matsim.contrib.dvrp.fleet.FleetSpecification; +import org.matsim.contrib.dvrp.run.AbstractDvrpModeModule; +import org.matsim.core.config.groups.QSimConfigGroup; +import org.matsim.core.controler.MatsimServices; + +/** + * @author steffenaxer + */ +public class ServiceAnalysisModule extends AbstractDvrpModeModule { + private static final int TIME_RESOLUTION = 5; // High resolution req. to visualize short tasks + DrtConfigGroup drtConfigGroup; + + public ServiceAnalysisModule(DrtConfigGroup drtConfigGroup) { + super(drtConfigGroup.mode); + this.drtConfigGroup = drtConfigGroup; + } + + @Override + public void install() { + + bindModal(DrtServiceProfileCalculator.class).toProvider(modalProvider( + getter -> new DrtServiceProfileCalculator(getMode(), getter.getModal(FleetSpecification.class), TIME_RESOLUTION, + getter.get(QSimConfigGroup.class)))).asEagerSingleton(); + addEventHandlerBinding().to(modalKey(DrtServiceProfileCalculator.class)); + + addControlerListenerBinding().toProvider(modalProvider(getter -> { + MatsimServices matsimServices = getter.get(MatsimServices.class); + String mode = drtConfigGroup.getMode(); + var profileView = new DrtServiceProfileView(getter.getModal(DrtServiceProfileCalculator.class)); + return new ProfileWriter(matsimServices, mode, profileView, "service_time_profiles"); + })); + } +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/dispatcher/ServiceTaskDispatcher.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/dispatcher/ServiceTaskDispatcher.java new file mode 100644 index 00000000000..8382efd7e17 --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/dispatcher/ServiceTaskDispatcher.java @@ -0,0 +1,33 @@ +/* + * *********************************************************************** * + * project: org.matsim.* + * *********************************************************************** * + * * + * copyright : (C) 2024 by the members listed in the COPYING, * + * LICENSE and WARRANTY file. * + * email : info at matsim dot org * + * * + * *********************************************************************** * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * See also COPYING, LICENSE and WARRANTY file * + * * + * *********************************************************************** * + */ +package org.matsim.contrib.drt.extension.services.dispatcher; + +import org.matsim.api.core.v01.Id; +import org.matsim.contrib.drt.extension.services.schedule.DrtService; +import org.matsim.contrib.dvrp.fleet.DvrpVehicle; + +/** + * @author steffenaxer + */ +public interface ServiceTaskDispatcher { + void dispatch(double timeStep); + void startService(DvrpVehicle dvrpVehicle, Id drtServiceId); + void stopService(DvrpVehicle dvrpVehicle, Id drtServiceId); +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/dispatcher/ServiceTaskDispatcherImpl.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/dispatcher/ServiceTaskDispatcherImpl.java new file mode 100644 index 00000000000..005e4070f31 --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/dispatcher/ServiceTaskDispatcherImpl.java @@ -0,0 +1,162 @@ +/* + * *********************************************************************** * + * project: org.matsim.* + * *********************************************************************** * + * * + * copyright : (C) 2024 by the members listed in the COPYING, * + * LICENSE and WARRANTY file. * + * email : info at matsim dot org * + * * + * *********************************************************************** * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * See also COPYING, LICENSE and WARRANTY file * + * * + * *********************************************************************** * + */ +package org.matsim.contrib.drt.extension.services.dispatcher; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.network.Link; +import org.matsim.contrib.drt.extension.services.schedule.DrtService; +import org.matsim.contrib.drt.extension.services.services.ServiceTriggerFactory; +import org.matsim.contrib.drt.extension.services.services.params.AbstractServiceTriggerParam; +import org.matsim.contrib.drt.extension.services.services.params.DrtServiceParams; +import org.matsim.contrib.drt.extension.services.schedule.ServiceTaskScheduler; +import org.matsim.contrib.drt.extension.services.services.params.DrtServicesParams; +import org.matsim.contrib.drt.extension.services.services.tracker.ServiceExecutionTracker; +import org.matsim.contrib.drt.extension.services.services.tracker.ServiceExecutionTrackers; +import org.matsim.contrib.drt.extension.services.services.triggers.ServiceExecutionTrigger; +import org.matsim.contrib.drt.extension.operations.operationFacilities.OperationFacility; +import org.matsim.contrib.drt.extension.operations.operationFacilities.OperationFacilityFinder; +import org.matsim.contrib.drt.schedule.DrtStayTask; +import org.matsim.contrib.drt.scheduler.EmptyVehicleRelocator; +import org.matsim.contrib.dvrp.fleet.DvrpVehicle; +import org.matsim.contrib.dvrp.fleet.Fleet; +import org.matsim.contrib.dvrp.schedule.DriveTask; +import org.matsim.contrib.dvrp.schedule.Schedule; +import org.matsim.contrib.dvrp.schedule.Task; +import org.matsim.contrib.dvrp.tracker.OnlineDriveTaskTracker; +import org.matsim.contrib.dvrp.util.LinkTimePair; +import org.matsim.core.config.ConfigGroup; +import org.matsim.core.mobsim.framework.MobsimTimer; + +import java.util.*; +import java.util.stream.Stream; + +/** + * @author steffenaxer + */ +public class ServiceTaskDispatcherImpl implements ServiceTaskDispatcher { + private static final Logger LOG = LogManager.getLogger(ServiceTaskDispatcherImpl.class); + private final DrtServicesParams drtServicesParams; + private final Fleet fleet; + private final ServiceTaskScheduler serviceTaskScheduler; + private final OperationFacilityFinder operationFacilityFinder; + private final ServiceTriggerFactory serviceTriggerFactory; + private final ServiceExecutionTrackers executionTrackers; + + public ServiceTaskDispatcherImpl(final DrtServicesParams drtServicesParams, + final Fleet fleet, + final ServiceTaskScheduler serviceTaskScheduler, + final OperationFacilityFinder operationFacilityFinder, + final ServiceTriggerFactory serviceTriggerFactory, + final ServiceExecutionTrackers executionTrackers) { + this.drtServicesParams = drtServicesParams; + this.fleet = fleet; + this.serviceTaskScheduler = serviceTaskScheduler; + this.operationFacilityFinder = operationFacilityFinder; + this.serviceTriggerFactory = serviceTriggerFactory; + this.executionTrackers = executionTrackers; + this.installTriggers(); + } + + record ServiceScheduleEntry(DvrpVehicle dvrpVehicle, OperationFacility operationFacility, DrtServiceParams drtServiceParams, Boolean stackable) { + } + + @Override + public void dispatch(double timeStep) { + Stream serviceEntries = this.fleet.getVehicles().values().stream() + .flatMap(v -> checkVehicleForService(v, timeStep).stream()); + dispatch(serviceEntries); + } + + @Override + public void startService(DvrpVehicle dvrpVehicle, Id drtServiceId) { + this.serviceTaskScheduler.startService(dvrpVehicle.getId(), drtServiceId); + } + + @Override + public void stopService(DvrpVehicle dvrpVehicle, Id drtServiceId) { + this.serviceTaskScheduler.stopService(dvrpVehicle.getId(), drtServiceId); + } + + void dispatch(Stream entries) { + entries.forEach(e -> this.serviceTaskScheduler.scheduleServiceTask(e.dvrpVehicle, e.operationFacility, e.drtServiceParams, e.stackable)); + } + + List checkVehicleForService(DvrpVehicle dvrpVehicle, double timeStep) { + List servicesToBeScheduled = new ArrayList<>(); + ServiceExecutionTracker serviceExecutionTracker = this.executionTrackers.getTrackers().get(dvrpVehicle.getId()); + for (DrtServiceParams drtServiceParams : serviceExecutionTracker.getServices()) { + int executionLimit = drtServiceParams.executionLimit; + int currentExecutions = serviceExecutionTracker.getScheduledCounter(drtServiceParams.name); + boolean stackable = drtServiceParams.enableTaskStacking; + + if (currentExecutions == executionLimit) { + LOG.debug("Execution limit for vehicle {} and service {} reached.", drtServiceParams.name, dvrpVehicle.getId()); + continue; + } + + for (ServiceExecutionTrigger serviceExecutionTrigger : serviceExecutionTracker.getTriggers(drtServiceParams)) { + if (serviceExecutionTrigger.requiresService(dvrpVehicle, timeStep)) { + LOG.debug("{} scheduled service {} for vehicle {} at {}.", serviceExecutionTrigger.getName(), drtServiceParams.name, dvrpVehicle.getId(), timeStep); + servicesToBeScheduled.add(new ServiceScheduleEntry(dvrpVehicle, findServiceFacility(dvrpVehicle), drtServiceParams, stackable)); + } + } + } + return servicesToBeScheduled; + } + + private void installTriggers() { + for (DvrpVehicle vehicle : this.fleet.getVehicles().values()) { + ServiceExecutionTracker serviceExecutionTracker = this.executionTrackers.getTrackers().get(vehicle.getId()); + for (DrtServiceParams drtServiceParams : this.drtServicesParams.getServices()) { + Collection> triggerSets = drtServiceParams.getParameterSets().values(); + for (Collection triggerSet : triggerSets) { + for (var trigger : triggerSet) { + // There could be multiple triggers of the same type + var triggerParam = (AbstractServiceTriggerParam) trigger; + serviceExecutionTracker.addTrigger(drtServiceParams, this.serviceTriggerFactory.get(vehicle.getId(), triggerParam)); + } + } + } + } + } + + private OperationFacility findServiceFacility(DvrpVehicle dvrpVehicle) { + final Schedule schedule = dvrpVehicle.getSchedule(); + Task currentTask = schedule.getCurrentTask(); + Link lastLink; + if (currentTask instanceof DriveTask + && currentTask.getTaskType().equals(EmptyVehicleRelocator.RELOCATE_VEHICLE_TASK_TYPE) + && currentTask.equals(schedule.getTasks().get(schedule.getTaskCount() - 2))) { + LinkTimePair start = ((OnlineDriveTaskTracker) currentTask.getTaskTracker()).getDiversionPoint(); + if (start != null) { + lastLink = start.link; + } else { + lastLink = ((DriveTask) currentTask).getPath().getToLink(); + } + } else { + lastLink = ((DrtStayTask) schedule.getTasks() + .get(schedule.getTaskCount() - 1)).getLink(); + } + return operationFacilityFinder.findFacility(lastLink.getCoord()).orElseThrow(); + } + +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/events/AbstractServiceEvent.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/events/AbstractServiceEvent.java new file mode 100644 index 00000000000..502bc076d39 --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/events/AbstractServiceEvent.java @@ -0,0 +1,93 @@ +/* + * *********************************************************************** * + * project: org.matsim.* + * *********************************************************************** * + * * + * copyright : (C) 2024 by the members listed in the COPYING, * + * LICENSE and WARRANTY file. * + * email : info at matsim dot org * + * * + * *********************************************************************** * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * See also COPYING, LICENSE and WARRANTY file * + * * + * *********************************************************************** * + */ +package org.matsim.contrib.drt.extension.services.events; + +import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.events.Event; +import org.matsim.api.core.v01.network.Link; +import org.matsim.contrib.drt.extension.operations.operationFacilities.OperationFacility; +import org.matsim.contrib.drt.extension.operations.shifts.shift.DrtShift; +import org.matsim.contrib.drt.extension.services.schedule.DrtService; +import org.matsim.contrib.dvrp.fleet.DvrpVehicle; + +import java.util.Map; + +/** + * @author steffenaxer + */ +public abstract class AbstractServiceEvent extends Event { + private final Id drtServiceId; + private final String mode; + private final String serviceType; + private final Id vehicleId; + private final Id linkId; + private final Id operationFacilityId; + + public static final String ATTRIBUTE_MODE = "mode"; + public static final String ATTRIBUTE_SERVICE_TYPE = "serviceType"; + public static final String ATTRIBUTE_LINK_ID = "linkId"; + public static final String ATTRIBUTE_VEHICLE_ID = "vehicleId"; + public static final String ATTRIBUTE_OPERATION_FACILITY_ID = "facilityId"; + + public AbstractServiceEvent(Id drtServiceId,double time, String mode, String serviceType, Id vehicleId, Id linkId, Id operationFacilityId) { + super(time); + this.drtServiceId = drtServiceId; + this.mode = mode; + this.serviceType = serviceType; + this.vehicleId = vehicleId; + this.linkId = linkId; + this.operationFacilityId = operationFacilityId; + } + + public String getMode() { + return mode; + } + + public String getServiceType() { + return serviceType; + } + + public Id getDrtServiceId() { + return drtServiceId; + } + + public Id getOperationFacilityId() { + return operationFacilityId; + } + + public Id getVehicleId() { + return vehicleId; + } + + public Id getLinkId() { + return linkId; + } + + @Override + public Map getAttributes() { + Map attr = super.getAttributes(); + attr.put(ATTRIBUTE_MODE, mode); + attr.put(ATTRIBUTE_LINK_ID, linkId.toString()); + attr.put(ATTRIBUTE_VEHICLE_ID, vehicleId.toString()); + attr.put(ATTRIBUTE_SERVICE_TYPE, serviceType); + attr.put(ATTRIBUTE_OPERATION_FACILITY_ID, operationFacilityId.toString()); + return attr; + } +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/events/DrtServiceEndedEvent.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/events/DrtServiceEndedEvent.java new file mode 100644 index 00000000000..8f07a920dcd --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/events/DrtServiceEndedEvent.java @@ -0,0 +1,42 @@ +/* + * *********************************************************************** * + * project: org.matsim.* + * *********************************************************************** * + * * + * copyright : (C) 2024 by the members listed in the COPYING, * + * LICENSE and WARRANTY file. * + * email : info at matsim dot org * + * * + * *********************************************************************** * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * See also COPYING, LICENSE and WARRANTY file * + * * + * *********************************************************************** * + */ +package org.matsim.contrib.drt.extension.services.events; + +import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.network.Link; +import org.matsim.contrib.drt.extension.operations.operationFacilities.OperationFacility; +import org.matsim.contrib.drt.extension.services.schedule.DrtService; +import org.matsim.contrib.dvrp.fleet.DvrpVehicle; + +/** + * @author steffenaxer + */ +public class DrtServiceEndedEvent extends AbstractServiceEvent { + public static final String EVENT_TYPE = "DRT service ended"; + + public DrtServiceEndedEvent(Id drtServiceId, double time, String mode, String serviceType, Id vehicleId, Id linkId, Id id) { + super(drtServiceId, time, mode, serviceType, vehicleId, linkId, id); + } + + @Override + public String getEventType() { + return EVENT_TYPE; + } +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/events/DrtServiceEndedEventHandler.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/events/DrtServiceEndedEventHandler.java new file mode 100644 index 00000000000..910eb36eba2 --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/events/DrtServiceEndedEventHandler.java @@ -0,0 +1,29 @@ +/* + * *********************************************************************** * + * project: org.matsim.* + * *********************************************************************** * + * * + * copyright : (C) 2024 by the members listed in the COPYING, * + * LICENSE and WARRANTY file. * + * email : info at matsim dot org * + * * + * *********************************************************************** * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * See also COPYING, LICENSE and WARRANTY file * + * * + * *********************************************************************** * + */ +package org.matsim.contrib.drt.extension.services.events; + +import org.matsim.core.events.handler.EventHandler; + +/** + * @author steffenaxer + */ +public interface DrtServiceEndedEventHandler extends EventHandler { + void handleEvent(DrtServiceEndedEvent event); +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/events/DrtServiceScheduledEvent.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/events/DrtServiceScheduledEvent.java new file mode 100644 index 00000000000..a708fe7d349 --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/events/DrtServiceScheduledEvent.java @@ -0,0 +1,115 @@ +/* + * *********************************************************************** * + * project: org.matsim.* + * *********************************************************************** * + * * + * copyright : (C) 2024 by the members listed in the COPYING, * + * LICENSE and WARRANTY file. * + * email : info at matsim dot org * + * * + * *********************************************************************** * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * See also COPYING, LICENSE and WARRANTY file * + * * + * *********************************************************************** * + */ +package org.matsim.contrib.drt.extension.services.events; + +import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.events.Event; +import org.matsim.api.core.v01.network.Link; +import org.matsim.contrib.drt.extension.operations.operationFacilities.OperationFacility; +import org.matsim.contrib.drt.extension.services.schedule.DrtService; +import org.matsim.contrib.dvrp.fleet.DvrpVehicle; + +import java.util.Map; + +/** + * @author steffenaxer + */ +public class DrtServiceScheduledEvent extends Event { + + private final double startTime; + private final double endTime; + private final String mode; + private final String serviceType; + private final Id vehicleId; + private final Id linkId; + private final Id operationFacilityId; + private final Id drtServiceId; + + public static final String ATTRIBUTE_LINK = "link"; + public static final String ATTRIBUTE_OPERATION_FACILITY = "operationFacility"; + public static final String ATTRIBUTE_SERVICE_TYPE = "serviceType"; + public static final String ATTRIBUTE_VEHICLE_ID = "vehicle"; + public static final String ATTRIBUTE_START_TIME = "startTime"; + public static final String ATTRIBUTE_END_TIME = "endTime"; + public static final String EVENT_TYPE = "DRT service scheduled"; + + + public DrtServiceScheduledEvent(Id drtServiceId, double time, double startTime, double endTime, String mode, String serviceType, Id vehicleId, + Id linkId, Id operationFacilityId) { + super(time); + this.drtServiceId = drtServiceId; + this.startTime = startTime; + this.endTime = endTime; + this.mode = mode; + this.serviceType = serviceType; + this.vehicleId = vehicleId; + this.linkId = linkId; + this.operationFacilityId = operationFacilityId; + } + + public Id getDrtServiceId() { + return drtServiceId; + } + + public Id getVehicleId() { + return vehicleId; + } + + public Id getLinkId() { + return linkId; + } + + public String getMode() { + return mode; + } + + public String getServiceType() { + return serviceType; + } + + public double getEndTime() { + return endTime; + } + + public double getStartTime() { + return startTime; + } + + public Id getOperationFacilityId() { + return operationFacilityId; + } + + @Override + public String getEventType() { + return EVENT_TYPE; + } + + @Override + public Map getAttributes() { + Map attr = super.getAttributes(); + attr.put(ATTRIBUTE_VEHICLE_ID, vehicleId + ""); + attr.put(ATTRIBUTE_LINK, linkId + ""); + attr.put(ATTRIBUTE_OPERATION_FACILITY, operationFacilityId + ""); + attr.put(ATTRIBUTE_SERVICE_TYPE, serviceType); + attr.put(ATTRIBUTE_START_TIME,startTime + ""); + attr.put(ATTRIBUTE_END_TIME,endTime + ""); + return attr; + } +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/events/DrtServiceScheduledEventHandler.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/events/DrtServiceScheduledEventHandler.java new file mode 100644 index 00000000000..bd2f654c892 --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/events/DrtServiceScheduledEventHandler.java @@ -0,0 +1,29 @@ +/* + * *********************************************************************** * + * project: org.matsim.* + * *********************************************************************** * + * * + * copyright : (C) 2024 by the members listed in the COPYING, * + * LICENSE and WARRANTY file. * + * email : info at matsim dot org * + * * + * *********************************************************************** * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * See also COPYING, LICENSE and WARRANTY file * + * * + * *********************************************************************** * + */ +package org.matsim.contrib.drt.extension.services.events; + +import org.matsim.core.events.handler.EventHandler; + +/** + * @author steffenaxer + */ +public interface DrtServiceScheduledEventHandler extends EventHandler { + void handleEvent (DrtServiceScheduledEvent event); +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/events/DrtServiceStartedEvent.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/events/DrtServiceStartedEvent.java new file mode 100644 index 00000000000..ab65a43fd1e --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/events/DrtServiceStartedEvent.java @@ -0,0 +1,42 @@ +/* + * *********************************************************************** * + * project: org.matsim.* + * *********************************************************************** * + * * + * copyright : (C) 2024 by the members listed in the COPYING, * + * LICENSE and WARRANTY file. * + * email : info at matsim dot org * + * * + * *********************************************************************** * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * See also COPYING, LICENSE and WARRANTY file * + * * + * *********************************************************************** * + */ +package org.matsim.contrib.drt.extension.services.events; + +import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.network.Link; +import org.matsim.contrib.drt.extension.operations.operationFacilities.OperationFacility; +import org.matsim.contrib.drt.extension.services.schedule.DrtService; +import org.matsim.contrib.dvrp.fleet.DvrpVehicle; + +/** + * @author steffenaxer + */ +public class DrtServiceStartedEvent extends AbstractServiceEvent { + public static final String EVENT_TYPE = "DRT service started"; + + public DrtServiceStartedEvent(Id drtServiceId, double time, String mode, String serviceType, Id vehicleId, Id linkId, Id id) { + super(drtServiceId, time, mode, serviceType, vehicleId, linkId, id); + } + + @Override + public String getEventType() { + return EVENT_TYPE; + } +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/events/DrtServiceStartedEventHandler.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/events/DrtServiceStartedEventHandler.java new file mode 100644 index 00000000000..e600d86d34e --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/events/DrtServiceStartedEventHandler.java @@ -0,0 +1,29 @@ +/* + * *********************************************************************** * + * project: org.matsim.* + * *********************************************************************** * + * * + * copyright : (C) 2024 by the members listed in the COPYING, * + * LICENSE and WARRANTY file. * + * email : info at matsim dot org * + * * + * *********************************************************************** * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * See also COPYING, LICENSE and WARRANTY file * + * * + * *********************************************************************** * + */ +package org.matsim.contrib.drt.extension.services.events; + +import org.matsim.core.events.handler.EventHandler; + +/** + * @author steffenaxer + */ +public interface DrtServiceStartedEventHandler extends EventHandler { + void handleEvent(DrtServiceStartedEvent event); +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/optimizer/DrtServiceEntryFactory.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/optimizer/DrtServiceEntryFactory.java new file mode 100644 index 00000000000..8190a42106c --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/optimizer/DrtServiceEntryFactory.java @@ -0,0 +1,60 @@ +/* + * *********************************************************************** * + * project: org.matsim.* + * *********************************************************************** * + * * + * copyright : (C) 2024 by the members listed in the COPYING, * + * LICENSE and WARRANTY file. * + * email : info at matsim dot org * + * * + * *********************************************************************** * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * See also COPYING, LICENSE and WARRANTY file * + * * + * *********************************************************************** * + */ +package org.matsim.contrib.drt.extension.services.optimizer; + +import org.matsim.contrib.drt.extension.operations.shifts.schedule.OperationalStop; +import org.matsim.contrib.drt.extension.services.tasks.DrtServiceTask; +import org.matsim.contrib.drt.optimizer.VehicleEntry; +import org.matsim.contrib.dvrp.fleet.DvrpVehicle; +import org.matsim.contrib.dvrp.schedule.Schedule; +import org.matsim.contrib.dvrp.schedule.Task; + +/** + * @author steffenaxer + */ +public class DrtServiceEntryFactory implements VehicleEntry.EntryFactory { + private final VehicleEntry.EntryFactory delegate; + + public DrtServiceEntryFactory(VehicleEntry.EntryFactory delegate) { + this.delegate = delegate; + } + + @Override + public VehicleEntry create(DvrpVehicle vehicle, double currentTime) { + Schedule schedule = vehicle.getSchedule(); + + // Do not insert into service tasks + if(vehicle.getSchedule().getCurrentTask() instanceof OperationalStop) + { + return null; + } + + int taskCount = schedule.getTaskCount(); + if (taskCount > 1) { + Task oneBeforeLast = schedule.getTasks().get(taskCount - 2); + if (oneBeforeLast.getStatus() != Task.TaskStatus.PERFORMED && oneBeforeLast.getTaskType() + .equals(DrtServiceTask.TYPE)) { + return null; + } + } + + return delegate.create(vehicle, currentTime); + } +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/optimizer/DrtServiceOptimizerQSimModule.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/optimizer/DrtServiceOptimizerQSimModule.java new file mode 100644 index 00000000000..9d3d091739f --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/optimizer/DrtServiceOptimizerQSimModule.java @@ -0,0 +1,85 @@ +/* + * *********************************************************************** * + * project: org.matsim.* + * *********************************************************************** * + * * + * copyright : (C) 2024 by the members listed in the COPYING, * + * LICENSE and WARRANTY file. * + * email : info at matsim dot org * + * * + * *********************************************************************** * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * See also COPYING, LICENSE and WARRANTY file * + * * + * *********************************************************************** * + */ +package org.matsim.contrib.drt.extension.services.optimizer; + +import org.matsim.contrib.drt.extension.services.dispatcher.ServiceTaskDispatcher; +import org.matsim.contrib.drt.extension.services.schedule.DrtServiceDynActionCreator; +import org.matsim.contrib.drt.extension.services.tasks.DrtServiceTaskFactoryImpl; +import org.matsim.contrib.drt.optimizer.*; +import org.matsim.contrib.drt.optimizer.depot.DepotFinder; +import org.matsim.contrib.drt.optimizer.insertion.UnplannedRequestInserter; +import org.matsim.contrib.drt.optimizer.rebalancing.RebalancingStrategy; +import org.matsim.contrib.drt.prebooking.PrebookingActionCreator; +import org.matsim.contrib.drt.run.DrtConfigGroup; +import org.matsim.contrib.drt.schedule.DrtTaskFactory; +import org.matsim.contrib.drt.schedule.DrtTaskFactoryImpl; +import org.matsim.contrib.drt.scheduler.DrtScheduleInquiry; +import org.matsim.contrib.drt.scheduler.EmptyVehicleRelocator; +import org.matsim.contrib.drt.vrpagent.DrtActionCreator; +import org.matsim.contrib.dvrp.fleet.Fleet; +import org.matsim.contrib.dvrp.run.AbstractDvrpModeQSimModule; +import org.matsim.contrib.dvrp.schedule.ScheduleTimingUpdater; +import org.matsim.contrib.dvrp.vrpagent.VrpAgentLogic; +import org.matsim.core.mobsim.framework.MobsimTimer; + +public class DrtServiceOptimizerQSimModule extends AbstractDvrpModeQSimModule { + DrtConfigGroup drtConfigGroup; + + public DrtServiceOptimizerQSimModule(DrtConfigGroup drtConfigGroup) { + super(drtConfigGroup.getMode()); + this.drtConfigGroup = drtConfigGroup; + } + + @Override + protected void configureQSim() { + bindModal(DrtServiceDynActionCreator.class).toProvider(modalProvider(getter -> { + VrpAgentLogic.DynActionCreator delegate = drtConfigGroup.getPrebookingParams().isPresent() + ? getter.getModal(PrebookingActionCreator.class) + : getter.getModal(DrtActionCreator.class); + + return new DrtServiceDynActionCreator(delegate, getter.get(MobsimTimer.class)); + })).asEagerSingleton(); + + bindModal(VrpAgentLogic.DynActionCreator.class).to(modalKey(DrtServiceDynActionCreator.class)); + + + bindModal(DrtTaskFactory.class).toProvider(modalProvider(getter -> + { + DrtTaskFactory delegate = new DrtTaskFactoryImpl(); + return new DrtServiceTaskFactoryImpl(delegate); + })).asEagerSingleton(); + + bindModal(VehicleEntry.EntryFactory.class).toProvider(modalProvider(getter -> + new DrtServiceEntryFactory(new VehicleDataEntryFactoryImpl()))).asEagerSingleton(); + + addModalComponent(DrtOptimizer.class, modalProvider( + getter -> { + var delegate = new DefaultDrtOptimizer(drtConfigGroup, getter.getModal(Fleet.class), getter.get(MobsimTimer.class), + getter.getModal(DepotFinder.class), getter.getModal(RebalancingStrategy.class), + getter.getModal(DrtScheduleInquiry.class), getter.getModal(ScheduleTimingUpdater.class), + getter.getModal(EmptyVehicleRelocator.class), getter.getModal(UnplannedRequestInserter.class), + getter.getModal(DrtRequestInsertionRetryQueue.class)); + return new DrtServiceTaskOptimizer(getter.getModal(ServiceTaskDispatcher.class), + delegate, + getter.getModal(ScheduleTimingUpdater.class), + getter.get(MobsimTimer.class)); + })); + } +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/optimizer/DrtServiceQSimModule.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/optimizer/DrtServiceQSimModule.java new file mode 100644 index 00000000000..41a515ef067 --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/optimizer/DrtServiceQSimModule.java @@ -0,0 +1,81 @@ +/* + * *********************************************************************** * + * project: org.matsim.* + * *********************************************************************** * + * * + * copyright : (C) 2024 by the members listed in the COPYING, * + * LICENSE and WARRANTY file. * + * email : info at matsim dot org * + * * + * *********************************************************************** * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * See also COPYING, LICENSE and WARRANTY file * + * * + * *********************************************************************** * + */ +package org.matsim.contrib.drt.extension.services.optimizer; + +import org.matsim.api.core.v01.network.Network; +import org.matsim.contrib.drt.extension.DrtWithExtensionsConfigGroup; +import org.matsim.contrib.drt.extension.services.services.tracker.ServiceExecutionTrackers; +import org.matsim.contrib.drt.extension.services.dispatcher.ServiceTaskDispatcher; +import org.matsim.contrib.drt.extension.services.dispatcher.ServiceTaskDispatcherImpl; +import org.matsim.contrib.drt.extension.services.services.*; +import org.matsim.contrib.drt.extension.services.schedule.ServiceTaskScheduler; +import org.matsim.contrib.drt.extension.services.schedule.ServiceTaskSchedulerImpl; +import org.matsim.contrib.drt.extension.services.services.params.DrtServicesParams; +import org.matsim.contrib.drt.extension.operations.operationFacilities.OperationFacilityFinder; +import org.matsim.contrib.drt.extension.services.tasks.StackableTasks; +import org.matsim.contrib.drt.run.DrtConfigGroup; +import org.matsim.contrib.drt.schedule.DrtTaskFactory; +import org.matsim.contrib.dvrp.fleet.Fleet; +import org.matsim.contrib.dvrp.run.AbstractDvrpModeQSimModule; +import org.matsim.core.api.experimental.events.EventsManager; +import org.matsim.core.mobsim.framework.MobsimTimer; +import org.matsim.core.router.costcalculators.TravelDisutilityFactory; +import org.matsim.core.router.util.TravelTime; + +/** + * @author steffenaxer + */ +public class DrtServiceQSimModule extends AbstractDvrpModeQSimModule { + + private final DrtServicesParams drtServicesParams; + private final DrtConfigGroup drtConfigGroup; + + public DrtServiceQSimModule(DrtConfigGroup drtConfigGroup) { + super(drtConfigGroup.getMode()); + this.drtConfigGroup = drtConfigGroup; + this.drtServicesParams = ((DrtWithExtensionsConfigGroup) drtConfigGroup).getServicesParams().orElseThrow(); + } + + @Override + protected void configureQSim() { + + bindModal(ServiceTaskDispatcher.class).toProvider(modalProvider(getter -> new ServiceTaskDispatcherImpl( + drtServicesParams, + getter.getModal(Fleet.class), + getter.getModal(ServiceTaskScheduler.class), + getter.getModal(OperationFacilityFinder.class), + getter.getModal(ServiceTriggerFactory.class), + getter.getModal(ServiceExecutionTrackers.class) + ))).asEagerSingleton(); + + bindModal(ServiceTaskScheduler.class).toProvider(modalProvider(getter -> new ServiceTaskSchedulerImpl( + drtConfigGroup, + getter.getModal(Network.class), + getter.getModal(TravelTime.class), + getter.getModal(TravelDisutilityFactory.class).createTravelDisutility(getter.getModal(TravelTime.class)), + getter.get(MobsimTimer.class), + getter.getModal(DrtTaskFactory.class), + getter.getModal(StackableTasks.class), + getter.get(EventsManager.class), + getter.get(MobsimTimer.class) + ))).asEagerSingleton(); + + } +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/optimizer/DrtServiceTaskOptimizer.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/optimizer/DrtServiceTaskOptimizer.java new file mode 100644 index 00000000000..067bef68074 --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/optimizer/DrtServiceTaskOptimizer.java @@ -0,0 +1,132 @@ +/* + * *********************************************************************** * + * project: org.matsim.* + * *********************************************************************** * + * * + * copyright : (C) 2024 by the members listed in the COPYING, * + * LICENSE and WARRANTY file. * + * email : info at matsim dot org * + * * + * *********************************************************************** * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * See also COPYING, LICENSE and WARRANTY file * + * * + * *********************************************************************** * + */ +package org.matsim.contrib.drt.extension.services.optimizer; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.matsim.contrib.drt.extension.services.dispatcher.ServiceTaskDispatcher; +import org.matsim.contrib.drt.extension.operations.shifts.optimizer.ShiftDrtOptimizer; +import org.matsim.contrib.drt.extension.services.tasks.DrtServiceTask; +import org.matsim.contrib.drt.optimizer.DrtOptimizer; +import org.matsim.contrib.dvrp.fleet.DvrpVehicle; +import org.matsim.contrib.dvrp.optimizer.Request; +import org.matsim.contrib.dvrp.schedule.Schedule; +import org.matsim.contrib.dvrp.schedule.ScheduleTimingUpdater; +import org.matsim.contrib.dvrp.schedule.Schedules; +import org.matsim.contrib.dvrp.schedule.Task; +import org.matsim.core.mobsim.framework.MobsimTimer; +import org.matsim.core.mobsim.framework.events.MobsimBeforeSimStepEvent; +import org.matsim.core.mobsim.framework.events.MobsimInitializedEvent; +import org.matsim.core.mobsim.framework.listeners.MobsimInitializedListener; + +/** + * @author steffenaxer + */ +public class DrtServiceTaskOptimizer implements DrtOptimizer, MobsimInitializedListener { + private static final Logger LOG = LogManager.getLogger(DrtServiceTaskOptimizer.class); + private final DrtOptimizer delegate; + private final ScheduleTimingUpdater scheduleTimingUpdater; + private final ServiceTaskDispatcher serviceTaskDispatcher; + + public DrtServiceTaskOptimizer(ServiceTaskDispatcher serviceTaskDispatcher, DrtOptimizer delegate, ScheduleTimingUpdater scheduleTimingUpdater, MobsimTimer mobsimTimer) { + this.delegate = delegate; + this.scheduleTimingUpdater = scheduleTimingUpdater; + this.serviceTaskDispatcher = serviceTaskDispatcher; + } + + @Override + public void requestSubmitted(Request request) { + this.delegate.requestSubmitted(request); + } + + @Override + public void nextTask(DvrpVehicle vehicle) { + scheduleTimingUpdater.updateBeforeNextTask(vehicle); + updateServiceEnds(vehicle); + + final Task previousTask = getTaskOrNull(vehicle); + delegate.nextTask(vehicle); + + final Task successivTask = getTaskOrNull(vehicle); + + observeServiceExecution(vehicle, previousTask, successivTask); + } + + private void updateServiceEnds(DvrpVehicle vehicle) { + Schedule schedule = vehicle.getSchedule(); + + if (schedule.getStatus() != Schedule.ScheduleStatus.STARTED || + schedule.getCurrentTask() == Schedules.getLastTask(schedule)) { + return; + } + + int currentTaskIdx = vehicle.getSchedule().getCurrentTask().getTaskIdx(); + var serviceTasks = vehicle.getSchedule().getTasks().stream() + .filter(t -> t.getTaskIdx() >= currentTaskIdx) + .filter(t -> t instanceof DrtServiceTask).toList(); + + serviceTasks.forEach(t -> enforceIntendedDuration(vehicle, (DrtServiceTask) t)); + } + + private void enforceIntendedDuration(DvrpVehicle dvrpVehicle, DrtServiceTask drtServiceTask) { + double intendedDuration = drtServiceTask.getIntendedDuration(); + double currentDuration = drtServiceTask.getEndTime() - drtServiceTask.getBeginTime(); + + if (currentDuration < intendedDuration) { + double endTime = drtServiceTask.getBeginTime() + intendedDuration; + drtServiceTask.setEndTime(endTime); + this.scheduleTimingUpdater.updateTimingsStartingFromTaskIdx(dvrpVehicle,drtServiceTask.getTaskIdx()+1, endTime); + } + } + + + private void observeServiceExecution(DvrpVehicle dvrpVehicle, Task previousTask, Task successivTask) { + if (previousTask != successivTask) { + if (successivTask instanceof DrtServiceTask drtServiceTask) { + this.serviceTaskDispatcher.startService(dvrpVehicle, drtServiceTask.getDrtServiceId()); + } + + if (previousTask instanceof DrtServiceTask drtServiceTask) { + this.serviceTaskDispatcher.stopService(dvrpVehicle, drtServiceTask.getDrtServiceId()); + } + } + } + + private Task getTaskOrNull(DvrpVehicle vehicle) { + var schedule = vehicle.getSchedule(); + if (schedule.getStatus() == Schedule.ScheduleStatus.STARTED) { + return schedule.getCurrentTask(); + } + return null; + } + + @Override + public void notifyMobsimBeforeSimStep(MobsimBeforeSimStepEvent e) { + this.serviceTaskDispatcher.dispatch(e.getSimulationTime()); + this.delegate.notifyMobsimBeforeSimStep(e); + } + + @Override + public void notifyMobsimInitialized(MobsimInitializedEvent e) { + if (this.delegate instanceof ShiftDrtOptimizer shiftDrtOptimizer) { + shiftDrtOptimizer.notifyMobsimInitialized(e); + } + } +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/optimizer/EDrtServiceOptimizerQSimModule.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/optimizer/EDrtServiceOptimizerQSimModule.java new file mode 100644 index 00000000000..98d7d1a5958 --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/optimizer/EDrtServiceOptimizerQSimModule.java @@ -0,0 +1,84 @@ +/* + * *********************************************************************** * + * project: org.matsim.* + * *********************************************************************** * + * * + * copyright : (C) 2024 by the members listed in the COPYING, * + * LICENSE and WARRANTY file. * + * email : info at matsim dot org * + * * + * *********************************************************************** * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * See also COPYING, LICENSE and WARRANTY file * + * * + * *********************************************************************** * + */ +package org.matsim.contrib.drt.extension.services.optimizer; + +import org.matsim.contrib.drt.extension.edrt.EDrtActionCreator; +import org.matsim.contrib.drt.extension.edrt.optimizer.EDrtOptimizer; +import org.matsim.contrib.drt.extension.edrt.optimizer.EDrtVehicleDataEntryFactory; +import org.matsim.contrib.drt.extension.edrt.scheduler.EmptyVehicleChargingScheduler; +import org.matsim.contrib.drt.extension.services.dispatcher.ServiceTaskDispatcher; +import org.matsim.contrib.drt.extension.services.schedule.EDrtServiceDynActionCreator; +import org.matsim.contrib.drt.extension.services.tasks.EDrtServiceTaskFactoryImpl; +import org.matsim.contrib.drt.optimizer.DefaultDrtOptimizer; +import org.matsim.contrib.drt.optimizer.DrtOptimizer; +import org.matsim.contrib.drt.optimizer.VehicleEntry; +import org.matsim.contrib.drt.prebooking.PrebookingActionCreator; +import org.matsim.contrib.drt.run.DrtConfigGroup; +import org.matsim.contrib.drt.schedule.DrtTaskFactory; +import org.matsim.contrib.drt.vrpagent.DrtActionCreator; +import org.matsim.contrib.dvrp.run.AbstractDvrpModeQSimModule; +import org.matsim.contrib.dvrp.schedule.ScheduleTimingUpdater; +import org.matsim.contrib.dvrp.vrpagent.VrpAgentLogic; +import org.matsim.core.mobsim.framework.MobsimTimer; + +public class EDrtServiceOptimizerQSimModule extends AbstractDvrpModeQSimModule { + DrtConfigGroup drtConfigGroup; + + public EDrtServiceOptimizerQSimModule(DrtConfigGroup drtConfigGroup) { + super(drtConfigGroup.getMode()); + this.drtConfigGroup = drtConfigGroup; + } + + @Override + protected void configureQSim() { + + bindModal(EDrtServiceDynActionCreator.class).toProvider(modalProvider(getter -> { + VrpAgentLogic.DynActionCreator delegate = drtConfigGroup.getPrebookingParams().isPresent() + ? getter.getModal(PrebookingActionCreator.class) + : getter.getModal(DrtActionCreator.class); + + return new EDrtServiceDynActionCreator(new EDrtActionCreator(delegate, getter.get(MobsimTimer.class)), getter.get(MobsimTimer.class)); + })).asEagerSingleton(); + + bindModal(VrpAgentLogic.DynActionCreator.class).to(modalKey(EDrtServiceDynActionCreator.class)); + + bindModal(DrtTaskFactory.class).toProvider(modalProvider(getter -> + new EDrtServiceTaskFactoryImpl())).asEagerSingleton(); + + bindModal(VehicleEntry.EntryFactory.class).toProvider(modalProvider(getter -> + { + // Reuse already bound EDrtVehicleDataEntryFactoryProvider + EDrtVehicleDataEntryFactory.EDrtVehicleDataEntryFactoryProvider provider = getter.get(EDrtVehicleDataEntryFactory.EDrtVehicleDataEntryFactoryProvider.class); + return new DrtServiceEntryFactory(provider.get()); + } + + )).asEagerSingleton(); + + addModalComponent(DrtOptimizer.class, modalProvider( + getter -> { + var delegate = new EDrtOptimizer(drtConfigGroup, getter.getModal(DefaultDrtOptimizer.class), + getter.getModal(EmptyVehicleChargingScheduler.class)); + return new DrtServiceTaskOptimizer(getter.getModal(ServiceTaskDispatcher.class), + delegate, + getter.getModal(ScheduleTimingUpdater.class), + getter.get(MobsimTimer.class)); + })); + } +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/run/DrtServicesControlerCreator.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/run/DrtServicesControlerCreator.java new file mode 100644 index 00000000000..752887c3584 --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/run/DrtServicesControlerCreator.java @@ -0,0 +1,82 @@ +/* + * *********************************************************************** * + * project: org.matsim.* + * *********************************************************************** * + * * + * copyright : (C) 2024 by the members listed in the COPYING, * + * LICENSE and WARRANTY file. * + * email : info at matsim dot org * + * * + * *********************************************************************** * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * See also COPYING, LICENSE and WARRANTY file * + * * + * *********************************************************************** * + */ +package org.matsim.contrib.drt.extension.services.run; + +import org.matsim.api.core.v01.Scenario; +import org.matsim.contrib.drt.extension.DrtWithExtensionsConfigGroup; +import org.matsim.contrib.drt.extension.operations.operationFacilities.OperationFacilitiesModeModule; +import org.matsim.contrib.drt.extension.operations.operationFacilities.OperationFacilitiesQSimModule; +import org.matsim.contrib.drt.extension.services.analysis.ServiceAnalysisModule; +import org.matsim.contrib.drt.extension.services.optimizer.DrtServiceOptimizerQSimModule; +import org.matsim.contrib.drt.extension.services.optimizer.DrtServiceQSimModule; +import org.matsim.contrib.drt.extension.services.services.ServiceExecutionModule; +import org.matsim.contrib.drt.extension.services.services.tracker.ServiceExecutionTrackingModule; +import org.matsim.contrib.drt.run.DrtConfigGroup; +import org.matsim.contrib.drt.run.DrtControlerCreator; +import org.matsim.contrib.drt.run.MultiModeDrtConfigGroup; +import org.matsim.contrib.dvrp.run.DvrpQSimComponents; +import org.matsim.core.config.Config; +import org.matsim.core.controler.Controler; + +/** + * @author steffenaxer + */ +public class DrtServicesControlerCreator { + /** + * Creates a controller in one step. + * + * @param config + * @param otfvis + * @return + */ + public static Controler createControler(Config config, boolean otfvis) { + Controler controler = DrtControlerCreator.createControler(config, otfvis); + return prepareController(config, controler); + } + + /** + * Creates a controller in one step. + * + * @param config + * @param scenario + * @param otfvis + * @return + */ + public static Controler createControler(Config config, Scenario scenario, boolean otfvis) { + Controler controler = DrtControlerCreator.createControler(config, scenario, otfvis); + return prepareController(config, controler); + } + + private static Controler prepareController(Config config, Controler controler) { + MultiModeDrtConfigGroup multiModeDrtConfig = MultiModeDrtConfigGroup.get(config); + for (DrtConfigGroup drtCfg : multiModeDrtConfig.getModalElements()) { + controler.addOverridingQSimModule(new DrtServiceQSimModule(drtCfg)); + controler.addOverridingModule(new ServiceExecutionTrackingModule(drtCfg)); + controler.addOverridingModule(new OperationFacilitiesModeModule((DrtWithExtensionsConfigGroup) drtCfg)); + controler.addOverridingModule(new ServiceExecutionModule(drtCfg)); + controler.addOverridingModule(new ServiceAnalysisModule(drtCfg)); + controler.addOverridingQSimModule(new OperationFacilitiesQSimModule(drtCfg)); + controler.addOverridingQSimModule(new DrtServiceOptimizerQSimModule(drtCfg)); + } + + controler.configureQSimComponents(DvrpQSimComponents.activateAllModes(multiModeDrtConfig)); + return controler; + } +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/run/EDrtServicesControlerCreator.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/run/EDrtServicesControlerCreator.java new file mode 100644 index 00000000000..bfd92160d14 --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/run/EDrtServicesControlerCreator.java @@ -0,0 +1,82 @@ +/* + * *********************************************************************** * + * project: org.matsim.* + * *********************************************************************** * + * * + * copyright : (C) 2024 by the members listed in the COPYING, * + * LICENSE and WARRANTY file. * + * email : info at matsim dot org * + * * + * *********************************************************************** * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * See also COPYING, LICENSE and WARRANTY file * + * * + * *********************************************************************** * + */ +package org.matsim.contrib.drt.extension.services.run; + +import org.matsim.api.core.v01.Scenario; +import org.matsim.contrib.drt.extension.DrtWithExtensionsConfigGroup; +import org.matsim.contrib.drt.extension.edrt.run.EDrtControlerCreator; +import org.matsim.contrib.drt.extension.operations.operationFacilities.OperationFacilitiesModeModule; +import org.matsim.contrib.drt.extension.operations.operationFacilities.OperationFacilitiesQSimModule; +import org.matsim.contrib.drt.extension.services.analysis.ServiceAnalysisModule; +import org.matsim.contrib.drt.extension.services.optimizer.DrtServiceQSimModule; +import org.matsim.contrib.drt.extension.services.optimizer.EDrtServiceOptimizerQSimModule; +import org.matsim.contrib.drt.extension.services.services.ServiceExecutionModule; +import org.matsim.contrib.drt.extension.services.services.tracker.ServiceExecutionTrackingModule; +import org.matsim.contrib.drt.run.DrtConfigGroup; +import org.matsim.contrib.drt.run.MultiModeDrtConfigGroup; +import org.matsim.contrib.dvrp.run.DvrpQSimComponents; +import org.matsim.core.config.Config; +import org.matsim.core.controler.Controler; + +/** + * @author steffenaxer + */ +public class EDrtServicesControlerCreator { + /** + * Creates a controller in one step. + * + * @param config + * @param otfvis + * @return + */ + public static Controler createControler(Config config, boolean otfvis) { + Controler controler = EDrtControlerCreator.createControler(config, otfvis); + return prepareController(config, controler); + } + + /** + * Creates a controller in one step. + * + * @param config + * @param scenario + * @param otfvis + * @return + */ + public static Controler createControler(Config config, Scenario scenario, boolean otfvis) { + Controler controler = EDrtControlerCreator.createControler(config, scenario, otfvis); + return prepareController(config, controler); + } + + private static Controler prepareController(Config config, Controler controler) { + MultiModeDrtConfigGroup multiModeDrtConfig = MultiModeDrtConfigGroup.get(config); + for (DrtConfigGroup drtCfg : multiModeDrtConfig.getModalElements()) { + controler.addOverridingQSimModule(new DrtServiceQSimModule(drtCfg)); + controler.addOverridingModule(new ServiceExecutionTrackingModule(drtCfg)); + controler.addOverridingModule(new OperationFacilitiesModeModule((DrtWithExtensionsConfigGroup) drtCfg)); + controler.addOverridingModule(new ServiceExecutionModule(drtCfg)); + controler.addOverridingModule(new ServiceAnalysisModule(drtCfg)); + controler.addOverridingQSimModule(new OperationFacilitiesQSimModule(drtCfg)); + controler.addOverridingQSimModule(new EDrtServiceOptimizerQSimModule(drtCfg)); + } + + controler.configureQSimComponents(DvrpQSimComponents.activateAllModes(multiModeDrtConfig)); + return controler; + } +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/schedule/DrtService.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/schedule/DrtService.java new file mode 100644 index 00000000000..b81170f1c90 --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/schedule/DrtService.java @@ -0,0 +1,89 @@ +/* + * *********************************************************************** * + * project: org.matsim.* + * *********************************************************************** * + * * + * copyright : (C) 2024 by the members listed in the COPYING, * + * LICENSE and WARRANTY file. * + * email : info at matsim dot org * + * * + * *********************************************************************** * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * See also COPYING, LICENSE and WARRANTY file * + * * + * *********************************************************************** * + */ +package org.matsim.contrib.drt.extension.services.schedule; + +import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.Identifiable; +import org.matsim.api.core.v01.network.Link; +import org.matsim.contrib.drt.extension.operations.operationFacilities.OperationFacility; + +/** + * @author steffenaxer + */ +public class DrtService implements Identifiable { + Id drtServiceId; + double scheduledStartTime; + double scheduledEndTime; + String serviceType; + Id linkId; + Id operationFacilityId; + boolean started = false; + boolean ended = false; + + public DrtService(Id drtServiceId, double scheduledStartTime, double scheduledEndTime, String serviceType, Id linkId, Id operationFacilityId) { + this.drtServiceId = drtServiceId; + this.scheduledStartTime = scheduledStartTime; + this.scheduledEndTime = scheduledEndTime; + this.serviceType = serviceType; + this.linkId = linkId; + this.operationFacilityId = operationFacilityId; + } + + public void start() { + if (!started) { + started = true; + } else { + throw new IllegalStateException("Service already started!"); + } + } + + public void end() { + if (!ended) { + ended = true; + } else { + throw new IllegalStateException("Service already ended!"); + } + } + + public double getScheduledStartTime() { + return scheduledStartTime; + } + + public double getScheduledEndTime() { + return scheduledEndTime; + } + + public String getServiceType() { + return serviceType; + } + + public Id getLinkId() { + return linkId; + } + + public Id getOperationFacilityId() { + return operationFacilityId; + } + + @Override + public Id getId() { + return drtServiceId; + } +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/schedule/DrtServiceDynActionCreator.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/schedule/DrtServiceDynActionCreator.java new file mode 100644 index 00000000000..81b69147cf6 --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/schedule/DrtServiceDynActionCreator.java @@ -0,0 +1,52 @@ +/* + * *********************************************************************** * + * project: org.matsim.* + * *********************************************************************** * + * * + * copyright : (C) 2024 by the members listed in the COPYING, * + * LICENSE and WARRANTY file. * + * email : info at matsim dot org * + * * + * *********************************************************************** * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * See also COPYING, LICENSE and WARRANTY file * + * * + * *********************************************************************** * + */ +package org.matsim.contrib.drt.extension.services.schedule; + +import org.matsim.contrib.drt.extension.services.tasks.DrtServiceTask; +import org.matsim.contrib.dvrp.fleet.DvrpVehicle; +import org.matsim.contrib.dvrp.schedule.Task; +import org.matsim.contrib.dvrp.vrpagent.VrpAgentLogic; +import org.matsim.contrib.dynagent.DynAction; +import org.matsim.contrib.dynagent.DynAgent; +import org.matsim.core.mobsim.framework.MobsimTimer; + +/** + * @author steffenaxer + */ +public class DrtServiceDynActionCreator implements VrpAgentLogic.DynActionCreator { + private final VrpAgentLogic.DynActionCreator delegate; + private final MobsimTimer timer; + + public DrtServiceDynActionCreator(VrpAgentLogic.DynActionCreator delegate, MobsimTimer timer) { + this.delegate = delegate; + this.timer = timer; + } + + public DynAction createAction(DynAgent dynAgent, DvrpVehicle vehicle, double now) { + + Task task = vehicle.getSchedule().getCurrentTask(); + if (task instanceof DrtServiceTask eDrtServiceTask) { + return new ServiceActivity(eDrtServiceTask); + } + + return delegate.createAction(dynAgent, vehicle, now); + } + +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/schedule/EDrtServiceDynActionCreator.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/schedule/EDrtServiceDynActionCreator.java new file mode 100644 index 00000000000..ebb01005a73 --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/schedule/EDrtServiceDynActionCreator.java @@ -0,0 +1,59 @@ +/* + * *********************************************************************** * + * project: org.matsim.* + * *********************************************************************** * + * * + * copyright : (C) 2024 by the members listed in the COPYING, * + * LICENSE and WARRANTY file. * + * email : info at matsim dot org * + * * + * *********************************************************************** * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * See also COPYING, LICENSE and WARRANTY file * + * * + * *********************************************************************** * + */ +package org.matsim.contrib.drt.extension.services.schedule; + +import org.matsim.contrib.drt.extension.services.tasks.EDrtServiceTask; +import org.matsim.contrib.dvrp.fleet.DvrpVehicle; +import org.matsim.contrib.dvrp.schedule.Task; +import org.matsim.contrib.dvrp.vrpagent.VrpAgentLogic; +import org.matsim.contrib.dynagent.DynAction; +import org.matsim.contrib.dynagent.DynAgent; +import org.matsim.contrib.evrp.EvDvrpVehicle; +import org.matsim.contrib.evrp.tracker.OfflineETaskTracker; +import org.matsim.core.mobsim.framework.MobsimTimer; + +/** + * @author steffenaxer + */ +public class EDrtServiceDynActionCreator implements VrpAgentLogic.DynActionCreator { + private final VrpAgentLogic.DynActionCreator delegate; + private final MobsimTimer timer; + + public EDrtServiceDynActionCreator(VrpAgentLogic.DynActionCreator delegate, MobsimTimer timer) { + this.delegate = delegate; + this.timer = timer; + } + + public DynAction createAction(DynAgent dynAgent, DvrpVehicle vehicle, double now) { + + Task task = vehicle.getSchedule().getCurrentTask(); + if (task instanceof EDrtServiceTask EDrtMaintenanceTask) { + task.initTaskTracker(new OfflineETaskTracker((EvDvrpVehicle) vehicle, timer)); + return new ServiceActivity(EDrtMaintenanceTask); + } + + DynAction dynAction = delegate.createAction(dynAgent, vehicle, now); + if (task.getTaskTracker() == null) { + task.initTaskTracker(new OfflineETaskTracker((EvDvrpVehicle) vehicle, timer)); + } + return dynAction; + } + +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/schedule/ServiceActivity.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/schedule/ServiceActivity.java new file mode 100644 index 00000000000..a8c639622f2 --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/schedule/ServiceActivity.java @@ -0,0 +1,49 @@ +/* + * *********************************************************************** * + * project: org.matsim.* + * *********************************************************************** * + * * + * copyright : (C) 2024 by the members listed in the COPYING, * + * LICENSE and WARRANTY file. * + * email : info at matsim dot org * + * * + * *********************************************************************** * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * See also COPYING, LICENSE and WARRANTY file * + * * + * *********************************************************************** * + */ +package org.matsim.contrib.drt.extension.services.schedule; + +import org.matsim.contrib.drt.extension.services.tasks.DrtServiceTask; +import org.matsim.contrib.dynagent.DynActivity; + +public class ServiceActivity implements DynActivity { + public static final String ACTIVITY_TYPE = "Service"; + private final DrtServiceTask drtServiceTask; + + public ServiceActivity(DrtServiceTask drtServiceTask) { + this.drtServiceTask = drtServiceTask; + } + + @Override + public String getActivityType() { + return ACTIVITY_TYPE; + } + + @Override + public double getEndTime() { + return this.drtServiceTask.getEndTime(); + } + + @Override + public void doSimStep(double now) { + + } + + +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/schedule/ServiceTaskScheduler.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/schedule/ServiceTaskScheduler.java new file mode 100644 index 00000000000..9689a9513ba --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/schedule/ServiceTaskScheduler.java @@ -0,0 +1,43 @@ +/* + * *********************************************************************** * + * project: org.matsim.* + * *********************************************************************** * + * * + * copyright : (C) 2024 by the members listed in the COPYING, * + * LICENSE and WARRANTY file. * + * email : info at matsim dot org * + * * + * *********************************************************************** * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * See also COPYING, LICENSE and WARRANTY file * + * * + * *********************************************************************** * + */ +package org.matsim.contrib.drt.extension.services.schedule; + +import org.matsim.api.core.v01.Id; +import org.matsim.contrib.drt.extension.services.services.params.DrtServiceParams; +import org.matsim.contrib.drt.extension.operations.operationFacilities.OperationFacility; +import org.matsim.contrib.drt.schedule.DrtTaskType; +import org.matsim.contrib.dvrp.fleet.DvrpVehicle; + +import java.util.*; +import java.util.concurrent.LinkedBlockingQueue; + +import static org.matsim.contrib.drt.schedule.DrtTaskBaseType.DRIVE; + +/** + * @author steffenaxer + */ +public interface ServiceTaskScheduler { + DrtTaskType RELOCATE_SERVICE_TASK_TYPE = new DrtTaskType("RELOCATE_SERVICE", DRIVE); + void scheduleServiceTask(DvrpVehicle vehicle, OperationFacility operationFacility, DrtServiceParams drtServiceParams, boolean enableTaskStacking); + Map,DrtService> getScheduledServices(Id dvrpVehicleId); + Map,DrtService> getStartedServices(Id dvrpVehicleId); + void startService(Id dvrpVehicleId, Id drtServiceId); + void stopService(Id dvrpVehicleId, Id drtServiceId); +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/schedule/ServiceTaskSchedulerImpl.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/schedule/ServiceTaskSchedulerImpl.java new file mode 100644 index 00000000000..a43d7536a77 --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/schedule/ServiceTaskSchedulerImpl.java @@ -0,0 +1,271 @@ +/* + * *********************************************************************** * + * project: org.matsim.* + * *********************************************************************** * + * * + * copyright : (C) 2024 by the members listed in the COPYING, * + * LICENSE and WARRANTY file. * + * email : info at matsim dot org * + * * + * *********************************************************************** * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * See also COPYING, LICENSE and WARRANTY file * + * * + * *********************************************************************** * + */ +package org.matsim.contrib.drt.extension.services.schedule; + +import com.google.common.base.Verify; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.IdMap; +import org.matsim.api.core.v01.network.Link; +import org.matsim.api.core.v01.network.Network; +import org.matsim.contrib.drt.extension.edrt.schedule.EDrtChargingTask; +import org.matsim.contrib.drt.extension.services.events.DrtServiceEndedEvent; +import org.matsim.contrib.drt.extension.services.events.DrtServiceScheduledEvent; +import org.matsim.contrib.drt.extension.services.events.DrtServiceStartedEvent; +import org.matsim.contrib.drt.extension.services.services.params.DrtServiceParams; +import org.matsim.contrib.drt.extension.services.tasks.DrtServiceTask; +import org.matsim.contrib.drt.extension.services.tasks.ServiceTaskFactory; +import org.matsim.contrib.drt.extension.services.tasks.StackableTasks; +import org.matsim.contrib.drt.extension.operations.operationFacilities.OperationFacility; +import org.matsim.contrib.drt.run.DrtConfigGroup; +import org.matsim.contrib.drt.schedule.DrtTaskFactory; +import org.matsim.contrib.drt.scheduler.EmptyVehicleRelocator; +import org.matsim.contrib.dvrp.fleet.DvrpVehicle; +import org.matsim.contrib.dvrp.path.VrpPathWithTravelData; +import org.matsim.contrib.dvrp.path.VrpPaths; +import org.matsim.contrib.dvrp.schedule.*; +import org.matsim.contrib.dvrp.tracker.OnlineDriveTaskTracker; +import org.matsim.contrib.dvrp.util.LinkTimePair; +import org.matsim.core.api.experimental.events.EventsManager; +import org.matsim.core.mobsim.framework.MobsimTimer; +import org.matsim.core.router.speedy.SpeedyALTFactory; +import org.matsim.core.router.util.LeastCostPathCalculator; +import org.matsim.core.router.util.TravelDisutility; +import org.matsim.core.router.util.TravelTime; + +import java.util.*; + +/** + * @author steffenaxer + */ +public class ServiceTaskSchedulerImpl implements ServiceTaskScheduler { + private static final Logger LOG = LogManager.getLogger(ServiceTaskSchedulerImpl.class); + private final StackableTasks stackableTasks; + private final DrtConfigGroup drtConfigGroup; + private final Network network; + private final TravelTime travelTime; + private final MobsimTimer timer; + private final ServiceTaskFactory taskFactory; + private final LeastCostPathCalculator router; + private final EventsManager eventsManager; + private final MobsimTimer mobsimTimer; + private final Map, HashMap, DrtService>> scheduledServices = new IdMap<>(DvrpVehicle.class); + private final Map, HashMap, DrtService>> startedServices = new IdMap<>(DvrpVehicle.class); + + public ServiceTaskSchedulerImpl(final DrtConfigGroup drtConfigGroup, + final Network network, + final TravelTime travelTime, + final TravelDisutility travelDisutility, + final MobsimTimer timer, + final DrtTaskFactory taskFactory, + final StackableTasks stackableTasks, + final EventsManager eventsManager, + final MobsimTimer mobsimTimer + ) { + this.drtConfigGroup = drtConfigGroup; + this.network = network; + this.travelTime = travelTime; + this.timer = timer; + this.taskFactory = (ServiceTaskFactory) taskFactory; + this.stackableTasks = stackableTasks; + this.eventsManager = eventsManager; + this.mobsimTimer = mobsimTimer; + this.router = new SpeedyALTFactory().createPathCalculator(network, travelDisutility, travelTime); + } + + @Override + public void scheduleServiceTask(DvrpVehicle vehicle, OperationFacility serviceFacility, DrtServiceParams drtServiceParams, boolean enableTaskStacking) { + double duration = drtServiceParams.duration; + + final Schedule schedule = vehicle.getSchedule(); + + final Task currentTask = schedule.getCurrentTask(); + + Link toLink = network.getLinks().get(serviceFacility.getLinkId()); + + if (currentTask instanceof DriveTask + && currentTask.getTaskType().equals(EmptyVehicleRelocator.RELOCATE_VEHICLE_TASK_TYPE) + && currentTask.equals(schedule.getTasks().get(schedule.getTaskCount() - 2))) { + //try to divert/cancel relocation + LinkTimePair start = ((OnlineDriveTaskTracker) currentTask.getTaskTracker()).getDiversionPoint(); + + VrpPathWithTravelData path; + if (start != null) { + toLink = network.getLinks().get(serviceFacility.getLinkId()); + path = VrpPaths.calcAndCreatePath(start.link, toLink, start.time, router, travelTime); + ((OnlineDriveTaskTracker) currentTask.getTaskTracker()).divertPath(path); + + // remove STAY + schedule.removeLastTask(); + } else { + start = new LinkTimePair(((DriveTask) currentTask).getPath().getToLink(), currentTask.getEndTime()); + path = VrpPaths.calcAndCreatePath(start.link, toLink, start.time, router, travelTime); + + // remove STAY + schedule.removeLastTask(); + + //add drive to maintenance location + schedule.addTask(taskFactory.createDriveTask(vehicle, path, RELOCATE_SERVICE_TASK_TYPE)); // add RELOCATE + } + + double startTime = path.getArrivalTime(); + double endTime = startTime + duration; + + addServiceTask(vehicle, drtServiceParams, startTime, endTime, toLink, serviceFacility); + + } + // Append new task to existing charging task + else if (currentTask instanceof EDrtChargingTask chargingTask && + Schedules.getLastTask(schedule) != currentTask && + !(Schedules.getNextTask(schedule) instanceof DrtServiceTask)) { + + double compensatedDuration = compensateDuration(currentTask, duration, drtServiceParams.name, enableTaskStacking); + schedule.removeLastTask(); //Remove stay + double startTime = currentTask.getEndTime(); + double endTime = startTime + compensatedDuration; + addServiceTask(vehicle, drtServiceParams, startTime, endTime, chargingTask.getLink(), serviceFacility); + } + // Append new task to existing service task + else if (currentTask instanceof EDrtChargingTask chargingTask && + Schedules.getLastTask(schedule) != currentTask && + (Schedules.getNextTask(schedule) instanceof DrtServiceTask)) { + + double compensatedDuration = compensateDuration(currentTask, duration, drtServiceParams.name, enableTaskStacking); + schedule.removeLastTask(); //Remove stay + + //Append to end + double startTime = Schedules.getLastTask(schedule).getEndTime(); + double endTime = startTime + compensatedDuration; + addServiceTask(vehicle, drtServiceParams, startTime, endTime, chargingTask.getLink(), serviceFacility); + } else { + double compensatedDuration = compensateDuration(currentTask, duration, drtServiceParams.name, enableTaskStacking); + final Task task = schedule.getTasks().get(schedule.getTaskCount() - 1); + final Link lastLink = ((StayTask) task).getLink(); + + if (lastLink.getId() != serviceFacility.getLinkId()) { + double departureTime = task.getBeginTime(); + + if (schedule.getCurrentTask() == task) { + departureTime = Math.max(task.getBeginTime(), timer.getTimeOfDay()); + } + + VrpPathWithTravelData path = VrpPaths.calcAndCreatePath(lastLink, toLink, + departureTime, router, + travelTime); + if (path.getArrivalTime() < vehicle.getServiceEndTime()) { + + if (schedule.getCurrentTask() == task) { + task.setEndTime(timer.getTimeOfDay()); + } else { + // remove STAY + schedule.removeLastTask(); + } + + //add drive to service location + schedule.addTask(taskFactory.createDriveTask(vehicle, path, RELOCATE_SERVICE_TASK_TYPE)); // add RELOCATE + double startTime = path.getArrivalTime(); + double endTime = startTime + compensatedDuration; + + addServiceTask(vehicle, drtServiceParams, startTime, endTime, toLink, serviceFacility); + } + } else { + double startTime; + if (schedule.getCurrentTask() == task) { + task.setEndTime(timer.getTimeOfDay()); + startTime = timer.getTimeOfDay(); + } else { + // remove STAY + startTime = task.getBeginTime(); + schedule.removeLastTask(); + } + double endTime = startTime + compensatedDuration; + + addServiceTask(vehicle, drtServiceParams, startTime, endTime, toLink, serviceFacility); + } + } + } + + private void addServiceTask(DvrpVehicle vehicle, DrtServiceParams drtServiceParams, double startTime, double endTime, Link link, OperationFacility operationFacility) { + + Verify.verify(link.getId().equals(operationFacility.getLinkId())); + + if (startTime > vehicle.getServiceEndTime() || endTime > vehicle.getServiceEndTime()) { + // Do not schedule behind service time + return; + } + + Schedule schedule = vehicle.getSchedule(); + // append DrtServiceTask + Id drtServiceId = Id.create(UUID.randomUUID().toString(), DrtService.class); + schedule.addTask(taskFactory.createServiceTask(drtServiceId, startTime, endTime, link, operationFacility)); + this.eventsManager.processEvent(new DrtServiceScheduledEvent(drtServiceId, mobsimTimer.getTimeOfDay(), startTime, endTime, drtConfigGroup.mode, drtServiceParams.name, vehicle.getId(), link.getId(), operationFacility.getId())); + this.scheduledServices.computeIfAbsent(vehicle.getId(), k -> new HashMap<>()).put(drtServiceId, new DrtService(drtServiceId, startTime, endTime, drtServiceParams.name, link.getId(), operationFacility.getId())); + + // append DrtStayTask + schedule.addTask(taskFactory.createStayTask(vehicle, endTime, Math.max(vehicle.getServiceEndTime(), endTime), link)); + } + + @Override + public Map, DrtService> getScheduledServices(Id dvrpVehicleId) { + return this.scheduledServices.get(dvrpVehicleId); + } + + @Override + public Map, DrtService> getStartedServices(Id dvrpVehicleId) { + return this.startedServices.get(dvrpVehicleId); + } + + @Override + public void startService(Id dvrpVehicleId, Id drtServiceId) { + DrtService drtService = this.scheduledServices.get(dvrpVehicleId).remove(drtServiceId); + Verify.verify(drtService != null); + drtService.start(); + this.startedServices.computeIfAbsent(dvrpVehicleId, k -> new HashMap<>()).put(drtService.drtServiceId, drtService); + this.eventsManager.processEvent(new DrtServiceStartedEvent(drtService.drtServiceId, mobsimTimer.getTimeOfDay(), drtConfigGroup.mode, drtService.serviceType, dvrpVehicleId, drtService.linkId, drtService.operationFacilityId)); + } + + @Override + public void stopService(Id dvrpVehicleId, Id drtServiceId) { + DrtService drtService = this.startedServices.get(dvrpVehicleId).remove(drtServiceId); + Verify.verify(drtService != null); + drtService.end(); + this.eventsManager.processEvent(new DrtServiceEndedEvent(drtService.drtServiceId, mobsimTimer.getTimeOfDay(), drtConfigGroup.mode, drtService.serviceType, dvrpVehicleId, drtService.linkId, drtService.operationFacilityId)); + } + + double compensateDuration(Task currentTask, double requestedDuration, String serviceName, boolean enableTaskStacking) { + if (stackableTasks.isStackableTask(currentTask) && enableTaskStacking) { + double currentTaskDuration = currentTask.getEndTime() - currentTask.getBeginTime(); + if (requestedDuration <= currentTaskDuration) { + LOG.debug("Service {} with requested {} seconds takes place while {}" + , serviceName, requestedDuration, currentTask.getTaskType().name()); + return 1.; + } else { + double compensatedDuration = Math.max(1, requestedDuration - currentTaskDuration); + LOG.debug("Service {} with requested {} seconds takes partially place while {}. Remaining {} seconds" + , serviceName, requestedDuration, currentTask.getTaskType().name(), compensatedDuration); + return compensatedDuration; + } + } + return requestedDuration; + } + + +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/services/DefaultTriggerFactoryImpl.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/services/DefaultTriggerFactoryImpl.java new file mode 100644 index 00000000000..40a2a923c60 --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/services/DefaultTriggerFactoryImpl.java @@ -0,0 +1,42 @@ +/* + * *********************************************************************** * + * project: org.matsim.* + * *********************************************************************** * + * * + * copyright : (C) 2024 by the members listed in the COPYING, * + * LICENSE and WARRANTY file. * + * email : info at matsim dot org * + * * + * *********************************************************************** * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * See also COPYING, LICENSE and WARRANTY file * + * * + * *********************************************************************** * + */ +package org.matsim.contrib.drt.extension.services.services; + +import org.matsim.api.core.v01.Id; +import org.matsim.contrib.drt.extension.services.services.triggers.*; +import org.matsim.contrib.drt.extension.services.services.params.*; +import org.matsim.contrib.dvrp.fleet.DvrpVehicle; + +/** + * @author steffenaxer + */ +public class DefaultTriggerFactoryImpl implements ServiceTriggerFactory { + + @Override + public ServiceExecutionTrigger get(Id vehicleId, AbstractServiceTriggerParam param) { + return switch (param) { + case StopsReachedTriggerParam stopBasedConditionParam -> new StopsReachedTrigger(vehicleId, stopBasedConditionParam); + case MileageReachedTriggerParam mileageBasedConditionParam -> new MileageReachedTrigger(vehicleId, mileageBasedConditionParam); + case ChargingStartedTriggerParam chargingBasedConditionParam -> new ChargingStartedTrigger(vehicleId,chargingBasedConditionParam); + case TimeOfDayReachedTriggerParam timeOfDayBasedConditionParam -> new TimeOfDayReachedTrigger(vehicleId, timeOfDayBasedConditionParam); + default -> throw new IllegalStateException("JobConditionFactory missing for MaintenanceParam " + param.getName()); + }; + } +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/services/ServiceExecutionModule.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/services/ServiceExecutionModule.java new file mode 100644 index 00000000000..20f59402e4a --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/services/ServiceExecutionModule.java @@ -0,0 +1,42 @@ +/* + * *********************************************************************** * + * project: org.matsim.* + * *********************************************************************** * + * * + * copyright : (C) 2024 by the members listed in the COPYING, * + * LICENSE and WARRANTY file. * + * email : info at matsim dot org * + * * + * *********************************************************************** * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * See also COPYING, LICENSE and WARRANTY file * + * * + * *********************************************************************** * + */ +package org.matsim.contrib.drt.extension.services.services; + + +import org.matsim.contrib.drt.extension.services.tasks.DefaultStackableTasksImpl; +import org.matsim.contrib.drt.extension.services.tasks.StackableTasks; +import org.matsim.contrib.drt.run.DrtConfigGroup; +import org.matsim.contrib.dvrp.run.AbstractDvrpModeModule; + +/** + * @author steffenaxer + */ +public class ServiceExecutionModule extends AbstractDvrpModeModule { + + public ServiceExecutionModule(DrtConfigGroup drtConfigGroup) { + super(drtConfigGroup.mode); + } + + @Override + public void install() { + bindModal(ServiceTriggerFactory.class).toInstance(new DefaultTriggerFactoryImpl()); + bindModal(StackableTasks.class).toInstance(new DefaultStackableTasksImpl()); + } +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/services/ServiceTriggerFactory.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/services/ServiceTriggerFactory.java new file mode 100644 index 00000000000..760b593f7f0 --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/services/ServiceTriggerFactory.java @@ -0,0 +1,32 @@ +/* + * *********************************************************************** * + * project: org.matsim.* + * *********************************************************************** * + * * + * copyright : (C) 2024 by the members listed in the COPYING, * + * LICENSE and WARRANTY file. * + * email : info at matsim dot org * + * * + * *********************************************************************** * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * See also COPYING, LICENSE and WARRANTY file * + * * + * *********************************************************************** * + */ +package org.matsim.contrib.drt.extension.services.services; + +import org.matsim.api.core.v01.Id; +import org.matsim.contrib.drt.extension.services.services.params.AbstractServiceTriggerParam; +import org.matsim.contrib.drt.extension.services.services.triggers.ServiceExecutionTrigger; +import org.matsim.contrib.dvrp.fleet.DvrpVehicle; + +/** + * @author steffenaxer + */ +public interface ServiceTriggerFactory { + ServiceExecutionTrigger get(Id vehicleId, AbstractServiceTriggerParam param); +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/services/params/AbstractServiceTriggerParam.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/services/params/AbstractServiceTriggerParam.java new file mode 100644 index 00000000000..45a3fc3835d --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/services/params/AbstractServiceTriggerParam.java @@ -0,0 +1,54 @@ +/* + * *********************************************************************** * + * project: org.matsim.* + * *********************************************************************** * + * * + * copyright : (C) 2024 by the members listed in the COPYING, * + * LICENSE and WARRANTY file. * + * email : info at matsim dot org * + * * + * *********************************************************************** * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * See also COPYING, LICENSE and WARRANTY file * + * * + * *********************************************************************** * + */ +package org.matsim.contrib.drt.extension.services.services.params; + +import jakarta.validation.constraints.NotNull; +import org.matsim.core.config.ConfigGroup; +import org.matsim.core.config.ReflectiveConfigGroup; + +/** + * @author steffenaxer + */ +public abstract class AbstractServiceTriggerParam extends ReflectiveConfigGroup { + + @NotNull + @Parameter + public String name; + + public AbstractServiceTriggerParam(String name) + { + super(name); + this.name = name; + } + + @Override + public void addParameterSet(ConfigGroup configGroup) { + if (configGroup instanceof AbstractServiceTriggerParam) { + if(!this.getParameterSets().isEmpty()) + { + throw new IllegalStateException("Adding more than one parameter is not allowed."); + } + super.addParameterSet(configGroup); + } else { + throw new IllegalArgumentException(); + } + } + +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/services/params/ChargingStartedTriggerParam.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/services/params/ChargingStartedTriggerParam.java new file mode 100644 index 00000000000..bf6d4092d60 --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/services/params/ChargingStartedTriggerParam.java @@ -0,0 +1,32 @@ +/* + * *********************************************************************** * + * project: org.matsim.* + * *********************************************************************** * + * * + * copyright : (C) 2024 by the members listed in the COPYING, * + * LICENSE and WARRANTY file. * + * email : info at matsim dot org * + * * + * *********************************************************************** * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * See also COPYING, LICENSE and WARRANTY file * + * * + * *********************************************************************** * + */ +package org.matsim.contrib.drt.extension.services.services.params; + + +/** + * @author steffenaxer + */ +public class ChargingStartedTriggerParam extends AbstractServiceTriggerParam { + public static final String SET_NAME = "ChargingStartedTrigger"; + + public ChargingStartedTriggerParam() { + super(SET_NAME); + } +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/services/params/DrtServiceParams.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/services/params/DrtServiceParams.java new file mode 100644 index 00000000000..c9a4c3c09b3 --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/services/params/DrtServiceParams.java @@ -0,0 +1,93 @@ +/* + * *********************************************************************** * + * project: org.matsim.* + * *********************************************************************** * + * * + * copyright : (C) 2024 by the members listed in the COPYING, * + * LICENSE and WARRANTY file. * + * email : info at matsim dot org * + * * + * *********************************************************************** * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * See also COPYING, LICENSE and WARRANTY file * + * * + * *********************************************************************** * + */ +package org.matsim.contrib.drt.extension.services.services.params; + +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Positive; +import org.matsim.core.config.ConfigGroup; +import org.matsim.core.config.ReflectiveConfigGroup; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.function.Supplier; + +/** + * @author steffenaxer + */ +public class DrtServiceParams extends ReflectiveConfigGroup { + + private static final Map> SUPPORTED_PARAMS; + static { + Map> map = new HashMap<>(); + map.put(TimeOfDayReachedTriggerParam.SET_NAME, TimeOfDayReachedTriggerParam::new); + map.put(StopsReachedTriggerParam.SET_NAME, StopsReachedTriggerParam::new); + map.put(MileageReachedTriggerParam.SET_NAME, MileageReachedTriggerParam::new); + map.put(ChargingStartedTriggerParam.SET_NAME, ChargingStartedTriggerParam::new); + SUPPORTED_PARAMS = Collections.unmodifiableMap(map); + } + + public static final String SET_TYPE = "service"; + + @NotNull + @Parameter + public String name; + + @NotNull + @Positive + @Parameter + public double duration; + + @Positive + @Parameter + public int executionLimit = Integer.MAX_VALUE; + + @Parameter + public boolean enableTaskStacking = false; + + public DrtServiceParams() { + this(null); + } + + public DrtServiceParams(String name) + { + super(SET_TYPE); + this.name = name; + } + + @Override + public ConfigGroup createParameterSet(final String type) { + if (SUPPORTED_PARAMS.containsKey(type)) + { + return SUPPORTED_PARAMS.get(type).get(); + } + throw new IllegalStateException("Unsupported ConfigGroup "+ type); + } + + + @Override + public void addParameterSet(ConfigGroup configGroup) { + if (configGroup instanceof AbstractServiceTriggerParam) { + super.addParameterSet(configGroup); + } else { + throw new IllegalStateException("Unsupported ConfigGroup "+ configGroup.getName()); + } + } +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/services/params/DrtServicesParams.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/services/params/DrtServicesParams.java new file mode 100644 index 00000000000..7dff8ac728c --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/services/params/DrtServicesParams.java @@ -0,0 +1,67 @@ +/* + * *********************************************************************** * + * project: org.matsim.* + * *********************************************************************** * + * * + * copyright : (C) 2024 by the members listed in the COPYING, * + * LICENSE and WARRANTY file. * + * email : info at matsim dot org * + * * + * *********************************************************************** * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * See also COPYING, LICENSE and WARRANTY file * + * * + * *********************************************************************** * + */ +package org.matsim.contrib.drt.extension.services.services.params; + +import org.matsim.core.config.ConfigGroup; +import org.matsim.core.config.ReflectiveConfigGroup; + +import java.util.List; +import java.util.Optional; + +/** + * @author steffenaxer + */ +public class DrtServicesParams extends ReflectiveConfigGroup { + public static final String SET_TYPE = "services"; + + public DrtServicesParams() + { + super(SET_TYPE); + } + + @Override + public ConfigGroup createParameterSet(final String type) { + if (type.equals(DrtServiceParams.SET_TYPE)) + { + return new DrtServiceParams(); + } + throw new IllegalStateException("Unsupported ConfigGroup "+ type); + } + + public List getServices() + { + return this.getParameterSets(DrtServiceParams.SET_TYPE).stream().map(s ->(DrtServiceParams) s ).toList(); + } + + public Optional getService(String serviceName) + { + return this.getParameterSets(DrtServiceParams.SET_TYPE).stream().map(s ->(DrtServiceParams) s ).filter(s -> s.name.equals(serviceName)).findFirst(); + } + + + @Override + public void addParameterSet(ConfigGroup configGroup) { + if (configGroup instanceof DrtServiceParams) { + super.addParameterSet(configGroup); + } else { + throw new IllegalArgumentException("Unsupported ConfigGroup "+ configGroup.getName()); + } + } +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/services/params/MileageReachedTriggerParam.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/services/params/MileageReachedTriggerParam.java new file mode 100644 index 00000000000..1048b3cbbbc --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/services/params/MileageReachedTriggerParam.java @@ -0,0 +1,36 @@ +/* + * *********************************************************************** * + * project: org.matsim.* + * *********************************************************************** * + * * + * copyright : (C) 2024 by the members listed in the COPYING, * + * LICENSE and WARRANTY file. * + * email : info at matsim dot org * + * * + * *********************************************************************** * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * See also COPYING, LICENSE and WARRANTY file * + * * + * *********************************************************************** * + */ +package org.matsim.contrib.drt.extension.services.services.params; + + +/** + * @author steffenaxer + */ +public class MileageReachedTriggerParam extends AbstractServiceTriggerParam { + public static final String SET_NAME = "MileageReachedTrigger"; + + public MileageReachedTriggerParam() { + super(SET_NAME); + } + + @Comment("Required mileage to dispatch maintenance") + @Parameter + public int requiredMileage = 200_000; +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/services/params/StopsReachedTriggerParam.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/services/params/StopsReachedTriggerParam.java new file mode 100644 index 00000000000..f7ded5dc331 --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/services/params/StopsReachedTriggerParam.java @@ -0,0 +1,36 @@ +/* + * *********************************************************************** * + * project: org.matsim.* + * *********************************************************************** * + * * + * copyright : (C) 2024 by the members listed in the COPYING, * + * LICENSE and WARRANTY file. * + * email : info at matsim dot org * + * * + * *********************************************************************** * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * See also COPYING, LICENSE and WARRANTY file * + * * + * *********************************************************************** * + */ +package org.matsim.contrib.drt.extension.services.services.params; + + +/** + * @author steffenaxer + */ +public class StopsReachedTriggerParam extends AbstractServiceTriggerParam { + public static final String SET_NAME = "StopsReachedTrigger"; + + public StopsReachedTriggerParam() { + super(SET_NAME); + } + + @Comment("Required stops to dispatch service") + @Parameter + public int requiredStops = 50; +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/services/params/TimeOfDayReachedTriggerParam.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/services/params/TimeOfDayReachedTriggerParam.java new file mode 100644 index 00000000000..b16c38623ee --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/services/params/TimeOfDayReachedTriggerParam.java @@ -0,0 +1,39 @@ +/* + * *********************************************************************** * + * project: org.matsim.* + * *********************************************************************** * + * * + * copyright : (C) 2024 by the members listed in the COPYING, * + * LICENSE and WARRANTY file. * + * email : info at matsim dot org * + * * + * *********************************************************************** * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * See also COPYING, LICENSE and WARRANTY file * + * * + * *********************************************************************** * + */ +package org.matsim.contrib.drt.extension.services.services.params; + + +import jakarta.validation.constraints.NotNull; + +/** + * @author steffenaxer + */ +public class TimeOfDayReachedTriggerParam extends AbstractServiceTriggerParam { + public static final String SET_NAME = "TimeOfDayReachedTrigger"; + + public TimeOfDayReachedTriggerParam() { + super(SET_NAME); + } + + @NotNull + @Comment("Execution time of the service") + @Parameter + public double executionTime; +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/services/tracker/ServiceExecutionTracker.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/services/tracker/ServiceExecutionTracker.java new file mode 100644 index 00000000000..83368adb267 --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/services/tracker/ServiceExecutionTracker.java @@ -0,0 +1,93 @@ +/* + * *********************************************************************** * + * project: org.matsim.* + * *********************************************************************** * + * * + * copyright : (C) 2024 by the members listed in the COPYING, * + * LICENSE and WARRANTY file. * + * email : info at matsim dot org * + * * + * *********************************************************************** * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * See also COPYING, LICENSE and WARRANTY file * + * * + * *********************************************************************** * + */ +package org.matsim.contrib.drt.extension.services.services.tracker; + +import com.google.common.base.Verify; +import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.IdMap; +import org.matsim.contrib.drt.extension.services.events.*; +import org.matsim.contrib.drt.extension.services.schedule.DrtService; +import org.matsim.contrib.drt.extension.services.services.params.DrtServiceParams; +import org.matsim.contrib.drt.extension.services.services.triggers.ServiceExecutionTrigger; +import org.matsim.contrib.drt.run.DrtConfigGroup; +import org.matsim.contrib.dvrp.fleet.DvrpVehicle; + +import java.util.*; + +/** + * @author steffenaxer + */ +public class ServiceExecutionTracker implements DrtServiceEndedEventHandler, DrtServiceStartedEventHandler, DrtServiceScheduledEventHandler { + private final Id vehicleId; + private final Map> service2Triggers = new HashMap<>(); + private final List executionLog = new ArrayList<>(); + private final Map> scheduledServices = new HashMap<>(); + private final DrtConfigGroup drtConfigGroup; + private final Map, DrtServiceStartedEvent> drtServicesStartedMap = new IdMap<>(DrtService.class); + + public ServiceExecutionTracker(Id vehicleId, DrtConfigGroup drtConfigGroup) { + this.vehicleId = vehicleId; + this.drtConfigGroup = drtConfigGroup; + } + + public Set getServices() { + return this.service2Triggers.keySet(); + } + + public void addTrigger(DrtServiceParams drtServiceParams, ServiceExecutionTrigger trigger) { + this.service2Triggers.computeIfAbsent(drtServiceParams, k -> new ArrayList<>()).add(trigger); + } + + public List getTriggers(DrtServiceParams drtServiceParams) { + return this.service2Triggers.get(drtServiceParams); + } + + public int getScheduledCounter(String serviceType) { + return this.scheduledServices.getOrDefault(serviceType, Collections.emptyList()).size(); + } + + public List getExecutionRecords() { + return Collections.unmodifiableList(this.executionLog); + } + + @Override + public void handleEvent(DrtServiceEndedEvent event) { + DrtServiceStartedEvent drtServiceStartedEvent = drtServicesStartedMap.remove(event.getDrtServiceId()); + this.executionLog.add(new DrtServiceEntry(drtServiceStartedEvent, event)); + } + + @Override + public void handleEvent(DrtServiceStartedEvent event) { + Verify.verify(drtConfigGroup.mode.equals(event.getMode())); + Verify.verify(event.getVehicleId().equals(this.vehicleId)); + drtServicesStartedMap.put(event.getDrtServiceId(), event); + } + + @Override + public void handleEvent(DrtServiceScheduledEvent event) { + Verify.verify(drtConfigGroup.mode.equals(event.getMode())); + Verify.verify(event.getVehicleId().equals(this.vehicleId)); + scheduledServices.computeIfAbsent(event.getServiceType(), k -> new ArrayList<>()).add(event); + } + + public record DrtServiceEntry(DrtServiceStartedEvent drtServiceStartedEvent, DrtServiceEndedEvent drtServiceEndedEvent) { + } + +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/services/tracker/ServiceExecutionTrackers.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/services/tracker/ServiceExecutionTrackers.java new file mode 100644 index 00000000000..63756f80578 --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/services/tracker/ServiceExecutionTrackers.java @@ -0,0 +1,36 @@ +/* + * *********************************************************************** * + * project: org.matsim.* + * *********************************************************************** * + * * + * copyright : (C) 2024 by the members listed in the COPYING, * + * LICENSE and WARRANTY file. * + * email : info at matsim dot org * + * * + * *********************************************************************** * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * See also COPYING, LICENSE and WARRANTY file * + * * + * *********************************************************************** * + */ +package org.matsim.contrib.drt.extension.services.services.tracker; + +import org.matsim.api.core.v01.Id; +import org.matsim.contrib.drt.extension.services.events.DrtServiceEndedEventHandler; +import org.matsim.contrib.drt.extension.services.events.DrtServiceScheduledEventHandler; +import org.matsim.contrib.drt.extension.services.events.DrtServiceStartedEventHandler; +import org.matsim.contrib.dvrp.fleet.DvrpVehicle; +import org.matsim.core.controler.listener.IterationEndsListener; + +import java.util.Map; + +/** + * @author steffenaxer + */ +public interface ServiceExecutionTrackers extends IterationEndsListener, DrtServiceStartedEventHandler, DrtServiceEndedEventHandler, DrtServiceScheduledEventHandler { + Map, ServiceExecutionTracker> getTrackers(); +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/services/tracker/ServiceExecutionTrackersImpl.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/services/tracker/ServiceExecutionTrackersImpl.java new file mode 100644 index 00000000000..a8308db8e26 --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/services/tracker/ServiceExecutionTrackersImpl.java @@ -0,0 +1,123 @@ +/* + * *********************************************************************** * + * project: org.matsim.* + * *********************************************************************** * + * * + * copyright : (C) 2024 by the members listed in the COPYING, * + * LICENSE and WARRANTY file. * + * email : info at matsim dot org * + * * + * *********************************************************************** * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * See also COPYING, LICENSE and WARRANTY file * + * * + * *********************************************************************** * + */ +package org.matsim.contrib.drt.extension.services.services.tracker; + +import org.apache.commons.csv.CSVFormat; +import org.apache.commons.csv.CSVPrinter; +import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.Identifiable; +import org.matsim.application.options.CsvOptions; +import org.matsim.contrib.drt.extension.services.events.DrtServiceEndedEvent; +import org.matsim.contrib.drt.extension.services.events.DrtServiceScheduledEvent; +import org.matsim.contrib.drt.extension.services.events.DrtServiceStartedEvent; +import org.matsim.contrib.drt.run.DrtConfigGroup; +import org.matsim.contrib.dvrp.fleet.DvrpVehicle; +import org.matsim.contrib.dvrp.fleet.FleetSpecification; +import org.matsim.core.controler.MatsimServices; +import org.matsim.core.controler.events.IterationEndsEvent; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Path; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @author steffenaxer + */ +public class ServiceExecutionTrackersImpl implements ServiceExecutionTrackers { + private final CsvOptions csvOptions; + private Map, ServiceExecutionTracker> delegates; + private final DrtConfigGroup drtConfigGroup; + private final MatsimServices matsimServices; + private final FleetSpecification fleetSpecification; + + public ServiceExecutionTrackersImpl(final FleetSpecification fleetSpecification, final DrtConfigGroup drtConfigGroup, final MatsimServices matsimServices) { + this.delegates = createExecutionsTrackers(fleetSpecification, drtConfigGroup); + this.drtConfigGroup = drtConfigGroup; + this.matsimServices = matsimServices; + this.csvOptions = new CsvOptions(CSVFormat.Predefined.Default, matsimServices.getConfig().global().getDefaultDelimiter().charAt(0), StandardCharsets.UTF_8); + this.fleetSpecification = fleetSpecification; + } + + @Override + public Map, ServiceExecutionTracker> getTrackers() { + return delegates; + } + + Map, ServiceExecutionTracker> createExecutionsTrackers(FleetSpecification fleetSpecification, DrtConfigGroup drtConfigGroup) { + return fleetSpecification.getVehicleSpecifications().values().stream() + .collect(Collectors.toUnmodifiableMap(Identifiable::getId, v -> new ServiceExecutionTracker(v.getId(), drtConfigGroup))); + } + + @Override + public void reset(int iteration) { + // Create new tracker delegates per iteration + this.delegates = createExecutionsTrackers(fleetSpecification, drtConfigGroup); + } + + public void writeServiceExecution() throws IOException { + + try (CSVPrinter printer = csvOptions.createPrinter(Path.of(matsimServices.getControlerIO().getIterationFilename(matsimServices.getIterationNumber(), "drt_service_executions" + "_" + drtConfigGroup.mode + ".csv")))) { + printer.printRecord("vehicleId", "serviceName", "linkId", "startTime", "endTime", "duration"); + for (ServiceExecutionTracker serviceExecutionTracker : delegates.values()) { + for (var drtServiceEntry : serviceExecutionTracker.getExecutionRecords()) { + double startTime = drtServiceEntry.drtServiceStartedEvent().getTime(); + double endTime = drtServiceEntry.drtServiceEndedEvent().getTime(); + printer.printRecord( + drtServiceEntry.drtServiceEndedEvent().getVehicleId(), + drtServiceEntry.drtServiceEndedEvent().getServiceType(), + drtServiceEntry.drtServiceEndedEvent().getLinkId(), + startTime, + endTime, + endTime - startTime); + } + } + } + } + + @Override + public void handleEvent(DrtServiceEndedEvent event) { + delegates.get(event.getVehicleId()).handleEvent(event); + } + + + @Override + public void handleEvent(DrtServiceStartedEvent event) { + delegates.get(event.getVehicleId()).handleEvent(event); + } + + @Override + public void notifyIterationEnds(IterationEndsEvent event) { + try { + writeServiceExecution(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + @Override + public void handleEvent(DrtServiceScheduledEvent event) { + delegates.get(event.getVehicleId()).handleEvent(event); + } +} + + + diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/services/tracker/ServiceExecutionTrackingModule.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/services/tracker/ServiceExecutionTrackingModule.java new file mode 100644 index 00000000000..81a16274f16 --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/services/tracker/ServiceExecutionTrackingModule.java @@ -0,0 +1,50 @@ +/* + * *********************************************************************** * + * project: org.matsim.* + * *********************************************************************** * + * * + * copyright : (C) 2024 by the members listed in the COPYING, * + * LICENSE and WARRANTY file. * + * email : info at matsim dot org * + * * + * *********************************************************************** * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * See also COPYING, LICENSE and WARRANTY file * + * * + * *********************************************************************** * + */ +package org.matsim.contrib.drt.extension.services.services.tracker; + +import org.matsim.contrib.drt.run.DrtConfigGroup; +import org.matsim.contrib.dvrp.fleet.FleetSpecification; +import org.matsim.contrib.dvrp.run.AbstractDvrpModeModule; +import org.matsim.core.controler.MatsimServices; + +/** + * @author steffenaxer + */ +public class ServiceExecutionTrackingModule extends AbstractDvrpModeModule { + DrtConfigGroup drtConfigGroup; + + public ServiceExecutionTrackingModule(DrtConfigGroup drtConfigGroup) { + super(drtConfigGroup.mode); + this.drtConfigGroup = drtConfigGroup; + } + + @Override + public void install() { + + bindModal(ServiceExecutionTrackers.class).toProvider(modalProvider(getter -> new ServiceExecutionTrackersImpl( + getter.getModal(FleetSpecification.class), + drtConfigGroup, + getter.get(MatsimServices.class) + ))).asEagerSingleton(); + + addEventHandlerBinding().to(modalKey(ServiceExecutionTrackers.class)); + addControlerListenerBinding().to(modalKey(ServiceExecutionTrackers.class)); + } +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/services/triggers/ChargingStartedTrigger.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/services/triggers/ChargingStartedTrigger.java new file mode 100644 index 00000000000..671837a104c --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/services/triggers/ChargingStartedTrigger.java @@ -0,0 +1,60 @@ +/* + * *********************************************************************** * + * project: org.matsim.* + * *********************************************************************** * + * * + * copyright : (C) 2024 by the members listed in the COPYING, * + * LICENSE and WARRANTY file. * + * email : info at matsim dot org * + * * + * *********************************************************************** * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * See also COPYING, LICENSE and WARRANTY file * + * * + * *********************************************************************** * + */ +package org.matsim.contrib.drt.extension.services.services.triggers; + +import org.matsim.api.core.v01.Id; +import org.matsim.contrib.drt.extension.services.services.params.ChargingStartedTriggerParam; +import org.matsim.contrib.dvrp.fleet.DvrpVehicle; +import org.matsim.contrib.dvrp.schedule.Schedule; +import org.matsim.contrib.dvrp.schedule.Schedules; +import org.matsim.contrib.evrp.ChargingTask; + +/** + * @author steffenaxer + */ +public class ChargingStartedTrigger implements ServiceExecutionTrigger { + ChargingStartedTriggerParam chargingBasedConditionParam; + + public ChargingStartedTrigger(Id vehicleId, ChargingStartedTriggerParam chargingBasedConditionParam) { + + this.chargingBasedConditionParam = chargingBasedConditionParam; + } + + @Override + public boolean requiresService(DvrpVehicle dvrpVehicle, double timeStep) { + return this.judgeVehicle(dvrpVehicle, timeStep); + } + + @Override + public String getName() { + return chargingBasedConditionParam.name; + } + + boolean judgeVehicle(DvrpVehicle dvrpVehicle, double timeStep) + { + Schedule schedule = dvrpVehicle.getSchedule(); + + return schedule.getStatus() == Schedule.ScheduleStatus.STARTED && + TriggerUtils.hasJustStarted(schedule,timeStep) && + schedule.getCurrentTask() instanceof ChargingTask && + schedule.getCurrentTask() != Schedules.getLastTask(schedule); + } + +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/services/triggers/MileageReachedTrigger.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/services/triggers/MileageReachedTrigger.java new file mode 100644 index 00000000000..90e2f901736 --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/services/triggers/MileageReachedTrigger.java @@ -0,0 +1,84 @@ +/* + * *********************************************************************** * + * project: org.matsim.* + * *********************************************************************** * + * * + * copyright : (C) 2024 by the members listed in the COPYING, * + * LICENSE and WARRANTY file. * + * email : info at matsim dot org * + * * + * *********************************************************************** * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * See also COPYING, LICENSE and WARRANTY file * + * * + * *********************************************************************** * + */ +package org.matsim.contrib.drt.extension.services.services.triggers; + +import com.google.common.collect.Streams; +import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.network.Link; +import org.matsim.contrib.drt.extension.services.services.params.MileageReachedTriggerParam; +import org.matsim.contrib.drt.extension.services.tasks.DrtServiceTask; +import org.matsim.contrib.drt.schedule.DrtDriveTask; +import org.matsim.contrib.dvrp.fleet.DvrpVehicle; +import org.matsim.contrib.dvrp.path.VrpPath; +import org.matsim.contrib.dvrp.schedule.Schedule; +import org.matsim.contrib.dvrp.schedule.Task; + +/** + * @author steffenaxer + */ +public class MileageReachedTrigger implements ServiceExecutionTrigger { + private final MileageReachedTriggerParam mileageReachedTriggerParam; + + public MileageReachedTrigger(Id vehicleId, MileageReachedTriggerParam mileageReachedTriggerParam) + { + this.mileageReachedTriggerParam = mileageReachedTriggerParam; + } + + @Override + public boolean requiresService(DvrpVehicle dvrpVehicle, double timeStep) { + return this.judgeVehicle(dvrpVehicle, timeStep); + } + + @Override + public String getName() { + return mileageReachedTriggerParam.name; + } + + boolean judgeVehicle(DvrpVehicle dvrpVehicle, double timeStep) + { + if(dvrpVehicle.getSchedule().getStatus() == Schedule.ScheduleStatus.STARTED) + { + double lastMaintenanceTime = dvrpVehicle.getSchedule().getTasks().stream() + .filter(t -> t instanceof DrtServiceTask) + .mapToDouble(Task::getEndTime) + .max() + .orElse(0); + + double drivenDistance = dvrpVehicle.getSchedule().getTasks().stream() + .filter(t -> t instanceof DrtDriveTask) + .filter(t -> t.getEndTime() > lastMaintenanceTime) + .filter(t -> t.getEndTime() < timeStep) + .mapToDouble(t -> getDistance(((DrtDriveTask) t).getPath())) + .sum(); + + return drivenDistance > mileageReachedTriggerParam.requiredMileage; + } + + return false; + + + } + + double getDistance(VrpPath path) + { + return Streams.stream(path.iterator()).mapToDouble(Link::getLength).sum(); + } + +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/services/triggers/ServiceExecutionTrigger.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/services/triggers/ServiceExecutionTrigger.java new file mode 100644 index 00000000000..fdfef536f1e --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/services/triggers/ServiceExecutionTrigger.java @@ -0,0 +1,30 @@ +/* + * *********************************************************************** * + * project: org.matsim.* + * *********************************************************************** * + * * + * copyright : (C) 2024 by the members listed in the COPYING, * + * LICENSE and WARRANTY file. * + * email : info at matsim dot org * + * * + * *********************************************************************** * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * See also COPYING, LICENSE and WARRANTY file * + * * + * *********************************************************************** * + */ +package org.matsim.contrib.drt.extension.services.services.triggers; + +import org.matsim.contrib.dvrp.fleet.DvrpVehicle; + +/** + * @author steffenaxer + */ +public interface ServiceExecutionTrigger { + boolean requiresService(DvrpVehicle dvrpVehicle, double timeStep); + String getName(); +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/services/triggers/StopsReachedTrigger.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/services/triggers/StopsReachedTrigger.java new file mode 100644 index 00000000000..57267735a2c --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/services/triggers/StopsReachedTrigger.java @@ -0,0 +1,69 @@ +/* + * *********************************************************************** * + * project: org.matsim.* + * *********************************************************************** * + * * + * copyright : (C) 2024 by the members listed in the COPYING, * + * LICENSE and WARRANTY file. * + * email : info at matsim dot org * + * * + * *********************************************************************** * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * See also COPYING, LICENSE and WARRANTY file * + * * + * *********************************************************************** * + */ +package org.matsim.contrib.drt.extension.services.services.triggers; + +import org.matsim.api.core.v01.Id; +import org.matsim.contrib.drt.extension.services.services.params.StopsReachedTriggerParam; +import org.matsim.contrib.drt.extension.services.tasks.DrtServiceTask; +import org.matsim.contrib.drt.schedule.DrtStopTask; +import org.matsim.contrib.dvrp.fleet.DvrpVehicle; +import org.matsim.contrib.dvrp.schedule.Schedule; +import org.matsim.contrib.dvrp.schedule.Task; + +/** + * @author steffenaxer + */ +public class StopsReachedTrigger implements ServiceExecutionTrigger { + private final StopsReachedTriggerParam stopReachedParam; + + public StopsReachedTrigger(Id vehicleId, StopsReachedTriggerParam stopReachedParam) + { + this.stopReachedParam = stopReachedParam; + } + + @Override + public boolean requiresService(DvrpVehicle dvrpVehicle, double timeStep) { + return this.judgeVehicle(dvrpVehicle, timeStep); + } + + @Override + public String getName() { + return stopReachedParam.name; + } + + boolean judgeVehicle(DvrpVehicle dvrpVehicle, double timeStep) + { + return dvrpVehicle.getSchedule().getStatus() == Schedule.ScheduleStatus.STARTED && + TriggerUtils.hasJustStarted(dvrpVehicle.getSchedule(), timeStep) && + calcStops(dvrpVehicle) > stopReachedParam.requiredStops; + } + + private int calcStops(DvrpVehicle dvrpVehicle) { + double lastService = dvrpVehicle.getSchedule().getTasks().stream() + .filter(t -> t instanceof DrtServiceTask) + .mapToDouble(Task::getEndTime) + .max() + .orElse(0); + + return (int) dvrpVehicle.getSchedule().getTasks().stream() + .filter(t -> t instanceof DrtStopTask) + .filter(t -> t.getBeginTime() > lastService).count(); + } +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/services/triggers/TimeOfDayReachedTrigger.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/services/triggers/TimeOfDayReachedTrigger.java new file mode 100644 index 00000000000..ea88f6b5337 --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/services/triggers/TimeOfDayReachedTrigger.java @@ -0,0 +1,54 @@ +/* + * *********************************************************************** * + * project: org.matsim.* + * *********************************************************************** * + * * + * copyright : (C) 2024 by the members listed in the COPYING, * + * LICENSE and WARRANTY file. * + * email : info at matsim dot org * + * * + * *********************************************************************** * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * See also COPYING, LICENSE and WARRANTY file * + * * + * *********************************************************************** * + */ +package org.matsim.contrib.drt.extension.services.services.triggers; + +import org.matsim.api.core.v01.Id; +import org.matsim.contrib.drt.extension.services.services.params.TimeOfDayReachedTriggerParam; +import org.matsim.contrib.dvrp.fleet.DvrpVehicle; +import org.matsim.contrib.dvrp.schedule.Schedule; + +/** + * @author steffenaxer + */ +public class TimeOfDayReachedTrigger implements ServiceExecutionTrigger { + private final TimeOfDayReachedTriggerParam timeOfDayReachedTriggerParam; + + public TimeOfDayReachedTrigger(Id vehicleId, TimeOfDayReachedTriggerParam timeOfDayBasedConditionParam) + { + this.timeOfDayReachedTriggerParam = timeOfDayBasedConditionParam; + } + + @Override + public boolean requiresService(DvrpVehicle dvrpVehicle, double timeStep) { + return this.judgeVehicle(dvrpVehicle, timeStep); + } + + @Override + public String getName() { + return timeOfDayReachedTriggerParam.name; + } + + boolean judgeVehicle(DvrpVehicle dvrpVehicle, double timeStep) + { + return dvrpVehicle.getSchedule().getStatus() == Schedule.ScheduleStatus.STARTED + && timeStep==this.timeOfDayReachedTriggerParam.executionTime; + } + +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/services/triggers/TriggerUtils.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/services/triggers/TriggerUtils.java new file mode 100644 index 00000000000..513aff91bdd --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/services/triggers/TriggerUtils.java @@ -0,0 +1,34 @@ +/* + * *********************************************************************** * + * project: org.matsim.* + * *********************************************************************** * + * * + * copyright : (C) 2024 by the members listed in the COPYING, * + * LICENSE and WARRANTY file. * + * email : info at matsim dot org * + * * + * *********************************************************************** * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * See also COPYING, LICENSE and WARRANTY file * + * * + * *********************************************************************** * + */ +package org.matsim.contrib.drt.extension.services.services.triggers; + +import org.matsim.contrib.dvrp.schedule.Schedule; + +/** + * @author steffenaxer + */ +public class TriggerUtils { + + public static boolean hasJustStarted(Schedule schedule, double timeStep) + { + // simulation knows only full seconds + return Math.floor(schedule.getCurrentTask().getBeginTime()+1) == timeStep; + } +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/tasks/DefaultStackableTasksImpl.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/tasks/DefaultStackableTasksImpl.java new file mode 100644 index 00000000000..9b0d91a359c --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/tasks/DefaultStackableTasksImpl.java @@ -0,0 +1,37 @@ +/* + * *********************************************************************** * + * project: org.matsim.* + * *********************************************************************** * + * * + * copyright : (C) 2024 by the members listed in the COPYING, * + * LICENSE and WARRANTY file. * + * email : info at matsim dot org * + * * + * *********************************************************************** * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * See also COPYING, LICENSE and WARRANTY file * + * * + * *********************************************************************** * + */ +package org.matsim.contrib.drt.extension.services.tasks; + +import org.matsim.contrib.dvrp.schedule.Task; +import org.matsim.contrib.evrp.ChargingTask; + +import java.util.Set; + +/** + * @author steffenaxer + */ +public class DefaultStackableTasksImpl implements StackableTasks { + private final static Set> STACKABLE_TASKS = Set.of(DrtServiceTask.class, ChargingTask.class); + + @Override + public boolean isStackableTask(Task task) { + return STACKABLE_TASKS.stream().anyMatch(t -> t.isAssignableFrom(task.getClass()) ); + } +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/tasks/DrtServiceTask.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/tasks/DrtServiceTask.java new file mode 100644 index 00000000000..aa98ca4ffd5 --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/tasks/DrtServiceTask.java @@ -0,0 +1,64 @@ +/* + * *********************************************************************** * + * project: org.matsim.* + * *********************************************************************** * + * * + * copyright : (C) 2024 by the members listed in the COPYING, * + * LICENSE and WARRANTY file. * + * email : info at matsim dot org * + * * + * *********************************************************************** * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * See also COPYING, LICENSE and WARRANTY file * + * * + * *********************************************************************** * + */ +package org.matsim.contrib.drt.extension.services.tasks; + +import com.google.common.base.Verify; +import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.network.Link; +import org.matsim.contrib.drt.extension.operations.operationFacilities.OperationFacility; +import org.matsim.contrib.drt.extension.operations.shifts.schedule.OperationalStop; +import org.matsim.contrib.drt.extension.services.schedule.DrtService; +import org.matsim.contrib.drt.schedule.DrtTaskType; +import org.matsim.contrib.dvrp.schedule.DefaultStayTask; + +import static org.matsim.contrib.drt.schedule.DrtTaskBaseType.STAY; + +/** + * @author steffenaxer + */ +public class DrtServiceTask extends DefaultStayTask implements OperationalStop { + + public static final DrtTaskType TYPE = new DrtTaskType("SERVICE", STAY); + OperationFacility operationFacility; + Id drtServiceId; + final double intendedDuration; + + public DrtServiceTask(Id drtServiceId, double beginTime, double endTime, Link link, OperationFacility operationFacility) { + super(TYPE,beginTime, endTime, link); + this.operationFacility = operationFacility; + this.drtServiceId = drtServiceId; + this.intendedDuration = endTime-beginTime; + Verify.verify(link.getId().equals(operationFacility.getLinkId())); + } + + @Override + public OperationFacility getFacility() { + return operationFacility; + } + + public Id getDrtServiceId() { + return drtServiceId; + } + + public double getIntendedDuration() { + return intendedDuration; + } +} + diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/tasks/DrtServiceTaskFactoryImpl.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/tasks/DrtServiceTaskFactoryImpl.java new file mode 100644 index 00000000000..e6f1e0cf04f --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/tasks/DrtServiceTaskFactoryImpl.java @@ -0,0 +1,65 @@ +/* + * *********************************************************************** * + * project: org.matsim.* + * *********************************************************************** * + * * + * copyright : (C) 2024 by the members listed in the COPYING, * + * LICENSE and WARRANTY file. * + * email : info at matsim dot org * + * * + * *********************************************************************** * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * See also COPYING, LICENSE and WARRANTY file * + * * + * *********************************************************************** * + */ +package org.matsim.contrib.drt.extension.services.tasks; + +import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.network.Link; +import org.matsim.contrib.drt.extension.operations.operationFacilities.OperationFacility; +import org.matsim.contrib.drt.extension.services.schedule.DrtService; +import org.matsim.contrib.drt.schedule.*; +import org.matsim.contrib.dvrp.fleet.DvrpVehicle; +import org.matsim.contrib.dvrp.path.VrpPathWithTravelData; +import org.matsim.contrib.dvrp.schedule.DefaultStayTask; + +/** + * @author steffenaxer + */ +public class DrtServiceTaskFactoryImpl implements ServiceTaskFactory { + private final DrtTaskFactory delegate; + + public DrtServiceTaskFactoryImpl(DrtTaskFactory delegate) { + this.delegate = delegate; + } + + @Override + public DrtServiceTask createServiceTask(Id drtServiceId, double beginTime, double endTime, Link link, OperationFacility operationFacility) { + return new DrtServiceTask(drtServiceId, beginTime, endTime, link, operationFacility); + } + + @Override + public DrtDriveTask createDriveTask(DvrpVehicle vehicle, VrpPathWithTravelData path, DrtTaskType drtTaskType) { + return delegate.createDriveTask(vehicle, path, drtTaskType); + } + + @Override + public DrtStopTask createStopTask(DvrpVehicle vehicle, double beginTime, double endTime, Link link) { + return delegate.createStopTask(vehicle, beginTime, endTime, link); + } + + @Override + public DrtStayTask createStayTask(DvrpVehicle vehicle, double beginTime, double endTime, Link link) { + return delegate.createStayTask(vehicle, beginTime, endTime, link); + } + + @Override + public DefaultStayTask createInitialTask(DvrpVehicle vehicle, double beginTime, double endTime, Link link) { + return delegate.createInitialTask(vehicle, beginTime, endTime, link); + } +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/tasks/EDrtServiceTask.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/tasks/EDrtServiceTask.java new file mode 100644 index 00000000000..f6005eaa1d0 --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/tasks/EDrtServiceTask.java @@ -0,0 +1,45 @@ +/* + * *********************************************************************** * + * project: org.matsim.* + * *********************************************************************** * + * * + * copyright : (C) 2024 by the members listed in the COPYING, * + * LICENSE and WARRANTY file. * + * email : info at matsim dot org * + * * + * *********************************************************************** * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * See also COPYING, LICENSE and WARRANTY file * + * * + * *********************************************************************** * + */ +package org.matsim.contrib.drt.extension.services.tasks; + +import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.network.Link; +import org.matsim.contrib.drt.extension.operations.operationFacilities.OperationFacility; +import org.matsim.contrib.drt.extension.services.schedule.DrtService; +import org.matsim.contrib.evrp.ETask; + +/** + * @author steffenaxer + */ +public class EDrtServiceTask extends DrtServiceTask implements ETask { + + private final double consumedEnergy; + + public EDrtServiceTask(Id drtServiceId, double beginTime, double endTime, Link link, double consumedEnergy, OperationFacility operationFacility) { + super(drtServiceId, beginTime, endTime, link, operationFacility); + this.consumedEnergy = consumedEnergy; + } + + @Override + public double getTotalEnergy() { + return consumedEnergy; + } +} + diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/tasks/EDrtServiceTaskFactoryImpl.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/tasks/EDrtServiceTaskFactoryImpl.java new file mode 100644 index 00000000000..d89175dad68 --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/tasks/EDrtServiceTaskFactoryImpl.java @@ -0,0 +1,38 @@ +/* + * *********************************************************************** * + * project: org.matsim.* + * *********************************************************************** * + * * + * copyright : (C) 2024 by the members listed in the COPYING, * + * LICENSE and WARRANTY file. * + * email : info at matsim dot org * + * * + * *********************************************************************** * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * See also COPYING, LICENSE and WARRANTY file * + * * + * *********************************************************************** * + */ +package org.matsim.contrib.drt.extension.services.tasks; + +import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.network.Link; +import org.matsim.contrib.drt.extension.edrt.schedule.EDrtTaskFactoryImpl; +import org.matsim.contrib.drt.extension.operations.operationFacilities.OperationFacility; +import org.matsim.contrib.drt.extension.services.schedule.DrtService; + +/** + * @author steffenaxer + */ +public class EDrtServiceTaskFactoryImpl extends EDrtTaskFactoryImpl implements ServiceTaskFactory { + + @Override + public DrtServiceTask createServiceTask(Id drtServiceId, double beginTime, double endTime, Link link, OperationFacility operationFacility) { + return new EDrtServiceTask(drtServiceId, beginTime,endTime,link,0, operationFacility); + } + +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/tasks/ServiceTaskFactory.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/tasks/ServiceTaskFactory.java new file mode 100644 index 00000000000..d54c9364818 --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/tasks/ServiceTaskFactory.java @@ -0,0 +1,33 @@ +/* + * *********************************************************************** * + * project: org.matsim.* + * *********************************************************************** * + * * + * copyright : (C) 2024 by the members listed in the COPYING, * + * LICENSE and WARRANTY file. * + * email : info at matsim dot org * + * * + * *********************************************************************** * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * See also COPYING, LICENSE and WARRANTY file * + * * + * *********************************************************************** * + */ +package org.matsim.contrib.drt.extension.services.tasks; + +import org.matsim.api.core.v01.Id; +import org.matsim.api.core.v01.network.Link; +import org.matsim.contrib.drt.extension.operations.operationFacilities.OperationFacility; +import org.matsim.contrib.drt.extension.services.schedule.DrtService; +import org.matsim.contrib.drt.schedule.DrtTaskFactory; + +/** + * @author steffenaxer + */ +public interface ServiceTaskFactory extends DrtTaskFactory { + DrtServiceTask createServiceTask(Id drtServiceId, double beginTime, double endTime, Link link, OperationFacility operationFacility); +} diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/tasks/StackableTasks.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/tasks/StackableTasks.java new file mode 100644 index 00000000000..e405c6de03f --- /dev/null +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/services/tasks/StackableTasks.java @@ -0,0 +1,29 @@ +/* + * *********************************************************************** * + * project: org.matsim.* + * *********************************************************************** * + * * + * copyright : (C) 2024 by the members listed in the COPYING, * + * LICENSE and WARRANTY file. * + * email : info at matsim dot org * + * * + * *********************************************************************** * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * See also COPYING, LICENSE and WARRANTY file * + * * + * *********************************************************************** * + */ +package org.matsim.contrib.drt.extension.services.tasks; + +import org.matsim.contrib.dvrp.schedule.Task; + +/** + * @author steffenaxer + */ +public interface StackableTasks { + boolean isStackableTask(Task task); +} diff --git a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/services/DrtServicesParamsIOTest.java b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/services/DrtServicesParamsIOTest.java new file mode 100644 index 00000000000..1674544bad3 --- /dev/null +++ b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/services/DrtServicesParamsIOTest.java @@ -0,0 +1,72 @@ +package org.matsim.contrib.drt.extension.services; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.matsim.contrib.drt.extension.DrtWithExtensionsConfigGroup; +import org.matsim.contrib.drt.extension.services.services.params.DrtServiceParams; +import org.matsim.contrib.drt.extension.services.services.params.DrtServicesParams; +import org.matsim.contrib.drt.extension.services.services.params.TimeOfDayReachedTriggerParam; +import org.matsim.core.config.Config; +import org.matsim.core.config.ConfigUtils; +import org.matsim.testcases.MatsimTestUtils; + +import java.nio.file.Path; + +/** + * @author steffenaxer + */ +public class DrtServicesParamsIOTest { + @RegisterExtension + private final MatsimTestUtils utils = new MatsimTestUtils(); + + @Test + void testServiceParamsIO() + { + final String outputDirectory = utils.getOutputDirectory(); + Path outputFile = Path.of(outputDirectory).resolve("config.xml"); + Config outputConfig = ConfigUtils.createConfig(); + DrtWithExtensionsConfigGroup drtConfigGroup = new DrtWithExtensionsConfigGroup(); + outputConfig.addModule(drtConfigGroup); + + DrtServicesParams drtServicesParams = new DrtServicesParams(); + + { + DrtServiceParams clean = new DrtServiceParams("clean"); + clean.executionLimit = 1; + clean.duration = 900; + var condition1 = new TimeOfDayReachedTriggerParam(); + condition1.executionTime = 53205; + clean.addParameterSet(condition1); + drtServicesParams.addParameterSet(clean); + } + + { + DrtServiceParams deepClean = new DrtServiceParams("deep clean"); + deepClean.executionLimit = 1; + deepClean.duration = 1800; + var condition1 = new TimeOfDayReachedTriggerParam(); + condition1.executionTime = 53205; + deepClean.addParameterSet(condition1); + drtServicesParams.addParameterSet(deepClean); + } + + drtConfigGroup.addParameterSet(drtServicesParams); + ConfigUtils.writeMinimalConfig(outputConfig,outputFile.toString()); + + + Config inputConfig = ConfigUtils.loadConfig(outputFile.toString()); + var drtConfigGroup2 = ConfigUtils.addOrGetModule(inputConfig,DrtWithExtensionsConfigGroup.class); + var servicesParams = drtConfigGroup2.getServicesParams().orElseThrow(); + var services = servicesParams.getServices(); + var service = servicesParams.getService("deep clean").orElseThrow(); + + Assertions.assertEquals(1, service.executionLimit); + Assertions.assertEquals(2, services.size()); + Assertions.assertTrue(drtConfigGroup2.getServicesParams().isPresent()); + + + } + + +} diff --git a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/services/RunDrtWithServicesScenarioIT.java b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/services/RunDrtWithServicesScenarioIT.java new file mode 100644 index 00000000000..1a47a02ed58 --- /dev/null +++ b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/services/RunDrtWithServicesScenarioIT.java @@ -0,0 +1,87 @@ +package org.matsim.contrib.drt.extension.services; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.matsim.api.core.v01.Id; +import org.matsim.contrib.drt.extension.services.run.DrtServicesControlerCreator; +import org.matsim.contrib.drt.extension.services.services.params.DrtServiceParams; +import org.matsim.contrib.drt.extension.services.services.params.DrtServicesParams; +import org.matsim.contrib.drt.extension.services.services.params.TimeOfDayReachedTriggerParam; +import org.matsim.contrib.drt.extension.services.trackers.ServiceTracker; +import org.matsim.contrib.drt.run.MultiModeDrtConfigGroup; +import org.matsim.contrib.dvrp.fleet.DvrpVehicle; +import org.matsim.core.config.Config; +import org.matsim.core.config.ConfigUtils; +import org.matsim.core.controler.AbstractModule; +import org.matsim.core.controler.Controler; +import org.matsim.testcases.MatsimTestUtils; + +public class RunDrtWithServicesScenarioIT { + @RegisterExtension + private final MatsimTestUtils utils = new MatsimTestUtils(); + + @Test + void test() { + final String outputDirectory = utils.getOutputDirectory(); + final Config config = ServicesTestUtils.configure(outputDirectory, false); + var multiModeDrtConfigGroup = ConfigUtils.addOrGetModule(config, MultiModeDrtConfigGroup.class); + var drtConfigGroup = multiModeDrtConfigGroup.getModalElements().stream().findFirst().orElseThrow(); + + DrtServicesParams drtServicesParams = new DrtServicesParams(); + + { + DrtServiceParams clean = new DrtServiceParams("clean"); + clean.executionLimit = 1; + clean.duration = 900; + var condition1 = new TimeOfDayReachedTriggerParam(); + condition1.executionTime = 53205; + clean.addParameterSet(condition1); + drtServicesParams.addParameterSet(clean); + } + + { + DrtServiceParams deepClean = new DrtServiceParams("deep clean"); + deepClean.executionLimit = 1; + deepClean.duration = 1800; + var condition1 = new TimeOfDayReachedTriggerParam(); + condition1.executionTime = 53205; + deepClean.addParameterSet(condition1); + drtServicesParams.addParameterSet(deepClean); + } + + drtConfigGroup.addParameterSet(drtServicesParams); + + Controler controler = DrtServicesControlerCreator.createControler(config, false); + + ServiceTracker serviceTracker = new ServiceTracker(); + + controler.addOverridingModule(new AbstractModule() { + @Override + public void install() { + addEventHandlerBinding().toInstance(serviceTracker); + } + }); + + + controler.run(); + + + // Check vehicles have been cleaned + for ( var entrySet: serviceTracker.serviceTracker.entrySet()) + { + Id vehicleId = entrySet.getKey(); + int nCleaning = (int) serviceTracker.serviceTracker.get(vehicleId).stream().filter(s -> s.getServiceType().equals("clean")).count(); + Assertions.assertEquals(1,nCleaning); + } + + // Check vehicles have been deep cleaned + for ( var entrySet: serviceTracker.serviceTracker.entrySet()) + { + Id vehicleId = entrySet.getKey(); + int nCleaning = (int) serviceTracker.serviceTracker.get(vehicleId).stream().filter(s -> s.getServiceType().equals("deep clean")).count(); + Assertions.assertEquals(1,nCleaning); + } + } + +} diff --git a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/services/RunEDrtWithServicesScenarioIT.java b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/services/RunEDrtWithServicesScenarioIT.java new file mode 100644 index 00000000000..b16dca56807 --- /dev/null +++ b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/services/RunEDrtWithServicesScenarioIT.java @@ -0,0 +1,129 @@ +package org.matsim.contrib.drt.extension.services; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.matsim.api.core.v01.Id; +import org.matsim.contrib.drt.extension.edrt.optimizer.EDrtVehicleDataEntryFactory; +import org.matsim.contrib.drt.extension.services.run.EDrtServicesControlerCreator; +import org.matsim.contrib.drt.extension.services.services.params.ChargingStartedTriggerParam; +import org.matsim.contrib.drt.extension.services.services.params.DrtServiceParams; +import org.matsim.contrib.drt.extension.services.services.params.DrtServicesParams; +import org.matsim.contrib.drt.extension.services.trackers.ChargingTracker; +import org.matsim.contrib.drt.extension.services.trackers.ServiceTracker; +import org.matsim.contrib.drt.run.MultiModeDrtConfigGroup; +import org.matsim.contrib.dvrp.fleet.DvrpVehicle; +import org.matsim.contrib.dvrp.run.AbstractDvrpModeModule; +import org.matsim.contrib.ev.charging.*; +import org.matsim.contrib.ev.temperature.TemperatureService; +import org.matsim.core.config.Config; +import org.matsim.core.config.ConfigUtils; +import org.matsim.core.controler.AbstractModule; +import org.matsim.core.controler.Controler; +import org.matsim.testcases.MatsimTestUtils; + +public class RunEDrtWithServicesScenarioIT { + public static final double MINIMUM_RELATIVE_SOC = 0.2; + public static final double MAX_SOC = 1.0; + public static final double RELATIVE_SPEED = 1.0; + public static final double TEMPERATURE = 20.; + + @RegisterExtension + private final MatsimTestUtils utils = new MatsimTestUtils(); + + + @Test + void test() { + final String outputDirectory = utils.getOutputDirectory(); + final Config config = ServicesTestUtils.configure(outputDirectory, true); + var multiModeDrtConfigGroup = ConfigUtils.addOrGetModule(config, MultiModeDrtConfigGroup.class); + var drtConfigGroup = multiModeDrtConfigGroup.getModalElements().stream().findFirst().orElseThrow(); + drtConfigGroup.idleVehiclesReturnToDepots = true; // Required for standard eDrt + + DrtServicesParams drtServicesParams = new DrtServicesParams(); + + { + DrtServiceParams clean = new DrtServiceParams("clean"); + clean.duration = 300; + clean.executionLimit = 2; + clean.enableTaskStacking = true; + var condition1 = new ChargingStartedTriggerParam(); + clean.addParameterSet(condition1); + drtServicesParams.addParameterSet(clean); + } + + { + DrtServiceParams clean = new DrtServiceParams("plug in/out"); + clean.duration = 15; + clean.enableTaskStacking = false; + var condition1 = new ChargingStartedTriggerParam(); + clean.addParameterSet(condition1); + drtServicesParams.addParameterSet(clean); + } + + + + drtConfigGroup.addParameterSet(drtServicesParams); + + final Controler controler = EDrtServicesControlerCreator.createControler(config,false); + controler.addOverridingModule(new AbstractDvrpModeModule(drtConfigGroup.getMode()) { + @Override + public void install() { + bind(EDrtVehicleDataEntryFactory.EDrtVehicleDataEntryFactoryProvider.class).toInstance( + new EDrtVehicleDataEntryFactory.EDrtVehicleDataEntryFactoryProvider(MINIMUM_RELATIVE_SOC)); + } + }); + + controler.addOverridingModule(new AbstractModule() { + @Override + public void install() { + bind(ChargingLogic.Factory.class).toProvider(new ChargingWithQueueingAndAssignmentLogic.FactoryProvider(charger -> new ChargeUpToMaxSocStrategy(charger, MAX_SOC))); + bind(ChargingPower.Factory.class).toInstance(ev -> new FixedSpeedCharging(ev, RELATIVE_SPEED)); + bind(TemperatureService.class).toInstance(linkId -> TEMPERATURE); + } + }); + + ServiceTracker serviceTracker = new ServiceTracker(); + ChargingTracker chargingTracker = new ChargingTracker(); + controler.addOverridingModule(new AbstractModule() { + @Override + public void install() { + addEventHandlerBinding().toInstance(serviceTracker); + } + }); + controler.addOverridingModule(new AbstractModule() { + @Override + public void install() { + addEventHandlerBinding().toInstance(chargingTracker); + } + }); + + + controler.run(); + + // Check vehicles have been cleaned while charging + for ( var entrySet: chargingTracker.chargingTracker.entrySet()) + { + Id vehicleId = entrySet.getKey(); + int nCharging = entrySet.getValue().size(); + int nCleaning = (int) serviceTracker.serviceTracker.get(vehicleId).stream().filter(s -> s.getServiceType().equals("clean")).count(); + int reqCharging = Math.min(nCharging,2); + Assertions.assertEquals(reqCharging,nCleaning); + } + + // Check vehicles have been plugged in/out while charging + for ( var entrySet: chargingTracker.chargingTracker.entrySet()) + { + Id vehicleId = entrySet.getKey(); + int nCharging = entrySet.getValue().size(); + int nPlugInOut = (int) serviceTracker.serviceTracker.get(vehicleId).stream().filter(s -> s.getServiceType().equals("plug in/out")).count(); + Assertions.assertEquals(nCharging,nPlugInOut); + } + + } + + + + + +} diff --git a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/services/ServicesTestUtils.java b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/services/ServicesTestUtils.java new file mode 100644 index 00000000000..3df75f84079 --- /dev/null +++ b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/services/ServicesTestUtils.java @@ -0,0 +1,161 @@ +package org.matsim.contrib.drt.extension.services; + +import org.matsim.api.core.v01.TransportMode; +import org.matsim.contrib.common.zones.systems.grid.square.SquareGridZoneSystemParams; +import org.matsim.contrib.drt.analysis.zonal.DrtZoneSystemParams; +import org.matsim.contrib.drt.extension.DrtWithExtensionsConfigGroup; +import org.matsim.contrib.drt.extension.operations.DrtOperationsParams; +import org.matsim.contrib.drt.extension.operations.operationFacilities.OperationFacilitiesParams; +import org.matsim.contrib.drt.fare.DrtFareParams; +import org.matsim.contrib.drt.optimizer.constraints.DefaultDrtOptimizationConstraintsSet; +import org.matsim.contrib.drt.optimizer.insertion.extensive.ExtensiveInsertionSearchParams; +import org.matsim.contrib.drt.optimizer.rebalancing.RebalancingParams; +import org.matsim.contrib.drt.optimizer.rebalancing.mincostflow.MinCostFlowRebalancingStrategyParams; +import org.matsim.contrib.drt.run.DrtConfigGroup; +import org.matsim.contrib.drt.run.MultiModeDrtConfigGroup; +import org.matsim.contrib.dvrp.run.DvrpConfigGroup; +import org.matsim.contrib.ev.EvConfigGroup; +import org.matsim.contrib.zone.skims.DvrpTravelTimeMatrixParams; +import org.matsim.core.config.Config; +import org.matsim.core.config.ConfigGroup; +import org.matsim.core.config.ConfigUtils; +import org.matsim.core.config.groups.QSimConfigGroup; +import org.matsim.core.config.groups.ReplanningConfigGroup; +import org.matsim.core.config.groups.ScoringConfigGroup; +import org.matsim.core.controler.OutputDirectoryHierarchy; +import org.matsim.examples.ExamplesUtils; + +import java.util.HashSet; +import java.util.Set; + +/** + * @author steffenaxer + */ +public class ServicesTestUtils { + + + public static Config configure(String outputDirectory,boolean electrified) + { + String fleetFile = "holzkirchenFleet.xml"; + String plansFile = "holzkirchenPlans.xml.gz"; + String networkFile = "holzkirchenNetwork.xml.gz"; + String opFacilitiesFile = "holzkirchenOperationFacilities.xml"; + String chargersFile = "holzkirchenChargers.xml"; + String evsFile = "holzkirchenElectricFleet.xml"; + + MultiModeDrtConfigGroup multiModeDrtConfigGroup = new MultiModeDrtConfigGroup(DrtWithExtensionsConfigGroup::new); + + DrtWithExtensionsConfigGroup drtConfigGroup = (DrtWithExtensionsConfigGroup) multiModeDrtConfigGroup.createParameterSet("drt"); + + drtConfigGroup.mode = TransportMode.drt; + DefaultDrtOptimizationConstraintsSet defaultConstraintsSet = + (DefaultDrtOptimizationConstraintsSet) drtConfigGroup.addOrGetDrtOptimizationConstraintsParams() + .addOrGetDefaultDrtOptimizationConstraintsSet(); + drtConfigGroup.stopDuration = 30.; + defaultConstraintsSet.maxTravelTimeAlpha = 1.5; + defaultConstraintsSet.maxTravelTimeBeta = 10. * 60.; + defaultConstraintsSet.maxWaitTime = 600.; + defaultConstraintsSet.rejectRequestIfMaxWaitOrTravelTimeViolated = true; + defaultConstraintsSet.maxWalkDistance = 1000.; + drtConfigGroup.useModeFilteredSubnetwork = false; + drtConfigGroup.vehiclesFile = fleetFile; + drtConfigGroup.operationalScheme = DrtConfigGroup.OperationalScheme.door2door; + drtConfigGroup.plotDetailedCustomerStats = true; + drtConfigGroup.idleVehiclesReturnToDepots = false; + + drtConfigGroup.addParameterSet(new ExtensiveInsertionSearchParams()); + + ConfigGroup rebalancing = drtConfigGroup.createParameterSet("rebalancing"); + drtConfigGroup.addParameterSet(rebalancing); + ((RebalancingParams) rebalancing).interval = 600; + + MinCostFlowRebalancingStrategyParams strategyParams = new MinCostFlowRebalancingStrategyParams(); + strategyParams.targetAlpha = 0.3; + strategyParams.targetBeta = 0.3; + + drtConfigGroup.getRebalancingParams().get().addParameterSet(strategyParams); + + DrtZoneSystemParams drtZoneSystemParams = new DrtZoneSystemParams(); + SquareGridZoneSystemParams zoneParams = (SquareGridZoneSystemParams) drtZoneSystemParams.createParameterSet(SquareGridZoneSystemParams.SET_NAME); + zoneParams.cellSize = 500.; + drtZoneSystemParams.addParameterSet(zoneParams); + drtZoneSystemParams.targetLinkSelection = DrtZoneSystemParams.TargetLinkSelection.mostCentral; + drtConfigGroup.addParameterSet(drtZoneSystemParams); + + multiModeDrtConfigGroup.addParameterSet(drtConfigGroup); + + DvrpConfigGroup dvrpConfigGroup = new DvrpConfigGroup(); + DvrpTravelTimeMatrixParams matrixParams = dvrpConfigGroup.getTravelTimeMatrixParams(); + matrixParams.addParameterSet(matrixParams.createParameterSet(SquareGridZoneSystemParams.SET_NAME)); + + final Config config = ConfigUtils.createConfig(multiModeDrtConfigGroup, + dvrpConfigGroup); + config.setContext(ExamplesUtils.getTestScenarioURL("holzkirchen")); + + Set modes = new HashSet<>(); + modes.add("drt"); + config.travelTimeCalculator().setAnalyzedModes(modes); + + ScoringConfigGroup.ModeParams scoreParams = new ScoringConfigGroup.ModeParams("drt"); + config.scoring().addModeParams(scoreParams); + ScoringConfigGroup.ModeParams scoreParams2 = new ScoringConfigGroup.ModeParams("walk"); + config.scoring().addModeParams(scoreParams2); + + config.plans().setInputFile(plansFile); + config.network().setInputFile(networkFile); + + config.qsim().setSimStarttimeInterpretation(QSimConfigGroup.StarttimeInterpretation.onlyUseStarttime); + config.qsim().setSimEndtimeInterpretation(QSimConfigGroup.EndtimeInterpretation.minOfEndtimeAndMobsimFinished); + + final ScoringConfigGroup.ActivityParams home = new ScoringConfigGroup.ActivityParams("home"); + home.setTypicalDuration(8 * 3600); + final ScoringConfigGroup.ActivityParams other = new ScoringConfigGroup.ActivityParams("other"); + other.setTypicalDuration(4 * 3600); + final ScoringConfigGroup.ActivityParams education = new ScoringConfigGroup.ActivityParams("education"); + education.setTypicalDuration(6 * 3600); + final ScoringConfigGroup.ActivityParams shopping = new ScoringConfigGroup.ActivityParams("shopping"); + shopping.setTypicalDuration(2 * 3600); + final ScoringConfigGroup.ActivityParams work = new ScoringConfigGroup.ActivityParams("work"); + work.setTypicalDuration(2 * 3600); + + config.scoring().addActivityParams(home); + config.scoring().addActivityParams(other); + config.scoring().addActivityParams(education); + config.scoring().addActivityParams(shopping); + config.scoring().addActivityParams(work); + + final ReplanningConfigGroup.StrategySettings stratSets = new ReplanningConfigGroup.StrategySettings(); + stratSets.setWeight(1); + stratSets.setStrategyName("ChangeExpBeta"); + config.replanning().addStrategySettings(stratSets); + + config.controller().setLastIteration(1); + config.controller().setWriteEventsInterval(1); + + config.controller().setOverwriteFileSetting(OutputDirectoryHierarchy.OverwriteFileSetting.deleteDirectoryIfExists); + config.controller().setOutputDirectory(outputDirectory); + + DrtOperationsParams operationsParams = (DrtOperationsParams) drtConfigGroup.createParameterSet(DrtOperationsParams.SET_NAME); + OperationFacilitiesParams operationFacilitiesParams = (OperationFacilitiesParams) operationsParams.createParameterSet(OperationFacilitiesParams.SET_NAME); + operationsParams.addParameterSet(operationFacilitiesParams); + operationFacilitiesParams.operationFacilityInputFile = opFacilitiesFile; + drtConfigGroup.addParameterSet(operationsParams); + + DrtFareParams drtFareParams = new DrtFareParams(); + drtFareParams.baseFare = 1.; + drtFareParams.distanceFare_m = 1. / 1000; + drtConfigGroup.addParameterSet(drtFareParams); + + if(electrified) + { + final EvConfigGroup evConfigGroup = new EvConfigGroup(); + evConfigGroup.chargersFile = chargersFile; + evConfigGroup.minimumChargeTime = 0; + evConfigGroup.timeProfiles = true; + config.addModule(evConfigGroup); + } + + config.vehicles().setVehiclesFile(evsFile); + return config; + } +} diff --git a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/services/trackers/ChargingTracker.java b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/services/trackers/ChargingTracker.java new file mode 100644 index 00000000000..364b9dad2af --- /dev/null +++ b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/services/trackers/ChargingTracker.java @@ -0,0 +1,33 @@ +package org.matsim.contrib.drt.extension.services.trackers; + +import org.matsim.api.core.v01.Id; +import org.matsim.contrib.drt.extension.edrt.schedule.EDrtChargingTask; +import org.matsim.contrib.dvrp.fleet.DvrpVehicle; +import org.matsim.contrib.dvrp.vrpagent.TaskStartedEvent; +import org.matsim.contrib.dvrp.vrpagent.TaskStartedEventHandler; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author steffenaxer + */ +public class ChargingTracker implements TaskStartedEventHandler { + public Map, List> chargingTracker = new HashMap<>(); + + @Override + public void handleEvent(TaskStartedEvent event) { + if (event.getTaskType().equals(EDrtChargingTask.TYPE)) + { + chargingTracker.computeIfAbsent(event.getDvrpVehicleId(), k -> new ArrayList<>()).add(event); + } + } + + @Override + public void reset(int iteration) + { + this.chargingTracker.clear(); + } +} diff --git a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/services/trackers/ServiceTracker.java b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/services/trackers/ServiceTracker.java new file mode 100644 index 00000000000..2e7a7adcd25 --- /dev/null +++ b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/services/trackers/ServiceTracker.java @@ -0,0 +1,28 @@ +package org.matsim.contrib.drt.extension.services.trackers; + +import org.matsim.api.core.v01.Id; +import org.matsim.contrib.drt.extension.services.events.DrtServiceScheduledEvent; +import org.matsim.contrib.drt.extension.services.events.DrtServiceScheduledEventHandler; +import org.matsim.contrib.dvrp.fleet.DvrpVehicle; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** +* @author steffenaxer +*/public class ServiceTracker implements DrtServiceScheduledEventHandler { + public Map, List> serviceTracker = new HashMap<>(); + + @Override + public void handleEvent(DrtServiceScheduledEvent event) { + serviceTracker.computeIfAbsent(event.getVehicleId(), k -> new ArrayList<>()).add(event); + } + + @Override + public void reset(int iteration) + { + this.serviceTracker.clear(); + } +} diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/constraints/DrtRouteConstraints.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/constraints/DrtRouteConstraints.java new file mode 100644 index 00000000000..68d0fb4ae2e --- /dev/null +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/constraints/DrtRouteConstraints.java @@ -0,0 +1,12 @@ +package org.matsim.contrib.drt.optimizer.constraints; + +/** + * @author Sebastian Hörl, IRT SystemX + */ +public record DrtRouteConstraints( // + double maxTravelTime, // + double maxRideTime, // + double maxWaitTime// +) { + +} diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/rebalancing/plusOne/PlusOneRebalancingStrategy.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/rebalancing/plusOne/PlusOneRebalancingStrategy.java index 2c67ee8640f..12469c783fb 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/rebalancing/plusOne/PlusOneRebalancingStrategy.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/optimizer/rebalancing/plusOne/PlusOneRebalancingStrategy.java @@ -99,7 +99,9 @@ public void handleEvent(DrtRequestSubmittedEvent event) { public void handleEvent(PassengerRequestScheduledEvent event) { if (event.getMode().equals(mode)) { Id linkId = potentialTargetLinks.remove(event.getRequestId()); - targets.add(new Target(linkId, event.getTime())); + if(linkId != null) { + targets.add(new Target(linkId, event.getTime())); + } } } diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/PrebookingManager.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/PrebookingManager.java index 04d8df45161..a5dad2f114b 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/PrebookingManager.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/PrebookingManager.java @@ -395,13 +395,23 @@ private void processRejections(double now) { if(abortRejectedPrebookings) { for (Id passengerId : item.request.getPassengerIds()) { MobsimAgent agent = internalInterface.getMobsim().getAgents().get(passengerId); - PlanElement planElement = WithinDayAgentUtils.getCurrentPlanElement(agent); - if(planElement instanceof Activity activity) { - activity.setEndTime(Double.POSITIVE_INFINITY); - activity.setMaximumDurationUndefined(); - ((HasModifiablePlan) agent).resetCaches(); - internalInterface.getMobsim().rescheduleActivityEnd(agent); + + int index = WithinDayAgentUtils.getCurrentPlanElementIndex(agent); + Plan plan = WithinDayAgentUtils.getModifiablePlan(agent); + PlanElement planElement = plan.getPlanElements().get(index); + Activity activity; + if(planElement instanceof Activity currentActivity) { + activity = currentActivity; + } else { + // If the current element is a leg, the agent is walking towards the pickup location + // We make the agent stuck at the interaction activity + activity = (Activity) plan.getPlanElements().get(index+1); } + activity.setEndTime(Double.POSITIVE_INFINITY); + activity.setMaximumDurationUndefined(); + + ((HasModifiablePlan) agent).resetCaches(); + internalInterface.getMobsim().rescheduleActivityEnd(agent); eventsManager.processEvent(new PersonStuckEvent(now, agent.getId(), agent.getCurrentLinkId(), this.mode)); internalInterface.getMobsim().getAgentCounter().incLost(); diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/routing/DefaultDrtRouteConstraintsCalculator.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/routing/DefaultDrtRouteConstraintsCalculator.java index 039890d8801..f8e1f9b36eb 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/routing/DefaultDrtRouteConstraintsCalculator.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/routing/DefaultDrtRouteConstraintsCalculator.java @@ -1,45 +1,53 @@ package org.matsim.contrib.drt.routing; +import org.matsim.api.core.v01.network.Link; +import org.matsim.api.core.v01.population.Person; +import org.matsim.contrib.drt.optimizer.constraints.ConstraintSetChooser; import org.matsim.contrib.drt.optimizer.constraints.DefaultDrtOptimizationConstraintsSet; import org.matsim.contrib.drt.optimizer.constraints.DrtOptimizationConstraintsSet; +import org.matsim.contrib.drt.optimizer.constraints.DrtRouteConstraints; +import org.matsim.contrib.drt.run.DrtConfigGroup; +import org.matsim.utils.objectattributes.attributable.Attributes; /** * @author nkuehnel / MOIA */ public class DefaultDrtRouteConstraintsCalculator implements DrtRouteConstraintsCalculator { - /** - * Calculates the maximum travel time defined as: drtCfg.getMaxTravelTimeAlpha() * unsharedRideTime + drtCfg.getMaxTravelTimeBeta() - * - * @param constraintsSet - * @param unsharedRideTime ride time of the direct (shortest-time) route - * @return maximum travel time - */ - @Override - public double getMaxTravelTime(DrtOptimizationConstraintsSet constraintsSet, double unsharedRideTime) { - if(constraintsSet instanceof DefaultDrtOptimizationConstraintsSet defaultSet) { - return defaultSet.maxTravelTimeAlpha * unsharedRideTime - + defaultSet.maxTravelTimeBeta; - } else { - throw new IllegalArgumentException("Constraint set is not a default set"); - } - } - - /** - * Calculates the maximum ride time defined as: drtCfg.maxDetourAlpha * unsharedRideTime + drtCfg.maxDetourBeta - * - * @param constraintsSet - * @param unsharedRideTime ride time of the direct (shortest-time) route - * @return maximum ride time - */ - @Override - public double getMaxRideTime(DrtOptimizationConstraintsSet constraintsSet, double unsharedRideTime) { - if(constraintsSet instanceof DefaultDrtOptimizationConstraintsSet defaultSet) { - return Math.min(unsharedRideTime + defaultSet.maxAbsoluteDetour, - defaultSet.maxDetourAlpha * unsharedRideTime - + defaultSet.maxDetourBeta); - } else { - throw new IllegalArgumentException("Constraint set is not a default set"); - } - } + private final DrtConfigGroup drtCfg; + private final ConstraintSetChooser constraintSetChooser; + + public DefaultDrtRouteConstraintsCalculator(DrtConfigGroup drtCfg, ConstraintSetChooser constraintSetChooser) { + this.drtCfg = drtCfg; + this.constraintSetChooser = constraintSetChooser; + } + + /** + * Calculates the maximum travel time defined as: drtCfg.getMaxTravelTimeAlpha() + * unsharedRideTime + drtCfg.getMaxTravelTimeBeta() + * + * Calculates the maximum ride time defined as: drtCfg.maxDetourAlpha * + * unsharedRideTime + drtCfg.maxDetourBeta + * + * @return DrtRouteConstraints constraints + */ + @Override + public DrtRouteConstraints calculateRouteConstraints(double departureTime, Link accessActLink, Link egressActLink, + Person person, Attributes tripAttributes, double unsharedRideTime, double unsharedDistance) { + DrtOptimizationConstraintsSet constraintsSet = constraintSetChooser + .chooseConstraintSet(departureTime, accessActLink, egressActLink, person, tripAttributes).orElse(drtCfg + .addOrGetDrtOptimizationConstraintsParams().addOrGetDefaultDrtOptimizationConstraintsSet()); + + if (constraintsSet instanceof DefaultDrtOptimizationConstraintsSet defaultSet) { + double maxTravelTime = defaultSet.maxTravelTimeAlpha * unsharedRideTime + defaultSet.maxTravelTimeBeta; + double maxRideTime = Math.min(unsharedRideTime + defaultSet.maxAbsoluteDetour, + defaultSet.maxDetourAlpha * unsharedRideTime + defaultSet.maxDetourBeta); + double maxWaitTime = constraintsSet.maxWaitTime; + + return new DrtRouteConstraints(maxTravelTime, maxRideTime, maxWaitTime); + } else { + throw new IllegalArgumentException("Constraint set is not a default set"); + } + + } } \ No newline at end of file diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/routing/DrtRouteConstraintsCalculator.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/routing/DrtRouteConstraintsCalculator.java index a22a942f35a..726d495fc1e 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/routing/DrtRouteConstraintsCalculator.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/routing/DrtRouteConstraintsCalculator.java @@ -1,13 +1,24 @@ package org.matsim.contrib.drt.routing; -import org.matsim.contrib.drt.optimizer.constraints.DrtOptimizationConstraintsSet; +import org.matsim.api.core.v01.network.Link; +import org.matsim.api.core.v01.population.Person; +import org.matsim.contrib.drt.optimizer.constraints.DrtRouteConstraints; +import org.matsim.utils.objectattributes.attributable.Attributes; /** * @author nkuehnel / MOIA + * @author Sebastian Hörl, IRT SystemX */ public interface DrtRouteConstraintsCalculator { - double getMaxTravelTime(DrtOptimizationConstraintsSet constraintsSet, double unsharedRideTime); + DrtRouteConstraints calculateRouteConstraints( // + double departureTime, // + Link accessActLink, // + Link egressActLink, // + Person person, // + Attributes tripAttributes, // + double unsharedRideTime, // + double unsharedDistance // + ); - double getMaxRideTime(DrtOptimizationConstraintsSet constraintsSet, double unsharedRideTime); } diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/routing/DrtRouteCreator.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/routing/DrtRouteCreator.java index b646494a1fc..258f862785f 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/routing/DrtRouteCreator.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/routing/DrtRouteCreator.java @@ -25,6 +25,7 @@ import org.matsim.api.core.v01.population.Route; import org.matsim.contrib.drt.optimizer.constraints.ConstraintSetChooser; import org.matsim.contrib.drt.optimizer.constraints.DrtOptimizationConstraintsSet; +import org.matsim.contrib.drt.optimizer.constraints.DrtRouteConstraints; import org.matsim.contrib.drt.run.DrtConfigGroup; import org.matsim.contrib.dvrp.path.VrpPathWithTravelData; import org.matsim.contrib.dvrp.path.VrpPaths; @@ -40,6 +41,7 @@ * @author jbischoff * @author michalm (Michal Maciejewski) * @author Kai Nagel + * @author Sebastian Hörl, IRT SystemX */ public class DrtRouteCreator implements DefaultMainLegRouter.RouteCreator { private final DrtConfigGroup drtCfg; @@ -48,16 +50,13 @@ public class DrtRouteCreator implements DefaultMainLegRouter.RouteCreator { private final DrtRouteConstraintsCalculator routeConstraintsCalculator; - private final ConstraintSetChooser constraintSetChooser; - public DrtRouteCreator(DrtConfigGroup drtCfg, Network modalNetwork, LeastCostPathCalculatorFactory leastCostPathCalculatorFactory, TravelTime travelTime, TravelDisutilityFactory travelDisutilityFactory, - DrtRouteConstraintsCalculator routeConstraintsCalculator, ConstraintSetChooser constraintSetChooser) { + DrtRouteConstraintsCalculator routeConstraintsCalculator) { this.drtCfg = drtCfg; this.travelTime = travelTime; this.routeConstraintsCalculator = routeConstraintsCalculator; - this.constraintSetChooser = constraintSetChooser; router = leastCostPathCalculatorFactory.createPathCalculator(modalNetwork, travelDisutilityFactory.createTravelDisutility(travelTime), travelTime); } @@ -71,18 +70,15 @@ public Route createRoute(double departureTime, Link accessActLink, Link egressAc double unsharedRideTime = unsharedPath.getTravelTime();//includes first & last link double unsharedDistance = VrpPaths.calcDistance(unsharedPath);//includes last link - DrtOptimizationConstraintsSet constraintsSet = - constraintSetChooser.chooseConstraintSet(departureTime, accessActLink, egressActLink, person, tripAttributes) - .orElse(drtCfg.addOrGetDrtOptimizationConstraintsParams().addOrGetDefaultDrtOptimizationConstraintsSet()); - double maxTravelTime = routeConstraintsCalculator.getMaxTravelTime(constraintsSet, unsharedRideTime); - double maxRideDuration = routeConstraintsCalculator.getMaxRideTime(constraintsSet, unsharedRideTime); + DrtRouteConstraints constraints = routeConstraintsCalculator.calculateRouteConstraints(departureTime, accessActLink, egressActLink, person, + tripAttributes, unsharedRideTime, unsharedDistance); DrtRoute route = routeFactories.createRoute(DrtRoute.class, accessActLink.getId(), egressActLink.getId()); route.setDistance(unsharedDistance); - route.setTravelTime(maxTravelTime); - route.setMaxRideTime(maxRideDuration); + route.setTravelTime(constraints.maxTravelTime()); + route.setMaxRideTime(constraints.maxRideTime()); route.setDirectRideTime(unsharedRideTime); - route.setMaxWaitTime(constraintsSet.maxWaitTime); + route.setMaxWaitTime(constraints.maxWaitTime()); if (this.drtCfg.storeUnsharedPath) { route.setUnsharedPath(unsharedPath); diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/run/DrtModeRoutingModule.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/run/DrtModeRoutingModule.java index fcbc25faea1..68ae4523ec9 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/run/DrtModeRoutingModule.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/run/DrtModeRoutingModule.java @@ -97,7 +97,8 @@ public void install() { // yyyy possibly not used for door2door; try to move inside the corresponding switch statement below. kai, feb'24 - bindModal(DrtRouteConstraintsCalculator.class).toProvider(modalProvider(getter -> new DefaultDrtRouteConstraintsCalculator())).in(Singleton.class); + bindModal(DrtRouteConstraintsCalculator.class).toProvider(modalProvider(getter -> new DefaultDrtRouteConstraintsCalculator( + drtCfg, getter.getModal(ConstraintSetChooser.class)))).in(Singleton.class); DrtOptimizationConstraintsSet optimizationConstraintsSet = drtCfg.addOrGetDrtOptimizationConstraintsParams().addOrGetDefaultDrtOptimizationConstraintsSet(); bindModal(ConstraintSetChooser.class).toProvider( () -> (departureTime, accessActLink, egressActLink, person, tripAttributes) @@ -159,8 +160,7 @@ public DrtRouteCreator get() { var travelTime = getModalInstance(TravelTime.class); return new DrtRouteCreator(drtCfg, getModalInstance(Network.class), leastCostPathCalculatorFactory, travelTime, getModalInstance(TravelDisutilityFactory.class), - getModalInstance(DrtRouteConstraintsCalculator.class), - getModalInstance(ConstraintSetChooser.class)); + getModalInstance(DrtRouteConstraintsCalculator.class)); } } diff --git a/contribs/drt/src/test/java/org/matsim/contrib/drt/routing/DrtRoutingModuleTest.java b/contribs/drt/src/test/java/org/matsim/contrib/drt/routing/DrtRoutingModuleTest.java index a9c0a735b47..9e2c2d2aad0 100644 --- a/contribs/drt/src/test/java/org/matsim/contrib/drt/routing/DrtRoutingModuleTest.java +++ b/contribs/drt/src/test/java/org/matsim/contrib/drt/routing/DrtRoutingModuleTest.java @@ -95,8 +95,8 @@ void testCottbusClosestAccessEgressStopFinder() { scenario.getNetwork(), QuadTrees.createQuadTree(drtStops.values())); DrtRouteCreator drtRouteCreator = new DrtRouteCreator(drtCfg, scenario.getNetwork(), new SpeedyDijkstraFactory(), new FreeSpeedTravelTime(), TimeAsTravelDisutility::new, - new DefaultDrtRouteConstraintsCalculator(), - (departureTime, accessActLink, egressActLink, person, tripAttributes) -> Optional.of(defaultConstraintsSet)); + new DefaultDrtRouteConstraintsCalculator(drtCfg, + (departureTime, accessActLink, egressActLink, person, tripAttributes) -> Optional.of(defaultConstraintsSet))); DefaultMainLegRouter mainRouter = new DefaultMainLegRouter(drtMode, scenario.getNetwork(), scenario.getPopulation().getFactory(), drtRouteCreator); DvrpRoutingModule dvrpRoutingModule = new DvrpRoutingModule(mainRouter, walkRouter, walkRouter, stopFinder, diff --git a/contribs/dvrp/src/main/java/org/matsim/contrib/zone/skims/DvrpTravelTimeMatrixParams.java b/contribs/dvrp/src/main/java/org/matsim/contrib/zone/skims/DvrpTravelTimeMatrixParams.java index a12930c5d42..52c3c332f09 100644 --- a/contribs/dvrp/src/main/java/org/matsim/contrib/zone/skims/DvrpTravelTimeMatrixParams.java +++ b/contribs/dvrp/src/main/java/org/matsim/contrib/zone/skims/DvrpTravelTimeMatrixParams.java @@ -20,6 +20,7 @@ package org.matsim.contrib.zone.skims; +import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.PositiveOrZero; import org.matsim.contrib.common.util.ReflectiveConfigGroupWithConfigurableParameterSets; import org.matsim.contrib.common.zones.ZoneSystemParams; @@ -55,6 +56,7 @@ public class DvrpTravelTimeMatrixParams extends ReflectiveConfigGroupWithConfigu + " The unit is seconds. Default value is 0 s (for backward compatibility).") @PositiveOrZero public double maxNeighborTravelTime = 0; //[s] + @NotNull private ZoneSystemParams zoneSystemParams; @@ -101,6 +103,11 @@ public void handleAddUnknownParam(String paramName, String value) { } public ZoneSystemParams getZoneSystemParams() { + if(this.zoneSystemParams == null) { + SquareGridZoneSystemParams squareGridZoneSystemParams = new SquareGridZoneSystemParams(); + squareGridZoneSystemParams.cellSize = 200; + this.zoneSystemParams = squareGridZoneSystemParams; + } return zoneSystemParams; } } diff --git a/contribs/freight/pom.xml b/contribs/freight/pom.xml index cfd34b6d514..d6dd0d20b65 100644 --- a/contribs/freight/pom.xml +++ b/contribs/freight/pom.xml @@ -64,6 +64,14 @@ 2025.0-SNAPSHOT + + + + + + + + org.mockito mockito-core diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/Carrier.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/Carrier.java index e4363accdf8..8ee9e1812e5 100644 --- a/contribs/freight/src/main/java/org/matsim/freight/carriers/Carrier.java +++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/Carrier.java @@ -76,7 +76,7 @@ public interface Carrier extends HasPlansAndId, Attributab /** * Sets a {@link CarrierPlan} as selected. * - *

If selectedPlan in not in plan-collection, it adds it. + *

The selected plan should be added to the list of plans before.

* * @param selectedPlan to be set */ diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierImpl.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierImpl.java index 9d8a439af32..8dcc53adc75 100644 --- a/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierImpl.java +++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/CarrierImpl.java @@ -82,15 +82,26 @@ public CarrierPlan getSelectedPlan() { } /** - * Selects the selectedPlan. - * - *

If the plan-collection does not contain the selectedPlan, it is added to that collection. - * + * Adds a new CarrierPlan. + * Makes it selected if no other selectedPlan exists. + * @param carrierPlan carrierPlan to be added + */ + @Override + public boolean addPlan(CarrierPlan carrierPlan) { + // Make sure there is a selected carrierPlan if there is at least one carrierPlan + if (this.selectedPlan == null) this.selectedPlan = carrierPlan; + return this.plans.add(carrierPlan); + } + + /** + * Set Plan as the selectedPlan. * @param selectedPlan to be selected */ @Override - public void setSelectedPlan(CarrierPlan selectedPlan) { - if(!plans.contains(selectedPlan)) plans.add(selectedPlan); + public void setSelectedPlan(final CarrierPlan selectedPlan) { + if (selectedPlan != null && !plans.contains( selectedPlan )) { + throw new IllegalStateException("The plan to be set as selected is neither not null nor stored in the carrier's plans"); + } this.selectedPlan = selectedPlan; } @@ -109,14 +120,12 @@ public Map, CarrierService> getServices(){ return services; } - @Override - public boolean addPlan(CarrierPlan p) { - throw new RuntimeException("not implemented") ; - } + @Override public CarrierPlan createCopyOfSelectedPlanAndMakeSelected() { CarrierPlan newPlan = CarriersUtils.copyPlan(this.selectedPlan ) ; + this.addPlan( newPlan ) ; this.setSelectedPlan( newPlan ) ; return newPlan ; } @@ -127,7 +136,10 @@ public boolean removePlan(CarrierPlan p) { } @Override - public void clearPlans() { this.plans.clear(); } + public void clearPlans() { + this.plans.clear(); + this.selectedPlan = null; + } @Override public Attributes getAttributes() { diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/CarriersUtils.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/CarriersUtils.java index de88f529862..7c8e7220e3e 100644 --- a/contribs/freight/src/main/java/org/matsim/freight/carriers/CarriersUtils.java +++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/CarriersUtils.java @@ -25,6 +25,7 @@ import com.graphhopper.jsprit.core.algorithm.VehicleRoutingAlgorithm; import com.graphhopper.jsprit.core.algorithm.listener.VehicleRoutingAlgorithmListeners; import com.graphhopper.jsprit.core.problem.VehicleRoutingProblem; +import com.graphhopper.jsprit.core.problem.job.Shipment; import com.graphhopper.jsprit.core.problem.solution.VehicleRoutingProblemSolution; import com.graphhopper.jsprit.core.util.Solutions; import org.apache.logging.log4j.LogManager; @@ -52,7 +53,7 @@ public class CarriersUtils { static final String CARRIER_VEHICLE = "carrierVehicle"; @SuppressWarnings("unused") - private static final Logger log = LogManager.getLogger(CarriersUtils.class); + private static final Logger log = LogManager.getLogger(CarriersUtils.class); /** * From the outside, rather use {@link CarriersUtils#getCarriers(Scenario)} . * This string constant will eventually become private. @@ -64,67 +65,82 @@ public class CarriersUtils { private static final String ATTR_JSPRIT_SCORE = "jspritScore"; private static final String ATTR_JSPRIT_Time = "jspritComputationTime"; - public static Carrier createCarrier( Id id ){ + /** + * Enum to decide for which carriers a new solution should be created. + * This makes only a difference if the carriers already have a plan. + */ + public enum CarrierSelectionForSolution { + solveForAllCarriersAndOverrideExistingPlans, //Overwrite all existing plans of the carriers and create new solutions. + solveOnlyForCarrierWithoutPlans, //Create new solutions only for carriers with no plans. Existing plans of other carriers are not changed. + solveForAllCarriersAndAddPLans // Add new plans to existing plans of carriers. The new plans are set as selected plans. + } + + public static Carrier createCarrier(Id id) { return new CarrierImpl(id); } /** - * Adds an carrierVehicle to the CarrierCapabilities of the Carrier. - * @param carrier - * @param carrierVehicle + * Adds a carrierVehicle to the CarrierCapabilities of the Carrier. + * + * @param carrier the carrier + * @param carrierVehicle the vehicle to add */ - public static void addCarrierVehicle(Carrier carrier, CarrierVehicle carrierVehicle){ + public static void addCarrierVehicle(Carrier carrier, CarrierVehicle carrierVehicle) { carrier.getCarrierCapabilities().getCarrierVehicles().put(carrierVehicle.getId(), carrierVehicle); } - public static CarrierVehicle getCarrierVehicle(Carrier carrier, Id vehicleId){ + public static CarrierVehicle getCarrierVehicle(Carrier carrier, Id vehicleId) { CarrierVehicle veh = carrier.getCarrierCapabilities().getCarrierVehicles().get(vehicleId); - if(veh != null){ + if (veh != null) { return veh; } - log.error("Vehicle with Id does not exists", new IllegalStateException("vehicle with id " + vehicleId + " is missing in Carrier: " + carrier.getId())); + log.error("Vehicle with Id does not exists", + new IllegalStateException("vehicle with id " + vehicleId + " is missing in Carrier: " + carrier.getId())); return null; } /** * Adds an {@link CarrierService} to the {@link Carrier}. - * @param carrier - * @param carrierService + * + * @param carrier the carrier + * @param carrierService the service */ - public static void addService(Carrier carrier, CarrierService carrierService){ + public static void addService(Carrier carrier, CarrierService carrierService) { carrier.getServices().put(carrierService.getId(), carrierService); } - public static CarrierService getService(Carrier carrier, Id serviceId){ + public static CarrierService getService(Carrier carrier, Id serviceId) { CarrierService service = carrier.getServices().get(serviceId); - if(service != null){ + if (service != null) { return service; } - log.error("Service with Id does not exists", new IllegalStateException("Service with id " + serviceId + " is missing in Carrier: " + carrier.getId())); + log.error("Service with Id does not exists", + new IllegalStateException("Service with id " + serviceId + " is missing in Carrier: " + carrier.getId())); return null; } /** * Adds an {@link CarrierShipment} to the {@link Carrier}. - * @param carrier - * @param carrierShipment + * + * @param carrier the carrier + * @param carrierShipment the shipment */ - public static void addShipment(Carrier carrier, CarrierShipment carrierShipment){ + public static void addShipment(Carrier carrier, CarrierShipment carrierShipment) { carrier.getShipments().put(carrierShipment.getId(), carrierShipment); } - public static CarrierShipment getShipment(Carrier carrier, Id serviceId){ + public static CarrierShipment getShipment(Carrier carrier, Id serviceId) { CarrierShipment shipment = carrier.getShipments().get(serviceId); - if(shipment != null){ + if (shipment != null) { return shipment; } - log.error("Shipment with Id does not exists", new IllegalStateException("Shipment with id " + serviceId + " is missing in Carrier: " + carrier.getId())); + log.error("Shipment with Id does not exists", + new IllegalStateException("Shipment with id " + serviceId + " is missing in Carrier: " + carrier.getId())); return null; } - - public static CarrierPlan copyPlan( CarrierPlan plan2copy ) { + public static CarrierPlan copyPlan(CarrierPlan plan2copy) { List tours = new ArrayList<>(); for (ScheduledTour sTour : plan2copy.getScheduledTours()) { double depTime = sTour.getDeparture(); @@ -139,77 +155,110 @@ public static CarrierPlan copyPlan( CarrierPlan plan2copy ) { } - private static final String CARRIER_MODE = "carrierMode" ; - public static String getCarrierMode( Carrier carrier ) { - String result = (String) carrier.getAttributes().getAttribute( CARRIER_MODE ); - if ( result == null ){ - return TransportMode.car ; + private static final String CARRIER_MODE = "carrierMode"; + + public static String getCarrierMode(Carrier carrier) { + String result = (String) carrier.getAttributes().getAttribute(CARRIER_MODE); + if (result == null) { + return TransportMode.car; } else { - return result ; + return result; } } - public static void setCarrierMode( Carrier carrier, String carrierMode ) { - carrier.getAttributes().putAttribute( CARRIER_MODE, carrierMode ) ; + + public static void setCarrierMode(Carrier carrier, String carrierMode) { + carrier.getAttributes().putAttribute(CARRIER_MODE, carrierMode); } - private static final String JSPRIT_ITERATIONS="jspritIterations" ; - public static int getJspritIterations( Carrier carrier ) { - Integer result = (Integer) carrier.getAttributes().getAttribute( JSPRIT_ITERATIONS ); - if (result == null){ + private static final String JSPRIT_ITERATIONS = "jspritIterations"; + + public static int getJspritIterations(Carrier carrier) { + Integer result = (Integer) carrier.getAttributes().getAttribute(JSPRIT_ITERATIONS); + if (result == null) { log.error("Requested attribute jspritIterations does not exists. Will return " + Integer.MIN_VALUE); return Integer.MIN_VALUE; } else { - return result ; + return result; } } - public static void setJspritIterations( Carrier carrier, int jspritIterations ) { - carrier.getAttributes().putAttribute( JSPRIT_ITERATIONS , jspritIterations ) ; + public static void setJspritIterations(Carrier carrier, int jspritIterations) { + carrier.getAttributes().putAttribute(JSPRIT_ITERATIONS, jspritIterations); } - /** * Runs jsprit and so solves the VehicleRoutingProblem (VRP) for all {@link Carriers}, doing the following steps: - * - creating NetbasedCosts based on the network - * - building and solving the VRP for all carriers using jsprit - * - take the (best) solution, route and add it as {@link CarrierPlan} to the {@link Carrier}. + * - creating NetBasedCosts based on the network + * - building and solving the VRP for all carriers using jsprit + * - take the (best) solution, route and add it as {@link CarrierPlan} to the {@link Carrier}. *

* - * @param scenario + * @param scenario the scenario * @throws ExecutionException, InterruptedException */ - public static void runJsprit(Scenario scenario) throws ExecutionException, InterruptedException{ - FreightCarriersConfigGroup freightCarriersConfigGroup = ConfigUtils.addOrGetModule( scenario.getConfig(), FreightCarriersConfigGroup.class ); + public static void runJsprit(Scenario scenario) throws ExecutionException, InterruptedException { + CarrierSelectionForSolution usedCarriersSolutionType = CarrierSelectionForSolution.solveForAllCarriersAndOverrideExistingPlans; + log.warn("Running jsprit for all carriers with default solution type: {}", usedCarriersSolutionType); + log.warn("This will overwrite all existing plans of the carriers and create new solutions."); + runJsprit(scenario, usedCarriersSolutionType); + } + + /** + * Runs jsprit and so solves the VehicleRoutingProblem (VRP) for all {@link Carriers}, doing the following steps: + * - creating NetBasedCosts based on the network + * - building and solving the VRP using jsprit for the carriers based on the selected CarrierSelectionForSolution + * - take the (best) solution, route and add it as {@link CarrierPlan} to the {@link Carrier}. + *

+ * + * @param scenario the scenario + * @param carriersSolutionType the type of which carriers should be solved + */ + public static void runJsprit(Scenario scenario, CarrierSelectionForSolution carriersSolutionType) throws ExecutionException, InterruptedException { + + // necessary to create FreightCarriersConfigGroup before submitting to ThreadPoolExecutor + ConfigUtils.addOrGetModule(scenario.getConfig(), FreightCarriersConfigGroup.class); final NetworkBasedTransportCosts netBasedCosts = NetworkBasedTransportCosts.Builder.newInstance( - scenario.getNetwork(), getCarrierVehicleTypes(scenario).getVehicleTypes().values() ).build() ; + scenario.getNetwork(), getCarrierVehicleTypes(scenario).getVehicleTypes().values()).build(); Carriers carriers = getCarriers(scenario); HashMap, Integer> carrierActivityCounterMap = new HashMap<>(); // Fill carrierActivityCounterMap -> basis for sorting the carriers by number of activities before solving in parallel + // This also selects the carriers for which a new solution should be created for (Carrier carrier : carriers.getCarriers().values()) { + switch (carriersSolutionType) { + case solveForAllCarriersAndOverrideExistingPlans -> carrier.clearPlans(); + case solveOnlyForCarrierWithoutPlans -> { + if (!carrier.getPlans().isEmpty()) { + continue; + } + } + case solveForAllCarriersAndAddPLans -> {carrier.setSelectedPlan(null);} // Keep existing plan(s), but make them not selected. + default -> throw new IllegalStateException("Unexpected value: " + carriersSolutionType); + } carrierActivityCounterMap.put(carrier.getId(), carrierActivityCounterMap.getOrDefault(carrier.getId(), 0) + carrier.getServices().size()); - carrierActivityCounterMap.put(carrier.getId(), carrierActivityCounterMap.getOrDefault(carrier.getId(), 0) + 2*carrier.getShipments().size()); + carrierActivityCounterMap.put(carrier.getId(), carrierActivityCounterMap.getOrDefault(carrier.getId(), 0) + 2 * carrier.getShipments().size()); } AtomicInteger startedVRPCounter = new AtomicInteger(0); - int nThreads = Runtime.getRuntime().availableProcessors(); + int nThreads = Runtime.getRuntime().availableProcessors(); log.info("Starting VRP solving for {} carriers in parallel with {} threads.", carriers.getCarriers().size(), nThreads); ThreadPoolExecutor executor = new JspritTreadPoolExecutor(new PriorityBlockingQueue<>(), nThreads); List> futures = new ArrayList<>(); List, Integer>> sorted = carrierActivityCounterMap.entrySet().stream() - .sorted(Map.Entry.comparingByValue((o1, o2) -> o2 - o1)) - .toList(); + .sorted(Map.Entry.comparingByValue((o1, o2) -> o2 - o1)) + .toList(); - for (Map.Entry, Integer> entry : sorted){ - JspritCarrierTask task = new JspritCarrierTask(entry.getValue(), carriers.getCarriers().get(entry.getKey()), scenario, netBasedCosts, startedVRPCounter, carriers.getCarriers().size()); + for (Map.Entry, Integer> entry : sorted) { + JspritCarrierTask task = new JspritCarrierTask(entry.getValue(), carriers.getCarriers().get(entry.getKey()), scenario, netBasedCosts, + startedVRPCounter, carriers.getCarriers().size()); log.info("Adding task for carrier {} with priority {}", entry.getKey(), entry.getValue()); - futures.add(executor.submit(task)); + futures.add(executor.submit(task)); } for (Future future : futures) { @@ -217,6 +266,37 @@ public static void runJsprit(Scenario scenario) throws ExecutionException, Inter } } + /** + * Checks if the selected plan handles all jobs of a carrier. + * The check is done only by counting the number of activities in the selected plan and compare them with the number of services or shipments of the carrier. + * @param carrier the carrier + */ + public static boolean allJobsHandledBySelectedPlan(Carrier carrier) { + if (carrier.getSelectedPlan() == null) { + log.warn("Carrier {}: No selected plan available!", carrier.getId()); + return false; + } + int planedJobs; + int handledJobs; + if (!carrier.getServices().isEmpty()) { + planedJobs = carrier.getServices().size(); + handledJobs = carrier.getSelectedPlan().getScheduledTours().stream().mapToInt( + tour -> (int) tour.getTour().getTourElements().stream().filter(element -> element instanceof Tour.ServiceActivity).count()).sum(); + } else { + planedJobs = carrier.getShipments().size(); + handledJobs = carrier.getSelectedPlan().getScheduledTours().stream().mapToInt( + tour -> (int) tour.getTour().getTourElements().stream().filter( + element -> element instanceof Tour.ShipmentBasedActivity).count()).sum(); + handledJobs = handledJobs / 2; // Shipment has two activities + } + if (planedJobs != handledJobs) { + log.warn("Carrier {}: {} of {} jobs were not handled!", carrier.getId(), planedJobs - handledJobs, planedJobs); + return false; + } else { + return true; + } + } + /** * Creates a new {@link Carriers} container only with {@link CarrierShipment}s * for creating a new VRP. As consequence of the transformation of @@ -252,11 +332,11 @@ public static Carriers createShipmentVRPCarrierFromServiceVRPSolution(Carriers c * @deprecated -- please inline. Reason: move syntax closer to how it is done in {@link ConfigUtils}. */ @Deprecated - public static Carriers getOrCreateCarriers(Scenario scenario){ - return addOrGetCarriers( scenario ); + public static Carriers getOrCreateCarriers(Scenario scenario) { + return addOrGetCarriers(scenario); } - public static Carriers addOrGetCarriers(Scenario scenario ) { + public static Carriers addOrGetCarriers(Scenario scenario) { // I have separated getOrCreateCarriers and getCarriers, since when the // controler is started, it is better to fail if the carriers are not found. // kai, oct'19 @@ -271,9 +351,9 @@ public static Carriers addOrGetCarriers(Scenario scenario ) { public static Carriers getCarriers(Scenario scenario) { // I have separated getOrCreateCarriers and getCarriers, since when the controler is started, it is better to fail if the carriers are // not found. kai, oct'19 - if ( scenario.getScenarioElement( CARRIERS ) == null ) { - throw new RuntimeException( "cannot retrieve carriers from scenario; typical ways to resolve that problem are to call " + - "CarrierControlerUtils.getOrCreateCarriers(...) or CarrierControlerUtils.loadCarriersAccordingToFreightConfig(...) early enough\n") ; + if (scenario.getScenarioElement(CARRIERS) == null) { + throw new RuntimeException("cannot retrieve carriers from scenario; typical ways to resolve that problem are to call " + + "CarrierControlerUtils.getOrCreateCarriers(...) or CarrierControlerUtils.loadCarriersAccordingToFreightConfig(...) early enough\n"); } return (Carriers) scenario.getScenarioElement(CARRIERS); } @@ -290,16 +370,18 @@ public static CarrierVehicleTypes getCarrierVehicleTypes(Scenario scenario) { /** * Use if carriers and carrierVehicleTypes are set by input file * - * @param scenario + * @param scenario the scenario */ public static void loadCarriersAccordingToFreightConfig(Scenario scenario) { FreightCarriersConfigGroup freightCarriersConfigGroup = ConfigUtils.addOrGetModule(scenario.getConfig(), FreightCarriersConfigGroup.class); CarrierVehicleTypes vehTypes = getCarrierVehicleTypes(scenario); - new CarrierVehicleTypeReader( vehTypes ).readURL( IOUtils.extendUrl(scenario.getConfig().getContext(), freightCarriersConfigGroup.getCarriersVehicleTypesFile()) ); + new CarrierVehicleTypeReader(vehTypes).readURL( + IOUtils.extendUrl(scenario.getConfig().getContext(), freightCarriersConfigGroup.getCarriersVehicleTypesFile())); - Carriers carriers = addOrGetCarriers( scenario ); // also registers with scenario - new CarrierPlanXmlReader( carriers, vehTypes ).readURL( IOUtils.extendUrl(scenario.getConfig().getContext(), freightCarriersConfigGroup.getCarriersFile() ) ); + Carriers carriers = addOrGetCarriers(scenario); // also registers with scenario + new CarrierPlanXmlReader(carriers, vehTypes).readURL( + IOUtils.extendUrl(scenario.getConfig().getContext(), freightCarriersConfigGroup.getCarriersFile())); // new CarrierVehicleTypeLoader( carriers ).loadVehicleTypes( vehTypes ); } @@ -350,22 +432,22 @@ private static void createShipmentsFromServices(Carrier carrierWS, Carrier carri for (CarrierService carrierService : carrier.getServices().values()) { log.debug("Converting CarrierService to CarrierShipment: {}", carrierService.getId()); CarrierShipment carrierShipment = CarrierShipment.Builder - .newInstance(Id.create(carrierService.getId().toString(), CarrierShipment.class), - depotServiceIsDeliveredFrom.get(carrierService.getId()), carrierService.getLocationLinkId(), - carrierService.getCapacityDemand()) - .setDeliveryServiceTime(carrierService.getServiceDuration()) - // .setPickupServiceTime(pickupServiceTime) //Not set yet, because in service we - // have now time for that. Maybe change it later, kmt sep18 - .setDeliveryTimeWindow(carrierService.getServiceStartTimeWindow()) - // Limited to end of delivery timeWindow (pickup later than the latest delivery is not useful). - .setPickupTimeWindow(TimeWindow.newInstance(0.0, carrierService.getServiceStartTimeWindow().getEnd())) - .build(); + .newInstance(Id.create(carrierService.getId().toString(), CarrierShipment.class), + depotServiceIsDeliveredFrom.get(carrierService.getId()), carrierService.getLocationLinkId(), + carrierService.getCapacityDemand()) + .setDeliveryServiceTime(carrierService.getServiceDuration()) + // .setPickupServiceTime(pickupServiceTime) //Not set yet, because in service we + // have now time for that. Maybe change it later, kmt sep18 + .setDeliveryTimeWindow(carrierService.getServiceStartTimeWindow()) + // Limited to end of delivery timeWindow (pickup later than the latest delivery is not useful). + .setPickupTimeWindow(TimeWindow.newInstance(0.0, carrierService.getServiceStartTimeWindow().getEnd())) + .build(); addShipment(carrierWS, carrierShipment); } } /** - * Adds a skill to the vehicle's {@link org.matsim.vehicles.VehicleType}. + * Adds a skill to the vehicle's {@link VehicleType}. * * @param vehicleType the vehicle type to change; * @param skill the skill. @@ -380,8 +462,8 @@ public static void addSkill(VehicleType vehicleType, String skill) { * @param type the {@link VehicleType}; * @param skill the free-form type skill. * @return true if the skill is in the skill set; or - * false if the skill is not in the skill set, or there is - * no skill set available/set. + * false if the skill is not in the skill set, or there is + * no skill set available/set. */ public static boolean hasSkill(VehicleType type, String skill) { return hasSkill(type.getAttributes(), skill); @@ -411,7 +493,7 @@ public static List getSkills(VehicleType type) { } /** - * Adds a skill to the {@link com.graphhopper.jsprit.core.problem.job.Shipment}. + * Adds a skill to the {@link Shipment}. * * @param shipment the vehicle type to change; * @param skill the skill. @@ -426,8 +508,8 @@ public static void addSkill(CarrierShipment shipment, String skill) { * @param shipment the {@link CarrierShipment}; * @param skill the free-form type skill. * @return true if the skill is in the skill set; or - * false if the skill is not in the skill set, or there is - * no skill set available/set. + * false if the skill is not in the skill set, or there is + * no skill set available/set. */ public static boolean hasSkill(CarrierShipment shipment, String skill) { return hasSkill(shipment.getAttributes(), skill); @@ -472,8 +554,8 @@ public static void addSkill(CarrierService service, String skill) { * @param service the {@link CarrierService}; * @param skill the free-form type skill. * @return true if the skill is in the skill set; or - * false if the skill is not in the skill set, or there is - * no skill set available/set. + * false if the skill is not in the skill set, or there is + * no skill set available/set. */ public static boolean hasSkill(CarrierService service, String skill) { return hasSkill(service.getAttributes(), skill); @@ -527,8 +609,8 @@ private static void addSkill(Attributes attributes, String skill) { * @param attributes the {@link Attributes} container to check for the skill; * @param skill the free-form type skill. * @return true if the skill is in the skill set; or - * false if the skill is not in the skill set, or there is - * no skill set available/set. + * false if the skill is not in the skill set, or there is + * no skill set available/set. */ private static boolean hasSkill(Attributes attributes, String skill) { if (attributes.getAttribute(ATTR_SKILLS) == null) { @@ -544,7 +626,7 @@ private static boolean hasSkill(Attributes attributes, String skill) { * @param attributes the {@link Attributes} container that is checked for the * skill(s) to be converted. * @return the {@link List} of skills, possibly empty, as parsed from the - * attribute. + * attribute. */ private static List convertSkillsAttributeToList(Attributes attributes) { if (attributes.getAttribute(ATTR_SKILLS) == null) { @@ -566,23 +648,23 @@ private static void setSkills(Attributes attributes, Set skills) { } } - public static Vehicle getVehicle(Plan plan ) { - return (Vehicle) plan.getAttributes().getAttribute( CARRIER_VEHICLE ); + public static Vehicle getVehicle(Plan plan) { + return (Vehicle) plan.getAttributes().getAttribute(CARRIER_VEHICLE); } - public static void putVehicle(Plan plan, Vehicle vehicle ){ - plan.getAttributes().putAttribute( CARRIER_VEHICLE, vehicle ); + public static void putVehicle(Plan plan, Vehicle vehicle) { + plan.getAttributes().putAttribute(CARRIER_VEHICLE, vehicle); } - public static void setJspritScore(CarrierPlan plan, Double jspritScore){ + public static void setJspritScore(CarrierPlan plan, Double jspritScore) { plan.getAttributes().putAttribute(ATTR_JSPRIT_SCORE, jspritScore); } - public static Double getJspritScore (CarrierPlan plan) { + public static Double getJspritScore(CarrierPlan plan) { return (Double) plan.getAttributes().getAttribute(ATTR_JSPRIT_SCORE); } - public static double getJspritComputationTime(Carrier carrier){ + public static double getJspritComputationTime(Carrier carrier) { try { return (double) carrier.getAttributes().getAttribute(ATTR_JSPRIT_Time); } catch (Exception e) { @@ -590,15 +672,16 @@ public static double getJspritComputationTime(Carrier carrier){ return Integer.MIN_VALUE; } } - public static void setJspritComputationTime(Carrier carrier, double time){ + + public static void setJspritComputationTime(Carrier carrier, double time) { carrier.getAttributes().putAttribute(ATTR_JSPRIT_Time, time); } - public static void writeCarriers(Carriers carriers, String filename ) { - new CarrierPlanWriter( carriers ).write( filename ); + public static void writeCarriers(Carriers carriers, String filename) { + new CarrierPlanWriter(carriers).write(filename); } - static class JspritCarrierTask implements Runnable{ + static class JspritCarrierTask implements Runnable { private final int priority; private final Carrier carrier; private final Scenario scenario; @@ -606,7 +689,8 @@ static class JspritCarrierTask implements Runnable{ private final AtomicInteger startedVRPCounter; private final int taskCount; - public JspritCarrierTask(int priority, Carrier carrier, Scenario scenario, NetworkBasedTransportCosts netBasedCosts, AtomicInteger startedVRPCounter, int taskCount) { + public JspritCarrierTask(int priority, Carrier carrier, Scenario scenario, NetworkBasedTransportCosts netBasedCosts, + AtomicInteger startedVRPCounter, int taskCount) { this.priority = priority; this.carrier = carrier; this.scenario = scenario; @@ -621,7 +705,8 @@ public int getPriority() { @Override public void run() { - FreightCarriersConfigGroup freightCarriersConfigGroup = ConfigUtils.addOrGetModule( scenario.getConfig(), FreightCarriersConfigGroup.class ); + FreightCarriersConfigGroup freightCarriersConfigGroup = ConfigUtils.addOrGetModule(scenario.getConfig(), + FreightCarriersConfigGroup.class); double start = System.currentTimeMillis(); if (!carrier.getServices().isEmpty()) @@ -630,11 +715,13 @@ else if (!carrier.getShipments().isEmpty()) log.info("Start tour planning for {} which has {} shipments", carrier.getId(), carrier.getShipments().size()); startedVRPCounter.incrementAndGet(); - log.info("started VRP solving for carrier number {} out of {} carriers. Thread id: {}. Priority: {}", startedVRPCounter.get(), taskCount, Thread.currentThread().getId(), this.priority); + log.info("started VRP solving for carrier number {} out of {} carriers. Thread id: {}. Priority: {}", startedVRPCounter.get(), taskCount, + Thread.currentThread().threadId(), this.priority); VehicleRoutingProblem problem = MatsimJspritFactory.createRoutingProblemBuilder(carrier, scenario.getNetwork()) - .setRoutingCost(netBasedCosts).build(); - VehicleRoutingAlgorithm algorithm = MatsimJspritFactory.loadOrCreateVehicleRoutingAlgorithm(scenario, freightCarriersConfigGroup, netBasedCosts, problem); + .setRoutingCost(netBasedCosts).build(); + VehicleRoutingAlgorithm algorithm = MatsimJspritFactory.loadOrCreateVehicleRoutingAlgorithm(scenario, freightCarriersConfigGroup, + netBasedCosts, problem); algorithm.getAlgorithmListeners().addListener(new StopWatch(), VehicleRoutingAlgorithmListeners.Priority.HIGH); int jspritIterations = getJspritIterations(carrier); @@ -661,16 +748,18 @@ else if (!carrier.getShipments().isEmpty()) NetworkRouter.routePlan(newPlan, netBasedCosts); double timeForPlanningAndRouting = (System.currentTimeMillis() - start) / 1000; log.info("routing for carrier {} finished. Tour planning plus routing took {} seconds. Thread id: {}", carrier.getId(), - timeForPlanningAndRouting, Thread.currentThread().getId()); + timeForPlanningAndRouting, Thread.currentThread().threadId()); - carrier.setSelectedPlan(newPlan); + carrier.addPlan(newPlan); setJspritComputationTime(carrier, timeForPlanningAndRouting); + if (!allJobsHandledBySelectedPlan(carrier)) + log.warn("Not all jobs of carrier {} are handled by the selected plan.", carrier.getId()); } } // we need this class because otherwise there is a runtime error in the PriorityBlockingQueue // https://jvmaware.com/priority-queue-and-threadpool/ - private static class JspritTreadPoolExecutor extends ThreadPoolExecutor{ + private static class JspritTreadPoolExecutor extends ThreadPoolExecutor { public JspritTreadPoolExecutor(BlockingQueue workQueue, int nThreads) { super(nThreads, nThreads, 0, TimeUnit.SECONDS, workQueue); } @@ -681,7 +770,7 @@ protected RunnableFuture newTaskFor(Runnable runnable, T value) { } } - private static class CustomFutureTask extends FutureTask implements Comparable>{ + private static class CustomFutureTask extends FutureTask implements Comparable> { private final JspritCarrierTask task; public CustomFutureTask(Runnable task) { diff --git a/contribs/vsp/src/main/java/org/matsim/freight/carriers/analysis/CarrierLoadAnalysis.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/analysis/CarrierLoadAnalysis.java similarity index 79% rename from contribs/vsp/src/main/java/org/matsim/freight/carriers/analysis/CarrierLoadAnalysis.java rename to contribs/freight/src/main/java/org/matsim/freight/carriers/analysis/CarrierLoadAnalysis.java index 7e858ee725d..7de5125e51e 100644 --- a/contribs/vsp/src/main/java/org/matsim/freight/carriers/analysis/CarrierLoadAnalysis.java +++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/analysis/CarrierLoadAnalysis.java @@ -25,11 +25,11 @@ import org.apache.logging.log4j.Logger; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.Scenario; -import org.matsim.api.core.v01.events.Event; import org.matsim.freight.carriers.Carriers; import org.matsim.freight.carriers.events.CarrierShipmentDeliveryStartEvent; import org.matsim.freight.carriers.events.CarrierShipmentPickupStartEvent; -import org.matsim.core.events.handler.BasicEventHandler; +import org.matsim.freight.carriers.events.eventhandler.CarrierShipmentDeliveryStartEventHandler; +import org.matsim.freight.carriers.events.eventhandler.CarrierShipmentPickupStartEventHandler; import org.matsim.vehicles.Vehicle; import org.matsim.vehicles.VehicleType; import org.matsim.vehicles.VehicleUtils; @@ -37,6 +37,7 @@ import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; +import java.nio.file.Path; import java.util.Comparator; import java.util.LinkedHashMap; import java.util.LinkedList; @@ -47,27 +48,21 @@ /** * @author Kai Martins-Turner (kturner) */ -public class CarrierLoadAnalysis implements BasicEventHandler { +public class CarrierLoadAnalysis implements CarrierShipmentPickupStartEventHandler, CarrierShipmentDeliveryStartEventHandler { private static final Logger log = LogManager.getLogger(CarrierLoadAnalysis.class); - + private final String delimiter; Carriers carriers; private final Map, LinkedList> vehicle2Load = new LinkedHashMap<>(); - public CarrierLoadAnalysis(Carriers carriers) { + public CarrierLoadAnalysis(String delimiter, Carriers carriers) { + this.delimiter = delimiter; this.carriers = carriers; } - @Override public void handleEvent(Event event) { - if (event.getEventType().equals(CarrierShipmentPickupStartEvent.EVENT_TYPE)) { - handlePickup( event); - } if (event.getEventType().equals(CarrierShipmentDeliveryStartEvent.EVENT_TYPE)) { - handleDelivery(event); - } - } - - private void handlePickup(Event event) { + @Override + public void handleEvent(CarrierShipmentPickupStartEvent event) { Id vehicleId = Id.createVehicleId(event.getAttributes().get("vehicle")); Integer demand = Integer.valueOf(event.getAttributes().get(ATTRIBUTE_CAPACITYDEMAND)); @@ -82,8 +77,8 @@ private void handlePickup(Event event) { vehicle2Load.put(vehicleId, list); } - - private void handleDelivery(Event event) { + @Override + public void handleEvent(CarrierShipmentDeliveryStartEvent event) { Id vehicleId = Id.createVehicleId(event.getAttributes().get("vehicle")); Integer demand = Integer.valueOf(event.getAttributes().get(ATTRIBUTE_CAPACITYDEMAND)); @@ -95,12 +90,15 @@ private void handleDelivery(Event event) { void writeLoadPerVehicle(String analysisOutputDirectory, Scenario scenario) throws IOException { log.info("Writing out vehicle load analysis ..."); //Load per vehicle - String fileName = analysisOutputDirectory + "Load_perVehicle.tsv"; + String fileName = Path.of(analysisOutputDirectory).resolve("Load_perVehicle.tsv").toString(); BufferedWriter bw1 = new BufferedWriter(new FileWriter(fileName)); //Write headline: - bw1.write("vehicleId \t capacity \t maxLoad \t load state during tour"); + bw1.write(String.join(delimiter,"vehicleId", + "capacity", + "maxLoad", + "load state during tour")); bw1.newLine(); for (Id vehicleId : vehicle2Load.keySet()) { @@ -112,13 +110,13 @@ void writeLoadPerVehicle(String analysisOutputDirectory, Scenario scenario) thro final Double capacity = vehicleType.getCapacity().getOther(); bw1.write(vehicleId.toString()); - bw1.write("\t" + capacity); - bw1.write("\t" + maxLoad); - bw1.write("\t" + load); + bw1.write(delimiter + capacity); + bw1.write(delimiter + maxLoad); + bw1.write(delimiter + load); bw1.newLine(); } bw1.close(); - log.info("Output written to " + fileName); + log.info("Output written to {}", fileName); } } diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/analysis/CarrierPlanAnalysis.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/analysis/CarrierPlanAnalysis.java new file mode 100644 index 00000000000..aeec93fd605 --- /dev/null +++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/analysis/CarrierPlanAnalysis.java @@ -0,0 +1,157 @@ +/* + * *********************************************************************** * + * project: org.matsim.* + * *********************************************************************** * + * * + * copyright : (C) by the members listed in the COPYING, * + * LICENSE and WARRANTY file. * + * email : info at matsim dot org * + * * + * *********************************************************************** * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * See also COPYING, LICENSE and WARRANTY file * + * * + * *********************************************************************** + * + */ + +package org.matsim.freight.carriers.analysis; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.matsim.api.core.v01.Id; +import org.matsim.core.utils.misc.Time; +import org.matsim.freight.carriers.*; + +import java.io.BufferedWriter; +import java.io.FileWriter; +import java.io.IOException; +import java.nio.file.Path; +import java.util.TreeMap; + +/** + * Some basic analysis / data collection for {@link Carriers}(files) + *

+ * For all carriers it writes out the: + * - score of the selected plan + * - number of tours (= vehicles) of the selected plan + * - number of Services (input) + * - number of Services (handled) + * - number of shipments (input) + * - number of shipments (handled) + * - number of not handled jobs + * - number of planned demand size + * - number of handled demand size + * to a tsv-file. + * + * @author Kai Martins-Turner (kturner), Ricardo Ewert + */ +public class CarrierPlanAnalysis { + + private static final Logger log = LogManager.getLogger(CarrierPlanAnalysis.class); + public final String delimiter; + + Carriers carriers; + + public CarrierPlanAnalysis(String delimiter, Carriers carriers) { + this.delimiter = delimiter; + this.carriers = carriers; + } + + public void runAnalysisAndWriteStats(String analysisOutputDirectory) throws IOException { + log.info("Writing out carrier analysis ..."); + //Load per vehicle + String fileName = Path.of(analysisOutputDirectory).resolve("Carrier_stats.tsv").toString(); + + try (BufferedWriter bw1 = new BufferedWriter(new FileWriter(fileName))) { + + //Write headline: + bw1.write(String.join(delimiter, + "carrierId", + "MATSimScoreSelectedPlan", + "jSpritScoreSelectedPlan", + "nuOfTours", + "nuOfShipments(input)", + "nuOfShipments(handled)", + "nuOfServices(input)", + "nuOfServices(handled)", + "noOfNotHandledJobs", + "nuOfPlanedDemandSize", + "nuOfHandledDemandSize", + "jspritComputationTime[HH:mm:ss]" + )); + bw1.newLine(); + + final TreeMap, Carrier> sortedCarrierMap = new TreeMap<>(carriers.getCarriers()); + + for (Carrier carrier : sortedCarrierMap.values()) { + + int numberOfPlanedShipments = carrier.getShipments().size(); + int numberOfPlanedServices = carrier.getServices().size(); + int numberOfHandledPickups = (int) carrier.getSelectedPlan().getScheduledTours().stream().mapToDouble( + t -> t.getTour().getTourElements().stream().filter(te -> te instanceof Tour.Pickup).count()).sum(); + int numberOfHandledDeliveries = (int) carrier.getSelectedPlan().getScheduledTours().stream().mapToDouble( + t -> t.getTour().getTourElements().stream().filter(te -> te instanceof Tour.Delivery).count()).sum(); + int nuOfServiceHandled = (int) carrier.getSelectedPlan().getScheduledTours().stream().mapToDouble( + t -> t.getTour().getTourElements().stream().filter(te -> te instanceof Tour.ServiceActivity).count()).sum(); + int numberOfPlanedDemandSize; + int numberOfHandledDemandSize; + int notHandledJobs; + if (numberOfPlanedShipments > 0) { + numberOfPlanedDemandSize = carrier.getShipments().values().stream().mapToInt(CarrierShipment::getSize).sum(); + numberOfHandledDemandSize = carrier.getSelectedPlan().getScheduledTours().stream().mapToInt( + t -> t.getTour().getTourElements().stream().filter(te -> te instanceof Tour.Pickup).mapToInt( + te -> (((Tour.Pickup) te).getShipment().getSize())).sum()).sum(); + notHandledJobs = numberOfPlanedShipments - numberOfHandledPickups; + } else { + numberOfPlanedDemandSize = carrier.getServices().values().stream().mapToInt(CarrierService::getCapacityDemand).sum(); + numberOfHandledDemandSize = carrier.getSelectedPlan().getScheduledTours().stream().mapToInt( + t -> t.getTour().getTourElements().stream().filter(te -> te instanceof Tour.ServiceActivity).mapToInt( + te -> ((Tour.ServiceActivity) te).getService().getCapacityDemand()).sum()).sum(); + notHandledJobs = numberOfPlanedServices - nuOfServiceHandled; + } + + if (numberOfPlanedServices != nuOfServiceHandled) { + log.warn("Number of services in input and handled are not equal for carrier {}. Jobs Input: {}, Jobs Handled: {}", + carrier.getId(), numberOfPlanedServices, nuOfServiceHandled); + } + if (numberOfPlanedShipments != numberOfHandledPickups) { + log.warn("Number of shipments in input and handled are not equal for carrier {}. Jobs Input: {}, Jobs Handled: {}", + carrier.getId(), numberOfPlanedShipments, numberOfHandledPickups); + } + if (numberOfHandledDeliveries != numberOfHandledPickups) { + log.warn( + "Number of handled pickups and deliveries are not equal for carrier {}. Pickups: {}, Deliveries: {}. This should not happen!!", + carrier.getId(), numberOfHandledPickups, numberOfHandledDeliveries); + } + bw1.write(carrier.getId().toString()); + bw1.write(delimiter + carrier.getSelectedPlan().getScore()); + bw1.write(delimiter + carrier.getSelectedPlan().getJspritScore()); + bw1.write(delimiter + carrier.getSelectedPlan().getScheduledTours().size()); + bw1.write(delimiter + numberOfPlanedShipments); + bw1.write(delimiter + numberOfHandledPickups); + bw1.write(delimiter + numberOfPlanedServices); + bw1.write(delimiter + nuOfServiceHandled); + bw1.write(delimiter + notHandledJobs); + bw1.write(delimiter + numberOfPlanedDemandSize); + bw1.write(delimiter + numberOfHandledDemandSize); + if (CarriersUtils.getJspritComputationTime(carrier) != Integer.MIN_VALUE) + bw1.write(delimiter + Time.writeTime(CarriersUtils.getJspritComputationTime(carrier), Time.TIMEFORMAT_HHMMSS)); + else + bw1.write(delimiter + "null"); + + bw1.newLine(); + } + + bw1.close(); + log.info("Output written to {}", fileName); + } catch (IOException e) { + log.error("Error writing output to file: {}", fileName); + throw e; + } + } +} diff --git a/contribs/vsp/src/main/java/org/matsim/freight/carriers/analysis/FreightTimeAndDistanceAnalysisEventsHandler.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/analysis/FreightTimeAndDistanceAnalysisEventsHandler.java similarity index 70% rename from contribs/vsp/src/main/java/org/matsim/freight/carriers/analysis/FreightTimeAndDistanceAnalysisEventsHandler.java rename to contribs/freight/src/main/java/org/matsim/freight/carriers/analysis/FreightTimeAndDistanceAnalysisEventsHandler.java index 3037716368c..c62863465d5 100644 --- a/contribs/vsp/src/main/java/org/matsim/freight/carriers/analysis/FreightTimeAndDistanceAnalysisEventsHandler.java +++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/analysis/FreightTimeAndDistanceAnalysisEventsHandler.java @@ -25,17 +25,21 @@ import org.apache.logging.log4j.Logger; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.Scenario; -import org.matsim.api.core.v01.events.Event; import org.matsim.api.core.v01.events.LinkEnterEvent; import org.matsim.api.core.v01.events.LinkLeaveEvent; import org.matsim.api.core.v01.events.VehicleEntersTrafficEvent; import org.matsim.api.core.v01.events.VehicleLeavesTrafficEvent; +import org.matsim.api.core.v01.events.handler.LinkEnterEventHandler; +import org.matsim.api.core.v01.events.handler.LinkLeaveEventHandler; +import org.matsim.api.core.v01.events.handler.VehicleEntersTrafficEventHandler; +import org.matsim.api.core.v01.events.handler.VehicleLeavesTrafficEventHandler; import org.matsim.freight.carriers.Carrier; import org.matsim.freight.carriers.CarriersUtils; import org.matsim.freight.carriers.Tour; import org.matsim.freight.carriers.events.CarrierTourEndEvent; import org.matsim.freight.carriers.events.CarrierTourStartEvent; -import org.matsim.core.events.handler.BasicEventHandler; +import org.matsim.freight.carriers.events.eventhandler.CarrierTourEndEventHandler; +import org.matsim.freight.carriers.events.eventhandler.CarrierTourStartEventHandler; import org.matsim.vehicles.Vehicle; import org.matsim.vehicles.VehicleType; import org.matsim.vehicles.VehicleUtils; @@ -43,6 +47,7 @@ import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; +import java.nio.file.Path; import java.util.LinkedHashMap; import java.util.Map; import java.util.TreeMap; @@ -50,9 +55,10 @@ /** * @author Kai Martins-Turner (kturner) */ -public class FreightTimeAndDistanceAnalysisEventsHandler implements BasicEventHandler { +public class FreightTimeAndDistanceAnalysisEventsHandler implements CarrierTourStartEventHandler, CarrierTourEndEventHandler, LinkEnterEventHandler, LinkLeaveEventHandler, VehicleEntersTrafficEventHandler, VehicleLeavesTrafficEventHandler { private final static Logger log = LogManager.getLogger(FreightTimeAndDistanceAnalysisEventsHandler.class); + private final String delimiter; private final Scenario scenario; private final Map, Double> vehicleId2TourDuration = new LinkedHashMap<>(); @@ -74,21 +80,24 @@ public class FreightTimeAndDistanceAnalysisEventsHandler implements BasicEventHa private final Map, Double> vehicleEnteredLinkTime = new LinkedHashMap<>(); - public FreightTimeAndDistanceAnalysisEventsHandler(Scenario scenario) { + public FreightTimeAndDistanceAnalysisEventsHandler(String delimiter, Scenario scenario) { + this.delimiter = delimiter; this.scenario = scenario; } - private void handleEvent(CarrierTourStartEvent event) { + @Override + public void handleEvent(CarrierTourStartEvent event) { // Save time of freight tour start final String key = event.getCarrierId().toString() + "_" + event.getTourId().toString(); tourStartTime.put(key, event.getTime()); } //Fix costs for vehicle usage - private void handleEvent(CarrierTourEndEvent event) { + @Override + public void handleEvent(CarrierTourEndEvent event) { final String key = event.getCarrierId().toString() + "_" + event.getTourId().toString(); double tourDuration = event.getTime() - tourStartTime.get(key); - vehicleId2TourDuration.put(event.getVehicleId(), tourDuration); + vehicleId2TourDuration.put(event.getVehicleId(), tourDuration); //TODO, check if this may overwrite old data and if this is intended to do so VehicleType vehType = VehicleUtils.findVehicle(event.getVehicleId(), scenario).getType(); vehicleTypeId2SumOfTourDuration.merge(vehType.getId(), tourDuration, Double::sum); @@ -99,7 +108,13 @@ private void handleEvent(CarrierTourEndEvent event) { vehicleId2VehicleType.putIfAbsent(event.getVehicleId(), vehType); } - private void handleEvent(LinkEnterEvent event) { + @Override + public void handleEvent(VehicleEntersTrafficEvent event){ + vehicleEnteredLinkTime.put(event.getVehicleId(), event.getTime()); + } + + @Override + public void handleEvent(LinkEnterEvent event) { final double distance = scenario.getNetwork().getLinks().get(event.getLinkId()).getLength(); vehicleId2TourLength.merge(event.getVehicleId(), distance, Double::sum); vehicleEnteredLinkTime.put(event.getVehicleId(), event.getTime()); //Safe time when entering the link. @@ -109,7 +124,8 @@ private void handleEvent(LinkEnterEvent event) { } //If the vehicle leaves a link at the end, the travelTime is calculated and stored. - private void handleEvent(LinkLeaveEvent event){ + @Override + public void handleEvent(LinkLeaveEvent event){ final Id vehicleId = event.getVehicleId(); if (vehicleEnteredLinkTime.containsKey(vehicleId)){ double tt = event.getTime() - vehicleEnteredLinkTime.get(vehicleId); @@ -123,7 +139,8 @@ private void handleEvent(LinkLeaveEvent event){ } //If the vehicle leaves a link because it reached its destination, the travelTime is calculated and stored. - private void handleEvent(VehicleLeavesTrafficEvent event){ + @Override + public void handleEvent(VehicleLeavesTrafficEvent event){ final Id vehicleId = event.getVehicleId(); if (vehicleEnteredLinkTime.containsKey(vehicleId)){ double tt = event.getTime() - vehicleEnteredLinkTime.get(vehicleId); @@ -136,39 +153,31 @@ private void handleEvent(VehicleLeavesTrafficEvent event){ } } - private void handleEvent(VehicleEntersTrafficEvent event){ - vehicleEnteredLinkTime.put(event.getVehicleId(), event.getTime()); - } - - @Override public void handleEvent(Event event) { - if (event instanceof CarrierTourStartEvent carrierTourStartEvent) { - handleEvent(carrierTourStartEvent); - } else if (event instanceof CarrierTourEndEvent carrierTourEndEvent) { - handleEvent(carrierTourEndEvent); - } else if (event instanceof LinkEnterEvent linkEnterEvent) { - handleEvent(linkEnterEvent); - } else if (event instanceof LinkLeaveEvent linkLeaveEvent) { - handleEvent(linkLeaveEvent); - } else if (event instanceof VehicleLeavesTrafficEvent vehicleLeavesTrafficEvent) { - handleEvent(vehicleLeavesTrafficEvent); - } else if (event instanceof VehicleEntersTrafficEvent vehicleEntersTrafficEvent) { - handleEvent(vehicleEntersTrafficEvent); - } - } - void writeTravelTimeAndDistancePerVehicle(String analysisOutputDirectory, Scenario scenario) throws IOException { log.info("Writing out Time & Distance & Costs ... perVehicle"); //Travel time and distance per vehicle - String fileName = analysisOutputDirectory + "TimeDistance_perVehicle.tsv"; + String fileName = Path.of(analysisOutputDirectory).resolve("TimeDistance_perVehicle.tsv").toString(); BufferedWriter bw1 = new BufferedWriter(new FileWriter(fileName)); //Write headline: - bw1.write("vehicleId \t carrierId \t vehicleTypeId \t tourId \t " - + "tourDuration[s] \t tourDuration[h] \t" - + "travelDistance[m] \t travelDistance[km] \t " + - "travelTime[s] \t travelTime[h] \t" + - "costPerSecond[EUR/s] \t costPerMeter[EUR/m] \t fixedCosts[EUR] \t varCostsTime[EUR] \t varCostsDist[EUR] \t totalCosts[EUR]"); + bw1.write(String.join(delimiter, + "vehicleId", + "carrierId", + "vehicleTypeId", + "tourId", + "tourDuration[s]", + "tourDuration[h]", + "travelDistance[m]", + "travelDistance[km]", + "travelTime[s]", + "travelTime[h]", + "costPerSecond[EUR/s]", + "costPerMeter[EUR/m]", + "fixedCosts[EUR]", + "varCostsTime[EUR]", + "varCostsDist[EUR]", + "totalCosts[EUR]")); bw1.newLine(); for (Id vehicleId : vehicleId2VehicleType.keySet()) { @@ -188,34 +197,33 @@ void writeTravelTimeAndDistancePerVehicle(String analysisOutputDirectory, Scenar final double totalVehCosts = fixedCost + varCostsTime + varCostsDist; bw1.write(vehicleId.toString()); - bw1.write("\t" + vehicleId2CarrierId.get(vehicleId)); - bw1.write("\t" + vehicleType.getId().toString()); - bw1.write("\t" + vehicleId2TourId.get(vehicleId)); + bw1.write(delimiter + vehicleId2CarrierId.get(vehicleId)); + bw1.write(delimiter + vehicleType.getId().toString()); + bw1.write(delimiter + vehicleId2TourId.get(vehicleId)); - bw1.write("\t" + durationInSeconds); - bw1.write("\t" + durationInSeconds /3600); + bw1.write(delimiter + durationInSeconds); + bw1.write(delimiter + durationInSeconds /3600); - bw1.write("\t" + distanceInMeters); - bw1.write("\t" + distanceInMeters/1000); + bw1.write(delimiter + distanceInMeters); + bw1.write(delimiter + distanceInMeters/1000); - bw1.write("\t" + travelTimeInSeconds); - bw1.write("\t" + travelTimeInSeconds /3600); + bw1.write(delimiter + travelTimeInSeconds); + bw1.write(delimiter + travelTimeInSeconds /3600); - bw1.write("\t" + costsPerSecond); - bw1.write("\t" + costsPerMeter); - bw1.write("\t" + fixedCost); - bw1.write("\t" + varCostsTime); - bw1.write("\t" + varCostsDist); - bw1.write("\t" + totalVehCosts); + bw1.write(delimiter + costsPerSecond); + bw1.write(delimiter + costsPerMeter); + bw1.write(delimiter + fixedCost); + bw1.write(delimiter + varCostsTime); + bw1.write(delimiter + varCostsDist); + bw1.write(delimiter + totalVehCosts); bw1.newLine(); } bw1.close(); - log.info("Output written to " + fileName); + log.info("Output written to {}", fileName); } - void writeTravelTimeAndDistancePerVehicleType(String analysisOutputDirectory, Scenario scenario) throws IOException { log.info("Writing out Time & Distance & Costs ... perVehicleType"); @@ -226,16 +234,26 @@ void writeTravelTimeAndDistancePerVehicleType(String analysisOutputDirectory, Sc vehicleTypesMap.putIfAbsent(vehicleType.getId(), vehicleType); } - String fileName = analysisOutputDirectory + "TimeDistance_perVehicleType.tsv"; + String fileName = Path.of(analysisOutputDirectory).resolve("TimeDistance_perVehicleType.tsv").toString(); BufferedWriter bw1 = new BufferedWriter(new FileWriter(fileName)); //Write headline: - bw1.write("vehicleTypeId \t nuOfVehicles \t " + - "SumOfTourDuration[s] \t SumOfTourDuration[h] \t" + - "SumOfTravelDistances[m] \t SumOfTravelDistances[km] \t " + - "SumOfTravelTime[s] \t SumOfTravelTime[h] \t" + - "costPerSecond[EUR/s] \t costPerMeter[EUR/m] \t fixedCosts[EUR/veh] \t" + - "varCostsTime[EUR] \t varCostsDist[EUR] \t fixedCosts[EUR] \t totalCosts[EUR]"); + bw1.write(String.join(delimiter, + "vehicleTypeId", + "nuOfVehicles", + "SumOfTourDuration[s]", + "SumOfTourDuration[h]", + "SumOfTravelDistances[m]", + "SumOfTravelDistances[km]", + "SumOfTravelTime[s]", + "SumOfTravelTime[h]", + "costPerSecond[EUR/s]", + "costPerMeter[EUR/m]", + "fixedCosts[EUR/veh]", + "varCostsTime[EUR]", + "varCostsDist[EUR]", + "fixedCosts[EUR]", + "totalCosts[EUR]")); bw1.newLine(); for (VehicleType vehicleType : vehicleTypesMap.values()) { @@ -255,25 +273,25 @@ void writeTravelTimeAndDistancePerVehicleType(String analysisOutputDirectory, Sc bw1.write(vehicleType.getId().toString()); - bw1.write("\t" + nuOfVehicles); - bw1.write("\t" + sumOfTourDurationInSeconds); - bw1.write("\t" + sumOfTourDurationInSeconds / 3600); - bw1.write("\t" + sumOfDistanceInMeters); - bw1.write("\t" + sumOfDistanceInMeters / 1000); - bw1.write("\t" + sumOfTravelTimeInSeconds); - bw1.write("\t" + sumOfTravelTimeInSeconds / 3600); - bw1.write("\t" + costRatePerSecond); - bw1.write("\t" + costRatePerMeter); - bw1.write("\t" + fixedCostPerVeh); - bw1.write("\t" + sumOfVarCostsTime); - bw1.write("\t" + sumOfVarCostsDistance); - bw1.write("\t" + sumOfFixCosts); - bw1.write("\t" + (sumOfFixCosts + sumOfVarCostsTime + sumOfVarCostsDistance)); + bw1.write(delimiter + nuOfVehicles); + bw1.write(delimiter + sumOfTourDurationInSeconds); + bw1.write(delimiter + sumOfTourDurationInSeconds / 3600); + bw1.write(delimiter + sumOfDistanceInMeters); + bw1.write(delimiter + sumOfDistanceInMeters / 1000); + bw1.write(delimiter + sumOfTravelTimeInSeconds); + bw1.write(delimiter + sumOfTravelTimeInSeconds / 3600); + bw1.write(delimiter + costRatePerSecond); + bw1.write(delimiter + costRatePerMeter); + bw1.write(delimiter + fixedCostPerVeh); + bw1.write(delimiter + sumOfVarCostsTime); + bw1.write(delimiter + sumOfVarCostsDistance); + bw1.write(delimiter + sumOfFixCosts); + bw1.write(delimiter + (sumOfFixCosts + sumOfVarCostsTime + sumOfVarCostsDistance)); bw1.newLine(); } bw1.close(); - log.info("Output written to " + fileName); + log.info("Output written to {}", fileName); } } diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/analysis/RunFreightAnalysisEventBased.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/analysis/RunFreightAnalysisEventBased.java new file mode 100644 index 00000000000..751e96a2f45 --- /dev/null +++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/analysis/RunFreightAnalysisEventBased.java @@ -0,0 +1,189 @@ +/* + * *********************************************************************** * + * project: org.matsim.* + * *********************************************************************** * + * * + * copyright : (C) by the members listed in the COPYING, * + * LICENSE and WARRANTY file. * + * email : info at matsim dot org * + * * + * *********************************************************************** * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * See also COPYING, LICENSE and WARRANTY file * + * * + * *********************************************************************** + * + */ + +package org.matsim.freight.carriers.analysis; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.matsim.api.core.v01.Scenario; +import org.matsim.core.api.experimental.events.EventsManager; +import org.matsim.core.config.Config; +import org.matsim.core.config.ConfigUtils; +import org.matsim.core.events.EventsUtils; +import org.matsim.core.events.MatsimEventsReader; +import org.matsim.core.scenario.ScenarioUtils; +import org.matsim.freight.carriers.Carrier; +import org.matsim.freight.carriers.Carriers; +import org.matsim.freight.carriers.CarriersUtils; +import org.matsim.freight.carriers.FreightCarriersConfigGroup; +import org.matsim.freight.carriers.events.CarrierEventsReaders; + +import java.io.File; +import java.io.IOException; + +//import static org.matsim.application.ApplicationUtils.globFile; + + +/** + * A first approach for some analysis based on the freight events introduced in 2022/23. + * This class comes from teaching SimGV in the winter term 2022/23. + *

+ * This class should get extended and prepared as a standardized analysis for freight output. + * This should also get aligned with the current development in Simwrapper. + * Todo: Add some tests. + * + * @author kturner (Kai Martins-Turner) + */ +public class RunFreightAnalysisEventBased { + + private static final Logger log = LogManager.getLogger(RunFreightAnalysisEventBased.class); + + //Where is your simulation output, that should be analysed? + private String EVENTS_PATH = null; + private final String ANALYSIS_OUTPUT_PATH; + private Scenario scenario = null; + private Carriers carriers = null; + private final String delimiter = "\t"; + + //TODO discuss renaming without EventBased. If this becomes the standard carrier output + /** + * This constructor automatically searches for the necessary output file in a simulation run output. + * + * @param simOutputPath The output directory of the simulation run + * @param analysisOutputPath The directory where the result of the analysis should go to + * @param globalCrs The CRS of the simulation + */ + public RunFreightAnalysisEventBased(String simOutputPath, String analysisOutputPath, String globalCrs) { + + this.ANALYSIS_OUTPUT_PATH = analysisOutputPath; +// this.EVENTS_PATH = globFile(simOutputPath, "*output_events.*"); +// Path vehiclesPath = globFile(simOutputPath, "*output_allVehicles.*"); +// Path networkPath = globFile(simOutputPath, "*output_network.*"); +// Path carriersPath = globFile(simOutputPath, "*output_carriers.*"); +// Path carriersVehicleTypesPath = globFile(simOutputPath, "*output_carriersVehicleTypes.*"); + +// this.EVENTS_PATH = simOutputPath.resolve("*output_events.xml.gz"); +// Path vehiclesPath = simOutputPath.resolve("*output_allVehicles.xml.gz"); +// Path networkPath = simOutputPath.resolve("*output_network.xml.gz"); +// Path carriersPath = simOutputPath.resolve("*output_carriers.xml.gz"); +// Path carriersVehicleTypesPath = simOutputPath.resolve("*output_carriersVehicleTypes.xml.gz"); +// +// createScenarioForFreightAnalysis(vehiclesPath, networkPath, carriersPath, carriersVehicleTypesPath, globalCrs); + } + + /** + * Alternative if you want to set the paths to the necessary resources directly. + * + * @param networkPath Path to the network file + * @param vehiclesPath Path to the vehicle file + * @param carriersPath Path to the carriers file + * @param carriersVehicleTypesPath Path to the carriersVehicleTypes file + * @param eventsPath Path to the events file + * @param analysisOutputPath Path to the output directory + * @param globalCrs The CRS of the simulation + */ + public RunFreightAnalysisEventBased(String networkPath, String vehiclesPath, String carriersPath, String carriersVehicleTypesPath, String eventsPath, + String analysisOutputPath, String globalCrs) { + this.EVENTS_PATH = eventsPath; + this.ANALYSIS_OUTPUT_PATH = analysisOutputPath; + + createScenarioForFreightAnalysis(vehiclesPath, networkPath, carriersPath, carriersVehicleTypesPath, globalCrs); + } + + /** + * Constructor, if you only want to have the carrier analysis. + * + * @param carriers The carriers to be analysed + * @param analysisOutputPath The directory where the result of the analysis should go to + */ + public RunFreightAnalysisEventBased(Carriers carriers, String analysisOutputPath) { + this.carriers = carriers; + this.ANALYSIS_OUTPUT_PATH = analysisOutputPath; + } + + private void createScenarioForFreightAnalysis(String vehiclesPath, String networkPath, String carriersPath, String carriersVehicleTypesPath, + String globalCrs) { + Config config = ConfigUtils.createConfig(); + config.vehicles().setVehiclesFile(vehiclesPath); + config.network().setInputFile(networkPath); + config.plans().setInputFile(null); + config.eventsManager().setNumberOfThreads(null); + config.eventsManager().setEstimatedNumberOfEvents(null); + config.global().setNumberOfThreads(1); + config.global().setCoordinateSystem(globalCrs); + + //freight settings + FreightCarriersConfigGroup freightCarriersConfigGroup = ConfigUtils.addOrGetModule(config, FreightCarriersConfigGroup.class); + freightCarriersConfigGroup.setCarriersFile(carriersPath); + freightCarriersConfigGroup.setCarriersVehicleTypesFile(carriersVehicleTypesPath.toString()); + + scenario = ScenarioUtils.loadScenario(config); + + //load carriers according to freight config + CarriersUtils.loadCarriersAccordingToFreightConfig( scenario ); + this.carriers = CarriersUtils.addOrGetCarriers(scenario); + } + + public void runCarriersAnalysis() throws IOException { + + //Where to store the analysis output? + File folder = new File(String.valueOf(ANALYSIS_OUTPUT_PATH)); + folder.mkdirs(); + if (allCarriersHavePlans(carriers)) { + CarrierPlanAnalysis carrierPlanAnalysis = new CarrierPlanAnalysis(delimiter, carriers); + carrierPlanAnalysis.runAnalysisAndWriteStats(ANALYSIS_OUTPUT_PATH); + } + else { + log.warn("########## Not all carriers have plans. Skipping CarrierPlanAnalysis."); //TODO perhaps skipp complete analysis + } + } + public void runCompleteAnalysis() throws IOException { + runCarriersAnalysis(); + + // Prepare eventsManager - start of event based Analysis; + EventsManager eventsManager = EventsUtils.createEventsManager(); + + FreightTimeAndDistanceAnalysisEventsHandler freightTimeAndDistanceAnalysisEventsHandler = new FreightTimeAndDistanceAnalysisEventsHandler(delimiter, scenario); + eventsManager.addHandler(freightTimeAndDistanceAnalysisEventsHandler); + + CarrierLoadAnalysis carrierLoadAnalysis = new CarrierLoadAnalysis(delimiter, CarriersUtils.getCarriers(scenario)); + eventsManager.addHandler(carrierLoadAnalysis); + + eventsManager.initProcessing(); + MatsimEventsReader matsimEventsReader = CarrierEventsReaders.createEventsReader(eventsManager); + + matsimEventsReader.readFile(EVENTS_PATH); + eventsManager.finishProcessing(); + + log.info("Analysis completed."); + log.info("Writing output..."); + freightTimeAndDistanceAnalysisEventsHandler.writeTravelTimeAndDistancePerVehicle(ANALYSIS_OUTPUT_PATH, scenario); + freightTimeAndDistanceAnalysisEventsHandler.writeTravelTimeAndDistancePerVehicleType(ANALYSIS_OUTPUT_PATH, scenario); + carrierLoadAnalysis.writeLoadPerVehicle(ANALYSIS_OUTPUT_PATH, scenario); + } + + private boolean allCarriersHavePlans(Carriers carriers) { + for (Carrier carrier : carriers.getCarriers().values()) + if (carrier.getSelectedPlan() == null) return false; + + return true; + } +} diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/usecases/chessboard/InitialCarrierPlanCreator.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/usecases/chessboard/InitialCarrierPlanCreator.java index cd2e07405f7..fb2979e4be1 100644 --- a/contribs/freight/src/main/java/org/matsim/freight/carriers/usecases/chessboard/InitialCarrierPlanCreator.java +++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/usecases/chessboard/InitialCarrierPlanCreator.java @@ -170,7 +170,7 @@ public static void main(String[] args) { for(Carrier carrier : carriers.getCarriers().values()){ CarrierPlan plan = new InitialCarrierPlanCreator(scenario.getNetwork()).createPlan(carrier); - carrier.setSelectedPlan(plan); + carrier.addPlan(plan); } new CarrierPlanWriter(carriers).write("input/usecases/chessboard/freight/carrierPlans_10minTW.xml"); diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/usecases/chessboard/RunPassengerAlongWithCarriers.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/usecases/chessboard/RunPassengerAlongWithCarriers.java index 9d54c7299e1..40a49ecf40c 100644 --- a/contribs/freight/src/main/java/org/matsim/freight/carriers/usecases/chessboard/RunPassengerAlongWithCarriers.java +++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/usecases/chessboard/RunPassengerAlongWithCarriers.java @@ -100,6 +100,7 @@ public void run() { public Config prepareConfig() { Config config = ConfigUtils.loadConfig(IOUtils.extendUrl(url, "config.xml")); config.controller().setOverwriteFileSetting( OutputDirectoryHierarchy.OverwriteFileSetting.overwriteExistingFiles ); + config.controller().setLastIteration(5); config.global().setRandomSeed(4177); config.controller().setOutputDirectory("./output/"); return config; diff --git a/contribs/vsp/src/test/java/org/matsim/freight/carriers/analysis/FreightAnalysisEventBasedTest.java b/contribs/freight/src/test/java/org/matsim/freight/carriers/analysis/FreightAnalysisEventBasedTest.java similarity index 50% rename from contribs/vsp/src/test/java/org/matsim/freight/carriers/analysis/FreightAnalysisEventBasedTest.java rename to contribs/freight/src/test/java/org/matsim/freight/carriers/analysis/FreightAnalysisEventBasedTest.java index 75986b3e94c..c7fc851bf24 100644 --- a/contribs/vsp/src/test/java/org/matsim/freight/carriers/analysis/FreightAnalysisEventBasedTest.java +++ b/contribs/freight/src/test/java/org/matsim/freight/carriers/analysis/FreightAnalysisEventBasedTest.java @@ -23,20 +23,51 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; +import org.matsim.core.utils.io.IOUtils; +import org.matsim.examples.ExamplesUtils; import org.matsim.testcases.MatsimTestUtils; import java.io.IOException; +import java.net.URL; public class FreightAnalysisEventBasedTest { @RegisterExtension private MatsimTestUtils testUtils = new MatsimTestUtils(); + final static URL SCENARIO_URL = ExamplesUtils.getTestScenarioURL("freight-chessboard-9x9"); @Test - void runFreightAnalysisEventBasedTest() throws IOException { + void runServiceEventTest() throws IOException { + // Note: I had to manually change the files for this test to run, as I did not have access to the original input file of the events-file + // This results in the carrier-plans not being related to the actual events. This is however no problem for testing the core functionality, + // as those are two disjunct analysis outputs, which do not depend on each other. (aleks Sep'24) + RunFreightAnalysisEventBased analysisEventBased = new RunFreightAnalysisEventBased( + IOUtils.extendUrl(SCENARIO_URL, "grid9x9.xml" ).toString(), + testUtils.getInputDirectory() + "in/output_allVehicles.xml", + IOUtils.extendUrl(SCENARIO_URL, "singleCarrierFiveActivities.xml" ).toString(), + IOUtils.extendUrl(SCENARIO_URL, "vehicleTypes.xml" ).toString(), + testUtils.getInputDirectory() + "in/serviceBasedEvents.xml", + testUtils.getOutputDirectory(), + null); + analysisEventBased.runCompleteAnalysis(); - RunFreightAnalysisEventBased analysisEventBased = new RunFreightAnalysisEventBased(testUtils.getClassInputDirectory(), testUtils.getOutputDirectory(),null); - analysisEventBased.runAnalysis(); + MatsimTestUtils.assertEqualFilesLineByLine(testUtils.getInputDirectory() + "Carrier_stats.tsv", testUtils.getOutputDirectory() + "Carrier_stats.tsv"); + MatsimTestUtils.assertEqualFilesLineByLine(testUtils.getInputDirectory() + "Load_perVehicle.tsv", testUtils.getOutputDirectory() + "Load_perVehicle.tsv"); + MatsimTestUtils.assertEqualFilesLineByLine(testUtils.getInputDirectory() + "TimeDistance_perVehicle.tsv", testUtils.getOutputDirectory() + "TimeDistance_perVehicle.tsv"); + MatsimTestUtils.assertEqualFilesLineByLine(testUtils.getInputDirectory() + "TimeDistance_perVehicleType.tsv", testUtils.getOutputDirectory() + "TimeDistance_perVehicleType.tsv"); + } + + @Test + void runShipmentEventTest() throws IOException { + RunFreightAnalysisEventBased analysisEventBased = new RunFreightAnalysisEventBased( + IOUtils.extendUrl(SCENARIO_URL, "grid9x9.xml" ).toString(), + testUtils.getInputDirectory() + "in/carrierVehicles.xml", + IOUtils.extendUrl(SCENARIO_URL, "singleCarrierFiveActivities_Shipments.xml" ).toString(), + IOUtils.extendUrl(SCENARIO_URL, "vehicleTypes.xml" ).toString(), + testUtils.getInputDirectory() + "in/shipmentBasedEvents.xml", + testUtils.getOutputDirectory(), + null); + analysisEventBased.runCompleteAnalysis(); MatsimTestUtils.assertEqualFilesLineByLine(testUtils.getInputDirectory() + "Carrier_stats.tsv", testUtils.getOutputDirectory() + "Carrier_stats.tsv"); MatsimTestUtils.assertEqualFilesLineByLine(testUtils.getInputDirectory() + "Load_perVehicle.tsv", testUtils.getOutputDirectory() + "Load_perVehicle.tsv"); diff --git a/contribs/freight/src/test/java/org/matsim/freight/carriers/jsprit/FixedCostsTest.java b/contribs/freight/src/test/java/org/matsim/freight/carriers/jsprit/FixedCostsTest.java index 13433ede378..7e0e4bbe12e 100644 --- a/contribs/freight/src/test/java/org/matsim/freight/carriers/jsprit/FixedCostsTest.java +++ b/contribs/freight/src/test/java/org/matsim/freight/carriers/jsprit/FixedCostsTest.java @@ -176,7 +176,7 @@ public void setUp() { //Routing bestPlan to Network CarrierPlan carrierPlan = MatsimJspritFactory.createPlan(carrier, bestSolution) ; NetworkRouter.routePlan(carrierPlan,netBasedCosts) ; - carrier.setSelectedPlan(carrierPlan) ; + carrier.addPlan(carrierPlan) ; carriersPlannedAndRouted.addCarrier(carrier); } } diff --git a/contribs/freight/src/test/java/org/matsim/freight/carriers/jsprit/IntegrationIT.java b/contribs/freight/src/test/java/org/matsim/freight/carriers/jsprit/IntegrationIT.java index 9aa5504cdf7..762a2efe08a 100644 --- a/contribs/freight/src/test/java/org/matsim/freight/carriers/jsprit/IntegrationIT.java +++ b/contribs/freight/src/test/java/org/matsim/freight/carriers/jsprit/IntegrationIT.java @@ -30,6 +30,7 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; +import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.Scenario; import org.matsim.api.core.v01.network.Network; import org.matsim.core.config.Config; @@ -78,6 +79,54 @@ void testJsprit() throws ExecutionException, InterruptedException { } double scoreRunWithOldStructure = generateCarrierPlans(scenario.getNetwork(), CarriersUtils.getCarriers(scenario), CarriersUtils.getCarrierVehicleTypes(scenario)); Assertions.assertEquals(scoreWithRunJsprit, scoreRunWithOldStructure, MatsimTestUtils.EPSILON, "The score of both runs are not the same"); + + for (Carrier carrier : CarriersUtils.getCarriers(scenario).getCarriers().values()) { + CarriersUtils.setJspritIterations(carrier, 20); + } + CarriersUtils.runJsprit(scenario, CarriersUtils.CarrierSelectionForSolution.solveForAllCarriersAndAddPLans); + for (Carrier carrier : CarriersUtils.getCarriers(scenario).getCarriers().values()) { + Assertions.assertEquals(2, carrier.getPlans().size(), "The number of plans is not as expected"); + // Test method if all jobs are handled + Assertions.assertTrue(CarriersUtils.allJobsHandledBySelectedPlan(carrier), "Not all jobs are handled"); + CarrierService newService = CarrierService.Builder.newInstance(Id.create( + "service" + carrier.getServices().size(), CarrierService.class), Id.createLinkId("100603")) + .setServiceDuration(10.).setServiceStartTimeWindow(TimeWindow.newInstance(0,86000)).build(); + carrier.getServices().put(newService.getId(), newService); + Assertions.assertFalse(CarriersUtils.allJobsHandledBySelectedPlan(carrier), "All jobs are handled although a new service was added"); + } + } + + @Test + void testJspritWithDefaultSolutionOption() throws ExecutionException, InterruptedException { + final String networkFilename = utils.getClassInputDirectory() + "/merged-network-simplified.xml.gz"; + final String vehicleTypeFilename = utils.getClassInputDirectory() + "/vehicleTypes.xml"; + final String carrierFilename = utils.getClassInputDirectory() + "/carrier.xml"; + + Config config = ConfigUtils.createConfig(); + config.global().setRandomSeed(4177); + + FreightCarriersConfigGroup freightCarriersConfigGroup = ConfigUtils.addOrGetModule(config, FreightCarriersConfigGroup.class); + freightCarriersConfigGroup.setCarriersFile(carrierFilename); + freightCarriersConfigGroup.setCarriersVehicleTypesFile(vehicleTypeFilename); + freightCarriersConfigGroup.setTravelTimeSliceWidth(24*3600); + freightCarriersConfigGroup.setTimeWindowHandling(FreightCarriersConfigGroup.TimeWindowHandling.enforceBeginnings); + + Scenario scenario = ScenarioUtils.createScenario(config); + new MatsimNetworkReader(scenario.getNetwork()).readFile(networkFilename); + + CarriersUtils.loadCarriersAccordingToFreightConfig(scenario); + + for (Carrier carrier : CarriersUtils.getCarriers(scenario).getCarriers().values()) { + CarriersUtils.setJspritIterations(carrier, 1); + } + + CarriersUtils.runJsprit(scenario, CarriersUtils.CarrierSelectionForSolution.solveForAllCarriersAndOverrideExistingPlans); + double scoreWithRunJsprit = 0; + for (Carrier carrier : CarriersUtils.getCarriers(scenario).getCarriers().values()) { + scoreWithRunJsprit = scoreWithRunJsprit + carrier.getSelectedPlan().getJspritScore(); + } + double scoreRunWithOldStructure = generateCarrierPlans(scenario.getNetwork(), CarriersUtils.getCarriers(scenario), CarriersUtils.getCarrierVehicleTypes(scenario)); + Assertions.assertEquals(scoreWithRunJsprit, scoreRunWithOldStructure, MatsimTestUtils.EPSILON, "The score of both runs are not the same"); } private static double generateCarrierPlans(Network network, Carriers carriers, CarrierVehicleTypes vehicleTypes) { @@ -105,7 +154,7 @@ private static double generateCarrierPlans(Network network, Carriers carriers, C // (maybe not optimal, but since re-routing is a matsim strategy, // certainly ok as initial solution) - carrier.setSelectedPlan(newPlan); + carrier.addPlan(newPlan); SolutionPrinter.print(problem, solution, SolutionPrinter.Print.VERBOSE); score = score + newPlan.getJspritScore(); diff --git a/contribs/freight/src/test/java/org/matsim/freight/carriers/jsprit/SkillsIT.java b/contribs/freight/src/test/java/org/matsim/freight/carriers/jsprit/SkillsIT.java index ad24848b155..8886010e74b 100644 --- a/contribs/freight/src/test/java/org/matsim/freight/carriers/jsprit/SkillsIT.java +++ b/contribs/freight/src/test/java/org/matsim/freight/carriers/jsprit/SkillsIT.java @@ -93,7 +93,7 @@ private VehicleRoutingProblemSolution generateCarrierPlans(Scenario scenario) { CarrierPlan newPlan = MatsimJspritFactory.createPlan(carrier, solution); NetworkRouter.routePlan(newPlan, networkBasedTransportCosts); - carrier.setSelectedPlan(newPlan); + carrier.addPlan(newPlan); SolutionPrinter.print(problem, solution, SolutionPrinter.Print.VERBOSE); // new CarrierPlanXmlWriterV3(CarrierControlerUtils.getCarriers(scenario)).write(utils.getOutputDirectory() + "carriers.xml"); diff --git a/contribs/freight/src/test/java/org/matsim/freight/carriers/utils/CarrierControlerUtilsIT.java b/contribs/freight/src/test/java/org/matsim/freight/carriers/utils/CarrierControllerUtilsIT.java similarity index 98% rename from contribs/freight/src/test/java/org/matsim/freight/carriers/utils/CarrierControlerUtilsIT.java rename to contribs/freight/src/test/java/org/matsim/freight/carriers/utils/CarrierControllerUtilsIT.java index 4b86789a97a..76738a411a9 100644 --- a/contribs/freight/src/test/java/org/matsim/freight/carriers/utils/CarrierControlerUtilsIT.java +++ b/contribs/freight/src/test/java/org/matsim/freight/carriers/utils/CarrierControllerUtilsIT.java @@ -53,7 +53,7 @@ * @author kturner * */ -public class CarrierControlerUtilsIT { +public class CarrierControllerUtilsIT{ private final Id CARRIER_SERVICES_ID = Id.create("CarrierWServices", Carrier.class); private final Id CARRIER_SHIPMENTS_ID = Id.create("CarrierWShipments", Carrier.class); @@ -140,7 +140,7 @@ public void setUp() { //Routing bestPlan to Network CarrierPlan carrierPlanServicesAndShipments = MatsimJspritFactory.createPlan(carrier, bestSolution) ; NetworkRouter.routePlan(carrierPlanServicesAndShipments,netBasedCosts) ; - carrier.setSelectedPlan(carrierPlanServicesAndShipments) ; + carrier.addPlan(carrierPlanServicesAndShipments) ; } /* @@ -168,7 +168,7 @@ public void setUp() { //Routing bestPlan to Network CarrierPlan carrierPlanServicesAndShipments = MatsimJspritFactory.createPlan(carrier, bestSolution) ; NetworkRouter.routePlan(carrierPlanServicesAndShipments,netBasedCosts) ; - carrier.setSelectedPlan(carrierPlanServicesAndShipments) ; + carrier.addPlan(carrierPlanServicesAndShipments) ; } carrierWShipmentsOnlyFromCarrierWServices = carriersWithShipmentsOnly.getCarriers().get(CARRIER_SERVICES_ID); //with converted Service diff --git a/contribs/freight/src/test/java/org/matsim/freight/carriers/utils/CarrierControlerUtilsTest.java b/contribs/freight/src/test/java/org/matsim/freight/carriers/utils/CarrierControllerUtilsTest.java similarity index 99% rename from contribs/freight/src/test/java/org/matsim/freight/carriers/utils/CarrierControlerUtilsTest.java rename to contribs/freight/src/test/java/org/matsim/freight/carriers/utils/CarrierControllerUtilsTest.java index ba52b1cfd00..87ac86ec9b3 100644 --- a/contribs/freight/src/test/java/org/matsim/freight/carriers/utils/CarrierControlerUtilsTest.java +++ b/contribs/freight/src/test/java/org/matsim/freight/carriers/utils/CarrierControllerUtilsTest.java @@ -59,12 +59,12 @@ import java.net.URL; import java.util.Collection; -public class CarrierControlerUtilsTest { +public class CarrierControllerUtilsTest{ @RegisterExtension private MatsimTestUtils utils = new MatsimTestUtils(); - private static final Logger log = LogManager.getLogger(CarrierControlerUtilsTest.class); + private static final Logger log = LogManager.getLogger( CarrierControllerUtilsTest.class ); private final Id CARRIER_SERVICES_ID = Id.create("CarrierWServices", Carrier.class); private final Id CARRIER_SHIPMENTS_ID = Id.create("CarrierWShipments", Carrier.class); @@ -149,7 +149,7 @@ public void setUp() { //Routing bestPlan to Network CarrierPlan carrierPlanServicesAndShipments = MatsimJspritFactory.createPlan(carrierWServices, bestSolution) ; NetworkRouter.routePlan(carrierPlanServicesAndShipments,netBasedCosts) ; - carrierWServices.setSelectedPlan(carrierPlanServicesAndShipments) ; + carrierWServices.addPlan(carrierPlanServicesAndShipments) ; /* * Now convert it to a only shipment-based VRP. diff --git a/contribs/freight/test/input/org/matsim/freight/carriers/analysis/FreightAnalysisEventBasedTest/runServiceEventTest/Carrier_stats.tsv b/contribs/freight/test/input/org/matsim/freight/carriers/analysis/FreightAnalysisEventBasedTest/runServiceEventTest/Carrier_stats.tsv new file mode 100644 index 00000000000..8a1b8ff7b0e --- /dev/null +++ b/contribs/freight/test/input/org/matsim/freight/carriers/analysis/FreightAnalysisEventBasedTest/runServiceEventTest/Carrier_stats.tsv @@ -0,0 +1,2 @@ +carrierId MATSimScoreSelectedPlan jSpritScoreSelectedPlan nuOfTours nuOfShipments(input) nuOfShipments(handled) nuOfServices(input) nuOfServices(handled) noOfNotHandledJobs nuOfPlanedDemandSize nuOfHandledDemandSize jspritComputationTime[HH:mm:ss] +carrier1 -210.81333333333333 null 1 0 0 7 7 0 7 7 null diff --git a/contribs/freight/test/input/org/matsim/freight/carriers/analysis/FreightAnalysisEventBasedTest/runServiceEventTest/Load_perVehicle.tsv b/contribs/freight/test/input/org/matsim/freight/carriers/analysis/FreightAnalysisEventBasedTest/runServiceEventTest/Load_perVehicle.tsv new file mode 100644 index 00000000000..67fb0e5f002 --- /dev/null +++ b/contribs/freight/test/input/org/matsim/freight/carriers/analysis/FreightAnalysisEventBasedTest/runServiceEventTest/Load_perVehicle.tsv @@ -0,0 +1 @@ +vehicleId capacity maxLoad load state during tour diff --git a/contribs/freight/test/input/org/matsim/freight/carriers/analysis/FreightAnalysisEventBasedTest/runServiceEventTest/TimeDistance_perVehicle.tsv b/contribs/freight/test/input/org/matsim/freight/carriers/analysis/FreightAnalysisEventBasedTest/runServiceEventTest/TimeDistance_perVehicle.tsv new file mode 100644 index 00000000000..9ed73be9e24 --- /dev/null +++ b/contribs/freight/test/input/org/matsim/freight/carriers/analysis/FreightAnalysisEventBasedTest/runServiceEventTest/TimeDistance_perVehicle.tsv @@ -0,0 +1,2 @@ +vehicleId carrierId vehicleTypeId tourId tourDuration[s] tourDuration[h] travelDistance[m] travelDistance[km] travelTime[s] travelTime[h] costPerSecond[EUR/s] costPerMeter[EUR/m] fixedCosts[EUR] varCostsTime[EUR] varCostsDist[EUR] totalCosts[EUR] +freight_carrier1_veh_carrier_19_heavyVehicle_1 carrier1 heavy unknown 8003.0 2.2230555555555553 44000.0 44.0 5896.0 1.6377777777777778 0.008 7.7E-4 130.0 64.024 33.879999999999995 227.904 diff --git a/contribs/freight/test/input/org/matsim/freight/carriers/analysis/FreightAnalysisEventBasedTest/runServiceEventTest/TimeDistance_perVehicleType.tsv b/contribs/freight/test/input/org/matsim/freight/carriers/analysis/FreightAnalysisEventBasedTest/runServiceEventTest/TimeDistance_perVehicleType.tsv new file mode 100644 index 00000000000..962761fc7b1 --- /dev/null +++ b/contribs/freight/test/input/org/matsim/freight/carriers/analysis/FreightAnalysisEventBasedTest/runServiceEventTest/TimeDistance_perVehicleType.tsv @@ -0,0 +1,3 @@ +vehicleTypeId nuOfVehicles SumOfTourDuration[s] SumOfTourDuration[h] SumOfTravelDistances[m] SumOfTravelDistances[km] SumOfTravelTime[s] SumOfTravelTime[h] costPerSecond[EUR/s] costPerMeter[EUR/m] fixedCosts[EUR/veh] varCostsTime[EUR] varCostsDist[EUR] fixedCosts[EUR] totalCosts[EUR] +heavy 1 8003.0 2.2230555555555553 44000.0 44.0 5896.0 1.6377777777777778 0.008 7.7E-4 130.0 64.024 33.879999999999995 130.0 227.904 +light 0 0.0 0.0 0.0 0.0 0.0 0.0 0.008 4.7E-4 84.0 0.0 0.0 0.0 0.0 diff --git a/contribs/freight/test/input/org/matsim/freight/carriers/analysis/FreightAnalysisEventBasedTest/runServiceEventTest/in/output_allVehicles.xml b/contribs/freight/test/input/org/matsim/freight/carriers/analysis/FreightAnalysisEventBasedTest/runServiceEventTest/in/output_allVehicles.xml new file mode 100644 index 00000000000..ee644f0e30f --- /dev/null +++ b/contribs/freight/test/input/org/matsim/freight/carriers/analysis/FreightAnalysisEventBasedTest/runServiceEventTest/in/output_allVehicles.xml @@ -0,0 +1,24 @@ + + + + + + + A heavy truck + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/contribs/freight/test/input/org/matsim/freight/carriers/analysis/FreightAnalysisEventBasedTest/runServiceEventTest/in/serviceBasedEvents.xml b/contribs/freight/test/input/org/matsim/freight/carriers/analysis/FreightAnalysisEventBasedTest/runServiceEventTest/in/serviceBasedEvents.xml new file mode 100644 index 00000000000..8da18029836 --- /dev/null +++ b/contribs/freight/test/input/org/matsim/freight/carriers/analysis/FreightAnalysisEventBasedTest/runServiceEventTest/in/serviceBasedEvents.xml @@ -0,0 +1,171 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/contribs/freight/test/input/org/matsim/freight/carriers/analysis/FreightAnalysisEventBasedTest/runShipmentEventTest/Carrier_stats.tsv b/contribs/freight/test/input/org/matsim/freight/carriers/analysis/FreightAnalysisEventBasedTest/runShipmentEventTest/Carrier_stats.tsv new file mode 100644 index 00000000000..f08676856fb --- /dev/null +++ b/contribs/freight/test/input/org/matsim/freight/carriers/analysis/FreightAnalysisEventBasedTest/runShipmentEventTest/Carrier_stats.tsv @@ -0,0 +1,2 @@ +carrierId MATSimScoreSelectedPlan jSpritScoreSelectedPlan nuOfTours nuOfShipments(input) nuOfShipments(handled) nuOfServices(input) nuOfServices(handled) noOfNotHandledJobs nuOfPlanedDemandSize nuOfHandledDemandSize jspritComputationTime[HH:mm:ss] +carrier1 -Infinity -215.4666666666667 1 5 5 0 0 0 26 26 00:00:00 diff --git a/contribs/freight/test/input/org/matsim/freight/carriers/analysis/FreightAnalysisEventBasedTest/runShipmentEventTest/Load_perVehicle.tsv b/contribs/freight/test/input/org/matsim/freight/carriers/analysis/FreightAnalysisEventBasedTest/runShipmentEventTest/Load_perVehicle.tsv new file mode 100644 index 00000000000..cf7f4992d37 --- /dev/null +++ b/contribs/freight/test/input/org/matsim/freight/carriers/analysis/FreightAnalysisEventBasedTest/runShipmentEventTest/Load_perVehicle.tsv @@ -0,0 +1,2 @@ +vehicleId capacity maxLoad load state during tour +freight_carrier1_veh_freight_carrier1_veh_heavyVehicle_1_1 50.0 26 [3, 8, 18, 25, 26, 23, 13, 12, 7, 0] diff --git a/contribs/freight/test/input/org/matsim/freight/carriers/analysis/FreightAnalysisEventBasedTest/runShipmentEventTest/TimeDistance_perVehicle.tsv b/contribs/freight/test/input/org/matsim/freight/carriers/analysis/FreightAnalysisEventBasedTest/runShipmentEventTest/TimeDistance_perVehicle.tsv new file mode 100644 index 00000000000..24a90a81255 --- /dev/null +++ b/contribs/freight/test/input/org/matsim/freight/carriers/analysis/FreightAnalysisEventBasedTest/runShipmentEventTest/TimeDistance_perVehicle.tsv @@ -0,0 +1,2 @@ +vehicleId carrierId vehicleTypeId tourId tourDuration[s] tourDuration[h] travelDistance[m] travelDistance[km] travelTime[s] travelTime[h] costPerSecond[EUR/s] costPerMeter[EUR/m] fixedCosts[EUR] varCostsTime[EUR] varCostsDist[EUR] totalCosts[EUR] +freight_carrier1_veh_freight_carrier1_veh_heavyVehicle_1_1 carrier1 heavy 1 6870.0 1.9083333333333334 40000.0 40.0 5360.0 1.488888888888889 0.008 7.7E-4 130.0 54.96 30.799999999999997 215.76 diff --git a/contribs/freight/test/input/org/matsim/freight/carriers/analysis/FreightAnalysisEventBasedTest/runShipmentEventTest/TimeDistance_perVehicleType.tsv b/contribs/freight/test/input/org/matsim/freight/carriers/analysis/FreightAnalysisEventBasedTest/runShipmentEventTest/TimeDistance_perVehicleType.tsv new file mode 100644 index 00000000000..f2090c11206 --- /dev/null +++ b/contribs/freight/test/input/org/matsim/freight/carriers/analysis/FreightAnalysisEventBasedTest/runShipmentEventTest/TimeDistance_perVehicleType.tsv @@ -0,0 +1,3 @@ +vehicleTypeId nuOfVehicles SumOfTourDuration[s] SumOfTourDuration[h] SumOfTravelDistances[m] SumOfTravelDistances[km] SumOfTravelTime[s] SumOfTravelTime[h] costPerSecond[EUR/s] costPerMeter[EUR/m] fixedCosts[EUR/veh] varCostsTime[EUR] varCostsDist[EUR] fixedCosts[EUR] totalCosts[EUR] +heavy 1 6870.0 1.9083333333333334 40000.0 40.0 5360.0 1.488888888888889 0.008 7.7E-4 130.0 54.96 30.799999999999997 130.0 215.76 +light 0 0.0 0.0 0.0 0.0 0.0 0.0 0.008 4.7E-4 84.0 0.0 0.0 0.0 0.0 diff --git a/contribs/freight/test/input/org/matsim/freight/carriers/analysis/FreightAnalysisEventBasedTest/runShipmentEventTest/in/carrierVehicles.xml b/contribs/freight/test/input/org/matsim/freight/carriers/analysis/FreightAnalysisEventBasedTest/runShipmentEventTest/in/carrierVehicles.xml new file mode 100644 index 00000000000..dbb3af477a7 --- /dev/null +++ b/contribs/freight/test/input/org/matsim/freight/carriers/analysis/FreightAnalysisEventBasedTest/runShipmentEventTest/in/carrierVehicles.xml @@ -0,0 +1,24 @@ + + + + + + + A heavy truck + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/contribs/freight/test/input/org/matsim/freight/carriers/analysis/FreightAnalysisEventBasedTest/runShipmentEventTest/in/shipmentBasedEvents.xml b/contribs/freight/test/input/org/matsim/freight/carriers/analysis/FreightAnalysisEventBasedTest/runShipmentEventTest/in/shipmentBasedEvents.xml new file mode 100644 index 00000000000..5dd11c5616b --- /dev/null +++ b/contribs/freight/test/input/org/matsim/freight/carriers/analysis/FreightAnalysisEventBasedTest/runShipmentEventTest/in/shipmentBasedEvents.xml @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/contribs/freight/test/input/org/matsim/freight/carriers/jsprit/IntegrationIT/carrier.xml b/contribs/freight/test/input/org/matsim/freight/carriers/jsprit/IntegrationIT/carrier.xml index 3d59578d423..e14845dfaff 100644 --- a/contribs/freight/test/input/org/matsim/freight/carriers/jsprit/IntegrationIT/carrier.xml +++ b/contribs/freight/test/input/org/matsim/freight/carriers/jsprit/IntegrationIT/carrier.xml @@ -1,198 +1,209 @@ - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + diff --git a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverTriggersCarrierReplanningListener.java b/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverTriggersCarrierReplanningListener.java index 938bef0d1d3..62a2a507aa2 100644 --- a/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverTriggersCarrierReplanningListener.java +++ b/contribs/freightreceiver/src/main/java/org/matsim/contrib/freightreceiver/ReceiverTriggersCarrierReplanningListener.java @@ -115,7 +115,7 @@ public void notifyIterationStarts(IterationStartsEvent event) { NetworkRouter.routePlan(newPlan, netBasedCosts); //assign this plan now to the carrier and make it the selected carrier plan - carrier.setSelectedPlan(newPlan); + carrier.addPlan(newPlan); } String outputdirectory = sc.getConfig().controller().getOutputDirectory(); diff --git a/contribs/hybridsim/pom.xml b/contribs/hybridsim/pom.xml index ac7da45f5b5..d8f69b28046 100644 --- a/contribs/hybridsim/pom.xml +++ b/contribs/hybridsim/pom.xml @@ -10,7 +10,7 @@ hybridsim - 4.28.0 + 4.28.3 1.66.0 @@ -36,7 +36,7 @@ io.opentelemetry opentelemetry-sdk - 1.40.0 + 1.42.1 diff --git a/contribs/multimodal/src/main/java/org/matsim/contrib/multimodal/RunMultimodalExample.java b/contribs/multimodal/src/main/java/org/matsim/contrib/multimodal/RunMultimodalExample.java index 6f1d5b48b0c..879c3d9dca5 100644 --- a/contribs/multimodal/src/main/java/org/matsim/contrib/multimodal/RunMultimodalExample.java +++ b/contribs/multimodal/src/main/java/org/matsim/contrib/multimodal/RunMultimodalExample.java @@ -26,8 +26,6 @@ import org.matsim.core.config.Config; import org.matsim.core.config.ConfigUtils; import org.matsim.core.controler.Controler; -import org.matsim.core.controler.ControlerUtils; -import org.matsim.core.controler.OutputDirectoryHierarchy; import org.matsim.core.scenario.ScenarioUtils; /** diff --git a/contribs/noise/src/main/java/org/matsim/contrib/noise/Grid.java b/contribs/noise/src/main/java/org/matsim/contrib/noise/Grid.java index 329744f3da5..6815899be8a 100644 --- a/contribs/noise/src/main/java/org/matsim/contrib/noise/Grid.java +++ b/contribs/noise/src/main/java/org/matsim/contrib/noise/Grid.java @@ -18,7 +18,7 @@ * *********************************************************************** */ /** - * + * */ package org.matsim.contrib.noise; @@ -34,6 +34,7 @@ import org.matsim.api.core.v01.population.Activity; import org.matsim.api.core.v01.population.Person; import org.matsim.contrib.noise.NoiseConfigGroup; +import org.matsim.core.population.PopulationUtils; import org.matsim.core.router.TripStructureUtils; import org.matsim.core.router.TripStructureUtils.StageActivityHandling; import org.matsim.core.utils.collections.QuadTree; @@ -46,50 +47,50 @@ /** * Computes a grid of receiver points and provides some basic spatial functionality, - * e.g. the nearest receiver point for the coordinates of each 'considered' activity type. - * + * e.g. the nearest receiver point for the coordinates of each 'considered' activity type. + * * @author lkroeger, ikaddoura * */ final class Grid { - + private static final Logger log = LogManager.getLogger(Grid.class); private final Scenario scenario; private final NoiseConfigGroup noiseParams; - + private final Map, List> personId2consideredActivityCoords = new HashMap, List>(); - + private final Set consideredActivityCoordsForSpatialFunctionality = new HashSet (); private final Set consideredActivityCoordsForReceiverPointGrid = new HashSet (); - + private final Set consideredActivitiesForSpatialFunctionality = new HashSet(); private final Set consideredActivitiesForReceiverPointGrid = new HashSet(); - + private double xCoordMin = Double.MAX_VALUE; private double xCoordMax = Double.MIN_VALUE; private double yCoordMin = Double.MAX_VALUE; private double yCoordMax = Double.MIN_VALUE; - + private final Map> activityCoord2receiverPointId = new HashMap>(); private Map, NoiseReceiverPoint> receiverPoints; - + public Grid(Scenario scenario) { - this.scenario = scenario; + this.scenario = scenario; if (this.scenario.getConfig().getModule("noise") == null) { throw new RuntimeException("Could not find a noise config group. " + "Check if the custom module is loaded, e.g. 'ConfigUtils.loadConfig(configFile, new NoiseConfigGroup())'" + " Aborting..."); } - + this.noiseParams = (NoiseConfigGroup) this.scenario.getConfig().getModule("noise"); - + this.receiverPoints = new HashMap<>(); - + String[] consideredActTypesForDamagesArray = noiseParams.getConsideredActivitiesForDamageCalculationArray(); Collections.addAll(this.consideredActivitiesForSpatialFunctionality, consideredActTypesForDamagesArray); - + String[] consideredActTypesForReceiverPointGridArray = noiseParams.getConsideredActivitiesForReceiverPointGridArray(); Collections.addAll(this.consideredActivitiesForReceiverPointGrid, consideredActTypesForReceiverPointGridArray); @@ -110,7 +111,7 @@ private void initialize() { log.info("Loading receiver points based on provided point coordinates in " + this.noiseParams.getReceiverPointsCSVFile()); loadGrid(); } - + setActivityCoord2NearestReceiverPointId(); // delete unnecessary information @@ -127,17 +128,19 @@ private void setActivityCoords () { List activityCoordinates = personId2consideredActivityCoords.computeIfAbsent(person.getId(), value -> new ArrayList<>()); activityCoordinates.add(activity.getCoord()); - - consideredActivityCoordsForSpatialFunctionality.add(activity.getCoord()); + + //activity.getCoord() might be null, so we need to handle that (by outsourcing that to PopulationUtils) + consideredActivityCoordsForSpatialFunctionality.add(PopulationUtils.decideOnCoordForActivity(activity, scenario)); } - + if (this.consideredActivitiesForReceiverPointGrid.contains(activity.getType()) || consideredActivityPrefix(activity.getType(), consideredActivitiesForReceiverPointGrid)) { - consideredActivityCoordsForReceiverPointGrid.add(activity.getCoord()); + //activity.getCoord() might be null, so we need to handle that (by outsourcing that to PopulationUtils) + consideredActivityCoordsForReceiverPointGrid.add(PopulationUtils.decideOnCoordForActivity(activity, scenario)); } } } } - + private boolean consideredActivityPrefix(String type, Set list) { for (String consideredActivity : list) { if (consideredActivity.endsWith("*")) { @@ -150,9 +153,9 @@ private boolean consideredActivityPrefix(String type, Set list) { } private void loadGrid() { - + String gridCSVFile = this.noiseParams.getReceiverPointsCSVFile(); - + CoordinateTransformation ct = TransformationFactory.getCoordinateTransformation(this.noiseParams.getReceiverPointsCSVFileCoordinateSystem(), this.scenario.getConfig().global().getCoordinateSystem()); try { readReceiverPoints(gridCSVFile, ct); @@ -175,7 +178,7 @@ private void loadGrid() { yCoordMax = coord.getY(); } } - + log.info("Total number of receiver points: " + receiverPoints.size()); } @@ -202,11 +205,11 @@ private void loadGridFromScenario() { private void createGrid() { - + if (this.noiseParams.getReceiverPointsGridMinX() == 0. && this.noiseParams.getReceiverPointsGridMinY() == 0. && this.noiseParams.getReceiverPointsGridMaxX() == 0. && this.noiseParams.getReceiverPointsGridMaxY() == 0.) { - + log.info("Creating receiver points for the entire area between the minimum and maximium x and y activity coordinates of all activity locations."); - + for (Coord coord : consideredActivityCoordsForReceiverPointGrid) { if (coord.getX() < xCoordMin) { xCoordMin = coord.getX(); @@ -221,28 +224,28 @@ private void createGrid() { yCoordMax = coord.getY(); } } - + } else { - + xCoordMin = this.noiseParams.getReceiverPointsGridMinX(); xCoordMax = this.noiseParams.getReceiverPointsGridMaxX(); yCoordMin = this.noiseParams.getReceiverPointsGridMinY(); yCoordMax = this.noiseParams.getReceiverPointsGridMaxY(); - - log.info("Creating receiver points for the area between the coordinates (" + xCoordMin + "/" + yCoordMin + ") and (" + xCoordMax + "/" + yCoordMax + ")."); + + log.info("Creating receiver points for the area between the coordinates (" + xCoordMin + "/" + yCoordMin + ") and (" + xCoordMax + "/" + yCoordMax + ")."); } - - createReceiverPoints(); + + createReceiverPoints(); } - + private void createReceiverPoints() { Counter counter = new Counter("create receiver point #"); - + for (double y = yCoordMax + 100. ; y > yCoordMin - 100. - noiseParams.getReceiverPointGap() ; y = y - noiseParams.getReceiverPointGap()) { - + for (double x = xCoordMin - 100. ; x < xCoordMax + 100. + noiseParams.getReceiverPointGap() ; x = x + noiseParams.getReceiverPointGap()) { - + Id id = Id.create(counter.getCounter(), ReceiverPoint.class); Coord coord = new Coord(x, y); NoiseReceiverPoint rp = new NoiseReceiverPoint(id, coord); @@ -253,7 +256,7 @@ private void createReceiverPoints() { counter.printCounter(); log.info("Total number of receiver points: " + receiverPoints.size()); } - + private void setActivityCoord2NearestReceiverPointId () { double gap = noiseParams.getReceiverPointGap(); Counter counter = new Counter("fill quadtree #") ; @@ -263,10 +266,10 @@ private void setActivityCoord2NearestReceiverPointId () { counter.incCounter(); } counter.printCounter(); - + counter = new Counter("compute nearest receiver-points #"); for (Coord coord : consideredActivityCoordsForSpatialFunctionality) { - + // TODO maybe add a check here so we consider only the rp in the 9 surrounding cells? ReceiverPoint rp = qTree.getClosest(coord.getX(), coord.getY()); if(rp != null) { @@ -274,16 +277,16 @@ private void setActivityCoord2NearestReceiverPointId () { log.warn("this must not happen"); } } - + counter.incCounter(); } counter.printCounter(); } private void readReceiverPoints(String file, CoordinateTransformation ct) throws IOException { - + Map, Coord> id2Coord = new HashMap<>(); - + BufferedReader br = IOUtils.getBufferedReader(file); String line = null; try { @@ -291,12 +294,12 @@ private void readReceiverPoints(String file, CoordinateTransformation ct) throws } catch (IOException e) { e.printStackTrace(); } - + String[] headers = line.split(","); log.info("id: " + headers[0]); log.info("xCoord: " + headers[1]); log.info("yCoord: " + headers[2]); - + int lineCounter = 0; while( (line = br.readLine()) != null) { @@ -308,13 +311,13 @@ private void readReceiverPoints(String file, CoordinateTransformation ct) throws String[] columns = line.split(","); if (line.isEmpty() || line.equals("") || columns.length != headers.length) { log.warn("Skipping line " + lineCounter + ". Line is empty or the columns are inconsistent with the headers: [" + line.toString() + "]"); - + } else { String id = null; double x = 0; double y = 0; - for (int column = 0; column < columns.length; column++){ + for (int column = 0; column < columns.length; column++){ if (column == 0) { id = columns[column]; } else if (column == 1) { @@ -329,11 +332,11 @@ private void readReceiverPoints(String file, CoordinateTransformation ct) throws NoiseReceiverPoint rp = new NoiseReceiverPoint(Id.create(id, ReceiverPoint.class), transformedCoord); receiverPoints.put(rp.getId(), rp); lineCounter++; - } + } } log.info("Done. Number of read lines: " + lineCounter); } - + public Map, List> getPersonId2listOfConsideredActivityCoords() { return personId2consideredActivityCoords; } diff --git a/contribs/protobuf/pom.xml b/contribs/protobuf/pom.xml index a08c2d527c8..53542aa2494 100644 --- a/contribs/protobuf/pom.xml +++ b/contribs/protobuf/pom.xml @@ -11,7 +11,7 @@ protobuf - 4.28.0 + 4.28.3 diff --git a/contribs/simwrapper/src/main/java/org/matsim/simwrapper/CreateSingleSimWrapperDashboard.java b/contribs/simwrapper/src/main/java/org/matsim/simwrapper/CreateSingleSimWrapperDashboard.java index fce848736a6..cbffd5a84a6 100644 --- a/contribs/simwrapper/src/main/java/org/matsim/simwrapper/CreateSingleSimWrapperDashboard.java +++ b/contribs/simwrapper/src/main/java/org/matsim/simwrapper/CreateSingleSimWrapperDashboard.java @@ -97,10 +97,10 @@ public Integer call() throws Exception { //add dashboard switch (dashboardType) { case noise -> { - sw.addDashboard(new NoiseDashboard()); + sw.addDashboard(new NoiseDashboard(config.global().getCoordinateSystem())); } case emissions -> { - sw.addDashboard(new EmissionsDashboard()); + sw.addDashboard(new EmissionsDashboard(config.global().getCoordinateSystem())); } case traffic -> { sw.addDashboard(new TrafficDashboard()); diff --git a/contribs/simwrapper/src/main/java/org/matsim/simwrapper/DashboardUtils.java b/contribs/simwrapper/src/main/java/org/matsim/simwrapper/DashboardUtils.java new file mode 100644 index 00000000000..600bb0cf298 --- /dev/null +++ b/contribs/simwrapper/src/main/java/org/matsim/simwrapper/DashboardUtils.java @@ -0,0 +1,23 @@ +package org.matsim.simwrapper; + +import org.matsim.simwrapper.viz.GridMap; + +public class DashboardUtils { + static final String DARK_BLUE = "#1175b3"; + static final String LIGHT_BLUE = "#95c7df"; + static final String ORANGE = "#f4a986"; + static final String RED = "#cc0c27"; + static final String SAND = "#dfb095"; + static final String YELLOW = "#dfdb95"; + + public static void setGridMapStandards(GridMap viz, Data data, String crs) { + viz.height = 12.0; + viz.cellSize = 100; + viz.opacity = 0.1; + viz.maxHeight = 15; + viz.projection = crs; + viz.center = data.context().getCenter(); + viz.zoom = data.context().mapZoomLevel; + viz.setColorRamp(new double[]{30, 40, 50, 60, 70}, new String[]{DARK_BLUE, LIGHT_BLUE, YELLOW, SAND, ORANGE, RED}); + } +} diff --git a/contribs/simwrapper/src/main/java/org/matsim/simwrapper/DefaultDashboardProvider.java b/contribs/simwrapper/src/main/java/org/matsim/simwrapper/DefaultDashboardProvider.java index 9a6f00f9520..a01674f4856 100644 --- a/contribs/simwrapper/src/main/java/org/matsim/simwrapper/DefaultDashboardProvider.java +++ b/contribs/simwrapper/src/main/java/org/matsim/simwrapper/DefaultDashboardProvider.java @@ -31,11 +31,11 @@ public List getDashboards(Config config, SimWrapper simWrapper) { } if (ConfigUtils.hasModule(config, EmissionsConfigGroup.class)) { - result.add(new EmissionsDashboard()); + result.add(new EmissionsDashboard(config.global().getCoordinateSystem())); } if (ConfigUtils.hasModule(config, NoiseConfigGroup.class)) { - result.add(new NoiseDashboard()); + result.add(new NoiseDashboard(config.global().getCoordinateSystem())); } result.add(new StuckAgentDashboard()); diff --git a/contribs/simwrapper/src/main/java/org/matsim/simwrapper/dashboard/EmissionsDashboard.java b/contribs/simwrapper/src/main/java/org/matsim/simwrapper/dashboard/EmissionsDashboard.java index a7487fd625b..69471e57815 100644 --- a/contribs/simwrapper/src/main/java/org/matsim/simwrapper/dashboard/EmissionsDashboard.java +++ b/contribs/simwrapper/src/main/java/org/matsim/simwrapper/dashboard/EmissionsDashboard.java @@ -1,14 +1,12 @@ package org.matsim.simwrapper.dashboard; import org.matsim.application.analysis.emissions.AirPollutionAnalysis; -import org.matsim.application.analysis.noise.NoiseAnalysis; import org.matsim.application.prepare.network.CreateAvroNetwork; -import org.matsim.application.prepare.network.CreateGeoJsonNetwork; import org.matsim.simwrapper.Dashboard; +import org.matsim.simwrapper.DashboardUtils; import org.matsim.simwrapper.Header; import org.matsim.simwrapper.Layout; import org.matsim.simwrapper.viz.GridMap; -import org.matsim.simwrapper.viz.Links; import org.matsim.simwrapper.viz.MapPlot; import org.matsim.simwrapper.viz.Table; @@ -16,27 +14,35 @@ * Shows emission in the scenario. */ public class EmissionsDashboard implements Dashboard { + + private final String coordinateSystem; + + /** + * Best provide the crs from {@link org.matsim.core.config.groups.GlobalConfigGroup} + * @param coordinateSystem + */ + public EmissionsDashboard(String coordinateSystem) { + this.coordinateSystem = coordinateSystem; + } + @Override public void configure(Header header, Layout layout) { - header.title = "Emissions"; - header.description = "Shows the emissions footprint and spatial distribution. Shown values are already upscaled from simulated sample size."; - + header.title = "Air Pollution"; + header.description = "Shows the air pollution footprint and its spatial distribution. Shown values are already upscaled from simulated sample size."; layout.row("links") .el(Table.class, (viz, data) -> { - - viz.title = "Emissions"; + viz.title = "Total Emission"; viz.description = "by pollutant"; viz.dataset = data.compute(AirPollutionAnalysis.class, "emissions_total.csv"); viz.enableFilter = false; viz.showAllRows = true; - viz.width = 1d; }) .el(MapPlot.class, (viz, data) -> { - viz.title = "Emissions per Link per Meter"; + viz.title = "Emission per Link per Meter"; viz.description = "Displays the emissions for each link per meter."; viz.height = 12.; viz.addDataset("emissions_per_link_per_m", data.compute(AirPollutionAnalysis.class, "emissions_per_link_per_m.csv")); @@ -57,14 +63,7 @@ public void configure(Header header, Layout layout) { viz.title = "CO₂ Emissions"; viz.unit = "CO₂ [g]"; viz.description = "per day"; - viz.height = 12.; - viz.cellSize = 100; - viz.opacity = 0.2; - viz.maxHeight = 100; - viz.projection = "EPSG:25832"; - viz.zoom = data.context().mapZoomLevel; - viz.center = data.context().getCenter(); - viz.setColorRamp("greenRed", 10, false); + DashboardUtils.setGridMapStandards(viz, data, this.coordinateSystem); viz.file = data.computeWithPlaceholder(AirPollutionAnalysis.class, "emissions_grid_per_day.%s", "avro"); }); @@ -73,15 +72,7 @@ public void configure(Header header, Layout layout) { viz.title = "CO₂ Emissions"; viz.unit = "CO₂ [g]"; viz.description = "per hour"; - viz.height = 12.; - viz.cellSize = 100; - viz.opacity = 0.2; - viz.maxHeight = 100; - viz.projection = "EPSG:25832"; - viz.zoom = data.context().mapZoomLevel; - viz.center = data.context().getCenter(); - - viz.setColorRamp("greenRed", 10, false); + DashboardUtils.setGridMapStandards(viz, data, this.coordinateSystem); viz.file = data.computeWithPlaceholder(AirPollutionAnalysis.class, "emissions_grid_per_hour.%s", "avro"); }); diff --git a/contribs/simwrapper/src/main/java/org/matsim/simwrapper/dashboard/NoiseDashboard.java b/contribs/simwrapper/src/main/java/org/matsim/simwrapper/dashboard/NoiseDashboard.java index 48f173a8adb..c345d0da7fe 100644 --- a/contribs/simwrapper/src/main/java/org/matsim/simwrapper/dashboard/NoiseDashboard.java +++ b/contribs/simwrapper/src/main/java/org/matsim/simwrapper/dashboard/NoiseDashboard.java @@ -1,11 +1,8 @@ package org.matsim.simwrapper.dashboard; import org.matsim.application.analysis.noise.NoiseAnalysis; -import org.matsim.application.analysis.population.StuckAgentAnalysis; import org.matsim.application.prepare.network.CreateAvroNetwork; -import org.matsim.simwrapper.Dashboard; -import org.matsim.simwrapper.Header; -import org.matsim.simwrapper.Layout; +import org.matsim.simwrapper.*; import org.matsim.simwrapper.viz.ColorScheme; import org.matsim.simwrapper.viz.GridMap; import org.matsim.simwrapper.viz.MapPlot; @@ -19,13 +16,14 @@ public class NoiseDashboard implements Dashboard { private double minDb = 40; private double maxDb = 80; + private final String coordinateSystem; + /** - * Set the min and max values for the noise map. + * Best provide the crs from {@link org.matsim.core.config.groups.GlobalConfigGroup} + * @param coordinateSystem for the {@link GridMap} */ - public NoiseDashboard withMinMaxDb(double minDb, double maxDb) { - this.minDb = minDb; - this.maxDb = maxDb; - return this; + public NoiseDashboard(String coordinateSystem) { + this.coordinateSystem = coordinateSystem; } @Override @@ -64,52 +62,30 @@ public void configure(Header header, Layout layout) { .el(GridMap.class, (viz, data) -> { viz.title = "Noise Immissions (Grid)"; viz.description = "Total Noise Immissions per day"; - viz.height = 12.0; - viz.cellSize = 250; - viz.opacity = 0.1; - viz.maxHeight = 40; - viz.center = data.context().getCenter(); - viz.zoom = data.context().mapZoomLevel; - viz.setColorRamp(new double[]{30, 40, 50, 60, 70}, new String[]{"#1175b3", "#95c7df", "#dfdb95", "#dfb095", "#f4a986", "#cc0c27"}); + DashboardUtils.setGridMapStandards(viz, data, this.coordinateSystem); viz.file = data.computeWithPlaceholder(NoiseAnalysis.class, "immission_per_day.%s", "avro"); }) .el(GridMap.class, (viz, data) -> { viz.title = "Hourly Noise Immissions (Grid)"; viz.description = "Noise Immissions per hour"; - viz.height = 12.0; - viz.cellSize = 250; - viz.opacity = 0.1; - viz.maxHeight = 40; - viz.center = data.context().getCenter(); - viz.zoom = data.context().mapZoomLevel; - viz.setColorRamp(new double[]{30, 40, 50, 60, 70}, new String[]{"#1175b3", "#95c7df", "#dfdb95", "#dfb095", "#f4a986", "#cc0c27"}); + DashboardUtils.setGridMapStandards(viz, data, this.coordinateSystem); viz.file = data.computeWithPlaceholder(NoiseAnalysis.class, "immission_per_hour.%s", "avro"); }); layout.row("damages") .el(GridMap.class, (viz, data) -> { viz.title = "Daily Noise Damages (Grid)"; viz.description = "Total Noise Damages per day [€]"; - viz.height = 12.0; - viz.cellSize = 250; - viz.opacity = 0.1; - viz.maxHeight = 40; - viz.center = data.context().getCenter(); - viz.zoom = data.context().mapZoomLevel; - viz.setColorRamp(ColorScheme.Oranges); + DashboardUtils.setGridMapStandards(viz, data, this.coordinateSystem); viz.file = data.computeWithPlaceholder(NoiseAnalysis.class, "damages_receiverPoint_per_day.%s", "avro"); }) .el(GridMap.class, (viz, data) -> { viz.title = "Hourly Noise Damages (Grid)"; viz.description = "Noise Damages per hour [€]"; - viz.height = 12.0; - viz.cellSize = 250; - viz.opacity = 0.2; - viz.maxHeight = 40; - viz.center = data.context().getCenter(); - viz.zoom = data.context().mapZoomLevel; -// viz.setColorRamp(new double[]{30, 40, 50, 60, 70}, new String[]{"#1175b3", "#95c7df", "#dfdb95", "#dfb095", "#f4a986", "#cc0c27"}); - viz.setColorRamp(ColorScheme.Oranges); + DashboardUtils.setGridMapStandards(viz, data, this.coordinateSystem); viz.file = data.computeWithPlaceholder(NoiseAnalysis.class, "damages_receiverPoint_per_hour.%s", "avro"); }); + + } + } diff --git a/contribs/simwrapper/src/main/java/org/matsim/simwrapper/dashboard/OverviewDashboard.java b/contribs/simwrapper/src/main/java/org/matsim/simwrapper/dashboard/OverviewDashboard.java index ef29484258b..0d5f54ca8e9 100644 --- a/contribs/simwrapper/src/main/java/org/matsim/simwrapper/dashboard/OverviewDashboard.java +++ b/contribs/simwrapper/src/main/java/org/matsim/simwrapper/dashboard/OverviewDashboard.java @@ -58,7 +58,7 @@ public void configure(Header header, Layout layout) { }); layout.row("config").el(XML.class, (viz, data) -> { - viz.file = data.output("*.output_config.xml"); + viz.file = data.output("(*.)?output_config.xml"); viz.height = 6d; viz.width = 2d; viz.unfoldLevel = 1; @@ -66,7 +66,7 @@ public void configure(Header header, Layout layout) { }).el(PieChart.class, (viz, data) -> { viz.title = "Mode Share"; viz.description = "at final Iteration"; - viz.dataset = data.output("*.modestats.csv"); + viz.dataset = data.output("(*.)?modestats.csv"); viz.ignoreColumns = List.of("iteration"); viz.useLastRow = true; }); @@ -75,7 +75,7 @@ public void configure(Header header, Layout layout) { layout.row("second").el(Line.class, (viz, data) -> { viz.title = "Score"; - viz.dataset = data.output("*.scorestats.csv"); + viz.dataset = data.output("(*.)?scorestats.csv"); viz.description = "per Iteration"; viz.x = "iteration"; viz.columns = List.of("avg_executed", "avg_worst", "avg_best"); @@ -88,7 +88,7 @@ public void configure(Header header, Layout layout) { .el(Area.class, (viz, data) -> { viz.title = "Mode Share Progression"; viz.description = "per Iteration"; - viz.dataset = data.output("*.modestats.csv"); + viz.dataset = data.output("(*.)?modestats.csv"); viz.x = "iteration"; viz.xAxisName = "Iteration"; viz.yAxisName = "Share"; diff --git a/contribs/simwrapper/src/main/java/org/matsim/simwrapper/dashboard/PublicTransitDashboard.java b/contribs/simwrapper/src/main/java/org/matsim/simwrapper/dashboard/PublicTransitDashboard.java index 6903902d098..fc902474591 100644 --- a/contribs/simwrapper/src/main/java/org/matsim/simwrapper/dashboard/PublicTransitDashboard.java +++ b/contribs/simwrapper/src/main/java/org/matsim/simwrapper/dashboard/PublicTransitDashboard.java @@ -5,24 +5,40 @@ import org.matsim.simwrapper.Layout; import org.matsim.simwrapper.viz.TransitViewer; +import java.util.ArrayList; +import java.util.List; + /** * Standard dashboard for public transit. */ public class PublicTransitDashboard implements Dashboard { + private List customRouteTypes = new ArrayList<>(); + + /** + * Add custom route types to the transit viewer. + */ + public PublicTransitDashboard withCustomRouteTypes(TransitViewer.CustomRouteType... custom) { + customRouteTypes.addAll(List.of(custom)); + return this; + } + @Override public void configure(Header header, Layout layout) { header.title = "Public Transit"; header.tab = "PT"; - header.triggerPattern = "*output_transitSchedule*xml*"; + header.triggerPattern = "(*.)?output_transitSchedule*xml*"; layout.row("viewer").el(TransitViewer.class, (viz, data) -> { viz.title = "Transit Viewer"; viz.height = 12d; viz.description = "Visualize the transit schedule."; - viz.network = "*output_network.xml.gz"; - viz.transitSchedule = data.output("*output_transitSchedule.xml.gz"); + viz.network = "(*.)?output_network.xml.gz"; + viz.transitSchedule = data.output("(*.)?output_transitSchedule.xml.gz"); + + if (!customRouteTypes.isEmpty()) + viz.customRouteTypes = customRouteTypes; }); } } diff --git a/contribs/simwrapper/src/main/java/org/matsim/simwrapper/dashboard/TripDashboard.java b/contribs/simwrapper/src/main/java/org/matsim/simwrapper/dashboard/TripDashboard.java index 7603da2b791..34c5f1ba1c3 100644 --- a/contribs/simwrapper/src/main/java/org/matsim/simwrapper/dashboard/TripDashboard.java +++ b/contribs/simwrapper/src/main/java/org/matsim/simwrapper/dashboard/TripDashboard.java @@ -247,7 +247,7 @@ public void configure(Header header, Layout layout) { .el(Plotly.class, (viz, data) -> { viz.title = "Mode usage"; - viz.description = "Share of persons using a main mode at least once per day."; + viz.description = "Share of persons using a main mode at least once per day"; viz.width = 2d; Plotly.DataSet ds = viz.addDataset(data.compute(TripAnalysis.class, "mode_users.csv")); @@ -267,6 +267,11 @@ public void configure(Header header, Layout layout) { viz.mergeDatasets = true; } + }).el(Sankey.class, (viz, data) -> { + viz.title = "Mode shift"; + viz.width = 1.5d; + viz.description = "by main mode. Compares initial input with output after the last iteration"; + viz.csv = data.compute(TripAnalysis.class, "mode_shift.csv", args); }); createDistancePlot(layout, args, tab); diff --git a/contribs/simwrapper/src/main/java/org/matsim/simwrapper/viz/TransitViewer.java b/contribs/simwrapper/src/main/java/org/matsim/simwrapper/viz/TransitViewer.java index ff9e8176b60..4f6622d2b11 100644 --- a/contribs/simwrapper/src/main/java/org/matsim/simwrapper/viz/TransitViewer.java +++ b/contribs/simwrapper/src/main/java/org/matsim/simwrapper/viz/TransitViewer.java @@ -2,6 +2,8 @@ import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.List; + /** * Transit viewer for pt schedules. */ @@ -13,7 +15,55 @@ public class TransitViewer extends Viz { @JsonProperty(required = true) public String transitSchedule; + public List customRouteTypes; + public TransitViewer() { super("transit"); } + + public CustomRouteType addCustomRouteType(String label, String color, boolean hide) { + CustomRouteType crt = new CustomRouteType(); + crt.label = label; + crt.color = color; + crt.hide = hide; + customRouteTypes.add(crt); + return crt; + } + + public static class CustomRouteType { + public String label; + public String color; + public Boolean hide; + Match match; + + public CustomRouteType addMatchTransportMode(String... transportMode) { + if (match == null) + match = new Match(); + + match.transportMode = transportMode; + return this; + } + + public CustomRouteType addMatchId(String... id) { + if (match == null) + match = new Match(); + + match.id = id; + return this; + } + + public CustomRouteType addMatchGtfsRouteType(Integer... gtfsRouteType) { + if (match == null) + match = new Match(); + + match.gtfsRouteType = gtfsRouteType; + return this; + } + } + + private static class Match { + Object transportMode; + Object id; + Object gtfsRouteType; + } } diff --git a/contribs/simwrapper/src/test/java/org/matsim/simwrapper/dashboard/DashboardTests.java b/contribs/simwrapper/src/test/java/org/matsim/simwrapper/dashboard/DashboardTests.java index 2a248f2e1ea..dca4a209df1 100644 --- a/contribs/simwrapper/src/test/java/org/matsim/simwrapper/dashboard/DashboardTests.java +++ b/contribs/simwrapper/src/test/java/org/matsim/simwrapper/dashboard/DashboardTests.java @@ -4,15 +4,21 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.application.MATSimApplication; +import org.matsim.application.options.CsvOptions; import org.matsim.core.config.Config; import org.matsim.core.config.ConfigUtils; import org.matsim.core.controler.Controler; +import org.matsim.core.utils.io.IOUtils; import org.matsim.simwrapper.Dashboard; import org.matsim.simwrapper.SimWrapper; import org.matsim.simwrapper.SimWrapperConfigGroup; import org.matsim.simwrapper.TestScenario; +import org.matsim.simwrapper.viz.TransitViewer; import org.matsim.testcases.MatsimTestUtils; +import tech.tablesaw.api.Table; +import tech.tablesaw.io.csv.CsvReadOptions; +import java.io.IOException; import java.nio.file.Path; import java.util.Set; @@ -67,9 +73,27 @@ void trip() { Path out = Path.of(utils.getOutputDirectory(), "analysis", "population"); run(new TripDashboard()); + Assertions.assertThat(out) + .isDirectoryContaining("glob:**trip_stats.csv") + .isDirectoryContaining("glob:**mode_share.csv") + .isDirectoryContaining("glob:**mode_shift.csv"); + } + + @Test + void tripPersonFilter() throws IOException { + + Path out = Path.of(utils.getOutputDirectory(), "analysis", "population"); + + run(new TripDashboard().setAnalysisArgs("--person-filter", "subpopulation=person")); Assertions.assertThat(out) .isDirectoryContaining("glob:**trip_stats.csv") .isDirectoryContaining("glob:**mode_share.csv"); + + Table tripStats = Table.read().csv(CsvReadOptions.builder(IOUtils.getBufferedReader(Path.of(utils.getOutputDirectory(), "analysis", "population", "trip_stats.csv").toString())) + .sample(false) + .separator(CsvOptions.detectDelimiter(Path.of(utils.getOutputDirectory(), "analysis", "population", "mode_share.csv").toString())).build()); + + Assertions.assertThat(tripStats.containsColumn("freight")).isFalse(); } @Test @@ -134,4 +158,24 @@ void odTrips() { } + @Test + void ptCustom() { + PublicTransitDashboard pt = new PublicTransitDashboard(); + + // bus + TransitViewer.CustomRouteType crt = new TransitViewer.CustomRouteType(); + crt.label = "Bus"; + crt.color = "#109192"; + crt.addMatchGtfsRouteType(3); + + // rail + TransitViewer.CustomRouteType crtRail = new TransitViewer.CustomRouteType(); + crtRail.label = "Rail"; + crtRail.color = "#EC0016"; + crtRail.addMatchGtfsRouteType(2); + + pt.withCustomRouteTypes(crt, crtRail); + + run(pt); + } } diff --git a/contribs/simwrapper/src/test/java/org/matsim/simwrapper/dashboard/EmissionsDashboardTest.java b/contribs/simwrapper/src/test/java/org/matsim/simwrapper/dashboard/EmissionsDashboardTest.java index 3eb8a85e3f4..822a7b467a5 100644 --- a/contribs/simwrapper/src/test/java/org/matsim/simwrapper/dashboard/EmissionsDashboardTest.java +++ b/contribs/simwrapper/src/test/java/org/matsim/simwrapper/dashboard/EmissionsDashboardTest.java @@ -57,7 +57,7 @@ void generate() { emissionsConfig.setDetailedVsAverageLookupBehavior(EmissionsConfigGroup.DetailedVsAverageLookupBehavior.tryDetailedThenTechnologyAverageThenAverageTable); SimWrapper sw = SimWrapper.create() - .addDashboard(new EmissionsDashboard()); + .addDashboard(new EmissionsDashboard(config.global().getCoordinateSystem())); Controler controler = MATSimApplication.prepare(new TestScenario(sw), config); diff --git a/contribs/simwrapper/src/test/java/org/matsim/simwrapper/dashboard/NoiseDashboardTests.java b/contribs/simwrapper/src/test/java/org/matsim/simwrapper/dashboard/NoiseDashboardTests.java index fdc846cdff5..a4ce705e001 100644 --- a/contribs/simwrapper/src/test/java/org/matsim/simwrapper/dashboard/NoiseDashboardTests.java +++ b/contribs/simwrapper/src/test/java/org/matsim/simwrapper/dashboard/NoiseDashboardTests.java @@ -38,7 +38,7 @@ void generate() { simWrapperConfigGroup.defaultParams().shp = IOUtils.extendUrl(kelheim, "area/area.shp").toString(); - SimWrapper sw = SimWrapper.create(config).addDashboard(new NoiseDashboard()); + SimWrapper sw = SimWrapper.create(config).addDashboard(new NoiseDashboard(config.global().getCoordinateSystem())); Controler controler = MATSimApplication.prepare(new TestScenario(sw), config); controler.run(); diff --git a/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/DefaultIntegrateExistingTrafficToSmallScaleCommercialImpl.java b/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/DefaultIntegrateExistingTrafficToSmallScaleCommercialImpl.java index 38bcf0744be..6652c17b955 100644 --- a/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/DefaultIntegrateExistingTrafficToSmallScaleCommercialImpl.java +++ b/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/DefaultIntegrateExistingTrafficToSmallScaleCommercialImpl.java @@ -311,6 +311,7 @@ public void readExistingCarriersFromFolder(Scenario scenario, double sampleScena else if (!carrier.getShipments().isEmpty()) newCarrier.getShipments().putAll(carrier.getShipments()); if (carrier.getSelectedPlan() != null) { + newCarrier.addPlan(carrier.getSelectedPlan()); newCarrier.setSelectedPlan(carrier.getSelectedPlan()); List startAreas = new ArrayList<>(); diff --git a/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/DefaultUnhandledServicesSolution.java b/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/DefaultUnhandledServicesSolution.java new file mode 100644 index 00000000000..4928ce2a401 --- /dev/null +++ b/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/DefaultUnhandledServicesSolution.java @@ -0,0 +1,136 @@ +package org.matsim.smallScaleCommercialTrafficGeneration; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.matsim.api.core.v01.Scenario; +import org.matsim.core.gbl.MatsimRandom; +import org.matsim.freight.carriers.Carrier; +import org.matsim.freight.carriers.CarrierService; +import org.matsim.freight.carriers.CarrierVehicle; +import org.matsim.freight.carriers.CarriersUtils; + +import java.util.*; +import java.util.concurrent.ExecutionException; + +public class DefaultUnhandledServicesSolution implements UnhandledServicesSolution { + private static final Logger log = LogManager.getLogger(DefaultUnhandledServicesSolution.class); + + // Generation data + Random rnd; + private final GenerateSmallScaleCommercialTrafficDemand generator; + + DefaultUnhandledServicesSolution(GenerateSmallScaleCommercialTrafficDemand generator){ + rnd = MatsimRandom.getRandom(); + this.generator = generator; + } + + public List createListOfCarrierWithUnhandledJobs(Scenario scenario){ + List carriersWithUnhandledJobs = new LinkedList<>(); + for (Carrier carrier : CarriersUtils.getCarriers(scenario).getCarriers().values()) { + if (!CarriersUtils.allJobsHandledBySelectedPlan(carrier)) + carriersWithUnhandledJobs.add(carrier); + } + + return carriersWithUnhandledJobs; + } + + public int getServiceTimePerStop(Carrier carrier, GenerateSmallScaleCommercialTrafficDemand.CarrierAttributes carrierAttributes, int additionalTravelBufferPerIterationInMinutes) { + GenerateSmallScaleCommercialTrafficDemand.ServiceDurationPerCategoryKey key = null; + if (carrierAttributes.smallScaleCommercialTrafficType().equals( + GenerateSmallScaleCommercialTrafficDemand.SmallScaleCommercialTrafficType.commercialPersonTraffic.toString())) + key = GenerateSmallScaleCommercialTrafficDemand.makeServiceDurationPerCategoryKey(carrierAttributes.selectedStartCategory(), null, carrierAttributes.smallScaleCommercialTrafficType()); + else if (carrierAttributes.smallScaleCommercialTrafficType().equals( + GenerateSmallScaleCommercialTrafficDemand.SmallScaleCommercialTrafficType.goodsTraffic.toString())) { + key = GenerateSmallScaleCommercialTrafficDemand.makeServiceDurationPerCategoryKey(carrierAttributes.selectedStartCategory(), carrierAttributes.modeORvehType(), carrierAttributes.smallScaleCommercialTrafficType()); + } + + //possible new Version by Ricardo + double maxVehicleAvailability = carrier.getCarrierCapabilities().getCarrierVehicles().values().stream().mapToDouble(vehicle -> vehicle.getLatestEndTime() - vehicle.getEarliestStartTime()).max().orElse(0); + int usedTravelTimeBuffer = additionalTravelBufferPerIterationInMinutes * 60; // buffer for the driving time; for unsolved carriers the buffer will be increased over time + for (int j = 0; j < 200; j++) { + GenerateSmallScaleCommercialTrafficDemand.DurationsBounds serviceDurationBounds = generator.getServiceDurationTimeSelector().get(key).sample(); + + for (int i = 0; i < 10; i++) { + int serviceDurationLowerBound = serviceDurationBounds.minDuration(); + int serviceDurationUpperBound = serviceDurationBounds.maxDuration(); + int possibleValue = rnd.nextInt(serviceDurationLowerBound * 60, serviceDurationUpperBound * 60); + // checks if the service duration will not exceed the vehicle availability including the buffer + if (possibleValue + usedTravelTimeBuffer <= maxVehicleAvailability) + return possibleValue; + } + if (j > 100){ + CarrierVehicle carrierVehicleToChange = carrier.getCarrierCapabilities().getCarrierVehicles().values().stream().sorted(Comparator.comparingDouble(vehicle -> vehicle.getLatestEndTime() - vehicle.getEarliestStartTime())).toList().getFirst(); + log.info("Changing vehicle availability for carrier {}. Old maxVehicleAvailability: {}", carrier.getId(), maxVehicleAvailability); + int tourDuration = 0; + int vehicleStartTime = 0; + int vehicleEndTime = 0; + while (tourDuration < maxVehicleAvailability) { + GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration t = generator.getTourDistribution().get(carrierAttributes.smallScaleCommercialTrafficType()).sample(); + vehicleStartTime = t.getVehicleStartTime(); + tourDuration = t.getVehicleTourDuration(); + vehicleEndTime = vehicleStartTime + tourDuration; + } + CarrierVehicle newCarrierVehicle = CarrierVehicle.Builder.newInstance(carrierVehicleToChange.getId(), carrierVehicleToChange.getLinkId(), + carrierVehicleToChange.getType()).setEarliestStart(vehicleStartTime).setLatestEnd(vehicleEndTime).build(); + carrier.getCarrierCapabilities().getCarrierVehicles().remove(carrierVehicleToChange.getId()); + carrier.getCarrierCapabilities().getCarrierVehicles().put(newCarrierVehicle.getId(), newCarrierVehicle); + maxVehicleAvailability = carrier.getCarrierCapabilities().getCarrierVehicles().values().stream().mapToDouble(vehicle -> vehicle.getLatestEndTime() - vehicle.getEarliestStartTime()).max().orElse(0); + log.info("New maxVehicleAvailability: {}", maxVehicleAvailability); + } + } + + throw new RuntimeException("No possible service duration found for employee category '" + carrierAttributes.selectedStartCategory() + "' and mode '" + + carrierAttributes.modeORvehType() + "' in traffic type '" + carrierAttributes.smallScaleCommercialTrafficType() + "'"); + } + + /** + * Redraws the service-durations of all {@link CarrierService}s of the given {@link Carrier}. + */ + private void redrawAllServiceDurations(Carrier carrier, GenerateSmallScaleCommercialTrafficDemand.CarrierAttributes carrierAttributes, int additionalTravelBufferPerIterationInMinutes) { + for (CarrierService service : carrier.getServices().values()) { + double newServiceDuration = getServiceTimePerStop(carrier, carrierAttributes, additionalTravelBufferPerIterationInMinutes); + CarrierService redrawnService = CarrierService.Builder.newInstance(service.getId(), service.getLocationLinkId()) + .setServiceDuration(newServiceDuration).setServiceStartTimeWindow(service.getServiceStartTimeWindow()).build(); + carrier.getServices().put(redrawnService.getId(), redrawnService); + } + } + + @Override + public void tryToSolveAllCarriersCompletely(Scenario scenario, List nonCompleteSolvedCarriers) { + int startNumberOfCarriersWithUnhandledJobs = nonCompleteSolvedCarriers.size(); + log.info("Starting with carrier-replanning loop."); + for (int i = 0; i < generator.getMaxReplanningIterations(); i++) { + log.info("carrier-replanning loop iteration: {}", i); + int numberOfCarriersWithUnhandledJobs = nonCompleteSolvedCarriers.size(); + for (Carrier nonCompleteSolvedCarrier : nonCompleteSolvedCarriers) { + //Delete old plan of carrier + nonCompleteSolvedCarrier.clearPlans(); + nonCompleteSolvedCarrier.setSelectedPlan(null); + GenerateSmallScaleCommercialTrafficDemand.CarrierAttributes carrierAttributes = generator.getCarrierId2carrierAttributes().get(nonCompleteSolvedCarrier.getId()); + + // Generate new services. The new service batch should have a smaller sum of serviceDurations than before (or otherwise it will not change anything) + redrawAllServiceDurations(nonCompleteSolvedCarrier, carrierAttributes, (i + 1) * generator.getAdditionalTravelBufferPerIterationInMinutes()); + log.info("Carrier should be changed..."); + } + try { + CarriersUtils.runJsprit(scenario, CarriersUtils.CarrierSelectionForSolution.solveOnlyForCarrierWithoutPlans); + } catch (ExecutionException | InterruptedException e) { + throw new RuntimeException(e); + } + + + nonCompleteSolvedCarriers = createListOfCarrierWithUnhandledJobs(scenario); + log.info( + "End of carrier-replanning loop iteration: {}. From the {} carriers with unhandled jobs ({} already solved), {} were solved in this iteration with an additionalBuffer of {} minutes.", + i, startNumberOfCarriersWithUnhandledJobs, startNumberOfCarriersWithUnhandledJobs - numberOfCarriersWithUnhandledJobs, + numberOfCarriersWithUnhandledJobs - nonCompleteSolvedCarriers.size(), (i + 1) * generator.getAdditionalTravelBufferPerIterationInMinutes()); + if (nonCompleteSolvedCarriers.isEmpty()) break; + } + + // Final check + if (!nonCompleteSolvedCarriers.isEmpty()) { + log.warn("Not all services were handled!"); + } + } + +} diff --git a/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/DefaultVehicleSelection.java b/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/DefaultVehicleSelection.java new file mode 100644 index 00000000000..c6221d61515 --- /dev/null +++ b/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/DefaultVehicleSelection.java @@ -0,0 +1,82 @@ +package org.matsim.smallScaleCommercialTrafficGeneration; + +import java.util.ArrayList; +import java.util.List; + +public class DefaultVehicleSelection implements VehicleSelection{ + @Override + public List getAllCategories() { + ArrayList categories = new ArrayList<>(7); + categories.add("Employee Primary Sector"); + categories.add("Employee Construction"); + categories.add("Employee Secondary Sector Rest"); + categories.add("Employee Retail"); + categories.add("Employee Traffic/Parcels"); + categories.add("Employee Tertiary Sector Rest"); + categories.add("Inhabitants"); + return categories; + } + + + @Override + public OdMatrixEntryInformation getOdMatrixEntryInformation(int purpose, String modeORvehType, String smallScaleCommercialTrafficType) { + VehicleSelection.OdMatrixEntryInformation information = new OdMatrixEntryInformation(); + information.occupancyRate = 0; + information.possibleVehicleTypes = null; + information.possibleStartCategories = new ArrayList<>(); + information.possibleStopCategories = new ArrayList<>(getAllCategories()); + + if (purpose == 1) { + if (smallScaleCommercialTrafficType.equals("commercialPersonTraffic")) { + information.possibleVehicleTypes = new String[]{"vwCaddy", "e_SpaceTourer"}; + information.occupancyRate = 1.5; + } + information.possibleStartCategories.add("Employee Secondary Sector Rest"); + information.possibleStopCategories.clear(); + information.possibleStopCategories.add("Employee Secondary Sector Rest"); + } else if (purpose == 2) { + if (smallScaleCommercialTrafficType.equals("commercialPersonTraffic")) { + information.possibleVehicleTypes = new String[]{"vwCaddy", "e_SpaceTourer"}; + information.occupancyRate = 1.6; + } + information.possibleStartCategories.add("Employee Secondary Sector Rest"); + } else if (purpose == 3) { + if (smallScaleCommercialTrafficType.equals("commercialPersonTraffic")) { + information.possibleVehicleTypes = new String[]{"golf1.4", "c_zero"}; + information.occupancyRate = 1.2; + } + information.possibleStartCategories.add("Employee Retail"); + information.possibleStartCategories.add("Employee Tertiary Sector Rest"); + } else if (purpose == 4) { + if (smallScaleCommercialTrafficType.equals("commercialPersonTraffic")) { + information.possibleVehicleTypes = new String[]{"golf1.4", "c_zero"}; + information.occupancyRate = 1.2; + } + information.possibleStartCategories.add("Employee Traffic/Parcels"); + } else if (purpose == 5) { + if (smallScaleCommercialTrafficType.equals("commercialPersonTraffic")) { + information.possibleVehicleTypes = new String[]{"mercedes313", "e_SpaceTourer"}; + information.occupancyRate = 1.7; + } + information.possibleStartCategories.add("Employee Construction"); + } else if (purpose == 6) { + information.possibleStartCategories.add("Inhabitants"); + } + + if (smallScaleCommercialTrafficType.equals("goodsTraffic")) { + information.occupancyRate = 1.; + switch (modeORvehType) { + case "vehTyp1" -> + information.possibleVehicleTypes = new String[]{"vwCaddy", "e_SpaceTourer"}; // possible to add more types, see source + case "vehTyp2" -> + information.possibleVehicleTypes = new String[]{"mercedes313", "e_SpaceTourer"}; + case "vehTyp3", "vehTyp4" -> + information.possibleVehicleTypes = new String[]{"light8t", "light8t_electro"}; + case "vehTyp5" -> + information.possibleVehicleTypes = new String[]{"medium18t", "medium18t_electro", "heavy40t", "heavy40t_electro"}; + } + } + + return information; + } +} diff --git a/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/GenerateSmallScaleCommercialTrafficDemand.java b/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/GenerateSmallScaleCommercialTrafficDemand.java index af8fbacf479..553b9abc689 100644 --- a/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/GenerateSmallScaleCommercialTrafficDemand.java +++ b/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/GenerateSmallScaleCommercialTrafficDemand.java @@ -17,6 +17,7 @@ * See also COPYING, LICENSE and WARRANTY file * * * * *********************************************************************** */ + package org.matsim.smallScaleCommercialTrafficGeneration; import com.google.inject.Inject; @@ -68,11 +69,11 @@ import org.matsim.core.utils.geometry.CoordinateTransformation; import org.matsim.facilities.ActivityFacility; import org.matsim.freight.carriers.*; -import org.matsim.freight.carriers.CarrierCapabilities.FleetSize; +import org.matsim.freight.carriers.analysis.RunFreightAnalysisEventBased; import org.matsim.freight.carriers.controler.*; import org.matsim.freight.carriers.usecases.chessboard.CarrierTravelDisutilities; +import org.matsim.smallScaleCommercialTrafficGeneration.data.CommercialTourSpecifications; import org.matsim.smallScaleCommercialTrafficGeneration.data.DefaultTourSpecificationsByUsingKID2002; -import org.matsim.smallScaleCommercialTrafficGeneration.data.GetCommercialTourSpecifications; import org.matsim.vehicles.CostInformation; import org.matsim.vehicles.Vehicle; import org.matsim.vehicles.VehicleType; @@ -94,7 +95,6 @@ * * @author Ricardo Ewert */ -//TODO: use EnumeratedDistribution for distributions with probabilities @CommandLine.Command(name = "generate-small-scale-commercial-traffic", description = "Generates plans for a small scale commercial traffic model", showDefaultValues = true) public class GenerateSmallScaleCommercialTrafficDemand implements MATSimAppCommand { // freight traffic from extern: @@ -108,7 +108,9 @@ public class GenerateSmallScaleCommercialTrafficDemand implements MATSimAppComma private static final Logger log = LogManager.getLogger(GenerateSmallScaleCommercialTrafficDemand.class); private final IntegrateExistingTrafficToSmallScaleCommercial integrateExistingTrafficToSmallScaleCommercial; - private final GetCommercialTourSpecifications getCommercialTourSpecifications; + private final CommercialTourSpecifications commercialTourSpecifications; + private final VehicleSelection vehicleSelection; + private final UnhandledServicesSolution unhandledServicesSolution; private enum CreationOption { useExistingCarrierFileWithSolution, createNewCarrierFile, useExistingCarrierFileWithoutSolution @@ -136,6 +138,12 @@ public enum SmallScaleCommercialTrafficType { @CommandLine.Option(names = "--jspritIterations", description = "Set number of jsprit iterations", required = true) private int jspritIterations; + @CommandLine.Option(names = "--additionalTravelBufferPerIterationInMinutes", description = "This buffer/driving time is used for service-route-planning. If set too low, carriers may not serve all their services.", defaultValue = "10") + private int additionalTravelBufferPerIterationInMinutes; + + @CommandLine.Option(names = "--maxReplanningIterations", description = "Limit of carrier replanning iterations, where carriers with unhandled services get new plans. If your carrier-plans are still not fully served, increase this limit.", defaultValue = "100") + private int maxReplanningIterations; + @CommandLine.Option(names = "--creationOption", description = "Set option of mode differentiation: useExistingCarrierFileWithSolution, createNewCarrierFile, useExistingCarrierFileWithoutSolution") private CreationOption usedCreationOption; @@ -169,19 +177,32 @@ public enum SmallScaleCommercialTrafficType { @CommandLine.Option(names = "--pathOutput", description = "Path for the output") private Path output; - private Random rnd; + private static Random rnd; private RandomGenerator rng; private final Map>> facilitiesPerZone = new HashMap<>(); + private final Map, CarrierAttributes> carrierId2carrierAttributes = new HashMap<>(); + + private Map> tourDistribution = null; + private Map> serviceDurationTimeSelector = null; + + private TripDistributionMatrix odMatrix; + private Map> resultingDataPerZone; + private Map, Link>> linksPerZone; private Index indexZones; public GenerateSmallScaleCommercialTrafficDemand() { this.integrateExistingTrafficToSmallScaleCommercial = new DefaultIntegrateExistingTrafficToSmallScaleCommercialImpl(); log.info("Using default {} if existing models are integrated!", DefaultIntegrateExistingTrafficToSmallScaleCommercialImpl.class.getSimpleName()); - this.getCommercialTourSpecifications = new DefaultTourSpecificationsByUsingKID2002(); + this.commercialTourSpecifications = new DefaultTourSpecificationsByUsingKID2002(); log.info("Using default {} for tour specifications!", DefaultTourSpecificationsByUsingKID2002.class.getSimpleName()); + this.vehicleSelection = new DefaultVehicleSelection(); + log.info("Using default {} for tour vehicle-selection!", DefaultVehicleSelection.class.getSimpleName()); + this.unhandledServicesSolution = new DefaultUnhandledServicesSolution(this); + log.info("Using default {} for tour unhandled-services-solution!", DefaultUnhandledServicesSolution.class.getSimpleName()); } - public GenerateSmallScaleCommercialTrafficDemand(IntegrateExistingTrafficToSmallScaleCommercial integrateExistingTrafficToSmallScaleCommercial, GetCommercialTourSpecifications getCommercialTourSpecifications) { + + public GenerateSmallScaleCommercialTrafficDemand(IntegrateExistingTrafficToSmallScaleCommercial integrateExistingTrafficToSmallScaleCommercial, CommercialTourSpecifications getCommercialTourSpecifications, VehicleSelection vehicleSelection, UnhandledServicesSolution unhandledServicesSolution) { if (integrateExistingTrafficToSmallScaleCommercial == null){ this.integrateExistingTrafficToSmallScaleCommercial = new DefaultIntegrateExistingTrafficToSmallScaleCommercialImpl(); log.info("Using default {} if existing models are integrated!", DefaultIntegrateExistingTrafficToSmallScaleCommercialImpl.class.getSimpleName()); @@ -190,12 +211,26 @@ public GenerateSmallScaleCommercialTrafficDemand(IntegrateExistingTrafficToSmall log.info("Using {} if existing models are integrated!", integrateExistingTrafficToSmallScaleCommercial.getClass().getSimpleName()); } if (getCommercialTourSpecifications == null){ - this.getCommercialTourSpecifications = new DefaultTourSpecificationsByUsingKID2002(); + this.commercialTourSpecifications = new DefaultTourSpecificationsByUsingKID2002(); log.info("Using default {} for tour specifications!", DefaultTourSpecificationsByUsingKID2002.class.getSimpleName()); } else { - this.getCommercialTourSpecifications = getCommercialTourSpecifications; + this.commercialTourSpecifications = getCommercialTourSpecifications; log.info("Using {} for tour specifications!", getCommercialTourSpecifications.getClass().getSimpleName()); } + if (vehicleSelection == null){ + this.vehicleSelection = new DefaultVehicleSelection(); + log.info("Using default {} for tour vehicle-selection!", DefaultVehicleSelection.class.getSimpleName()); + } else { + this.vehicleSelection = vehicleSelection; + log.info("Using {} for tour vehicle-selection!", vehicleSelection.getClass().getSimpleName()); + } + if (unhandledServicesSolution == null){ + this.unhandledServicesSolution = new DefaultUnhandledServicesSolution(this); + log.info("Using default {} for unhandled-services-solution", DefaultUnhandledServicesSolution.class.getSimpleName()); + } else { + this.unhandledServicesSolution = unhandledServicesSolution; + log.info("Using {} for unhandled-services-solution!", unhandledServicesSolution.getClass().getSimpleName()); + } } public static void main(String[] args) { @@ -243,7 +278,7 @@ public Integer call() throws Exception { readVehicleTypes.keySet().removeIf(vehicleType -> !usedCarrierVehicleTypes.contains(vehicleType)); if (Objects.requireNonNull(usedCreationOption) == CreationOption.useExistingCarrierFileWithoutSolution) { - solveSeparatedVRPs(scenario, null); + solveSeparatedVRPs(scenario); } } default -> { @@ -252,20 +287,20 @@ public Integer call() throws Exception { } indexZones = SmallScaleCommercialTrafficUtils.getIndexZones(shapeFileZonePath, shapeCRS, shapeFileZoneNameColumn); - Map> resultingDataPerZone = readDataDistribution(pathToDataDistributionToZones); + resultingDataPerZone = readDataDistribution(pathToDataDistributionToZones); filterFacilitiesForZones(scenario, facilitiesPerZone); - Map, Link>> linksPerZone = filterLinksForZones(scenario, indexZones, facilitiesPerZone, shapeFileZoneNameColumn); + linksPerZone = filterLinksForZones(scenario, indexZones, facilitiesPerZone, shapeFileZoneNameColumn); switch (usedSmallScaleCommercialTrafficType) { case commercialPersonTraffic, goodsTraffic -> - createCarriersAndDemand(output, scenario, resultingDataPerZone, linksPerZone, + createCarriersAndDemand(output, scenario, usedSmallScaleCommercialTrafficType.toString(), includeExistingModels); case completeSmallScaleCommercialTraffic -> { - createCarriersAndDemand(output, scenario, resultingDataPerZone, linksPerZone, "commercialPersonTraffic", + createCarriersAndDemand(output, scenario, "commercialPersonTraffic", includeExistingModels); includeExistingModels = false; // because already included in the step before - createCarriersAndDemand(output, scenario, resultingDataPerZone, linksPerZone, "goodsTraffic", + createCarriersAndDemand(output, scenario, "goodsTraffic", includeExistingModels); } default -> throw new RuntimeException("No traffic type selected."); @@ -277,7 +312,7 @@ public Integer call() throws Exception { new CarrierPlanWriter(CarriersUtils.addOrGetCarriers(scenario)) .write(scenario.getConfig().controller().getOutputDirectory() + "/" + scenario.getConfig().controller().getRunId() + ".output_CarrierDemand.xml"); - solveSeparatedVRPs(scenario, linksPerZone); + solveSeparatedVRPs(scenario); } } if (config.controller().getRunId() == null) @@ -298,13 +333,21 @@ public Integer call() throws Exception { controler.run(); + //Analysis + System.out.println("Starting Analysis for Carriers of small scale commercial traffic."); + //TODO perhaps change to complete carrier analysis + RunFreightAnalysisEventBased freightAnalysis = new RunFreightAnalysisEventBased(CarriersUtils.addOrGetCarriers(scenario), output.resolve("CarrierAnalysis").toString()); + freightAnalysis.runCarriersAnalysis(); + System.out.println("Finishing Analysis of Carrier."); + SmallScaleCommercialTrafficUtils.createPlansBasedOnCarrierPlans(controler.getScenario(), usedSmallScaleCommercialTrafficType.toString(), output, modelName, sampleName, nameOutputPopulation, numberOfPlanVariantsPerAgent); return 0; } - /** Creates a map with the different facility types per building. + /** + * Creates a map with the different facility types per building. * @param scenario complete Scenario * @param facilitiesPerZone Map with facilities per zone */ @@ -318,11 +361,13 @@ private void filterFacilitiesForZones(Scenario scenario, Map, Link>> linksPerZone) throws Exception { - + private void solveSeparatedVRPs(Scenario originalScenario) throws Exception { boolean splitCarrier = true; boolean splitVRPs = false; int maxServicesPerCarrier = 100; @@ -330,6 +375,7 @@ private void solveSeparatedVRPs(Scenario originalScenario, Map, Carrier> solvedCarriers = new HashMap<>(); List> keyList = new ArrayList<>(allCarriers.keySet()); + Map, List>> carrierId2subCarrierIds = new HashMap<>(); CarriersUtils.getCarriers(originalScenario).getCarriers().values().forEach(carrier -> { if (CarriersUtils.getJspritIterations(carrier) == 0) { allCarriers.remove(carrier.getId()); @@ -389,6 +435,9 @@ private void solveSeparatedVRPs(Scenario originalScenario, Map newCarrier.getAttributes() .putAttribute(attribute, carrier.getAttributes().getAttribute(attribute))); + carrierId2subCarrierIds.putIfAbsent(carrier.getId(), new LinkedList<>()); + carrierId2subCarrierIds.get(carrier.getId()).add(newCarrier.getId()); + List> vehiclesForNewCarrier = new ArrayList<>( carrier.getCarrierCapabilities().getCarrierVehicles().keySet()); List> servicesForNewCarrier = new ArrayList<>( @@ -428,9 +477,20 @@ private void solveSeparatedVRPs(Scenario originalScenario, Map oldCarrierId : carrierId2subCarrierIds.keySet()) { + for (Id newCarrierId : carrierId2subCarrierIds.get(oldCarrierId)) { + carrierId2carrierAttributes.put(newCarrierId, carrierId2carrierAttributes.get(oldCarrierId)); + } + } + log.info("Solving carriers {}-{} of all {} carriers. This are {} VRP to solve.", fromIndex + 1, toIndex, allCarriers.size(), subCarriers.size()); CarriersUtils.runJsprit(originalScenario); + List nonCompleteSolvedCarriers = unhandledServicesSolution.createListOfCarrierWithUnhandledJobs(originalScenario); + if (!nonCompleteSolvedCarriers.isEmpty()) + unhandledServicesSolution.tryToSolveAllCarriersCompletely(originalScenario, nonCompleteSolvedCarriers); solvedCarriers.putAll(CarriersUtils.getCarriers(originalScenario).getCarriers()); CarriersUtils.getCarriers(originalScenario).getCarriers().clear(); if (!splitVRPs) @@ -453,10 +513,8 @@ private void solveSeparatedVRPs(Scenario originalScenario, Map> resultingDataPerZone, - Map, Link>> linksPerZone, String smallScaleCommercialTrafficType, + String smallScaleCommercialTrafficType, boolean includeExistingModels) throws Exception { - ArrayList modesORvehTypes; if (smallScaleCommercialTrafficType.equals("goodsTraffic")) modesORvehTypes = new ArrayList<>( @@ -478,16 +536,15 @@ else if (smallScaleCommercialTrafficType.equals("commercialPersonTraffic")) integrateExistingTrafficToSmallScaleCommercial.reduceDemandBasedOnExistingCarriers(scenario, linksPerZone, smallScaleCommercialTrafficType, trafficVolumePerTypeAndZone_start, trafficVolumePerTypeAndZone_stop); } - final TripDistributionMatrix odMatrix = createTripDistribution(trafficVolumePerTypeAndZone_start, - trafficVolumePerTypeAndZone_stop, smallScaleCommercialTrafficType, scenario, output, linksPerZone); - createCarriers(scenario, odMatrix, resultingDataPerZone, smallScaleCommercialTrafficType, linksPerZone); + odMatrix = createTripDistribution(trafficVolumePerTypeAndZone_start, + trafficVolumePerTypeAndZone_stop, smallScaleCommercialTrafficType, scenario, output); + createCarriers(scenario, smallScaleCommercialTrafficType); } /** * Reads and checks config if all necessary parameters are set. */ private Config readAndCheckConfig(Path configPath, String modelName, String sampleName, Path output) throws Exception { - Config config = ConfigUtils.loadConfig(configPath.toString()); if (output == null || output.toString().isEmpty()) config.controller().setOutputDirectory(Path.of(config.controller().getOutputDirectory()).resolve(modelName) @@ -559,18 +616,22 @@ public void install() { /** * Creates the carriers and the related demand, based on the generated * TripDistributionMatrix. + * @param scenario Scenario (loaded from your config), where the carriers will be put into + * @param smallScaleCommercialTrafficType Selected traffic types. Options: commercialPersonTraffic, goodsTraffic */ - private void createCarriers(Scenario scenario, TripDistributionMatrix odMatrix, - Map> resultingDataPerZone, String smallScaleCommercialTrafficType, - Map, Link>> linksPerZone) { + public void createCarriers(Scenario scenario, + String smallScaleCommercialTrafficType) { + //Save the given data + RandomGenerator rng = new MersenneTwister(scenario.getConfig().global().getRandomSeed()); + int maxNumberOfCarrier = odMatrix.getListOfPurposes().size() * odMatrix.getListOfZones().size() * odMatrix.getListOfModesOrVehTypes().size(); int createdCarrier = 0; int fixedNumberOfVehiclePerTypeAndLocation = 1; //TODO possible improvement, perhaps check KiD - EnumeratedDistribution tourDistribution = getCommercialTourSpecifications.createTourDistribution(smallScaleCommercialTrafficType, rng); + tourDistribution = commercialTourSpecifications.createTourDistribution(rng); - Map> stopDurationTimeSelector = getCommercialTourSpecifications.createStopDurationDistributionPerCategory(smallScaleCommercialTrafficType, rng); + serviceDurationTimeSelector = commercialTourSpecifications.createStopDurationDistributionPerCategory(rng); CarrierVehicleTypes carrierVehicleTypes = CarriersUtils.getCarrierVehicleTypes(scenario); Map, VehicleType> additionalCarrierVehicleTypes = scenario.getVehicles().getVehicleTypes(); @@ -589,6 +650,8 @@ private void createCarriers(Scenario scenario, TripDistributionMatrix odMatrix, for (Integer purpose : odMatrix.getListOfPurposes()) { for (String startZone : odMatrix.getListOfZones()) { for (String modeORvehType : odMatrix.getListOfModesOrVehTypes()) { + + // Check if this purpose, startZone, modeORvehType combination is a possiblr starting location (by looking if it has a trip-distribution-entry) boolean isStartingLocation = false; checkIfIsStartingPosition: { @@ -601,87 +664,32 @@ private void createCarriers(Scenario scenario, TripDistributionMatrix odMatrix, } } } - //TODO make vehcile selection configurable + if (isStartingLocation) { - double occupancyRate = 0; - String[] possibleVehicleTypes = null; - ArrayList startCategory = new ArrayList<>(); - ArrayList stopCategory = new ArrayList<>(); - stopCategory.add("Employee Primary Sector"); - stopCategory.add("Employee Construction"); - stopCategory.add("Employee Secondary Sector Rest"); - stopCategory.add("Employee Retail"); - stopCategory.add("Employee Traffic/Parcels"); - stopCategory.add("Employee Tertiary Sector Rest"); - stopCategory.add("Inhabitants"); - if (purpose == 1) { - if (smallScaleCommercialTrafficType.equals("commercialPersonTraffic")) { - possibleVehicleTypes = new String[]{"vwCaddy", "e_SpaceTourer"}; - occupancyRate = 1.5; - } - startCategory.add("Employee Secondary Sector Rest"); - stopCategory.clear(); - stopCategory.add("Employee Secondary Sector Rest"); - } else if (purpose == 2) { - if (smallScaleCommercialTrafficType.equals("commercialPersonTraffic")) { - possibleVehicleTypes = new String[]{"vwCaddy", "e_SpaceTourer"}; - occupancyRate = 1.6; - } - startCategory.add("Employee Secondary Sector Rest"); - } else if (purpose == 3) { - if (smallScaleCommercialTrafficType.equals("commercialPersonTraffic")) { - possibleVehicleTypes = new String[]{"golf1.4", "c_zero"}; - occupancyRate = 1.2; - } - startCategory.add("Employee Retail"); - startCategory.add("Employee Tertiary Sector Rest"); - } else if (purpose == 4) { - if (smallScaleCommercialTrafficType.equals("commercialPersonTraffic")) { - possibleVehicleTypes = new String[]{"golf1.4", "c_zero"}; - occupancyRate = 1.2; - } - startCategory.add("Employee Traffic/Parcels"); - } else if (purpose == 5) { - if (smallScaleCommercialTrafficType.equals("commercialPersonTraffic")) { - possibleVehicleTypes = new String[]{"mercedes313", "e_SpaceTourer"}; - occupancyRate = 1.7; - } - startCategory.add("Employee Construction"); - } else if (purpose == 6) { - startCategory.add("Inhabitants"); - } - if (smallScaleCommercialTrafficType.equals("goodsTraffic")) { - occupancyRate = 1.; - switch (modeORvehType) { - case "vehTyp1" -> - possibleVehicleTypes = new String[]{"vwCaddy", "e_SpaceTourer"}; // possible to add more types, see source - case "vehTyp2" -> - possibleVehicleTypes = new String[]{"mercedes313", "e_SpaceTourer"}; - case "vehTyp3", "vehTyp4" -> - possibleVehicleTypes = new String[]{"light8t", "light8t_electro"}; - case "vehTyp5" -> - possibleVehicleTypes = new String[]{"medium18t", "medium18t_electro", "heavy40t", "heavy40t_electro"}; - } - } + // Get the vehicle-types and start/stop-categories + VehicleSelection.OdMatrixEntryInformation odMatrixEntry = vehicleSelection.getOdMatrixEntryInformation(purpose, modeORvehType, smallScaleCommercialTrafficType); // use only types of the possibleTypes which are in the given types file List vehicleTypes = new ArrayList<>(); - assert possibleVehicleTypes != null; + assert odMatrixEntry.possibleVehicleTypes != null; - for (String possibleVehicleType : possibleVehicleTypes) { + for (String possibleVehicleType : odMatrixEntry.possibleVehicleTypes) { if (CarriersUtils.getCarrierVehicleTypes(scenario).getVehicleTypes().containsKey( Id.create(possibleVehicleType, VehicleType.class))) vehicleTypes.add(possibleVehicleType); } - // find a start category with existing employees in this zone - Collections.shuffle(startCategory, rnd); - String selectedStartCategory = startCategory.getFirst(); + + // find a (random) start category with existing employees in this zone + Collections.shuffle(odMatrixEntry.possibleStartCategories, rnd); + String selectedStartCategory = odMatrixEntry.possibleStartCategories.getFirst(); for (int count = 1; resultingDataPerZone.get(startZone).getDouble(selectedStartCategory) == 0; count++) { - if (count <= startCategory.size()) - selectedStartCategory = startCategory.get(rnd.nextInt(startCategory.size())); + if (count <= odMatrixEntry.possibleStartCategories.size()) + selectedStartCategory = odMatrixEntry.possibleStartCategories.get(rnd.nextInt(odMatrixEntry.possibleStartCategories.size())); else - selectedStartCategory = stopCategory.get(rnd.nextInt(stopCategory.size())); + selectedStartCategory = odMatrixEntry.possibleStopCategories.get(rnd.nextInt(odMatrixEntry.possibleStopCategories.size())); } + + // Generate carrierName String carrierName = null; if (smallScaleCommercialTrafficType.equals("goodsTraffic")) { carrierName = "Carrier_Goods_" + startZone + "_purpose_" + purpose + "_" + modeORvehType; @@ -689,94 +697,96 @@ private void createCarriers(Scenario scenario, TripDistributionMatrix odMatrix, carrierName = "Carrier_Business_" + startZone + "_purpose_" + purpose; int numberOfDepots = odMatrix.getSumOfServicesForStartZone(startZone, modeORvehType, purpose, smallScaleCommercialTrafficType); - FleetSize fleetSize = FleetSize.FINITE; + + // Create the Carrier + CarrierCapabilities.FleetSize fleetSize = CarrierCapabilities.FleetSize.FINITE; ArrayList vehicleDepots = new ArrayList<>(); createdCarrier++; log.info("Create carrier number {} of a maximum Number of {} carriers.", createdCarrier, maxNumberOfCarrier); log.info("Carrier: {}; depots: {}; services: {}", carrierName, numberOfDepots, (int) Math.ceil(odMatrix.getSumOfServicesForStartZone(startZone, modeORvehType, - purpose, smallScaleCommercialTrafficType) / occupancyRate)); - createNewCarrierAndAddVehicleTypes(scenario, purpose, startZone, - selectedStartCategory, carrierName, vehicleTypes, numberOfDepots, fleetSize, - fixedNumberOfVehiclePerTypeAndLocation, vehicleDepots, linksPerZone, smallScaleCommercialTrafficType, - tourDistribution); - log.info("Create services for carrier: {}", carrierName); - for (String stopZone : odMatrix.getListOfZones()) { - int trafficVolumeForOD = Math.round((float)odMatrix.getTripDistributionValue(startZone, - stopZone, modeORvehType, purpose, smallScaleCommercialTrafficType)); - int numberOfJobs = (int) Math.ceil(trafficVolumeForOD / occupancyRate); - if (numberOfJobs == 0) - continue; - // find a category for the tour stop with existing employees in this zone - String selectedStopCategory = stopCategory.get(rnd.nextInt(stopCategory.size())); - while (resultingDataPerZone.get(stopZone).getDouble(selectedStopCategory) == 0) - selectedStopCategory = stopCategory.get(rnd.nextInt(stopCategory.size())); - String[] serviceArea = new String[]{stopZone}; - int serviceTimePerStop; - if (selectedStartCategory.equals("Inhabitants")) - serviceTimePerStop = getServiceTimePerStop(stopDurationTimeSelector, startCategory.getFirst(), modeORvehType, smallScaleCommercialTrafficType); - else - serviceTimePerStop = getServiceTimePerStop(stopDurationTimeSelector, selectedStartCategory, modeORvehType, smallScaleCommercialTrafficType); + purpose, smallScaleCommercialTrafficType) / odMatrixEntry.occupancyRate)); - TimeWindow serviceTimeWindow = TimeWindow.newInstance(0, - 24 * 3600); //TODO eventuell anpassen wegen veränderter Tourzeiten - createServices(scenario, vehicleDepots, selectedStopCategory, carrierName, - numberOfJobs, serviceArea, serviceTimePerStop, serviceTimeWindow, linksPerZone); - } + CarrierAttributes carrierAttributes = new CarrierAttributes(purpose, startZone, selectedStartCategory, modeORvehType, + smallScaleCommercialTrafficType, vehicleDepots, odMatrixEntry); + carrierId2carrierAttributes.put(Id.create(carrierName, Carrier.class), carrierAttributes); + + createNewCarrierAndAddVehicleTypes( + scenario, carrierName, carrierAttributes, + vehicleTypes, numberOfDepots, fleetSize, + fixedNumberOfVehiclePerTypeAndLocation); + + // Now Create services for this carrier + Carrier newCarrier = CarriersUtils.getCarriers(scenario).getCarriers().get(Id.create(carrierName, Carrier.class)); + + createServices(newCarrier, carrierAttributes); } } } } - -// System.out.println("Final results for the start time distribution"); -// tourStartTimeSelector.writeResults(); - -// System.out.println("Final results for the tour duration distribution"); -// tourDurationTimeSelector.writeResults(); - -// for (StopDurationGoodTrafficKey sector : stopDurationTimeSelector.keySet()) { -// System.out.println("Final results for the stop duration distribution in sector " + sector); -// stopDurationTimeSelector.get(sector); -// } - log.warn("The jspritIterations are now set to {} in this simulation!", jspritIterations); log.info("Finished creating {} carriers including related services.", createdCarrier); } /** - * Creates the services for one carrier. + * Generates and adds the services for the given carrier. */ - private void createServices(Scenario scenario, ArrayList noPossibleLinks, - String selectedStopCategory, String carrierName, int numberOfJobs, String[] serviceArea, - Integer serviceTimePerStop, TimeWindow serviceTimeWindow, - Map, Link>> linksPerZone) { + private void createServices(Carrier newCarrier, + CarrierAttributes carrierAttributes) { + log.info("Create services for carrier: {}", newCarrier.getId()); + for (String stopZone : odMatrix.getListOfZones()) { + int trafficVolumeForOD = Math.round((float)odMatrix.getTripDistributionValue(carrierAttributes.startZone, + stopZone, carrierAttributes.modeORvehType, carrierAttributes.purpose, carrierAttributes.smallScaleCommercialTrafficType)); + int numberOfJobs = (int) Math.ceil(trafficVolumeForOD / carrierAttributes.odMatrixEntry.occupancyRate); + if (numberOfJobs == 0) + continue; + // find a category for the tour stop with existing employees in this zone + String selectedStopCategory = carrierAttributes.odMatrixEntry.possibleStopCategories.get(rnd.nextInt(carrierAttributes.odMatrixEntry.possibleStopCategories.size())); + while (resultingDataPerZone.get(stopZone).getDouble(selectedStopCategory) == 0) + selectedStopCategory = carrierAttributes.odMatrixEntry.possibleStopCategories.get(rnd.nextInt(carrierAttributes.odMatrixEntry.possibleStopCategories.size())); + for (int i = 0; i < numberOfJobs; i++) { + int serviceTimePerStop; + if (carrierAttributes.selectedStartCategory.equals("Inhabitants")){ + CarrierAttributes inhabitantAttributes = new CarrierAttributes(carrierAttributes.purpose, carrierAttributes.startZone, + carrierAttributes.odMatrixEntry.possibleStartCategories.getFirst(), carrierAttributes.modeORvehType, + carrierAttributes.smallScaleCommercialTrafficType, carrierAttributes.vehicleDepots, carrierAttributes.odMatrixEntry); + serviceTimePerStop = unhandledServicesSolution.getServiceTimePerStop(newCarrier, inhabitantAttributes, 0); - String stopZone = serviceArea[0]; + } + else { + serviceTimePerStop = unhandledServicesSolution.getServiceTimePerStop(newCarrier, carrierAttributes, 0); + } - for (int i = 0; i < numberOfJobs; i++) { + TimeWindow serviceTimeWindow = TimeWindow.newInstance(0, + 36 * 3600); // extended time window, so that late tours can handle it + createService(newCarrier, carrierAttributes.vehicleDepots, selectedStopCategory, stopZone, serviceTimePerStop, serviceTimeWindow); + } + } + } - Id linkId = findPossibleLink(stopZone, selectedStopCategory, noPossibleLinks, linksPerZone); - Id idNewService = Id.create(carrierName + "_" + linkId + "_" + rnd.nextInt(10000), - CarrierService.class); + /** + * Adds a service with the given attributes to the carrier. + */ + private void createService(Carrier newCarrier, ArrayList noPossibleLinks, String selectedStopCategory, String stopZone, + Integer serviceTimePerStop, TimeWindow serviceTimeWindow) { - CarrierService thisService = CarrierService.Builder.newInstance(idNewService, linkId) - .setServiceDuration(serviceTimePerStop).setServiceStartTimeWindow(serviceTimeWindow).build(); - CarriersUtils.getCarriers(scenario).getCarriers().get(Id.create(carrierName, Carrier.class)).getServices() - .put(thisService.getId(), thisService); - } + Id linkId = findPossibleLink(stopZone, selectedStopCategory, noPossibleLinks); + Id idNewService = Id.create(newCarrier.getId().toString() + "_" + linkId + "_" + rnd.nextInt(10000), + CarrierService.class); + CarrierService thisService = CarrierService.Builder.newInstance(idNewService, linkId) + .setServiceDuration(serviceTimePerStop).setServiceStartTimeWindow(serviceTimeWindow).build(); + newCarrier.getServices().put(thisService.getId(), thisService); } + + /** * Creates the carrier and the related vehicles. */ - private void createNewCarrierAndAddVehicleTypes(Scenario scenario, Integer purpose, String startZone, - String selectedStartCategory, String carrierName, - List vehicleTypes, int numberOfDepots, FleetSize fleetSize, - int fixedNumberOfVehiclePerTypeAndLocation, - List vehicleDepots, Map, Link>> linksPerZone, - String smallScaleCommercialTrafficType, - EnumeratedDistribution tourStartTimeSelector) { + private void createNewCarrierAndAddVehicleTypes(Scenario scenario, String carrierName, CarrierAttributes carrierAttributes, + List vehicleTypes, int numberOfDepots, CarrierCapabilities.FleetSize fleetSize, + int fixedNumberOfVehiclePerTypeAndLocation) { Carriers carriers = CarriersUtils.addOrGetCarriers(scenario); CarrierVehicleTypes carrierVehicleTypes = CarriersUtils.getCarrierVehicleTypes(scenario); @@ -784,28 +794,29 @@ private void createNewCarrierAndAddVehicleTypes(Scenario scenario, Integer purpo CarrierCapabilities carrierCapabilities; Carrier thisCarrier = CarriersUtils.createCarrier(Id.create(carrierName, Carrier.class)); - if (smallScaleCommercialTrafficType.equals("commercialPersonTraffic") && purpose == 3) - thisCarrier.getAttributes().putAttribute("subpopulation", smallScaleCommercialTrafficType + "_service"); + if (carrierAttributes.smallScaleCommercialTrafficType.equals("commercialPersonTraffic") && carrierAttributes.purpose == 3) + thisCarrier.getAttributes().putAttribute("subpopulation", carrierAttributes.smallScaleCommercialTrafficType + "_service"); else - thisCarrier.getAttributes().putAttribute("subpopulation", smallScaleCommercialTrafficType); + thisCarrier.getAttributes().putAttribute("subpopulation", carrierAttributes.smallScaleCommercialTrafficType); - thisCarrier.getAttributes().putAttribute("purpose", purpose); - thisCarrier.getAttributes().putAttribute("tourStartArea", startZone); + thisCarrier.getAttributes().putAttribute("purpose", carrierAttributes.purpose); + thisCarrier.getAttributes().putAttribute("tourStartArea", carrierAttributes.startZone); if (jspritIterations > 0) CarriersUtils.setJspritIterations(thisCarrier, jspritIterations); carrierCapabilities = CarrierCapabilities.Builder.newInstance().setFleetSize(fleetSize).build(); + carriers.addCarrier(thisCarrier); - while (vehicleDepots.size() < numberOfDepots) { - Id linkId = findPossibleLink(startZone, selectedStartCategory, null, linksPerZone); - vehicleDepots.add(linkId.toString()); + while (carrierAttributes.vehicleDepots.size() < numberOfDepots) { + Id linkId = findPossibleLink(carrierAttributes.startZone, carrierAttributes.selectedStartCategory, null); + carrierAttributes.vehicleDepots.add(linkId.toString()); } - for (String singleDepot : vehicleDepots) { - TourStartAndDuration t = tourStartTimeSelector.sample(); + for (String singleDepot : carrierAttributes.vehicleDepots) { + GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration t = tourDistribution.get(carrierAttributes.smallScaleCommercialTrafficType).sample(); - int vehicleStartTime = getVehicleStartTime(t); - int tourDuration = getVehicleTourDuration(t); + int vehicleStartTime = t.getVehicleStartTime(); + int tourDuration = t.getVehicleTourDuration(); int vehicleEndTime = vehicleStartTime + tourDuration; for (String thisVehicleType : vehicleTypes) { //TODO Flottenzusammensetzung anpassen. Momentan pro Depot alle Fahrzeugtypen 1x erzeugen VehicleType thisType = carrierVehicleTypes.getVehicleTypes() @@ -831,52 +842,10 @@ private void createNewCarrierAndAddVehicleTypes(Scenario scenario, Integer purpo } } - /** - * Gives a duration for the created tour under the given probability. - * - */ - private int getVehicleTourDuration(TourStartAndDuration t) { - return (int) rnd.nextDouble(t.minDuration * 60, t.maxDuration * 60); - } - - /** - * Gives a tour start time for the created tour under the given probability. - */ - private int getVehicleStartTime(TourStartAndDuration t) { - return rnd.nextInt(t.hourLower * 3600, t.hourUpper * 3600); - } - - - /** - * Give a service duration based on the purpose and the trafficType under a given probability - * - * @param serviceDurationTimeSelector the selector for the service duration - * @param employeeCategory the category of the employee - * @param modeORvehType the mode or vehicle type - * @param smallScaleCommercialTrafficType the traffic type - * @return the service duration - */ - private Integer getServiceTimePerStop(Map> serviceDurationTimeSelector, - String employeeCategory, - String modeORvehType, String smallScaleCommercialTrafficType) { - StopDurationGoodTrafficKey key = null; - if (smallScaleCommercialTrafficType.equals(SmallScaleCommercialTrafficType.commercialPersonTraffic.toString())) - key = makeStopDurationGoodTrafficKey(employeeCategory, null); - else if (smallScaleCommercialTrafficType.equals(SmallScaleCommercialTrafficType.goodsTraffic.toString())) { - key = makeStopDurationGoodTrafficKey(employeeCategory, modeORvehType); - } - DurationsBounds serviceDurationBounds = serviceDurationTimeSelector.get(key).sample(); - int serviceDurationLowerBound = serviceDurationBounds.minDuration(); - int serviceDurationUpperBound = serviceDurationBounds.maxDuration(); - return rnd.nextInt(serviceDurationLowerBound * 60, serviceDurationUpperBound * 60); - } - /** * Finds a possible link for a service or the vehicle location. */ - private Id findPossibleLink(String zone, String selectedCategory, List noPossibleLinks, - Map, Link>> linksPerZone) { - + private Id findPossibleLink(String zone, String selectedCategory, List noPossibleLinks) { Id newLink = null; for (int a = 0; newLink == null && a < facilitiesPerZone.get(zone).get(selectedCategory).size() * 2; a++) { @@ -958,7 +927,7 @@ private static void findNearestLinkForZonesWithoutLinks(Network networkToChange, private TripDistributionMatrix createTripDistribution( Map> trafficVolume_start, Map> trafficVolume_stop, - String smallScaleCommercialTrafficType, Scenario scenario, Path output, Map, Link>> linksPerZone) + String smallScaleCommercialTrafficType, Scenario scenario, Path output) throws Exception { ArrayList listOfZones = new ArrayList<>(); @@ -991,6 +960,26 @@ private TripDistributionMatrix createTripDistribution( return odMatrix; } + public Map> getTourDistribution() { + return tourDistribution; + } + + public Map> getServiceDurationTimeSelector() { + return serviceDurationTimeSelector; + } + + public Map, CarrierAttributes> getCarrierId2carrierAttributes() { + return carrierId2carrierAttributes; + } + + public int getMaxReplanningIterations(){ + return maxReplanningIterations; + } + + public int getAdditionalTravelBufferPerIterationInMinutes(){ + return additionalTravelBufferPerIterationInMinutes; + } + private static class MyCarrierScoringFunctionFactory implements CarrierScoringFunctionFactory { @Inject @@ -1203,33 +1192,68 @@ public double getScore() { } - public record StopDurationGoodTrafficKey(String employeeCategory, String vehicleType) { + public record ServiceDurationPerCategoryKey(String employeeCategory, String vehicleType, String smallScaleCommercialTrafficType) { @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + ServiceDurationPerCategoryKey other = (ServiceDurationPerCategoryKey) obj; + if (employeeCategory == null) { + if (other.employeeCategory != null) return false; - StopDurationGoodTrafficKey other = (StopDurationGoodTrafficKey) obj; - if (employeeCategory == null) { - if (other.employeeCategory != null) - return false; - } else if (!employeeCategory.equals(other.employeeCategory)) + } else if (!employeeCategory.equals(other.employeeCategory)) + return false; + if (vehicleType == null) { + if (other.vehicleType != null) return false; - if (vehicleType == null) { - return other.vehicleType == null; - } else return vehicleType.equals(other.vehicleType); - } + } else if (!vehicleType.equals(other.vehicleType)) + return false; + if (smallScaleCommercialTrafficType == null) { + return other.smallScaleCommercialTrafficType == null; + } else return smallScaleCommercialTrafficType.equals(other.smallScaleCommercialTrafficType); } - public static StopDurationGoodTrafficKey makeStopDurationGoodTrafficKey(String employeeCategory, String vehicleType) { - return new StopDurationGoodTrafficKey(employeeCategory, vehicleType); + } + public static ServiceDurationPerCategoryKey makeServiceDurationPerCategoryKey(String employeeCategory, String vehicleType, String smallScaleCommercialTrafficType) { + return new ServiceDurationPerCategoryKey(employeeCategory, vehicleType, smallScaleCommercialTrafficType); } - public record TourStartAndDuration(int hourLower, int hourUpper, double minDuration, double maxDuration) {} + public record TourStartAndDuration(int hourLower, int hourUpper, double minDuration, double maxDuration) { + /** + * Gives a duration for the created tour under the given probability. + */ + public int getVehicleTourDuration() { + if (minDuration == 0.) + return (int) maxDuration() * 60; + else + return (int) rnd.nextDouble(minDuration * 60, maxDuration * 60); + } + + /** + * Gives a tour start time for the created tour under the given probability. + */ + public int getVehicleStartTime() { + return rnd.nextInt(hourLower * 3600, hourUpper * 3600); + } + } public record DurationsBounds(int minDuration, int maxDuration) {} + /** + * The attributes of a carrier, used during the generation + * @param purpose purpose of this carrier denoted as an index. Can be used in {@link VehicleSelection} to get more information about this carrier. + * @param startZone start zone of this carrier, entry from {@link TripDistributionMatrix#getListOfZones()} + * @param selectedStartCategory start category of this carrier, selected randomly from {@link VehicleSelection.OdMatrixEntryInformation#possibleStartCategories} + * @param modeORvehType entry from {@link TripDistributionMatrix#getListOfModesOrVehTypes()} + * @param smallScaleCommercialTrafficType Entry from {@link SmallScaleCommercialTrafficType} for this carrier + * (NOTE: This value only differs between carriers if {@link SmallScaleCommercialTrafficType#completeSmallScaleCommercialTraffic is selected) + * @param vehicleDepots Containing the depots of this carrier with linkIds as strings + */ + public record CarrierAttributes(int purpose, String startZone, String selectedStartCategory, String modeORvehType, + String smallScaleCommercialTrafficType, ArrayList vehicleDepots, + VehicleSelection.OdMatrixEntryInformation odMatrixEntry) {} } diff --git a/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/TrafficVolumeGeneration.java b/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/TrafficVolumeGeneration.java index a536f751552..34af805ee00 100644 --- a/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/TrafficVolumeGeneration.java +++ b/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/TrafficVolumeGeneration.java @@ -25,6 +25,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.matsim.core.utils.io.IOUtils; +import org.matsim.smallScaleCommercialTrafficGeneration.data.GetGenerationRates; import java.io.BufferedWriter; import java.io.IOException; @@ -246,865 +247,16 @@ private static void writeCSVTrafficVolume(Map> setGenerationRates(String smallScaleCommercialTrafficType, - String generationType) { - - Map> generationRates = new HashMap<>(); - Map ratesPerPurpose1 = new HashMap<>(); - Map ratesPerPurpose2 = new HashMap<>(); - Map ratesPerPurpose3 = new HashMap<>(); - Map ratesPerPurpose4 = new HashMap<>(); - Map ratesPerPurpose5 = new HashMap<>(); - Map ratesPerPurpose6 = new HashMap<>(); - if (smallScaleCommercialTrafficType.equals("commercialPersonTraffic")) { - if (generationType.equals("start")) { - ratesPerPurpose1.put("Inhabitants", 0.0); - ratesPerPurpose1.put("Employee", 0.0); - ratesPerPurpose1.put("Employee Primary Sector", 0.0); - ratesPerPurpose1.put("Employee Construction", 0.0); - ratesPerPurpose1.put("Employee Secondary Sector Rest", 0.059); - ratesPerPurpose1.put("Employee Retail", 0.0); - ratesPerPurpose1.put("Employee Traffic/Parcels", 0.0); - ratesPerPurpose1.put("Employee Tertiary Sector Rest", 0.0); - - ratesPerPurpose2.put("Inhabitants", 0.0); - ratesPerPurpose2.put("Employee", 0.029); - ratesPerPurpose2.put("Employee Primary Sector", 0.0); - ratesPerPurpose2.put("Employee Construction", 0.0); - ratesPerPurpose2.put("Employee Secondary Sector Rest", 0.045); - ratesPerPurpose2.put("Employee Retail", 0.0); - ratesPerPurpose2.put("Employee Traffic/Parcels", 0.0); - ratesPerPurpose2.put("Employee Tertiary Sector Rest", 0.0); - - ratesPerPurpose3.put("Inhabitants", 0.0); - ratesPerPurpose3.put("Employee", 0.021); - ratesPerPurpose3.put("Employee Primary Sector", 0.0); - ratesPerPurpose3.put("Employee Construction", 0.0); - ratesPerPurpose3.put("Employee Secondary Sector Rest", 0.0); - ratesPerPurpose3.put("Employee Retail", 0.0192); - ratesPerPurpose3.put("Employee Traffic/Parcels", 0.0); - ratesPerPurpose3.put("Employee Tertiary Sector Rest", 0.184); - - ratesPerPurpose4.put("Inhabitants", 0.0); - ratesPerPurpose4.put("Employee", 0.021); - ratesPerPurpose4.put("Employee Primary Sector", 0.0); - ratesPerPurpose4.put("Employee Construction", 0.0); - ratesPerPurpose4.put("Employee Secondary Sector Rest", 0.0); - ratesPerPurpose4.put("Employee Retail", 0.0); - ratesPerPurpose4.put("Employee Traffic/Parcels", 0.203); - ratesPerPurpose4.put("Employee Tertiary Sector Rest", 0.0); - - ratesPerPurpose5.put("Inhabitants", 0.0); - ratesPerPurpose5.put("Employee", 0.03); - ratesPerPurpose5.put("Employee Primary Sector", 0.0); - ratesPerPurpose5.put("Employee Construction", 0.29); - ratesPerPurpose5.put("Employee Secondary Sector Rest", 0.0); - ratesPerPurpose5.put("Employee Retail", 0.0); - ratesPerPurpose5.put("Employee Traffic/Parcels", 0.0); - ratesPerPurpose5.put("Employee Tertiary Sector Rest", 0.0); - } else if (generationType.equals("stop")) { - ratesPerPurpose1.put("Inhabitants", 0.0); - ratesPerPurpose1.put("Employee", 0.0); - ratesPerPurpose1.put("Employee Primary Sector", 0.0); - ratesPerPurpose1.put("Employee Construction", 0.0); - ratesPerPurpose1.put("Employee Secondary Sector Rest", 0.02); - ratesPerPurpose1.put("Employee Retail", 0.0); - ratesPerPurpose1.put("Employee Traffic/Parcels", 0.0); - ratesPerPurpose1.put("Employee Tertiary Sector Rest", 0.0); - - ratesPerPurpose2.put("Inhabitants", 0.002); - ratesPerPurpose2.put("Employee", 0.0); - ratesPerPurpose2.put("Employee Primary Sector", 0.029); - ratesPerPurpose2.put("Employee Construction", 0.029); - ratesPerPurpose2.put("Employee Secondary Sector Rest", 0.009); - ratesPerPurpose2.put("Employee Retail", 0.029); - ratesPerPurpose2.put("Employee Traffic/Parcels", 0.039); - ratesPerPurpose2.put("Employee Tertiary Sector Rest", 0.029); - - ratesPerPurpose3.put("Inhabitants", 0.025); - ratesPerPurpose3.put("Employee", 0.0); - ratesPerPurpose3.put("Employee Primary Sector", 0.0168); - ratesPerPurpose3.put("Employee Construction", 0.168); - ratesPerPurpose3.put("Employee Secondary Sector Rest", 0.0168); - ratesPerPurpose3.put("Employee Retail", 0.0168); - ratesPerPurpose3.put("Employee Traffic/Parcels", 0.097); - ratesPerPurpose3.put("Employee Tertiary Sector Rest", 0.168); - - ratesPerPurpose4.put("Inhabitants", 0.002); - ratesPerPurpose4.put("Employee", 0.0); - ratesPerPurpose4.put("Employee Primary Sector", 0.025); - ratesPerPurpose4.put("Employee Construction", 0.025); - ratesPerPurpose4.put("Employee Secondary Sector Rest", 0.025); - ratesPerPurpose4.put("Employee Retail", 0.025); - ratesPerPurpose4.put("Employee Traffic/Parcels", 0.075); - ratesPerPurpose4.put("Employee Tertiary Sector Rest", 0.025); - - ratesPerPurpose5.put("Inhabitants", 0.004); - ratesPerPurpose5.put("Employee", 0.0); - ratesPerPurpose5.put("Employee Primary Sector", 0.015); - ratesPerPurpose5.put("Employee Construction", 0.002); - ratesPerPurpose5.put("Employee Secondary Sector Rest", 0.015); - ratesPerPurpose5.put("Employee Retail", 0.015); - ratesPerPurpose5.put("Employee Traffic/Parcels", 0.02); - ratesPerPurpose5.put("Employee Tertiary Sector Rest", 0.015); - - } - } else if (smallScaleCommercialTrafficType.equals("goodsTraffic")) { - if (generationType.equals("start")) { - ratesPerPurpose1.put("Inhabitants", 0.0); - ratesPerPurpose1.put("Employee", 0.0); - ratesPerPurpose1.put("Employee Primary Sector", 0.0); - ratesPerPurpose1.put("Employee Construction", 0.0); - ratesPerPurpose1.put("Employee Secondary Sector Rest", 0.023); - ratesPerPurpose1.put("Employee Retail", 0.0); - ratesPerPurpose1.put("Employee Traffic/Parcels", 0.0); - ratesPerPurpose1.put("Employee Tertiary Sector Rest", 0.0); - - ratesPerPurpose2.put("Inhabitants", 0.0); - ratesPerPurpose2.put("Employee", 0.002); - ratesPerPurpose2.put("Employee Primary Sector", 0.0); - ratesPerPurpose2.put("Employee Construction", 0.0); - ratesPerPurpose2.put("Employee Secondary Sector Rest", 0.049); - ratesPerPurpose2.put("Employee Retail", 0.0); - ratesPerPurpose2.put("Employee Traffic/Parcels", 0.0); - ratesPerPurpose2.put("Employee Tertiary Sector Rest", 0.0); - - ratesPerPurpose3.put("Inhabitants", 0.0); - ratesPerPurpose3.put("Employee", 0.002); - ratesPerPurpose3.put("Employee Primary Sector", 0.0); - ratesPerPurpose3.put("Employee Construction", 0.0); - ratesPerPurpose3.put("Employee Secondary Sector Rest", 0.0); - ratesPerPurpose3.put("Employee Retail", 0.139); - ratesPerPurpose3.put("Employee Traffic/Parcels", 0.0); - ratesPerPurpose3.put("Employee Tertiary Sector Rest", 0.059); - - ratesPerPurpose4.put("Inhabitants", 0.0); - ratesPerPurpose4.put("Employee", 0.002); - ratesPerPurpose4.put("Employee Primary Sector", 0.0); - ratesPerPurpose4.put("Employee Construction", 0.0); - ratesPerPurpose4.put("Employee Secondary Sector Rest", 0.0); - ratesPerPurpose4.put("Employee Retail", 0.0); - ratesPerPurpose4.put("Employee Traffic/Parcels", 0.333); - ratesPerPurpose4.put("Employee Tertiary Sector Rest", 0.0); - - ratesPerPurpose5.put("Inhabitants", 0.0); - ratesPerPurpose5.put("Employee", 0.002); - ratesPerPurpose5.put("Employee Primary Sector", 0.0); - ratesPerPurpose5.put("Employee Construction", 0.220); - ratesPerPurpose5.put("Employee Secondary Sector Rest", 0.0); - ratesPerPurpose5.put("Employee Retail", 0.0); - ratesPerPurpose5.put("Employee Traffic/Parcels", 0.0); - ratesPerPurpose5.put("Employee Tertiary Sector Rest", 0.0); - - ratesPerPurpose6.put("Inhabitants", 0.009); - ratesPerPurpose6.put("Employee", 0.0); - ratesPerPurpose6.put("Employee Primary Sector", 0.0); - ratesPerPurpose6.put("Employee Construction", 0.0); - ratesPerPurpose6.put("Employee Secondary Sector Rest", 0.0); - ratesPerPurpose6.put("Employee Retail", 0.0); - ratesPerPurpose6.put("Employee Traffic/Parcels", 0.0); - ratesPerPurpose6.put("Employee Tertiary Sector Rest", 0.0); - - } else if (generationType.equals("stop")) { - ratesPerPurpose1.put("Inhabitants", 0.0); - ratesPerPurpose1.put("Employee", 0.0); - ratesPerPurpose1.put("Employee Primary Sector", 0.0); - ratesPerPurpose1.put("Employee Construction", 0.0); - ratesPerPurpose1.put("Employee Secondary Sector Rest", 0.031); - ratesPerPurpose1.put("Employee Retail", 0.0); - ratesPerPurpose1.put("Employee Traffic/Parcels", 0.0); - ratesPerPurpose1.put("Employee Tertiary Sector Rest", 0.0); - - ratesPerPurpose2.put("Inhabitants", 0.001); - ratesPerPurpose2.put("Employee", 0.0); - ratesPerPurpose2.put("Employee Primary Sector", 0.001); - ratesPerPurpose2.put("Employee Construction", 0.01); - ratesPerPurpose2.put("Employee Secondary Sector Rest", 0.011); - ratesPerPurpose2.put("Employee Retail", 0.021); - ratesPerPurpose2.put("Employee Traffic/Parcels", 0.001); - ratesPerPurpose2.put("Employee Tertiary Sector Rest", 0.001); - - ratesPerPurpose3.put("Inhabitants", 0.009); - ratesPerPurpose3.put("Employee", 0.0); - ratesPerPurpose3.put("Employee Primary Sector", 0.02); - ratesPerPurpose3.put("Employee Construction", 0.005); - ratesPerPurpose3.put("Employee Secondary Sector Rest", 0.029); - ratesPerPurpose3.put("Employee Retail", 0.055); - ratesPerPurpose3.put("Employee Traffic/Parcels", 0.02); - ratesPerPurpose3.put("Employee Tertiary Sector Rest", 0.02); - - ratesPerPurpose4.put("Inhabitants", 0.014); - ratesPerPurpose4.put("Employee", 0.0); - ratesPerPurpose4.put("Employee Primary Sector", 0.02); - ratesPerPurpose4.put("Employee Construction", 0.002); - ratesPerPurpose4.put("Employee Secondary Sector Rest", 0.11); - ratesPerPurpose4.put("Employee Retail", 0.154); - ratesPerPurpose4.put("Employee Traffic/Parcels", 0.02); - ratesPerPurpose4.put("Employee Tertiary Sector Rest", 0.02); - - ratesPerPurpose5.put("Inhabitants", 0.002); - ratesPerPurpose5.put("Employee", 0.0); - ratesPerPurpose5.put("Employee Primary Sector", 0.005); - ratesPerPurpose5.put("Employee Construction", 0.002); - ratesPerPurpose5.put("Employee Secondary Sector Rest", 0.01); - ratesPerPurpose5.put("Employee Retail", 0.01); - ratesPerPurpose5.put("Employee Traffic/Parcels", 0.005); - ratesPerPurpose5.put("Employee Tertiary Sector Rest", 0.005); - - ratesPerPurpose6.put("Inhabitants", 0.002); - ratesPerPurpose6.put("Employee", 0.0); - ratesPerPurpose6.put("Employee Primary Sector", 0.005); - ratesPerPurpose6.put("Employee Construction", 0.002); - ratesPerPurpose6.put("Employee Secondary Sector Rest", 0.01); - ratesPerPurpose6.put("Employee Retail", 0.01); - ratesPerPurpose6.put("Employee Traffic/Parcels", 0.005); - ratesPerPurpose6.put("Employee Tertiary Sector Rest", 0.005); - } - generationRates.put(6, ratesPerPurpose6); - } - generationRates.put(1, ratesPerPurpose1); - generationRates.put(2, ratesPerPurpose2); - generationRates.put(3, ratesPerPurpose3); - generationRates.put(4, ratesPerPurpose4); - generationRates.put(5, ratesPerPurpose5); - return generationRates; - } - - /** - * Sets the commitment rates based on the IVV 2005 for the goodsTraffic. The - * commitment rate for the commercialPersonTraffic is 1, because mode choice will be - * done in MATSim. - * - * @param smallScaleCommercialTrafficType used trafficType (freight or business traffic) - * @param commitmentType start or stop parameter - */ - private static Map> setCommitmentRates(String smallScaleCommercialTrafficType, - String commitmentType) { - Map> commitmentRates = new HashMap<>(); - - if (smallScaleCommercialTrafficType.equals("goodsTraffic")) { - - // the first number is the purpose; second number the vehicle type - Map ratesPerPurpose1_1 = new HashMap<>(); - Map ratesPerPurpose1_2 = new HashMap<>(); - Map ratesPerPurpose1_3 = new HashMap<>(); - Map ratesPerPurpose1_4 = new HashMap<>(); - Map ratesPerPurpose1_5 = new HashMap<>(); - Map ratesPerPurpose2_1 = new HashMap<>(); - Map ratesPerPurpose2_2 = new HashMap<>(); - Map ratesPerPurpose2_3 = new HashMap<>(); - Map ratesPerPurpose2_4 = new HashMap<>(); - Map ratesPerPurpose2_5 = new HashMap<>(); - Map ratesPerPurpose3_1 = new HashMap<>(); - Map ratesPerPurpose3_2 = new HashMap<>(); - Map ratesPerPurpose3_3 = new HashMap<>(); - Map ratesPerPurpose3_4 = new HashMap<>(); - Map ratesPerPurpose3_5 = new HashMap<>(); - Map ratesPerPurpose4_1 = new HashMap<>(); - Map ratesPerPurpose4_2 = new HashMap<>(); - Map ratesPerPurpose4_3 = new HashMap<>(); - Map ratesPerPurpose4_4 = new HashMap<>(); - Map ratesPerPurpose4_5 = new HashMap<>(); - Map ratesPerPurpose5_1 = new HashMap<>(); - Map ratesPerPurpose5_2 = new HashMap<>(); - Map ratesPerPurpose5_3 = new HashMap<>(); - Map ratesPerPurpose5_4 = new HashMap<>(); - Map ratesPerPurpose5_5 = new HashMap<>(); - Map ratesPerPurpose6_1 = new HashMap<>(); - Map ratesPerPurpose6_2 = new HashMap<>(); - Map ratesPerPurpose6_3 = new HashMap<>(); - Map ratesPerPurpose6_4 = new HashMap<>(); - Map ratesPerPurpose6_5 = new HashMap<>(); - if (commitmentType.equals("start")) { - ratesPerPurpose1_1.put("Inhabitants", 0.0); - ratesPerPurpose1_1.put("Employee", 0.8); - ratesPerPurpose1_1.put("Employee Primary Sector", 0.0); - ratesPerPurpose1_1.put("Employee Construction", 0.0); - ratesPerPurpose1_1.put("Employee Secondary Sector Rest", 0.44); - ratesPerPurpose1_1.put("Employee Retail", 0.0); - ratesPerPurpose1_1.put("Employee Traffic/Parcels", 0.0); - ratesPerPurpose1_1.put("Employee Tertiary Sector Rest", 0.0); - - ratesPerPurpose1_2.put("Inhabitants", 0.0); - ratesPerPurpose1_2.put("Employee", 0.1); - ratesPerPurpose1_2.put("Employee Primary Sector", 0.0); - ratesPerPurpose1_2.put("Employee Construction", 0.0); - ratesPerPurpose1_2.put("Employee Secondary Sector Rest", 0.11); - ratesPerPurpose1_2.put("Employee Retail", 0.0); - ratesPerPurpose1_2.put("Employee Traffic/Parcels", 0.0); - ratesPerPurpose1_2.put("Employee Tertiary Sector Rest", 0.0); - - ratesPerPurpose1_3.put("Inhabitants", 0.0); - ratesPerPurpose1_3.put("Employee", 0.1); - ratesPerPurpose1_3.put("Employee Primary Sector", 0.0); - ratesPerPurpose1_3.put("Employee Construction", 0.0); - ratesPerPurpose1_3.put("Employee Secondary Sector Rest", 0.22); - ratesPerPurpose1_3.put("Employee Retail", 0.0); - ratesPerPurpose1_3.put("Employee Traffic/Parcels", 0.0); - ratesPerPurpose1_3.put("Employee Tertiary Sector Rest", 0.0); - - ratesPerPurpose1_4.put("Inhabitants", 0.0); - ratesPerPurpose1_4.put("Employee", 0.0); - ratesPerPurpose1_4.put("Employee Primary Sector", 0.0); - ratesPerPurpose1_4.put("Employee Construction", 0.0); - ratesPerPurpose1_4.put("Employee Secondary Sector Rest", 0.06); - ratesPerPurpose1_4.put("Employee Retail", 0.0); - ratesPerPurpose1_4.put("Employee Traffic/Parcels", 0.0); - ratesPerPurpose1_4.put("Employee Tertiary Sector Rest", 0.0); - - ratesPerPurpose1_5.put("Inhabitants", 0.0); - ratesPerPurpose1_5.put("Employee", 0.0); - ratesPerPurpose1_5.put("Employee Primary Sector", 0.0); - ratesPerPurpose1_5.put("Employee Construction", 0.0); - ratesPerPurpose1_5.put("Employee Secondary Sector Rest", 0.16); - ratesPerPurpose1_5.put("Employee Retail", 0.0); - ratesPerPurpose1_5.put("Employee Traffic/Parcels", 0.0); - ratesPerPurpose1_5.put("Employee Tertiary Sector Rest", 0.0); - - ratesPerPurpose2_1.put("Inhabitants", 0.0); - ratesPerPurpose2_1.put("Employee", 0.8); - ratesPerPurpose2_1.put("Employee Primary Sector", 0.0); - ratesPerPurpose2_1.put("Employee Construction", 0.0); - ratesPerPurpose2_1.put("Employee Secondary Sector Rest", 0.44); - ratesPerPurpose2_1.put("Employee Retail", 0.0); - ratesPerPurpose2_1.put("Employee Traffic/Parcels", 0.0); - ratesPerPurpose2_1.put("Employee Tertiary Sector Rest", 0.0); - - ratesPerPurpose2_2.put("Inhabitants", 0.0); - ratesPerPurpose2_2.put("Employee", 0.1); - ratesPerPurpose2_2.put("Employee Primary Sector", 0.0); - ratesPerPurpose2_2.put("Employee Construction", 0.0); - ratesPerPurpose2_2.put("Employee Secondary Sector Rest", 0.11); - ratesPerPurpose2_2.put("Employee Retail", 0.0); - ratesPerPurpose2_2.put("Employee Traffic/Parcels", 0.0); - ratesPerPurpose2_2.put("Employee Tertiary Sector Rest", 0.0); - - ratesPerPurpose2_3.put("Inhabitants", 0.0); - ratesPerPurpose2_3.put("Employee", 0.1); - ratesPerPurpose2_3.put("Employee Primary Sector", 0.0); - ratesPerPurpose2_3.put("Employee Construction", 0.0); - ratesPerPurpose2_3.put("Employee Secondary Sector Rest", 0.22); - ratesPerPurpose2_3.put("Employee Retail", 0.0); - ratesPerPurpose2_3.put("Employee Traffic/Parcels", 0.0); - ratesPerPurpose2_3.put("Employee Tertiary Sector Rest", 0.0); - - ratesPerPurpose2_4.put("Inhabitants", 0.0); - ratesPerPurpose2_4.put("Employee", 0.0); - ratesPerPurpose2_4.put("Employee Primary Sector", 0.0); - ratesPerPurpose2_4.put("Employee Construction", 0.0); - ratesPerPurpose2_4.put("Employee Secondary Sector Rest", 0.06); - ratesPerPurpose2_4.put("Employee Retail", 0.0); - ratesPerPurpose2_4.put("Employee Traffic/Parcels", 0.0); - ratesPerPurpose2_4.put("Employee Tertiary Sector Rest", 0.0); - - ratesPerPurpose2_5.put("Inhabitants", 0.0); - ratesPerPurpose2_5.put("Employee", 0.0); - ratesPerPurpose2_5.put("Employee Primary Sector", 0.0); - ratesPerPurpose2_5.put("Employee Construction", 0.0); - ratesPerPurpose2_5.put("Employee Secondary Sector Rest", 0.16); - ratesPerPurpose2_5.put("Employee Retail", 0.0); - ratesPerPurpose2_5.put("Employee Traffic/Parcels", 0.0); - ratesPerPurpose2_5.put("Employee Tertiary Sector Rest", 0.0); - - ratesPerPurpose3_1.put("Inhabitants", 0.0); - ratesPerPurpose3_1.put("Employee", 0.8); - ratesPerPurpose3_1.put("Employee Primary Sector", 0.0); - ratesPerPurpose3_1.put("Employee Construction", 0.0); - ratesPerPurpose3_1.put("Employee Secondary Sector Rest", 0.0); - ratesPerPurpose3_1.put("Employee Retail", 0.46); - ratesPerPurpose3_1.put("Employee Traffic/Parcels", 0.0); - ratesPerPurpose3_1.put("Employee Tertiary Sector Rest", 0.54); - - ratesPerPurpose3_2.put("Inhabitants", 0.0); - ratesPerPurpose3_2.put("Employee", 0.1); - ratesPerPurpose3_2.put("Employee Primary Sector", 0.0); - ratesPerPurpose3_2.put("Employee Construction", 0.0); - ratesPerPurpose3_2.put("Employee Secondary Sector Rest", 0.0); - ratesPerPurpose3_2.put("Employee Retail", 0.1); - ratesPerPurpose3_2.put("Employee Traffic/Parcels", 0.0); - ratesPerPurpose3_2.put("Employee Tertiary Sector Rest", 0.1); - - ratesPerPurpose3_3.put("Inhabitants", 0.0); - ratesPerPurpose3_3.put("Employee", 0.1); - ratesPerPurpose3_3.put("Employee Primary Sector", 0.0); - ratesPerPurpose3_3.put("Employee Construction", 0.0); - ratesPerPurpose3_3.put("Employee Secondary Sector Rest", 0.0); - ratesPerPurpose3_3.put("Employee Retail", 0.23); - ratesPerPurpose3_3.put("Employee Traffic/Parcels", 0.0); - ratesPerPurpose3_3.put("Employee Tertiary Sector Rest", 0.2); - - ratesPerPurpose3_4.put("Inhabitants", 0.0); - ratesPerPurpose3_4.put("Employee", 0.0); - ratesPerPurpose3_4.put("Employee Primary Sector", 0.0); - ratesPerPurpose3_4.put("Employee Construction", 0.0); - ratesPerPurpose3_4.put("Employee Secondary Sector Rest", 0.0); - ratesPerPurpose3_4.put("Employee Retail", 0.06); - ratesPerPurpose3_4.put("Employee Traffic/Parcels", 0.0); - ratesPerPurpose3_4.put("Employee Tertiary Sector Rest", 0.02); - - ratesPerPurpose3_5.put("Inhabitants", 0.0); - ratesPerPurpose3_5.put("Employee", 0.0); - ratesPerPurpose3_5.put("Employee Primary Sector", 0.0); - ratesPerPurpose3_5.put("Employee Construction", 0.0); - ratesPerPurpose3_5.put("Employee Secondary Sector Rest", 0.0); - ratesPerPurpose3_5.put("Employee Retail", 0.15); - ratesPerPurpose3_5.put("Employee Traffic/Parcels", 0.0); - ratesPerPurpose3_5.put("Employee Tertiary Sector Rest", 0.14); - - ratesPerPurpose4_1.put("Inhabitants", 0.009); - ratesPerPurpose4_1.put("Employee", 0.8); - ratesPerPurpose4_1.put("Employee Primary Sector", 0.0); - ratesPerPurpose4_1.put("Employee Construction", 0.0); - ratesPerPurpose4_1.put("Employee Secondary Sector Rest", 0.0); - ratesPerPurpose4_1.put("Employee Retail", 0.0); - ratesPerPurpose4_1.put("Employee Traffic/Parcels", 0.18); - ratesPerPurpose4_1.put("Employee Tertiary Sector Rest", 0.0); - - ratesPerPurpose4_2.put("Inhabitants", 0.0); - ratesPerPurpose4_2.put("Employee", 0.1); - ratesPerPurpose4_2.put("Employee Primary Sector", 0.0); - ratesPerPurpose4_2.put("Employee Construction", 0.0); - ratesPerPurpose4_2.put("Employee Secondary Sector Rest", 0.0); - ratesPerPurpose4_2.put("Employee Retail", 0.0); - ratesPerPurpose4_2.put("Employee Traffic/Parcels", 0.06); - ratesPerPurpose4_2.put("Employee Tertiary Sector Rest", 0.0); - - ratesPerPurpose4_3.put("Inhabitants", 0.0); - ratesPerPurpose4_3.put("Employee", 0.1); - ratesPerPurpose4_3.put("Employee Primary Sector", 0.0); - ratesPerPurpose4_3.put("Employee Construction", 0.0); - ratesPerPurpose4_3.put("Employee Secondary Sector Rest", 0.0); - ratesPerPurpose4_3.put("Employee Retail", 0.0); - ratesPerPurpose4_3.put("Employee Traffic/Parcels", 0.25); - ratesPerPurpose4_3.put("Employee Tertiary Sector Rest", 0.0); - - ratesPerPurpose4_4.put("Inhabitants", 0.0); - ratesPerPurpose4_4.put("Employee", 0.0); - ratesPerPurpose4_4.put("Employee Primary Sector", 0.0); - ratesPerPurpose4_4.put("Employee Construction", 0.0); - ratesPerPurpose4_4.put("Employee Secondary Sector Rest", 0.0); - ratesPerPurpose4_4.put("Employee Retail", 0.0); - ratesPerPurpose4_4.put("Employee Traffic/Parcels", 0.08); - ratesPerPurpose4_4.put("Employee Tertiary Sector Rest", 0.0); - - ratesPerPurpose4_5.put("Inhabitants", 0.0); - ratesPerPurpose4_5.put("Employee", 0.0); - ratesPerPurpose4_5.put("Employee Primary Sector", 0.0); - ratesPerPurpose4_5.put("Employee Construction", 0.0); - ratesPerPurpose4_5.put("Employee Secondary Sector Rest", 0.0); - ratesPerPurpose4_5.put("Employee Retail", 0.0); - ratesPerPurpose4_5.put("Employee Traffic/Parcels", 0.43); - ratesPerPurpose4_5.put("Employee Tertiary Sector Rest", 0.0); - - ratesPerPurpose5_1.put("Inhabitants", 0.0); - ratesPerPurpose5_1.put("Employee", 0.8); - ratesPerPurpose5_1.put("Employee Primary Sector", 0.0); - ratesPerPurpose5_1.put("Employee Construction", 0.25); - ratesPerPurpose5_1.put("Employee Secondary Sector Rest", 0.0); - ratesPerPurpose5_1.put("Employee Retail", 0.0); - ratesPerPurpose5_1.put("Employee Traffic/Parcels", 0.0); - ratesPerPurpose5_1.put("Employee Tertiary Sector Rest", 0.0); - - ratesPerPurpose5_2.put("Inhabitants", 0.0); - ratesPerPurpose5_2.put("Employee", 0.1); - ratesPerPurpose5_2.put("Employee Primary Sector", 0.0); - ratesPerPurpose5_2.put("Employee Construction", 0.2); - ratesPerPurpose5_2.put("Employee Secondary Sector Rest", 0.0); - ratesPerPurpose5_2.put("Employee Retail", 0.0); - ratesPerPurpose5_2.put("Employee Traffic/Parcels", 0.0); - ratesPerPurpose5_2.put("Employee Tertiary Sector Rest", 0.0); - - ratesPerPurpose5_3.put("Inhabitants", 0.0); - ratesPerPurpose5_3.put("Employee", 0.1); - ratesPerPurpose5_3.put("Employee Primary Sector", 0.0); - ratesPerPurpose5_3.put("Employee Construction", 0.25); - ratesPerPurpose5_3.put("Employee Secondary Sector Rest", 0.0); - ratesPerPurpose5_3.put("Employee Retail", 0.139); - ratesPerPurpose5_3.put("Employee Traffic/Parcels", 0.0); - ratesPerPurpose5_3.put("Employee Tertiary Sector Rest", 0.059); - - ratesPerPurpose5_4.put("Inhabitants", 0.0); - ratesPerPurpose5_4.put("Employee", 0.0); - ratesPerPurpose5_4.put("Employee Primary Sector", 0.0); - ratesPerPurpose5_4.put("Employee Construction", 0.02); - ratesPerPurpose5_4.put("Employee Secondary Sector Rest", 0.0); - ratesPerPurpose5_4.put("Employee Retail", 0.0); - ratesPerPurpose5_4.put("Employee Traffic/Parcels", 0.0); - ratesPerPurpose5_4.put("Employee Tertiary Sector Rest", 0.0); - - ratesPerPurpose5_5.put("Inhabitants", 0.0); - ratesPerPurpose5_5.put("Employee", 0.0); - ratesPerPurpose5_5.put("Employee Primary Sector", 0.0); - ratesPerPurpose5_5.put("Employee Construction", 0.28); - ratesPerPurpose5_5.put("Employee Secondary Sector Rest", 0.0); - ratesPerPurpose5_5.put("Employee Retail", 0.0); - ratesPerPurpose5_5.put("Employee Traffic/Parcels", 0.0); - ratesPerPurpose5_5.put("Employee Tertiary Sector Rest", 0.0); - - ratesPerPurpose6_1.put("Inhabitants", 0.0); - ratesPerPurpose6_1.put("Employee", 0.0); - ratesPerPurpose6_1.put("Employee Primary Sector", 0.0); - ratesPerPurpose6_1.put("Employee Construction", 0.0); - ratesPerPurpose6_1.put("Employee Secondary Sector Rest", 0.0); - ratesPerPurpose6_1.put("Employee Retail", 0.0); - ratesPerPurpose6_1.put("Employee Traffic/Parcels", 0.0); - ratesPerPurpose6_1.put("Employee Tertiary Sector Rest", 0.0); - - ratesPerPurpose6_2.put("Inhabitants", 0.29); - ratesPerPurpose6_2.put("Employee", 0.0); - ratesPerPurpose6_2.put("Employee Primary Sector", 0.0); - ratesPerPurpose6_2.put("Employee Construction", 0.0); - ratesPerPurpose6_2.put("Employee Secondary Sector Rest", 0.0); - ratesPerPurpose6_2.put("Employee Retail", 0.0); - ratesPerPurpose6_2.put("Employee Traffic/Parcels", 0.0); - ratesPerPurpose6_2.put("Employee Tertiary Sector Rest", 0.0); - - ratesPerPurpose6_3.put("Inhabitants", 0.63); - ratesPerPurpose6_3.put("Employee", 0.0); - ratesPerPurpose6_3.put("Employee Primary Sector", 0.0); - ratesPerPurpose6_3.put("Employee Construction", 0.0); - ratesPerPurpose6_3.put("Employee Secondary Sector Rest", 0.0); - ratesPerPurpose6_3.put("Employee Retail", 0.0); - ratesPerPurpose6_3.put("Employee Traffic/Parcels", 0.0); - ratesPerPurpose6_3.put("Employee Tertiary Sector Rest", 0.0); - - ratesPerPurpose6_4.put("Inhabitants", 0.07); - ratesPerPurpose6_4.put("Employee", 0.0); - ratesPerPurpose6_4.put("Employee Primary Sector", 0.0); - ratesPerPurpose6_4.put("Employee Construction", 0.0); - ratesPerPurpose6_4.put("Employee Secondary Sector Rest", 0.0); - ratesPerPurpose6_4.put("Employee Retail", 0.0); - ratesPerPurpose6_4.put("Employee Traffic/Parcels", 0.0); - ratesPerPurpose6_4.put("Employee Tertiary Sector Rest", 0.0); - - ratesPerPurpose6_5.put("Inhabitants", 0.001); - ratesPerPurpose6_5.put("Employee", 0.0); - ratesPerPurpose6_5.put("Employee Primary Sector", 0.0); - ratesPerPurpose6_5.put("Employee Construction", 0.2); - ratesPerPurpose6_5.put("Employee Secondary Sector Rest", 0.0); - ratesPerPurpose6_5.put("Employee Retail", 0.0); - ratesPerPurpose6_5.put("Employee Traffic/Parcels", 0.0); - ratesPerPurpose6_5.put("Employee Tertiary Sector Rest", 0.0); - } else if (commitmentType.equals("stop")) { - ratesPerPurpose1_1.put("Inhabitants", 0.0); - ratesPerPurpose1_1.put("Employee", 0.0); - ratesPerPurpose1_1.put("Employee Primary Sector", 0.0); - ratesPerPurpose1_1.put("Employee Construction", 0.0); - ratesPerPurpose1_1.put("Employee Secondary Sector Rest", 0.35); - ratesPerPurpose1_1.put("Employee Retail", 0.0); - ratesPerPurpose1_1.put("Employee Traffic/Parcels", 0.0); - ratesPerPurpose1_1.put("Employee Tertiary Sector Rest", 0.0); - - ratesPerPurpose1_2.put("Inhabitants", 0.0); - ratesPerPurpose1_2.put("Employee", 0.0); - ratesPerPurpose1_2.put("Employee Primary Sector", 0.0); - ratesPerPurpose1_2.put("Employee Construction", 0.0); - ratesPerPurpose1_2.put("Employee Secondary Sector Rest", 0.1); - ratesPerPurpose1_2.put("Employee Retail", 0.0); - ratesPerPurpose1_2.put("Employee Traffic/Parcels", 0.0); - ratesPerPurpose1_2.put("Employee Tertiary Sector Rest", 0.0); - - ratesPerPurpose1_3.put("Inhabitants", 0.0); - ratesPerPurpose1_3.put("Employee", 0.0); - ratesPerPurpose1_3.put("Employee Primary Sector", 0.0); - ratesPerPurpose1_3.put("Employee Construction", 0.0); - ratesPerPurpose1_3.put("Employee Secondary Sector Rest", 0.27); - ratesPerPurpose1_3.put("Employee Retail", 0.0); - ratesPerPurpose1_3.put("Employee Traffic/Parcels", 0.0); - ratesPerPurpose1_3.put("Employee Tertiary Sector Rest", 0.0); - - ratesPerPurpose1_4.put("Inhabitants", 0.0); - ratesPerPurpose1_4.put("Employee", 0.0); - ratesPerPurpose1_4.put("Employee Primary Sector", 0.0); - ratesPerPurpose1_4.put("Employee Construction", 0.0); - ratesPerPurpose1_4.put("Employee Secondary Sector Rest", 0.01); - ratesPerPurpose1_4.put("Employee Retail", 0.0); - ratesPerPurpose1_4.put("Employee Traffic/Parcels", 0.0); - ratesPerPurpose1_4.put("Employee Tertiary Sector Rest", 0.0); - - ratesPerPurpose1_5.put("Inhabitants", 0.0); - ratesPerPurpose1_5.put("Employee", 0.0); - ratesPerPurpose1_5.put("Employee Primary Sector", 0.0); - ratesPerPurpose1_5.put("Employee Construction", 0.0); - ratesPerPurpose1_5.put("Employee Secondary Sector Rest", 0.27); - ratesPerPurpose1_5.put("Employee Retail", 0.0); - ratesPerPurpose1_5.put("Employee Traffic/Parcels", 0.0); - ratesPerPurpose1_5.put("Employee Tertiary Sector Rest", 0.0); - - ratesPerPurpose2_1.put("Inhabitants", 0.55); - ratesPerPurpose2_1.put("Employee", 0.0); - ratesPerPurpose2_1.put("Employee Primary Sector", 0.46); - ratesPerPurpose2_1.put("Employee Construction", 0.46); - ratesPerPurpose2_1.put("Employee Secondary Sector Rest", 0.46); - ratesPerPurpose2_1.put("Employee Retail", 0.46); - ratesPerPurpose2_1.put("Employee Traffic/Parcels", 0.34); - ratesPerPurpose2_1.put("Employee Tertiary Sector Rest", 0.46); - - ratesPerPurpose2_2.put("Inhabitants", 0.09); - ratesPerPurpose2_2.put("Employee", 0.0); - ratesPerPurpose2_2.put("Employee Primary Sector", 0.09); - ratesPerPurpose2_2.put("Employee Construction", 0.09); - ratesPerPurpose2_2.put("Employee Secondary Sector Rest", 0.09); - ratesPerPurpose2_2.put("Employee Retail", 0.09); - ratesPerPurpose2_2.put("Employee Traffic/Parcels", 0.1); - ratesPerPurpose2_2.put("Employee Tertiary Sector Rest", 0.09); - - ratesPerPurpose2_3.put("Inhabitants", 0.21); - ratesPerPurpose2_3.put("Employee", 0.0); - ratesPerPurpose2_3.put("Employee Primary Sector", 0.22); - ratesPerPurpose2_3.put("Employee Construction", 0.22); - ratesPerPurpose2_3.put("Employee Secondary Sector Rest", 0.22); - ratesPerPurpose2_3.put("Employee Retail", 0.22); - ratesPerPurpose2_3.put("Employee Traffic/Parcels", 0.29); - ratesPerPurpose2_3.put("Employee Tertiary Sector Rest", 0.22); - - ratesPerPurpose2_4.put("Inhabitants", 0.06); - ratesPerPurpose2_4.put("Employee", 0.0); - ratesPerPurpose2_4.put("Employee Primary Sector", 0.06); - ratesPerPurpose2_4.put("Employee Construction", 0.06); - ratesPerPurpose2_4.put("Employee Secondary Sector Rest", 0.06); - ratesPerPurpose2_4.put("Employee Retail", 0.06); - ratesPerPurpose2_4.put("Employee Traffic/Parcels", 0.0); - ratesPerPurpose2_4.put("Employee Tertiary Sector Rest", 0.06); - - ratesPerPurpose2_5.put("Inhabitants", 0.1); - ratesPerPurpose2_5.put("Employee", 0.0); - ratesPerPurpose2_5.put("Employee Primary Sector", 0.17); - ratesPerPurpose2_5.put("Employee Construction", 0.17); - ratesPerPurpose2_5.put("Employee Secondary Sector Rest", 0.17); - ratesPerPurpose2_5.put("Employee Retail", 0.17); - ratesPerPurpose2_5.put("Employee Traffic/Parcels", 0.27); - ratesPerPurpose2_5.put("Employee Tertiary Sector Rest", 0.17); - - ratesPerPurpose3_1.put("Inhabitants", 0.489); - ratesPerPurpose3_1.put("Employee", 0.0); - ratesPerPurpose3_1.put("Employee Primary Sector", 0.538); - ratesPerPurpose3_1.put("Employee Construction", 0.538); - ratesPerPurpose3_1.put("Employee Secondary Sector Rest", 0.538); - ratesPerPurpose3_1.put("Employee Retail", 0.538); - ratesPerPurpose3_1.put("Employee Traffic/Parcels", 0.59); - ratesPerPurpose3_1.put("Employee Tertiary Sector Rest", 0.538); - - ratesPerPurpose3_2.put("Inhabitants", 0.106); - ratesPerPurpose3_2.put("Employee", 0.0); - ratesPerPurpose3_2.put("Employee Primary Sector", 0.092); - ratesPerPurpose3_2.put("Employee Construction", 0.092); - ratesPerPurpose3_2.put("Employee Secondary Sector Rest", 0.092); - ratesPerPurpose3_2.put("Employee Retail", 0.092); - ratesPerPurpose3_2.put("Employee Traffic/Parcels", 0.03); - ratesPerPurpose3_2.put("Employee Tertiary Sector Rest", 0.092); - - ratesPerPurpose3_3.put("Inhabitants", 0.26); - ratesPerPurpose3_3.put("Employee", 0.0); - ratesPerPurpose3_3.put("Employee Primary Sector", 0.19); - ratesPerPurpose3_3.put("Employee Construction", 0.19); - ratesPerPurpose3_3.put("Employee Secondary Sector Rest", 0.19); - ratesPerPurpose3_3.put("Employee Retail", 0.19); - ratesPerPurpose3_3.put("Employee Traffic/Parcels", 0.102); - ratesPerPurpose3_3.put("Employee Tertiary Sector Rest", 0.19); - - ratesPerPurpose3_4.put("Inhabitants", 0.033); - ratesPerPurpose3_4.put("Employee", 0.0); - ratesPerPurpose3_4.put("Employee Primary Sector", 0.032); - ratesPerPurpose3_4.put("Employee Construction", 0.032); - ratesPerPurpose3_4.put("Employee Secondary Sector Rest", 0.032); - ratesPerPurpose3_4.put("Employee Retail", 0.032); - ratesPerPurpose3_4.put("Employee Traffic/Parcels", 0.058); - ratesPerPurpose3_4.put("Employee Tertiary Sector Rest", 0.032); - - ratesPerPurpose3_5.put("Inhabitants", 0.112); - ratesPerPurpose3_5.put("Employee", 0.0); - ratesPerPurpose3_5.put("Employee Primary Sector", 0.147); - ratesPerPurpose3_5.put("Employee Construction", 0.147); - ratesPerPurpose3_5.put("Employee Secondary Sector Rest", 0.147); - ratesPerPurpose3_5.put("Employee Retail", 0.147); - ratesPerPurpose3_5.put("Employee Traffic/Parcels", 0.219); - ratesPerPurpose3_5.put("Employee Tertiary Sector Rest", 0.147); - - ratesPerPurpose4_1.put("Inhabitants", 0.37); - ratesPerPurpose4_1.put("Employee", 0.0); - ratesPerPurpose4_1.put("Employee Primary Sector", 0.14); - ratesPerPurpose4_1.put("Employee Construction", 0.14); - ratesPerPurpose4_1.put("Employee Secondary Sector Rest", 0.14); - ratesPerPurpose4_1.put("Employee Retail", 0.14); - ratesPerPurpose4_1.put("Employee Traffic/Parcels", 0.06); - ratesPerPurpose4_1.put("Employee Tertiary Sector Rest", 0.14); - - ratesPerPurpose4_2.put("Inhabitants", 0.05); - ratesPerPurpose4_2.put("Employee", 0.0); - ratesPerPurpose4_2.put("Employee Primary Sector", 0.07); - ratesPerPurpose4_2.put("Employee Construction", 0.07); - ratesPerPurpose4_2.put("Employee Secondary Sector Rest", 0.07); - ratesPerPurpose4_2.put("Employee Retail", 0.07); - ratesPerPurpose4_2.put("Employee Traffic/Parcels", 0.07); - ratesPerPurpose4_2.put("Employee Tertiary Sector Rest", 0.07); - - ratesPerPurpose4_3.put("Inhabitants", 0.4); - ratesPerPurpose4_3.put("Employee", 0.0); - ratesPerPurpose4_3.put("Employee Primary Sector", 0.21); - ratesPerPurpose4_3.put("Employee Construction", 0.21); - ratesPerPurpose4_3.put("Employee Secondary Sector Rest", 0.21); - ratesPerPurpose4_3.put("Employee Retail", 0.21); - ratesPerPurpose4_3.put("Employee Traffic/Parcels", 0.19); - ratesPerPurpose4_3.put("Employee Tertiary Sector Rest", 0.21); - - ratesPerPurpose4_4.put("Inhabitants", 0.13); - ratesPerPurpose4_4.put("Employee", 0.0); - ratesPerPurpose4_4.put("Employee Primary Sector", 0.05); - ratesPerPurpose4_4.put("Employee Construction", 0.05); - ratesPerPurpose4_4.put("Employee Secondary Sector Rest", 0.05); - ratesPerPurpose4_4.put("Employee Retail", 0.05); - ratesPerPurpose4_4.put("Employee Traffic/Parcels", 0.08); - ratesPerPurpose4_4.put("Employee Tertiary Sector Rest", 0.05); - - ratesPerPurpose4_5.put("Inhabitants", 0.05); - ratesPerPurpose4_5.put("Employee", 0.0); - ratesPerPurpose4_5.put("Employee Primary Sector", 0.54); - ratesPerPurpose4_5.put("Employee Construction", 0.54); - ratesPerPurpose4_5.put("Employee Secondary Sector Rest", 0.54); - ratesPerPurpose4_5.put("Employee Retail", 0.54); - ratesPerPurpose4_5.put("Employee Traffic/Parcels", 0.61); - ratesPerPurpose4_5.put("Employee Tertiary Sector Rest", 0.54); - - ratesPerPurpose5_1.put("Inhabitants", 0.16); - ratesPerPurpose5_1.put("Employee", 0.0); - ratesPerPurpose5_1.put("Employee Primary Sector", 0.4); - ratesPerPurpose5_1.put("Employee Construction", 0.4); - ratesPerPurpose5_1.put("Employee Secondary Sector Rest", 0.4); - ratesPerPurpose5_1.put("Employee Retail", 0.4); - ratesPerPurpose5_1.put("Employee Traffic/Parcels", 0.14); - ratesPerPurpose5_1.put("Employee Tertiary Sector Rest", 0.4); - - ratesPerPurpose5_2.put("Inhabitants", 0.55); - ratesPerPurpose5_2.put("Employee", 0.11); - ratesPerPurpose5_2.put("Employee Primary Sector", 0.11); - ratesPerPurpose5_2.put("Employee Construction", 0.11); - ratesPerPurpose5_2.put("Employee Secondary Sector Rest", 0.11); - ratesPerPurpose5_2.put("Employee Retail", 0.11); - ratesPerPurpose5_2.put("Employee Traffic/Parcels", 0.06); - ratesPerPurpose5_2.put("Employee Tertiary Sector Rest", 0.11); - - ratesPerPurpose5_3.put("Inhabitants", 0.22); - ratesPerPurpose5_3.put("Employee", 0.0); - ratesPerPurpose5_3.put("Employee Primary Sector", 0.17); - ratesPerPurpose5_3.put("Employee Construction", 0.17); - ratesPerPurpose5_3.put("Employee Secondary Sector Rest", 0.17); - ratesPerPurpose5_3.put("Employee Retail", 0.17); - ratesPerPurpose5_3.put("Employee Traffic/Parcels", 0.21); - ratesPerPurpose5_3.put("Employee Tertiary Sector Rest", 0.17); - - ratesPerPurpose5_4.put("Inhabitants", 0.0); - ratesPerPurpose5_4.put("Employee", 0.0); - ratesPerPurpose5_4.put("Employee Primary Sector", 0.04); - ratesPerPurpose5_4.put("Employee Construction", 0.04); - ratesPerPurpose5_4.put("Employee Secondary Sector Rest", 0.04); - ratesPerPurpose5_4.put("Employee Retail", 0.04); - ratesPerPurpose5_4.put("Employee Traffic/Parcels", 0.0); - ratesPerPurpose5_4.put("Employee Tertiary Sector Rest", 0.04); - - ratesPerPurpose5_5.put("Inhabitants", 0.06); - ratesPerPurpose5_5.put("Employee", 0.0); - ratesPerPurpose5_5.put("Employee Primary Sector", 0.28); - ratesPerPurpose5_5.put("Employee Construction", 0.28); - ratesPerPurpose5_5.put("Employee Secondary Sector Rest", 0.28); - ratesPerPurpose5_5.put("Employee Retail", 0.28); - ratesPerPurpose5_5.put("Employee Traffic/Parcels", 0.58); - ratesPerPurpose5_5.put("Employee Tertiary Sector Rest", 0.28); - - ratesPerPurpose6_1.put("Inhabitants", 0.0); - ratesPerPurpose6_1.put("Employee", 0.0); - ratesPerPurpose6_1.put("Employee Primary Sector", 0.0); - ratesPerPurpose6_1.put("Employee Construction", 0.0); - ratesPerPurpose6_1.put("Employee Secondary Sector Rest", 0.0); - ratesPerPurpose6_1.put("Employee Retail", 0.0); - ratesPerPurpose6_1.put("Employee Traffic/Parcels", 0.0); - ratesPerPurpose6_1.put("Employee Tertiary Sector Rest", 0.0); - - ratesPerPurpose6_2.put("Inhabitants", 0.85); - ratesPerPurpose6_2.put("Employee", 0.0); - ratesPerPurpose6_2.put("Employee Primary Sector", 0.21); - ratesPerPurpose6_2.put("Employee Construction", 0.21); - ratesPerPurpose6_2.put("Employee Secondary Sector Rest", 0.21); - ratesPerPurpose6_2.put("Employee Retail", 0.21); - ratesPerPurpose6_2.put("Employee Traffic/Parcels", 0.09); - ratesPerPurpose6_2.put("Employee Tertiary Sector Rest", 0.21); - - ratesPerPurpose6_3.put("Inhabitants", 0.15); - ratesPerPurpose6_3.put("Employee", 0.0); - ratesPerPurpose6_3.put("Employee Primary Sector", 0.58); - ratesPerPurpose6_3.put("Employee Construction", 0.58); - ratesPerPurpose6_3.put("Employee Secondary Sector Rest", 0.58); - ratesPerPurpose6_3.put("Employee Retail", 0.58); - ratesPerPurpose6_3.put("Employee Traffic/Parcels", 0.55); - ratesPerPurpose6_3.put("Employee Tertiary Sector Rest", 0.58); - - ratesPerPurpose6_4.put("Inhabitants", 0.0); - ratesPerPurpose6_4.put("Employee", 0.0); - ratesPerPurpose6_4.put("Employee Primary Sector", 0.21); - ratesPerPurpose6_4.put("Employee Construction", 0.21); - ratesPerPurpose6_4.put("Employee Secondary Sector Rest", 0.21); - ratesPerPurpose6_4.put("Employee Retail", 0.21); - ratesPerPurpose6_4.put("Employee Traffic/Parcels", 0.25); - ratesPerPurpose6_4.put("Employee Tertiary Sector Rest", 0.21); - - ratesPerPurpose6_5.put("Inhabitants", 0.0); - ratesPerPurpose6_5.put("Employee", 0.0); - ratesPerPurpose6_5.put("Employee Primary Sector", 0.0); - ratesPerPurpose6_5.put("Employee Construction", 0.0); - ratesPerPurpose6_5.put("Employee Secondary Sector Rest", 0.0); - ratesPerPurpose6_5.put("Employee Retail", 0.0); - ratesPerPurpose6_5.put("Employee Traffic/Parcels", 0.11); - ratesPerPurpose6_5.put("Employee Tertiary Sector Rest", 0.0); - } - commitmentRates.put("1_1", ratesPerPurpose1_1); - commitmentRates.put("1_2", ratesPerPurpose1_2); - commitmentRates.put("1_3", ratesPerPurpose1_3); - commitmentRates.put("1_4", ratesPerPurpose1_4); - commitmentRates.put("1_5", ratesPerPurpose1_5); - commitmentRates.put("2_1", ratesPerPurpose2_1); - commitmentRates.put("2_2", ratesPerPurpose2_2); - commitmentRates.put("2_3", ratesPerPurpose2_3); - commitmentRates.put("2_4", ratesPerPurpose2_4); - commitmentRates.put("2_5", ratesPerPurpose2_5); - commitmentRates.put("3_1", ratesPerPurpose3_1); - commitmentRates.put("3_2", ratesPerPurpose3_2); - commitmentRates.put("3_3", ratesPerPurpose3_3); - commitmentRates.put("3_4", ratesPerPurpose3_4); - commitmentRates.put("3_5", ratesPerPurpose3_5); - commitmentRates.put("4_1", ratesPerPurpose4_1); - commitmentRates.put("4_2", ratesPerPurpose4_2); - commitmentRates.put("4_3", ratesPerPurpose4_3); - commitmentRates.put("4_4", ratesPerPurpose4_4); - commitmentRates.put("4_5", ratesPerPurpose4_5); - commitmentRates.put("5_1", ratesPerPurpose5_1); - commitmentRates.put("5_2", ratesPerPurpose5_2); - commitmentRates.put("5_3", ratesPerPurpose5_3); - commitmentRates.put("5_4", ratesPerPurpose5_4); - commitmentRates.put("5_5", ratesPerPurpose5_5); - commitmentRates.put("6_1", ratesPerPurpose6_1); - commitmentRates.put("6_2", ratesPerPurpose6_2); - commitmentRates.put("6_3", ratesPerPurpose6_3); - commitmentRates.put("6_4", ratesPerPurpose6_4); - commitmentRates.put("6_5", ratesPerPurpose6_5); - } - return commitmentRates; - } } diff --git a/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/UnhandledServicesSolution.java b/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/UnhandledServicesSolution.java new file mode 100644 index 00000000000..e5db51e8557 --- /dev/null +++ b/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/UnhandledServicesSolution.java @@ -0,0 +1,39 @@ +package org.matsim.smallScaleCommercialTrafficGeneration; + +import org.matsim.api.core.v01.Scenario; +import org.matsim.freight.carriers.Carrier; + +import java.util.List; + +/** + * When generating service-durations for {@link Carrier}s it may happen service durations of their plans + * are too long to be fully handled. This implementation solves this problem. + */ +public interface UnhandledServicesSolution { + + /** + * @param scenario Scenario to search for carriers with unhandled jobs + * @return List with the found carriers + */ + List createListOfCarrierWithUnhandledJobs(Scenario scenario); + + /** + * Give a service duration based on the purpose and the trafficType under a given probability + * + * @param carrier The carrier for which we generate the serviceTime + * @param carrierAttributes attributes of the carrier to generate the service time for. + * selectedStartCategory: the category of the employee + * @param additionalTravelBufferPerIterationInMinutes additional buffer for the travel time + * @return the service duration + */ + int getServiceTimePerStop(Carrier carrier, GenerateSmallScaleCommercialTrafficDemand.CarrierAttributes carrierAttributes, int additionalTravelBufferPerIterationInMinutes); + + /** + * + * Checks and recalculates plans of carriers, which did not serve all services. + * This step may take a few minutes. + * @param scenario Scenario to handle the carriers for. Needed to execute {@link org.matsim.freight.carriers.CarriersUtils#runJsprit(Scenario)} and {@link UnhandledServicesSolution#createListOfCarrierWithUnhandledJobs(Scenario)} + * @param nonCompleteSolvedCarriers List of carriers, that are not solved. Can be obtained by {@link UnhandledServicesSolution#createListOfCarrierWithUnhandledJobs(Scenario)} + */ + void tryToSolveAllCarriersCompletely(Scenario scenario, List nonCompleteSolvedCarriers); +} diff --git a/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/VehicleAvailabilityAllocator.java b/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/VehicleAvailabilityAllocator.java new file mode 100644 index 00000000000..e13cce7efcf --- /dev/null +++ b/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/VehicleAvailabilityAllocator.java @@ -0,0 +1,106 @@ +package org.matsim.smallScaleCommercialTrafficGeneration; + +import java.util.*; + +/** + * A small allocator to solve the time-window problems in the Vehicle and Service generation using a Best-Fit Allocator.
+ * NOTE: This class does not actually change anything in the scenario. It is just a tool to check if Service and Vehicle TimeWindows are + * compatible. + */ +public class VehicleAvailabilityAllocator { + private List availableVehicleTime; + + /** + * Prepares the allocator for a vehicle fleet. + * @param availableVehicleTime This Collection should contain the duration of available-time-frames of the vehicles. + * For example: 4x vehicles are available from 1:00 to 4:00 (3 hours), then the {@code availableVehicles} Collection should + * contain 4 entries with value: 3*3600=10800. If a vehicle has a non-coherent availability-time-frame, add it as two + * separate entries. + */ + public VehicleAvailabilityAllocator(List availableVehicleTime){ + this.availableVehicleTime = availableVehicleTime; + } + + /** + * Prepares the allocator for one vehicle. + * @param availableVehicleTime This Collection should contain the duration of available-time-frames of the vehicle. + */ + public VehicleAvailabilityAllocator(double availableVehicleTime){ + this.availableVehicleTime = new ArrayList<>(1); + this.availableVehicleTime.add(availableVehicleTime); + } + + /** + * Checks if a vehicle is available for the given amount of time. If not, then the time is set to the largest possible duration, + * which can be allocated. + * @return the reduced serviceDuration (unchanged, if a vehicle was found, that was available for the full duration) + */ + public double makeServiceDurationViable(double serviceDuration){ + for(Double vehicleTime : availableVehicleTime){ + if(vehicleTime >= serviceDuration) return serviceDuration; + } + return availableVehicleTime.stream().mapToDouble(v -> v).max().orElseThrow(); + } + + /** + * Tries to allocate a single vehicle to the service and reduces the allocated vehicle available time by the serviceDuration. + * If no vehicle is available nothing happens. You should then consider to reduce the duration with {@link VehicleAvailabilityAllocator#makeServiceDurationViable} + * @return true if a vehicle was allocated, false if no vehicle is available for the given duration + */ + public boolean allocateServiceDuration(double serviceDuration){ + //Best-Fit Allocation + int bestFit = -1; + double bestRemaining = Double.MAX_VALUE; + for(int i = 0; i < availableVehicleTime.size(); i++){ + double remaining = availableVehicleTime.get(i) - serviceDuration; + if(remaining >= 0 && remaining < bestRemaining){ + bestFit = i; + bestRemaining = remaining; + } + } + if(bestFit == -1) return false; + //Allocate + availableVehicleTime.set(bestFit, availableVehicleTime.get(bestFit) - serviceDuration); + return true; + } + + /** + * This method checks for a given amount of same serviceDurations, whether you can allocate a vehicle to all of them or not. + * If not, the Allocator reduces the serviceDurations in a balanced way, so that the duration-cutoff is distributed across all given services. + * If you do not care if some services get much more time than others, you can use the {@link VehicleAvailabilityAllocator#makeServiceDurationViable} method. + * @param serviceDuration The duration of the services. + * @return An array which contains the maximum possible service durations (reverse order) + */ + public double makeMultipleServiceDurationsBalancedViable(int serviceAmount, double serviceDuration){ + //Check for serviceDuration first + int allocatedServices = 0; + for (Double d : availableVehicleTime) { + allocatedServices += (int) Math.floor(d / serviceDuration); + } + + if(allocatedServices >= serviceAmount){ + return serviceDuration; + } + + //If not found yet, get the best next value + double lastValue = Double.POSITIVE_INFINITY; + while(true){ + //Get largest value below lastValue + double thisValue = 0; + for(double d : availableVehicleTime){ + if(d > thisValue && d < lastValue) thisValue = d; + } + + allocatedServices = 0; + for (Double d : availableVehicleTime) { + allocatedServices += (int) Math.floor(d / thisValue); + } + + if(allocatedServices >= serviceAmount){ + return thisValue; + } + + lastValue = thisValue; + } + } +} diff --git a/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/VehicleSelection.java b/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/VehicleSelection.java new file mode 100644 index 00000000000..fdcf721a98d --- /dev/null +++ b/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/VehicleSelection.java @@ -0,0 +1,31 @@ +package org.matsim.smallScaleCommercialTrafficGeneration; + +import java.util.ArrayList; +import java.util.List; +/** + * Interface to set the categories needed by {@link GenerateSmallScaleCommercialTrafficDemand}. + * Standard implementation is {@link DefaultVehicleSelection}. + * Any configuration settings and external data-sources should be saved as attributes during initialization in the constructor of the class. + */ +public interface VehicleSelection{ + + class OdMatrixEntryInformation { + double occupancyRate; + String[] possibleVehicleTypes; + List possibleStartCategories = new ArrayList<>(); + List possibleStopCategories = new ArrayList<>(); + } + + /** + * @return all possible stop/start-categories. + */ + List getAllCategories(); + + /** + * @param purpose entry from {@link TripDistributionMatrix#getListOfPurposes()} + * @param modeORvehType entry from {@link TripDistributionMatrix#getListOfModesOrVehTypes()} + * @param smallScaleCommercialTrafficType Selected traffic types. Options: commercialPersonTraffic, goodsTraffic + * @return class holding the information that is specified by the given entry. + */ + OdMatrixEntryInformation getOdMatrixEntryInformation(int purpose, String modeORvehType, String smallScaleCommercialTrafficType); +} diff --git a/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/data/GetCommercialTourSpecifications.java b/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/data/CommercialTourSpecifications.java similarity index 71% rename from contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/data/GetCommercialTourSpecifications.java rename to contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/data/CommercialTourSpecifications.java index ce6bce3c04c..5cd6256c1ea 100644 --- a/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/data/GetCommercialTourSpecifications.java +++ b/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/data/CommercialTourSpecifications.java @@ -6,25 +6,23 @@ import java.util.Map; -public interface GetCommercialTourSpecifications { +public interface CommercialTourSpecifications { /** * Creates the probability distribution for the duration of the services. * The values are given in [min] and have an upperBound. * - * @param smallScaleCommercialTrafficType the type of small scale commercial traffic * @return the probability distribution for the duration of the services */ - Map> createStopDurationDistributionPerCategory( - String smallScaleCommercialTrafficType, RandomGenerator rng); + Map> createStopDurationDistributionPerCategory( + RandomGenerator rng); /** * Creates the distribution of the tour start and the related duration. * - * @param smallScaleCommercialTrafficType the type of the small scale commercial traffic * @return the distribution of the tour start and the related duration */ - EnumeratedDistribution createTourDistribution(String smallScaleCommercialTrafficType, RandomGenerator rng); + Map> createTourDistribution(RandomGenerator rng); /** * Creates the probability distribution for the tour start times for the day. diff --git a/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/data/DefaultTourSpecificationsByUsingKID2002.java b/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/data/DefaultTourSpecificationsByUsingKID2002.java index ec4bd9640ab..46f6887f0cd 100644 --- a/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/data/DefaultTourSpecificationsByUsingKID2002.java +++ b/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/data/DefaultTourSpecificationsByUsingKID2002.java @@ -10,1279 +10,1787 @@ import java.util.List; import java.util.Map; -import static org.matsim.smallScaleCommercialTrafficGeneration.GenerateSmallScaleCommercialTrafficDemand.makeStopDurationGoodTrafficKey; +import static org.matsim.smallScaleCommercialTrafficGeneration.GenerateSmallScaleCommercialTrafficDemand.makeServiceDurationPerCategoryKey; -public class DefaultTourSpecificationsByUsingKID2002 implements GetCommercialTourSpecifications { +public class DefaultTourSpecificationsByUsingKID2002 implements CommercialTourSpecifications { @Override - public Map> createStopDurationDistributionPerCategory(String smallScaleCommercialTrafficType, RandomGenerator rng) { - Map> stopDurationProbabilityDistribution = new HashMap<>(); + public Map> createStopDurationDistributionPerCategory( + RandomGenerator rng) { + Map> stopDurationProbabilityDistribution = new HashMap<>(); - if (smallScaleCommercialTrafficType.equals(GenerateSmallScaleCommercialTrafficDemand.SmallScaleCommercialTrafficType.commercialPersonTraffic.toString())) { - List> thisStopDurationProbabilityDistribution = new ArrayList<>(); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 30), 0.098)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 60), 0.17)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 90), 0.127)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.11)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 180), 0.17)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.076)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.057)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 360), 0.01)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(360, 420), 0.026)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 480), 0.045)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(480, 540), 0.064)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(540, 600), 0.034)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(600, 720), 0.012)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(720, 840), 0.002)); - stopDurationProbabilityDistribution.put(makeStopDurationGoodTrafficKey("Employee Primary Sector",null), - new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); - thisStopDurationProbabilityDistribution.clear(); + List> thisStopDurationProbabilityDistribution = new ArrayList<>(); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 30), 0.098)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 60), 0.17)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 90), 0.127)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.11)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 180), 0.17)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.076)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.057)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 360), 0.01)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(360, 420), 0.026)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 480), 0.045)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(480, 540), 0.064)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(540, 600), 0.034)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(600, 720), 0.012)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(720, 840), 0.002)); + stopDurationProbabilityDistribution.put(makeServiceDurationPerCategoryKey("Employee Primary Sector", null, + GenerateSmallScaleCommercialTrafficDemand.SmallScaleCommercialTrafficType.commercialPersonTraffic.toString()), + new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); + thisStopDurationProbabilityDistribution.clear(); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 30), 0.054)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 60), 0.164)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 90), 0.153)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.087)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 180), 0.12)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.055)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.044)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 360), 0.02)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(360, 420), 0.025)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 480), 0.069)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(480, 540), 0.132)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(540, 600), 0.058)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(600, 720), 0.016)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(720, 840), 0.002)); - stopDurationProbabilityDistribution.put(makeStopDurationGoodTrafficKey("Employee Construction",null), - new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); - thisStopDurationProbabilityDistribution.clear(); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 30), 0.054)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 60), 0.164)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 90), 0.153)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.087)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 180), 0.12)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.055)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.044)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 360), 0.02)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(360, 420), 0.025)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 480), 0.069)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(480, 540), 0.132)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(540, 600), 0.058)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(600, 720), 0.016)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(720, 840), 0.002)); + stopDurationProbabilityDistribution.put(makeServiceDurationPerCategoryKey("Employee Construction", null, + GenerateSmallScaleCommercialTrafficDemand.SmallScaleCommercialTrafficType.commercialPersonTraffic.toString()), + new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); + thisStopDurationProbabilityDistribution.clear(); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 30), 0.13)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 60), 0.324)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 90), 0.178)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.108)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 180), 0.097)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.034)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.02)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 360), 0.018)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(360, 420), 0.02)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 480), 0.027)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(480, 540), 0.029)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(540, 600), 0.008)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(600, 720), 0.006)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(720, 840), 0.001)); - stopDurationProbabilityDistribution.put(makeStopDurationGoodTrafficKey("Employee Secondary Sector Rest",null), - new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); - thisStopDurationProbabilityDistribution.clear(); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 30), 0.13)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 60), 0.324)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 90), 0.178)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.108)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 180), 0.097)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.034)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.02)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 360), 0.018)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(360, 420), 0.02)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 480), 0.027)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(480, 540), 0.029)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(540, 600), 0.008)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(600, 720), 0.006)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(720, 840), 0.001)); + stopDurationProbabilityDistribution.put(makeServiceDurationPerCategoryKey("Employee Secondary Sector Rest", null, + GenerateSmallScaleCommercialTrafficDemand.SmallScaleCommercialTrafficType.commercialPersonTraffic.toString()), + new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); + thisStopDurationProbabilityDistribution.clear(); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 30), 0.178)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 60), 0.301)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 90), 0.192)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.104)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 180), 0.092)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.043)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.013)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 360), 0.017)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(360, 420), 0.011)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 480), 0.016)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(480, 540), 0.016)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(540, 600), 0.007)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(600, 720), 0.007)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(720, 840), 0.001)); - stopDurationProbabilityDistribution.put(makeStopDurationGoodTrafficKey("Employee Retail",null), - new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); - thisStopDurationProbabilityDistribution.clear(); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 30), 0.178)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 60), 0.301)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 90), 0.192)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.104)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 180), 0.092)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.043)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.013)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 360), 0.017)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(360, 420), 0.011)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 480), 0.016)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(480, 540), 0.016)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(540, 600), 0.007)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(600, 720), 0.007)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(720, 840), 0.001)); + stopDurationProbabilityDistribution.put(makeServiceDurationPerCategoryKey("Employee Retail", null, + GenerateSmallScaleCommercialTrafficDemand.SmallScaleCommercialTrafficType.commercialPersonTraffic.toString()), + new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); + thisStopDurationProbabilityDistribution.clear(); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 30), 0.144)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 60), 0.372)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 90), 0.203)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.069)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 180), 0.112)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.038)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.011)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 360), 0.011)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(360, 420), 0.011)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 480), 0.012)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(480, 540), 0.007)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(540, 600), 0.005)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(600, 720), 0.005)); - stopDurationProbabilityDistribution.put(makeStopDurationGoodTrafficKey("Employee Traffic/Parcels",null), - new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); - thisStopDurationProbabilityDistribution.clear(); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 30), 0.144)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 60), 0.372)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 90), 0.203)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.069)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 180), 0.112)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.038)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.011)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 360), 0.011)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(360, 420), 0.011)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 480), 0.012)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(480, 540), 0.007)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(540, 600), 0.005)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(600, 720), 0.005)); + stopDurationProbabilityDistribution.put(makeServiceDurationPerCategoryKey("Employee Traffic/Parcels", null, + GenerateSmallScaleCommercialTrafficDemand.SmallScaleCommercialTrafficType.commercialPersonTraffic.toString()), + new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); + thisStopDurationProbabilityDistribution.clear(); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 30), 0.196)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 60), 0.292)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 90), 0.19)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.101)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 180), 0.105)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.034)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.017)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 360), 0.009)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(360, 420), 0.013)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 480), 0.019)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(480, 540), 0.014)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(540, 600), 0.006)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(600, 720), 0.004)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(720, 840), 0.001)); - stopDurationProbabilityDistribution.put(makeStopDurationGoodTrafficKey("Employee Tertiary Sector Rest",null), - new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 30), 0.196)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 60), 0.292)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 90), 0.19)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.101)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 180), 0.105)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.034)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.017)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 360), 0.009)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(360, 420), 0.013)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 480), 0.019)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(480, 540), 0.014)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(540, 600), 0.006)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(600, 720), 0.004)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(720, 840), 0.001)); + stopDurationProbabilityDistribution.put(makeServiceDurationPerCategoryKey("Employee Tertiary Sector Rest", null, + GenerateSmallScaleCommercialTrafficDemand.SmallScaleCommercialTrafficType.commercialPersonTraffic.toString()), + new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); + thisStopDurationProbabilityDistribution.clear(); - } else if (smallScaleCommercialTrafficType.equals(GenerateSmallScaleCommercialTrafficDemand.SmallScaleCommercialTrafficType.goodsTraffic.toString())) { - List> thisStopDurationProbabilityDistribution = new ArrayList<>(); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.038)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.049)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.052)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.094)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.125)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.094)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.167)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.094)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.113)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.056)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(150, 180), 0.04)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.024)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.009)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 420), 0.016)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 540), 0.026)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(540, 660), 0.002)); - stopDurationProbabilityDistribution.put(makeStopDurationGoodTrafficKey("Employee Primary Sector", "vehTyp1"), - new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); - thisStopDurationProbabilityDistribution.clear(); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.038)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.049)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.052)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.094)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.125)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.094)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.167)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.094)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.113)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.056)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(150, 180), 0.04)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.024)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.009)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 420), 0.016)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 540), 0.026)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(540, 660), 0.002)); + stopDurationProbabilityDistribution.put(makeServiceDurationPerCategoryKey("Employee Primary Sector", "vehTyp1", + GenerateSmallScaleCommercialTrafficDemand.SmallScaleCommercialTrafficType.goodsTraffic.toString()), + new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); + thisStopDurationProbabilityDistribution.clear(); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.025)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.025)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.05)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.043)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.112)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.168)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.149)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.081)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.168)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.068)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.068)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 540), 0.025)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(540, 660), 0.019)); - stopDurationProbabilityDistribution.put(makeStopDurationGoodTrafficKey("Employee Primary Sector", "vehTyp2"), - new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); - thisStopDurationProbabilityDistribution.clear(); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.025)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.025)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.05)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.043)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.112)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.168)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.149)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.081)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.168)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.068)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.068)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 540), 0.025)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(540, 660), 0.019)); + stopDurationProbabilityDistribution.put(makeServiceDurationPerCategoryKey("Employee Primary Sector", "vehTyp2", + GenerateSmallScaleCommercialTrafficDemand.SmallScaleCommercialTrafficType.goodsTraffic.toString()), + new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); + thisStopDurationProbabilityDistribution.clear(); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.036)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.098)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.036)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.016)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.042)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.124)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.085)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.144)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.105)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.052)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(150, 180), 0.072)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.052)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.023)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 420), 0.033)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 540), 0.062)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(540, 660), 0.016)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(660, 780), 0.003)); - stopDurationProbabilityDistribution.put(makeStopDurationGoodTrafficKey("Employee Primary Sector", "vehTyp3"), - new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); - thisStopDurationProbabilityDistribution.clear(); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.036)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.098)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.036)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.016)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.042)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.124)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.085)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.144)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.105)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.052)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(150, 180), 0.072)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.052)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.023)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 420), 0.033)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 540), 0.062)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(540, 660), 0.016)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(660, 780), 0.003)); + stopDurationProbabilityDistribution.put(makeServiceDurationPerCategoryKey("Employee Primary Sector", "vehTyp3", + GenerateSmallScaleCommercialTrafficDemand.SmallScaleCommercialTrafficType.goodsTraffic.toString()), + new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); + thisStopDurationProbabilityDistribution.clear(); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.071)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.143)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.429)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.179)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.107)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 420), 0.071)); - stopDurationProbabilityDistribution.put(makeStopDurationGoodTrafficKey("Employee Primary Sector", "vehTyp4"), - new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); - thisStopDurationProbabilityDistribution.clear(); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.071)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.143)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.429)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.179)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.107)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 420), 0.071)); + stopDurationProbabilityDistribution.put(makeServiceDurationPerCategoryKey("Employee Primary Sector", "vehTyp4", + GenerateSmallScaleCommercialTrafficDemand.SmallScaleCommercialTrafficType.goodsTraffic.toString()), + new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); + thisStopDurationProbabilityDistribution.clear(); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.026)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.395)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.158)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.132)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.026)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.105)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.079)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(150, 180), 0.026)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(540, 660), 0.053)); - stopDurationProbabilityDistribution.put(makeStopDurationGoodTrafficKey("Employee Primary Sector", "vehTyp5"), - new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); - thisStopDurationProbabilityDistribution.clear(); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.026)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.395)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.158)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.132)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.026)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.105)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.079)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(150, 180), 0.026)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(540, 660), 0.053)); + stopDurationProbabilityDistribution.put(makeServiceDurationPerCategoryKey("Employee Primary Sector", "vehTyp5", + GenerateSmallScaleCommercialTrafficDemand.SmallScaleCommercialTrafficType.goodsTraffic.toString()), + new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); + thisStopDurationProbabilityDistribution.clear(); - thisStopDurationProbabilityDistribution = new ArrayList<>(); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.014)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.033)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.064)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.109)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.088)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.095)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.112)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.105)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.114)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.053)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(150, 180), 0.088)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.038)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.012)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 420), 0.01)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 540), 0.051)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(540, 660), 0.015)); - stopDurationProbabilityDistribution.put(makeStopDurationGoodTrafficKey("Employee Construction", "vehTyp1"), - new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); - thisStopDurationProbabilityDistribution.clear(); + thisStopDurationProbabilityDistribution = new ArrayList<>(); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.014)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.033)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.064)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.109)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.088)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.095)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.112)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.105)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.114)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.053)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(150, 180), 0.088)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.038)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.012)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 420), 0.01)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 540), 0.051)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(540, 660), 0.015)); + stopDurationProbabilityDistribution.put(makeServiceDurationPerCategoryKey("Employee Construction", "vehTyp1", + GenerateSmallScaleCommercialTrafficDemand.SmallScaleCommercialTrafficType.goodsTraffic.toString()), + new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); + thisStopDurationProbabilityDistribution.clear(); - thisStopDurationProbabilityDistribution = new ArrayList<>(); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.02)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.027)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.061)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.045)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.068)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.083)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.112)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.114)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.146)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.058)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(150, 180), 0.114)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.036)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.022)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 420), 0.007)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 540), 0.065)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(540, 660), 0.023)); - stopDurationProbabilityDistribution.put(makeStopDurationGoodTrafficKey("Employee Construction", "vehTyp2"), - new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); - thisStopDurationProbabilityDistribution.clear(); + thisStopDurationProbabilityDistribution = new ArrayList<>(); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.02)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.027)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.061)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.045)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.068)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.083)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.112)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.114)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.146)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.058)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(150, 180), 0.114)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.036)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.022)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 420), 0.007)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 540), 0.065)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(540, 660), 0.023)); + stopDurationProbabilityDistribution.put(makeServiceDurationPerCategoryKey("Employee Construction", "vehTyp2", + GenerateSmallScaleCommercialTrafficDemand.SmallScaleCommercialTrafficType.goodsTraffic.toString()), + new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); + thisStopDurationProbabilityDistribution.clear(); - thisStopDurationProbabilityDistribution = new ArrayList<>(); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.009)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.04)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.074)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.09)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.086)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.069)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.113)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.135)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.071)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.008)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(150, 180), 0.044)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.041)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.03)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 420), 0.021)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 540), 0.075)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(540, 660), 0.022)); - stopDurationProbabilityDistribution.put(makeStopDurationGoodTrafficKey("Employee Construction", "vehTyp3"), - new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); - thisStopDurationProbabilityDistribution.clear(); + thisStopDurationProbabilityDistribution = new ArrayList<>(); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.009)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.04)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.074)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.09)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.086)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.069)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.113)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.135)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.071)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.008)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(150, 180), 0.044)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.041)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.03)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 420), 0.021)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 540), 0.075)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(540, 660), 0.022)); + stopDurationProbabilityDistribution.put(makeServiceDurationPerCategoryKey("Employee Construction", "vehTyp3", + GenerateSmallScaleCommercialTrafficDemand.SmallScaleCommercialTrafficType.goodsTraffic.toString()), + new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); + thisStopDurationProbabilityDistribution.clear(); - thisStopDurationProbabilityDistribution = new ArrayList<>(); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.036)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.055)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.018)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.236)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.073)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.018)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.164)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.091)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(150, 180), 0.109)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.055)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.018)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 420), 0.055)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 540), 0.055)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(540, 660), 0.018)); - stopDurationProbabilityDistribution.put(makeStopDurationGoodTrafficKey("Employee Construction", "vehTyp4"), - new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); - thisStopDurationProbabilityDistribution.clear(); + thisStopDurationProbabilityDistribution = new ArrayList<>(); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.036)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.055)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.018)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.236)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.073)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.018)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.164)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.091)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(150, 180), 0.109)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.055)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.018)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 420), 0.055)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 540), 0.055)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(540, 660), 0.018)); + stopDurationProbabilityDistribution.put(makeServiceDurationPerCategoryKey("Employee Construction", "vehTyp4", + GenerateSmallScaleCommercialTrafficDemand.SmallScaleCommercialTrafficType.goodsTraffic.toString()), + new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); + thisStopDurationProbabilityDistribution.clear(); - thisStopDurationProbabilityDistribution = new ArrayList<>(); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.014)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.163)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.21)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.165)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.125)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.095)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.101)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.04)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.03)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.024)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(150, 180), 0.006)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.008)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.002)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 420), 0.004)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 540), 0.008)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(540, 660), 0.004)); - stopDurationProbabilityDistribution.put(makeStopDurationGoodTrafficKey("Employee Construction", "vehTyp5"), - new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); - thisStopDurationProbabilityDistribution.clear(); + thisStopDurationProbabilityDistribution = new ArrayList<>(); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.014)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.163)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.21)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.165)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.125)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.095)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.101)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.04)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.03)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.024)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(150, 180), 0.006)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.008)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.002)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 420), 0.004)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 540), 0.008)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(540, 660), 0.004)); + stopDurationProbabilityDistribution.put(makeServiceDurationPerCategoryKey("Employee Construction", "vehTyp5", + GenerateSmallScaleCommercialTrafficDemand.SmallScaleCommercialTrafficType.goodsTraffic.toString()), + new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); + thisStopDurationProbabilityDistribution.clear(); - thisStopDurationProbabilityDistribution = new ArrayList<>(); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.072)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.093)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.123)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.113)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.137)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.081)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.102)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.087)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.079)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.032)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(150, 180), 0.021)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.018)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.016)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 420), 0.009)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 540), 0.014)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(540, 780), 0.002)); - stopDurationProbabilityDistribution.put(makeStopDurationGoodTrafficKey("Employee Secondary Sector Rest", "vehTyp1"), - new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); - thisStopDurationProbabilityDistribution.clear(); + thisStopDurationProbabilityDistribution = new ArrayList<>(); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.072)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.093)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.123)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.113)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.137)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.081)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.102)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.087)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.079)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.032)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(150, 180), 0.021)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.018)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.016)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 420), 0.009)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 540), 0.014)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(540, 780), 0.002)); + stopDurationProbabilityDistribution.put(makeServiceDurationPerCategoryKey("Employee Secondary Sector Rest", "vehTyp1", + GenerateSmallScaleCommercialTrafficDemand.SmallScaleCommercialTrafficType.goodsTraffic.toString()), + new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); + thisStopDurationProbabilityDistribution.clear(); - thisStopDurationProbabilityDistribution = new ArrayList<>(); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.062)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.14)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.093)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.115)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.133)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.102)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.098)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.071)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.067)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.038)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(150, 180), 0.027)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.011)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.009)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 420), 0.024)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 540), 0.011)); - stopDurationProbabilityDistribution.put(makeStopDurationGoodTrafficKey("Employee Secondary Sector Rest", "vehTyp2"), - new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); - thisStopDurationProbabilityDistribution.clear(); + thisStopDurationProbabilityDistribution = new ArrayList<>(); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.062)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.14)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.093)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.115)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.133)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.102)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.098)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.071)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.067)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.038)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(150, 180), 0.027)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.011)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.009)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 420), 0.024)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 540), 0.011)); + stopDurationProbabilityDistribution.put(makeServiceDurationPerCategoryKey("Employee Secondary Sector Rest", "vehTyp2", + GenerateSmallScaleCommercialTrafficDemand.SmallScaleCommercialTrafficType.goodsTraffic.toString()), + new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); + thisStopDurationProbabilityDistribution.clear(); - thisStopDurationProbabilityDistribution = new ArrayList<>(); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.051)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.214)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.146)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.129)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.10)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.072)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.083)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.063)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.054)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.02)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(150, 180), 0.016)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.022)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.008)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 420), 0.007)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 540), 0.011)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(540, 900), 0.003)); - stopDurationProbabilityDistribution.put(makeStopDurationGoodTrafficKey("Employee Secondary Sector Rest", "vehTyp3"), - new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); - thisStopDurationProbabilityDistribution.clear(); + thisStopDurationProbabilityDistribution = new ArrayList<>(); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.051)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.214)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.146)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.129)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.10)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.072)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.083)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.063)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.054)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.02)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(150, 180), 0.016)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.022)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.008)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 420), 0.007)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 540), 0.011)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(540, 900), 0.003)); + stopDurationProbabilityDistribution.put(makeServiceDurationPerCategoryKey("Employee Secondary Sector Rest", "vehTyp3", + GenerateSmallScaleCommercialTrafficDemand.SmallScaleCommercialTrafficType.goodsTraffic.toString()), + new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); + thisStopDurationProbabilityDistribution.clear(); - thisStopDurationProbabilityDistribution = new ArrayList<>(); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.163)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.224)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.153)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.061)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.173)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.082)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.122)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.01)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 540), 0.01)); - stopDurationProbabilityDistribution.put(makeStopDurationGoodTrafficKey("Employee Secondary Sector Rest", "vehTyp4"), - new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); - thisStopDurationProbabilityDistribution.clear(); + thisStopDurationProbabilityDistribution = new ArrayList<>(); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.163)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.224)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.153)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.061)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.173)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.082)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.122)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.01)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 540), 0.01)); + stopDurationProbabilityDistribution.put(makeServiceDurationPerCategoryKey("Employee Secondary Sector Rest", "vehTyp4", + GenerateSmallScaleCommercialTrafficDemand.SmallScaleCommercialTrafficType.goodsTraffic.toString()), + new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); + thisStopDurationProbabilityDistribution.clear(); - thisStopDurationProbabilityDistribution = new ArrayList<>(); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.003)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.195)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.225)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.16)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.143)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.089)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.075)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.031)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.048)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.01)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.003)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.007)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 660), 0.009)); - stopDurationProbabilityDistribution.put(makeStopDurationGoodTrafficKey("Employee Secondary Sector Rest", "vehTyp5"), - new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); - thisStopDurationProbabilityDistribution.clear(); + thisStopDurationProbabilityDistribution = new ArrayList<>(); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.003)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.195)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.225)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.16)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.143)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.089)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.075)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.031)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.048)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.01)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.003)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.007)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 660), 0.009)); + stopDurationProbabilityDistribution.put(makeServiceDurationPerCategoryKey("Employee Secondary Sector Rest", "vehTyp5", + GenerateSmallScaleCommercialTrafficDemand.SmallScaleCommercialTrafficType.goodsTraffic.toString()), + new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); + thisStopDurationProbabilityDistribution.clear(); - thisStopDurationProbabilityDistribution = new ArrayList<>(); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.057)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.108)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.093)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.133)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.133)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.11)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.102)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.064)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.104)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.049)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(150, 180), 0.015)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.015)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.003)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 420), 0.005)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 540), 0.006)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(540, 660), 0.003)); - stopDurationProbabilityDistribution.put(makeStopDurationGoodTrafficKey("Employee Retail", "vehTyp1"), - new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); - thisStopDurationProbabilityDistribution.clear(); + thisStopDurationProbabilityDistribution = new ArrayList<>(); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.057)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.108)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.093)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.133)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.133)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.11)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.102)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.064)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.104)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.049)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(150, 180), 0.015)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.015)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.003)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 420), 0.005)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 540), 0.006)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(540, 660), 0.003)); + stopDurationProbabilityDistribution.put(makeServiceDurationPerCategoryKey("Employee Retail", "vehTyp1", + GenerateSmallScaleCommercialTrafficDemand.SmallScaleCommercialTrafficType.goodsTraffic.toString()), + new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); + thisStopDurationProbabilityDistribution.clear(); - thisStopDurationProbabilityDistribution = new ArrayList<>(); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.084)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.119)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.183)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.076)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.085)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.101)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.124)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.069)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.057)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.041)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(150, 180), 0.002)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.025)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.011)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 420), 0.007)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 540), 0.007)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(540, 660), 0.004)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(780, 900), 0.002)); - stopDurationProbabilityDistribution.put(makeStopDurationGoodTrafficKey("Employee Retail", "vehTyp2"), - new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); - thisStopDurationProbabilityDistribution.clear(); + thisStopDurationProbabilityDistribution = new ArrayList<>(); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.084)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.119)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.183)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.076)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.085)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.101)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.124)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.069)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.057)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.041)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(150, 180), 0.002)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.025)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.011)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 420), 0.007)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 540), 0.007)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(540, 660), 0.004)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(780, 900), 0.002)); + stopDurationProbabilityDistribution.put(makeServiceDurationPerCategoryKey("Employee Retail", "vehTyp2", + GenerateSmallScaleCommercialTrafficDemand.SmallScaleCommercialTrafficType.goodsTraffic.toString()), + new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); + thisStopDurationProbabilityDistribution.clear(); - thisStopDurationProbabilityDistribution = new ArrayList<>(); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.103)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.23)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.193)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.08)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.065)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.071)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.072)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.044)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.054)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.035)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(150, 180), 0.009)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.013)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.014)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 420), 0.01)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 540), 0.003)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(540, 660), 0.003)); - stopDurationProbabilityDistribution.put(makeStopDurationGoodTrafficKey("Employee Retail", "vehTyp3"), - new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); - thisStopDurationProbabilityDistribution.clear(); + thisStopDurationProbabilityDistribution = new ArrayList<>(); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.103)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.23)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.193)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.08)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.065)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.071)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.072)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.044)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.054)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.035)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(150, 180), 0.009)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.013)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.014)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 420), 0.01)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 540), 0.003)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(540, 660), 0.003)); + stopDurationProbabilityDistribution.put(makeServiceDurationPerCategoryKey("Employee Retail", "vehTyp3", + GenerateSmallScaleCommercialTrafficDemand.SmallScaleCommercialTrafficType.goodsTraffic.toString()), + new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); + thisStopDurationProbabilityDistribution.clear(); - thisStopDurationProbabilityDistribution = new ArrayList<>(); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.094)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.179)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.094)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.245)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.123)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.075)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.094)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.038)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(150, 180), 0.019)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.009)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.009)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 540), 0.019)); - stopDurationProbabilityDistribution.put(makeStopDurationGoodTrafficKey("Employee Retail", "vehTyp4"), - new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); - thisStopDurationProbabilityDistribution.clear(); + thisStopDurationProbabilityDistribution = new ArrayList<>(); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.094)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.179)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.094)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.245)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.123)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.075)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.094)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.038)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(150, 180), 0.019)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.009)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.009)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 540), 0.019)); + stopDurationProbabilityDistribution.put(makeServiceDurationPerCategoryKey("Employee Retail", "vehTyp4", + GenerateSmallScaleCommercialTrafficDemand.SmallScaleCommercialTrafficType.goodsTraffic.toString()), + new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); + thisStopDurationProbabilityDistribution.clear(); - thisStopDurationProbabilityDistribution = new ArrayList<>(); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.066)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.063)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.142)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.165)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.135)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.102)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.122)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.033)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.086)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.043)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(150, 180), 0.023)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.017)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.003)); - stopDurationProbabilityDistribution.put(makeStopDurationGoodTrafficKey("Employee Retail", "vehTyp5"), - new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); - thisStopDurationProbabilityDistribution.clear(); + thisStopDurationProbabilityDistribution = new ArrayList<>(); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.066)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.063)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.142)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.165)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.135)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.102)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.122)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.033)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.086)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.043)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(150, 180), 0.023)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.017)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.003)); + stopDurationProbabilityDistribution.put(makeServiceDurationPerCategoryKey("Employee Retail", "vehTyp5", + GenerateSmallScaleCommercialTrafficDemand.SmallScaleCommercialTrafficType.goodsTraffic.toString()), + new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); + thisStopDurationProbabilityDistribution.clear(); - thisStopDurationProbabilityDistribution = new ArrayList<>(); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.159)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.173)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.173)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.088)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.115)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.071)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.024)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.051)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.041)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.02)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(150, 180), 0.031)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.024)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.017)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 420), 0.007)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 540), 0.007)); - stopDurationProbabilityDistribution.put(makeStopDurationGoodTrafficKey("Employee Traffic/Parcels", "vehTyp1"), - new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); - thisStopDurationProbabilityDistribution.clear(); + thisStopDurationProbabilityDistribution = new ArrayList<>(); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.159)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.173)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.173)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.088)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.115)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.071)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.024)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.051)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.041)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.02)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(150, 180), 0.031)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.024)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.017)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 420), 0.007)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 540), 0.007)); + stopDurationProbabilityDistribution.put(makeServiceDurationPerCategoryKey("Employee Traffic/Parcels", "vehTyp1", + GenerateSmallScaleCommercialTrafficDemand.SmallScaleCommercialTrafficType.goodsTraffic.toString()), + new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); + thisStopDurationProbabilityDistribution.clear(); - thisStopDurationProbabilityDistribution = new ArrayList<>(); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.292)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.135)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.062)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.197)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.051)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.079)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.022)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.045)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.056)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.034)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.006)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 420), 0.022)); - stopDurationProbabilityDistribution.put(makeStopDurationGoodTrafficKey("Employee Traffic/Parcels", "vehTyp2"), - new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); - thisStopDurationProbabilityDistribution.clear(); + thisStopDurationProbabilityDistribution = new ArrayList<>(); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.292)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.135)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.062)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.197)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.051)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.079)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.022)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.045)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.056)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.034)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.006)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 420), 0.022)); + stopDurationProbabilityDistribution.put(makeServiceDurationPerCategoryKey("Employee Traffic/Parcels", "vehTyp2", + GenerateSmallScaleCommercialTrafficDemand.SmallScaleCommercialTrafficType.goodsTraffic.toString()), + new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); + thisStopDurationProbabilityDistribution.clear(); - thisStopDurationProbabilityDistribution = new ArrayList<>(); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.092)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.111)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.224)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.173)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.09)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.103)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.045)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.028)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.056)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.017)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(150, 180), 0.019)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.025)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.006)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 420), 0.007)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 540), 0.006)); - stopDurationProbabilityDistribution.put(makeStopDurationGoodTrafficKey("Employee Traffic/Parcels", "vehTyp3"), - new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); - thisStopDurationProbabilityDistribution.clear(); + thisStopDurationProbabilityDistribution = new ArrayList<>(); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.092)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.111)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.224)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.173)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.09)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.103)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.045)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.028)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.056)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.017)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(150, 180), 0.019)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.025)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.006)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 420), 0.007)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 540), 0.006)); + stopDurationProbabilityDistribution.put(makeServiceDurationPerCategoryKey("Employee Traffic/Parcels", "vehTyp3", + GenerateSmallScaleCommercialTrafficDemand.SmallScaleCommercialTrafficType.goodsTraffic.toString()), + new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); + thisStopDurationProbabilityDistribution.clear(); - thisStopDurationProbabilityDistribution = new ArrayList<>(); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.146)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.098)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.146)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.195)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.268)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.012)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.024)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.024)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.024)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.037)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.012)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 420), 0.012)); - stopDurationProbabilityDistribution.put(makeStopDurationGoodTrafficKey("Employee Traffic/Parcels", "vehTyp4"), - new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); - thisStopDurationProbabilityDistribution.clear(); + thisStopDurationProbabilityDistribution = new ArrayList<>(); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.146)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.098)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.146)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.195)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.268)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.012)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.024)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.024)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.024)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.037)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.012)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 420), 0.012)); + stopDurationProbabilityDistribution.put(makeServiceDurationPerCategoryKey("Employee Traffic/Parcels", "vehTyp4", + GenerateSmallScaleCommercialTrafficDemand.SmallScaleCommercialTrafficType.goodsTraffic.toString()), + new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); + thisStopDurationProbabilityDistribution.clear(); - thisStopDurationProbabilityDistribution = new ArrayList<>(); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.026)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.042)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.062)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.121)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.133)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.144)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.144)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.104)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.121)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.046)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(150, 180), 0.011)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.026)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.007)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 420), 0.005)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 900), 0.008)); - stopDurationProbabilityDistribution.put(makeStopDurationGoodTrafficKey("Employee Traffic/Parcels", "vehTyp5"), - new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); - thisStopDurationProbabilityDistribution.clear(); + thisStopDurationProbabilityDistribution = new ArrayList<>(); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.026)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.042)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.062)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.121)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.133)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.144)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.144)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.104)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.121)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.046)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(150, 180), 0.011)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.026)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.007)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 420), 0.005)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 900), 0.008)); + stopDurationProbabilityDistribution.put(makeServiceDurationPerCategoryKey("Employee Traffic/Parcels", "vehTyp5", + GenerateSmallScaleCommercialTrafficDemand.SmallScaleCommercialTrafficType.goodsTraffic.toString()), + new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); + thisStopDurationProbabilityDistribution.clear(); - thisStopDurationProbabilityDistribution = new ArrayList<>(); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.061)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.093)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.101)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.125)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.125)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.101)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.124)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.08)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.093)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.046)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(150, 180), 0.013)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.017)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.011)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 420), 0.004)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 540), 0.005)); - stopDurationProbabilityDistribution.put(makeStopDurationGoodTrafficKey("Employee Tertiary Sector Rest", "vehTyp1"), - new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); - thisStopDurationProbabilityDistribution.clear(); + thisStopDurationProbabilityDistribution = new ArrayList<>(); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.061)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.093)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.101)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.125)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.125)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.101)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.124)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.08)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.093)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.046)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(150, 180), 0.013)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.017)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.011)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 420), 0.004)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 540), 0.005)); + stopDurationProbabilityDistribution.put(makeServiceDurationPerCategoryKey("Employee Tertiary Sector Rest", "vehTyp1", + GenerateSmallScaleCommercialTrafficDemand.SmallScaleCommercialTrafficType.goodsTraffic.toString()), + new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); + thisStopDurationProbabilityDistribution.clear(); - thisStopDurationProbabilityDistribution = new ArrayList<>(); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.081)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.101)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.101)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.109)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.124)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.065)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.109)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.124)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.097)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.032)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(150, 180), 0.022)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.017)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.003)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 420), 0.007)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 540), 0.008)); - stopDurationProbabilityDistribution.put(makeStopDurationGoodTrafficKey("Employee Tertiary Sector Rest", "vehTyp2"), - new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); - thisStopDurationProbabilityDistribution.clear(); + thisStopDurationProbabilityDistribution = new ArrayList<>(); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.081)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.101)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.101)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.109)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.124)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.065)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.109)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.124)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.097)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.032)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(150, 180), 0.022)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.017)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.003)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 420), 0.007)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 540), 0.008)); + stopDurationProbabilityDistribution.put(makeServiceDurationPerCategoryKey("Employee Tertiary Sector Rest", "vehTyp2", + GenerateSmallScaleCommercialTrafficDemand.SmallScaleCommercialTrafficType.goodsTraffic.toString()), + new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); + thisStopDurationProbabilityDistribution.clear(); - thisStopDurationProbabilityDistribution = new ArrayList<>(); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.052)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.114)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.155)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.111)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.151)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.112)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.125)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.043)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.051)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.026)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(150, 180), 0.014)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.016)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.011)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 420), 0.007)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 540), 0.009)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(660, 780), 0.003)); - stopDurationProbabilityDistribution.put(makeStopDurationGoodTrafficKey("Employee Tertiary Sector Rest", "vehTyp3"), - new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); - thisStopDurationProbabilityDistribution.clear(); + thisStopDurationProbabilityDistribution = new ArrayList<>(); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.052)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.114)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.155)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.111)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.151)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.112)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.125)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.043)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.051)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.026)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(150, 180), 0.014)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.016)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.011)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 420), 0.007)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 540), 0.009)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(660, 780), 0.003)); + stopDurationProbabilityDistribution.put(makeServiceDurationPerCategoryKey("Employee Tertiary Sector Rest", "vehTyp3", + GenerateSmallScaleCommercialTrafficDemand.SmallScaleCommercialTrafficType.goodsTraffic.toString()), + new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); + thisStopDurationProbabilityDistribution.clear(); - thisStopDurationProbabilityDistribution = new ArrayList<>(); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.02)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.082)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.102)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.449)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.061)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.163)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.102)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.02)); - stopDurationProbabilityDistribution.put(makeStopDurationGoodTrafficKey("Employee Tertiary Sector Rest", "vehTyp4"), - new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); - thisStopDurationProbabilityDistribution.clear(); + thisStopDurationProbabilityDistribution = new ArrayList<>(); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.02)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.082)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.102)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.449)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.061)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.163)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.102)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.02)); + stopDurationProbabilityDistribution.put(makeServiceDurationPerCategoryKey("Employee Tertiary Sector Rest", "vehTyp4", + GenerateSmallScaleCommercialTrafficDemand.SmallScaleCommercialTrafficType.goodsTraffic.toString()), + new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); + thisStopDurationProbabilityDistribution.clear(); - thisStopDurationProbabilityDistribution = new ArrayList<>(); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.02)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.02)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.151)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.296)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.156)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.065)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.121)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.05)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.075)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(150, 180), 0.01)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.015)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.01)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 420), 0.005)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 540), 0.005)); - stopDurationProbabilityDistribution.put(makeStopDurationGoodTrafficKey("Employee Tertiary Sector Rest", "vehTyp5"), - new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); - thisStopDurationProbabilityDistribution.clear(); + thisStopDurationProbabilityDistribution = new ArrayList<>(); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.02)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.02)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.151)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.296)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.156)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.065)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.121)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.05)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.075)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(150, 180), 0.01)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.015)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.01)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 420), 0.005)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 540), 0.005)); + stopDurationProbabilityDistribution.put(makeServiceDurationPerCategoryKey("Employee Tertiary Sector Rest", "vehTyp5", + GenerateSmallScaleCommercialTrafficDemand.SmallScaleCommercialTrafficType.goodsTraffic.toString()), + new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); + thisStopDurationProbabilityDistribution.clear(); - // because no data für private persons; use average numbers of all employee categories - thisStopDurationProbabilityDistribution = new ArrayList<>(); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.056)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.084)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.095)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.118)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.12)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.096)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.112)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.083)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.095)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.045)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(150, 180), 0.033)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.022)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.011)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 420), 0.007)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 540), 0.018)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(540, 660), 0.004)); - stopDurationProbabilityDistribution.put(makeStopDurationGoodTrafficKey("Inhabitants", "vehTyp1"), - new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); - thisStopDurationProbabilityDistribution.clear(); + // because no data für private persons; use average numbers of all employee categories + thisStopDurationProbabilityDistribution = new ArrayList<>(); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.056)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.084)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.095)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.118)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.12)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.096)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.112)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.083)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.095)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.045)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(150, 180), 0.033)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.022)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.011)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 420), 0.007)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 540), 0.018)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(540, 660), 0.004)); + stopDurationProbabilityDistribution.put(makeServiceDurationPerCategoryKey("Inhabitants", "vehTyp1", + GenerateSmallScaleCommercialTrafficDemand.SmallScaleCommercialTrafficType.goodsTraffic.toString()), + new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); + thisStopDurationProbabilityDistribution.clear(); - thisStopDurationProbabilityDistribution = new ArrayList<>(); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.077)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.093)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.103)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.092)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.098)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.091)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.108)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.092)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.095)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.043)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(150, 180), 0.035)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.024)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.01)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 420), 0.011)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 540), 0.021)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(540, 660), 0.007)); - stopDurationProbabilityDistribution.put(makeStopDurationGoodTrafficKey("Inhabitants", "vehTyp2"), - new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); - thisStopDurationProbabilityDistribution.clear(); + thisStopDurationProbabilityDistribution = new ArrayList<>(); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.077)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.093)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.103)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.092)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.098)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.091)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.108)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.092)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.095)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.043)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(150, 180), 0.035)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.024)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.01)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 420), 0.011)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 540), 0.021)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(540, 660), 0.007)); + stopDurationProbabilityDistribution.put(makeServiceDurationPerCategoryKey("Inhabitants", "vehTyp2", + GenerateSmallScaleCommercialTrafficDemand.SmallScaleCommercialTrafficType.goodsTraffic.toString()), + new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); + thisStopDurationProbabilityDistribution.clear(); - thisStopDurationProbabilityDistribution = new ArrayList<>(); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.06)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.141)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.152)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.107)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.094)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.087)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.089)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.067)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.06)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.037)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(150, 180), 0.023)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.025)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.015)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 420), 0.012)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 540), 0.024)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(540, 660), 0.006)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(660, 780), 0.001)); - stopDurationProbabilityDistribution.put(makeStopDurationGoodTrafficKey("Inhabitants", "vehTyp3"), - new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); - thisStopDurationProbabilityDistribution.clear(); + thisStopDurationProbabilityDistribution = new ArrayList<>(); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.06)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.141)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.152)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.107)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.094)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.087)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.089)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.067)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.06)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.037)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(150, 180), 0.023)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.025)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.015)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 420), 0.012)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 540), 0.024)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(540, 660), 0.006)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(660, 780), 0.001)); + stopDurationProbabilityDistribution.put(makeServiceDurationPerCategoryKey("Inhabitants", "vehTyp3", + GenerateSmallScaleCommercialTrafficDemand.SmallScaleCommercialTrafficType.goodsTraffic.toString()), + new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); + thisStopDurationProbabilityDistribution.clear(); - thisStopDurationProbabilityDistribution = new ArrayList<>(); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.062)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.11)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.12)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.144)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.151)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.129)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.062)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.079)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.041)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.031)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(150, 180), 0.019)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.014)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.007)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 420), 0.014)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 540), 0.014)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(540, 660), 0.002)); - stopDurationProbabilityDistribution.put(makeStopDurationGoodTrafficKey("Inhabitants", "vehTyp4"), - new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); - thisStopDurationProbabilityDistribution.clear(); + thisStopDurationProbabilityDistribution = new ArrayList<>(); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.062)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.11)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.12)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.144)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.151)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.129)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.062)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.079)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.041)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.031)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(150, 180), 0.019)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.014)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.007)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 420), 0.014)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 540), 0.014)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(540, 660), 0.002)); + stopDurationProbabilityDistribution.put(makeServiceDurationPerCategoryKey("Inhabitants", "vehTyp4", + GenerateSmallScaleCommercialTrafficDemand.SmallScaleCommercialTrafficType.goodsTraffic.toString()), + new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); + thisStopDurationProbabilityDistribution.clear(); + + thisStopDurationProbabilityDistribution = new ArrayList<>(); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.024)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.099)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.147)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.17)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.133)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.108)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.116)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.058)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.075)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.03)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(150, 180), 0.01)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.014)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.005)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 420), 0.004)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 660), 0.007)); + thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(660, 900), 0.002)); + stopDurationProbabilityDistribution.put(makeServiceDurationPerCategoryKey("Inhabitants", "vehTyp5", + GenerateSmallScaleCommercialTrafficDemand.SmallScaleCommercialTrafficType.goodsTraffic.toString()), + new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); + thisStopDurationProbabilityDistribution.clear(); - thisStopDurationProbabilityDistribution = new ArrayList<>(); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(0, 10), 0.024)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(10, 20), 0.099)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(20, 30), 0.147)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(30, 40), 0.17)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(40, 50), 0.133)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(50, 60), 0.108)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(60, 75), 0.116)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(75, 90), 0.058)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(90, 120), 0.075)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(120, 150), 0.03)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(150, 180), 0.01)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(180, 240), 0.014)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(240, 300), 0.005)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(300, 420), 0.004)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(420, 660), 0.007)); - thisStopDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.DurationsBounds(660, 900), 0.002)); - stopDurationProbabilityDistribution.put(makeStopDurationGoodTrafficKey("Inhabitants", "vehTyp5"), - new EnumeratedDistribution<>(rng, thisStopDurationProbabilityDistribution)); - thisStopDurationProbabilityDistribution.clear(); - } return stopDurationProbabilityDistribution; } @Override - public EnumeratedDistribution createTourDistribution( - String smallScaleCommercialTrafficType, RandomGenerator rng) { + public Map> createTourDistribution( + RandomGenerator rng) { + Map> tourDistribution = new HashMap<>(); List> tourDurationProbabilityDistribution = new ArrayList<>(); - if (smallScaleCommercialTrafficType.equals(GenerateSmallScaleCommercialTrafficDemand.SmallScaleCommercialTrafficType.commercialPersonTraffic.toString())) { + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 0.0, 30.0), 0.0005917893035900173)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 30.0, 60.0), 0.00021859484237437887)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 90.0, 120.0), 0.00037490287407786324)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 120.0, 180.0), 0.0004337321926125666)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 180.0, 240.0), 0.0005834182239827621)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 240.0, 300.0), 0.0005116938323661723)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 300.0, 360.0), 0.0005027065159573272)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 360.0, 420.0), 0.0006719740164147071)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 420.0, 480.0), 0.00022375027665644004)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 480.0, 540.0), 0.00022103749529549306)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 540.0, 600.0), 0.00022119440831885122)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 600.0, 660.0), 0.0002732185104003396)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 660.0, 720.0), 7.287567629774946e-05)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 720.0, 780.0), 0.0005090670761685264)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 780.0, 840.0), 0.0002169454122557984)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 840.0, 1080.0), 0.0016947794402011696)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 0.0, 30.0), 0.00033050926084770643)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 30.0, 60.0), 0.0004963985976117265)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 60.0, 90.0), 0.0009458837608304906)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 90.0, 120.0), 0.0006507941771038976)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 120.0, 180.0), 0.0002949035696660126)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 180.0, 240.0), 0.0005812406149568905)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 240.0, 300.0), 0.00072666224822023)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 300.0, 360.0), 0.0006017750128936798)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 360.0, 420.0), 0.0007696491628020603)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 420.0, 480.0), 0.0006951014583380694)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 480.0, 540.0), 0.0006675367479652174)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 540.0, 600.0), 0.0009951412624367468)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 600.0, 660.0), 0.0006193958232902363)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 660.0, 720.0), 0.0005496335422364244)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 720.0, 780.0), 0.000963763774344583)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 780.0, 840.0), 0.001585152586657775)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 840.0, 1080.0), 0.0022779973751500433)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 0.0, 30.0), 0.003678291745870938)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 30.0, 60.0), 0.0037749680865755936)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 60.0, 90.0), 0.0021464058981758467)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 90.0, 120.0), 0.0010105726369455444)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 120.0, 180.0), 0.0017166729332290624)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 180.0, 240.0), 0.001218657902054598)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 240.0, 300.0), 0.0019212859349972463)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 300.0, 360.0), 0.0018498349748915703)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 360.0, 420.0), 0.0020820722844894844)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 420.0, 480.0), 0.0033255032578691536)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 480.0, 540.0), 0.004499580798913233)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 540.0, 600.0), 0.004508722079694882)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 600.0, 660.0), 0.009460453046374911)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 660.0, 720.0), 0.008632039128635343)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 720.0, 780.0), 0.005173130409039029)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 780.0, 840.0), 0.0021287189901771954)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 840.0, 1080.0), 0.002735246591728173)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 0.0, 30.0), 0.015534599731489868)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 30.0, 60.0), 0.009424737666749776)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 60.0, 90.0), 0.003979757502241877)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 90.0, 120.0), 0.0026219034509082214)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 120.0, 180.0), 0.004373894821911171)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 180.0, 240.0), 0.005349695968407728)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 240.0, 300.0), 0.008398668008895199)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 300.0, 360.0), 0.013017576110359298)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 360.0, 420.0), 0.013178466937493282)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 420.0, 480.0), 0.015799261066253244)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 480.0, 540.0), 0.031932993774084484)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 540.0, 600.0), 0.056976770375347194)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 600.0, 660.0), 0.03411514635058722)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 660.0, 720.0), 0.010952547256934878)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 720.0, 780.0), 0.005071677294689363)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 780.0, 840.0), 0.002758017802376135)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 840.0, 1080.0), 0.003182481371327368)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 0.0, 30.0), 0.018010507239762663)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 30.0, 60.0), 0.009246211080247332)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 60.0, 90.0), 0.006297103845359016)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 90.0, 120.0), 0.003415561088528113)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 120.0, 180.0), 0.010918022744746231)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 180.0, 240.0), 0.011371721163141522)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 240.0, 300.0), 0.01861910064916215)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 300.0, 360.0), 0.015443374909900384)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 360.0, 420.0), 0.020470726990450452)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 420.0, 480.0), 0.030727618880727087)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 480.0, 540.0), 0.07364088624635841)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 540.0, 600.0), 0.04082061588575034)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 600.0, 660.0), 0.012935881167590665)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 660.0, 720.0), 0.005469250367916343)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 720.0, 780.0), 0.0030030673084490513)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 780.0, 840.0), 0.0011042643367551329)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 840.0, 1080.0), 0.0011327583672022575)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 0.0, 30.0), 0.015589932735904798)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 30.0, 60.0), 0.007157798082590814)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 60.0, 90.0), 0.006563655710107534)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 90.0, 120.0), 0.004888423230467872)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 120.0, 180.0), 0.01261126944262904)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 180.0, 240.0), 0.013275311108363174)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 240.0, 300.0), 0.011059737216827653)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 300.0, 360.0), 0.00980644443311104)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 360.0, 420.0), 0.013476523854959467)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 420.0, 480.0), 0.01766932338862498)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 480.0, 540.0), 0.013855266610087914)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 540.0, 600.0), 0.006090238569895901)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 600.0, 660.0), 0.00326688741194661)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 660.0, 720.0), 0.0009742217966822537)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 720.0, 780.0), 0.0008462163162537791)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 780.0, 840.0), 0.0009357453082055104)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 840.0, 1080.0), 0.0006867783494497427)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 0.0, 30.0), 0.011836581569331607)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 30.0, 60.0), 0.0060475163532472224)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 60.0, 90.0), 0.006091033719221284)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 90.0, 120.0), 0.004870323217391879)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 120.0, 180.0), 0.009852214102720915)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 180.0, 240.0), 0.006649077724867284)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 240.0, 300.0), 0.006549809619698136)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 300.0, 360.0), 0.00743649188225418)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 360.0, 420.0), 0.008370330719772223)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 420.0, 480.0), 0.006055410372169952)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 480.0, 540.0), 0.003221026290023441)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 540.0, 600.0), 0.00270804359225063)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 600.0, 660.0), 0.0011328763880567346)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 660.0, 720.0), 0.0005295062815147344)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 720.0, 780.0), 0.0005244739409173669)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 780.0, 840.0), 0.00022261373811852168)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 840.0, 1080.0), 0.0002976820307410009)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 0.0, 30.0), 0.0072347359578799255)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 30.0, 60.0), 0.005528762818372258)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 60.0, 90.0), 0.004301874597910846)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 90.0, 120.0), 0.002706271535768685)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 120.0, 180.0), 0.004461225555303183)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 180.0, 240.0), 0.003289266637558867)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 240.0, 300.0), 0.004773112389257731)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 300.0, 360.0), 0.004153307715767419)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 360.0, 420.0), 0.0023002274828502435)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 420.0, 480.0), 0.002295722460734858)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 480.0, 540.0), 0.0008008191218782178)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 540.0, 600.0), 0.0005302938593833011)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 600.0, 660.0), 0.00012017333498779025)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 660.0, 720.0), 0.00029497120761336085)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 720.0, 780.0), 7.442207741095891e-05)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 780.0, 840.0), 7.491510042413546e-05)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(11, 12, 0.0, 30.0), 0.005979044848708125)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(11, 12, 30.0, 60.0), 0.0030727725862362003)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(11, 12, 60.0, 90.0), 0.0018328582061095421)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(11, 12, 90.0, 120.0), 0.0015730248216810105)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(11, 12, 120.0, 180.0), 0.0025909176745678485)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(11, 12, 180.0, 240.0), 0.0023584284876344117)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(11, 12, 240.0, 300.0), 0.002888683132930499)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(11, 12, 300.0, 360.0), 0.0026723295114103734)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(11, 12, 360.0, 420.0), 0.001368034507711622)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(11, 12, 420.0, 480.0), 0.001322142609646873)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(11, 12, 480.0, 540.0), 0.00014896322977011863)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(11, 12, 540.0, 600.0), 0.00036793050573151096)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(11, 12, 600.0, 660.0), 0.0003024749417379503)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(11, 12, 660.0, 720.0), 7.263766179594998e-05)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(11, 12, 720.0, 780.0), 7.737798495114381e-05)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(11, 12, 840.0, 1080.0), 7.360037219024495e-05)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(12, 13, 0.0, 30.0), 0.005442934607459622)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(12, 13, 30.0, 60.0), 0.0023099603288455053)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(12, 13, 60.0, 90.0), 0.0015476125810207045)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(12, 13, 90.0, 120.0), 0.0015690710859882222)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(12, 13, 120.0, 180.0), 0.003155552178314994)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(12, 13, 180.0, 240.0), 0.0024715148201473933)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(12, 13, 240.0, 300.0), 0.00214638868043489)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(12, 13, 300.0, 360.0), 0.0017134793037846727)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(12, 13, 360.0, 420.0), 0.0009684921868733149)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(12, 13, 420.0, 480.0), 0.0005519992558366529)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(12, 13, 480.0, 540.0), 0.0004441672064981391)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(12, 13, 540.0, 600.0), 0.00022332686365997108)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(12, 13, 600.0, 660.0), 0.00023780343565208111)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(12, 13, 660.0, 720.0), 0.00014898555439278127)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(13, 14, 0.0, 30.0), 0.0065652971880044205)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(13, 14, 30.0, 60.0), 0.0033645458423904226)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(13, 14, 60.0, 90.0), 0.002247264924524252)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(13, 14, 90.0, 120.0), 0.0021755851670695867)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(13, 14, 120.0, 180.0), 0.00292250684836152)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(13, 14, 180.0, 240.0), 0.0029939610328467135)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(13, 14, 240.0, 300.0), 0.0013771262994841458)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(13, 14, 300.0, 360.0), 0.0005929387919824101)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(13, 14, 360.0, 420.0), 0.0007299574379337656)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(13, 14, 420.0, 480.0), 0.00015161310680499916)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(13, 14, 480.0, 540.0), 0.00022326623210165028)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(13, 14, 540.0, 600.0), 0.00021908720500178134)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(14, 15, 0.0, 30.0), 0.004700575755513116)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(14, 15, 30.0, 60.0), 0.002876930233578738)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(14, 15, 60.0, 90.0), 0.0012326059557891803)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(14, 15, 90.0, 120.0), 0.001688513011030605)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(14, 15, 120.0, 180.0), 0.0024148215923521744)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(14, 15, 180.0, 240.0), 0.0009664823712470381)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(14, 15, 240.0, 300.0), 0.0008158516384741175)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(14, 15, 300.0, 360.0), 0.0005326476409500361)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(14, 15, 360.0, 420.0), 0.00037447250704764534)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(14, 15, 420.0, 480.0), 7.278074100962308e-05)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(14, 15, 480.0, 540.0), 0.00015460621875651884)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(14, 15, 540.0, 600.0), 0.00022625636961834557)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(14, 15, 840.0, 1080.0), 7.369704340227916e-05)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(15, 16, 0.0, 30.0), 0.005421542133242069)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(15, 16, 30.0, 60.0), 0.0028543297205245563)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(15, 16, 60.0, 90.0), 0.001320449445343739)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(15, 16, 90.0, 120.0), 0.0011372744623221703)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(15, 16, 120.0, 180.0), 0.0011175546229352943)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(15, 16, 180.0, 240.0), 0.0005212091408906178)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(15, 16, 240.0, 300.0), 0.00025063117439263165)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(15, 16, 300.0, 360.0), 0.0002906557976189996)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(15, 16, 360.0, 420.0), 6.934683987097806e-05)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(15, 16, 420.0, 480.0), 7.198332684426051e-05)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(16, 17, 0.0, 30.0), 0.005997678933359281)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(16, 17, 30.0, 60.0), 0.0014450238860978966)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(16, 17, 60.0, 90.0), 0.0008909835110546583)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(16, 17, 90.0, 120.0), 0.0008692603958852261)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(16, 17, 120.0, 180.0), 0.0004645626068627116)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(16, 17, 180.0, 240.0), 0.0005161866418057845)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(16, 17, 240.0, 300.0), 0.00047492492382272117)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(16, 17, 300.0, 360.0), 7.348989097075777e-05)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(16, 17, 360.0, 420.0), 0.0003000342936128893)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(17, 18, 0.0, 30.0), 0.004621906661329853)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(17, 18, 30.0, 60.0), 0.0015152391398060199)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(17, 18, 60.0, 90.0), 0.0006769045119123614)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(17, 18, 90.0, 120.0), 0.00044820275277284946)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(17, 18, 120.0, 180.0), 0.0007140653752077821)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(17, 18, 180.0, 240.0), 0.0001502672132808765)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(17, 18, 240.0, 300.0), 0.0003842231300012746)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(17, 18, 300.0, 360.0), 0.00021634404805889257)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(18, 19, 0.0, 30.0), 0.0034023082743939916)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(18, 19, 30.0, 60.0), 0.0006251774232962365)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(18, 19, 60.0, 90.0), 0.00022163965781205308)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(18, 19, 90.0, 120.0), 7.360037219024495e-05)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(18, 19, 120.0, 180.0), 0.00045934601255169126)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(18, 19, 180.0, 240.0), 7.511874968194916e-05)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(18, 19, 240.0, 300.0), 0.0001486019187134722)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(18, 19, 300.0, 360.0), 7.505084488366769e-05)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(18, 19, 420.0, 480.0), 7.594714627228585e-05)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(19, 24, 0.0, 30.0), 0.005137034953520923)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(19, 24, 30.0, 60.0), 0.0010774703023578233)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(19, 24, 60.0, 90.0), 0.00048539418673270443)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(19, 24, 90.0, 120.0), 0.0002988049182984063)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(19, 24, 120.0, 180.0), 0.00032644209078127245)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(19, 24, 180.0, 240.0), 0.0005357497395368892)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(19, 24, 240.0, 300.0), 0.0002944914928100358)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(19, 24, 300.0, 360.0), 0.00022851651374757815)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 0.0, 30.0), 0.0005917893035900173)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 30.0, 60.0), 0.00021859484237437887)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 90.0, 120.0), 0.00037490287407786324)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 120.0, 180.0), 0.0004337321926125666)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 180.0, 240.0), 0.0005834182239827621)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 240.0, 300.0), 0.0005116938323661723)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 300.0, 360.0), 0.0005027065159573272)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 360.0, 420.0), 0.0006719740164147071)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 420.0, 480.0), 0.00022375027665644004)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 480.0, 540.0), 0.00022103749529549306)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 540.0, 600.0), 0.00022119440831885122)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 600.0, 660.0), 0.0002732185104003396)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 660.0, 720.0), 7.287567629774946e-05)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 720.0, 780.0), 0.0005090670761685264)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 780.0, 840.0), 0.0002169454122557984)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 840.0, 1080.0), 0.0016947794402011696)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 0.0, 30.0), 0.00033050926084770643)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 30.0, 60.0), 0.0004963985976117265)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 60.0, 90.0), 0.0009458837608304906)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 90.0, 120.0), 0.0006507941771038976)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 120.0, 180.0), 0.0002949035696660126)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 180.0, 240.0), 0.0005812406149568905)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 240.0, 300.0), 0.00072666224822023)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 300.0, 360.0), 0.0006017750128936798)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 360.0, 420.0), 0.0007696491628020603)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 420.0, 480.0), 0.0006951014583380694)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 480.0, 540.0), 0.0006675367479652174)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 540.0, 600.0), 0.0009951412624367468)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 600.0, 660.0), 0.0006193958232902363)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 660.0, 720.0), 0.0005496335422364244)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 720.0, 780.0), 0.000963763774344583)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 780.0, 840.0), 0.001585152586657775)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 840.0, 1080.0), 0.0022779973751500433)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 0.0, 30.0), 0.003678291745870938)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 30.0, 60.0), 0.0037749680865755936)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 60.0, 90.0), 0.0021464058981758467)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 90.0, 120.0), 0.0010105726369455444)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 120.0, 180.0), 0.0017166729332290624)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 180.0, 240.0), 0.001218657902054598)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 240.0, 300.0), 0.0019212859349972463)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 300.0, 360.0), 0.0018498349748915703)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 360.0, 420.0), 0.0020820722844894844)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 420.0, 480.0), 0.0033255032578691536)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 480.0, 540.0), 0.004499580798913233)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 540.0, 600.0), 0.004508722079694882)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 600.0, 660.0), 0.009460453046374911)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 660.0, 720.0), 0.008632039128635343)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 720.0, 780.0), 0.005173130409039029)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 780.0, 840.0), 0.0021287189901771954)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 840.0, 1080.0), 0.002735246591728173)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 0.0, 30.0), 0.015534599731489868)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 30.0, 60.0), 0.009424737666749776)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 60.0, 90.0), 0.003979757502241877)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 90.0, 120.0), 0.0026219034509082214)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 120.0, 180.0), 0.004373894821911171)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 180.0, 240.0), 0.005349695968407728)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 240.0, 300.0), 0.008398668008895199)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 300.0, 360.0), 0.013017576110359298)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 360.0, 420.0), 0.013178466937493282)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 420.0, 480.0), 0.015799261066253244)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 480.0, 540.0), 0.031932993774084484)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 540.0, 600.0), 0.056976770375347194)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 600.0, 660.0), 0.03411514635058722)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 660.0, 720.0), 0.010952547256934878)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 720.0, 780.0), 0.005071677294689363)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 780.0, 840.0), 0.002758017802376135)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 840.0, 1080.0), 0.003182481371327368)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 0.0, 30.0), 0.018010507239762663)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 30.0, 60.0), 0.009246211080247332)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 60.0, 90.0), 0.006297103845359016)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 90.0, 120.0), 0.003415561088528113)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 120.0, 180.0), 0.010918022744746231)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 180.0, 240.0), 0.011371721163141522)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 240.0, 300.0), 0.01861910064916215)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 300.0, 360.0), 0.015443374909900384)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 360.0, 420.0), 0.020470726990450452)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 420.0, 480.0), 0.030727618880727087)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 480.0, 540.0), 0.07364088624635841)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 540.0, 600.0), 0.04082061588575034)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 600.0, 660.0), 0.012935881167590665)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 660.0, 720.0), 0.005469250367916343)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 720.0, 780.0), 0.0030030673084490513)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 780.0, 840.0), 0.0011042643367551329)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 840.0, 1080.0), 0.0011327583672022575)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 0.0, 30.0), 0.015589932735904798)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 30.0, 60.0), 0.007157798082590814)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 60.0, 90.0), 0.006563655710107534)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 90.0, 120.0), 0.004888423230467872)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 120.0, 180.0), 0.01261126944262904)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 180.0, 240.0), 0.013275311108363174)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 240.0, 300.0), 0.011059737216827653)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 300.0, 360.0), 0.00980644443311104)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 360.0, 420.0), 0.013476523854959467)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 420.0, 480.0), 0.01766932338862498)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 480.0, 540.0), 0.013855266610087914)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 540.0, 600.0), 0.006090238569895901)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 600.0, 660.0), 0.00326688741194661)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 660.0, 720.0), 0.0009742217966822537)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 720.0, 780.0), 0.0008462163162537791)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 780.0, 840.0), 0.0009357453082055104)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 840.0, 1080.0), 0.0006867783494497427)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 0.0, 30.0), 0.011836581569331607)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 30.0, 60.0), 0.0060475163532472224)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 60.0, 90.0), 0.006091033719221284)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 90.0, 120.0), 0.004870323217391879)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 120.0, 180.0), 0.009852214102720915)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 180.0, 240.0), 0.006649077724867284)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 240.0, 300.0), 0.006549809619698136)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 300.0, 360.0), 0.00743649188225418)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 360.0, 420.0), 0.008370330719772223)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 420.0, 480.0), 0.006055410372169952)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 480.0, 540.0), 0.003221026290023441)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 540.0, 600.0), 0.00270804359225063)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 600.0, 660.0), 0.0011328763880567346)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 660.0, 720.0), 0.0005295062815147344)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 720.0, 780.0), 0.0005244739409173669)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 780.0, 840.0), 0.00022261373811852168)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 840.0, 1080.0), 0.0002976820307410009)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 0.0, 30.0), 0.0072347359578799255)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 30.0, 60.0), 0.005528762818372258)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 60.0, 90.0), 0.004301874597910846)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 90.0, 120.0), 0.002706271535768685)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 120.0, 180.0), 0.004461225555303183)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 180.0, 240.0), 0.003289266637558867)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 240.0, 300.0), 0.004773112389257731)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 300.0, 360.0), 0.004153307715767419)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 360.0, 420.0), 0.0023002274828502435)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 420.0, 480.0), 0.002295722460734858)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 480.0, 540.0), 0.0008008191218782178)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 540.0, 600.0), 0.0005302938593833011)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 600.0, 660.0), 0.00012017333498779025)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 660.0, 720.0), 0.00029497120761336085)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 720.0, 780.0), 7.442207741095891e-05)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 780.0, 840.0), 7.491510042413546e-05)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(11, 12, 0.0, 30.0), 0.005979044848708125)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(11, 12, 30.0, 60.0), 0.0030727725862362003)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(11, 12, 60.0, 90.0), 0.0018328582061095421)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(11, 12, 90.0, 120.0), 0.0015730248216810105)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(11, 12, 120.0, 180.0), 0.0025909176745678485)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(11, 12, 180.0, 240.0), 0.0023584284876344117)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(11, 12, 240.0, 300.0), 0.002888683132930499)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(11, 12, 300.0, 360.0), 0.0026723295114103734)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(11, 12, 360.0, 420.0), 0.001368034507711622)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(11, 12, 420.0, 480.0), 0.001322142609646873)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(11, 12, 480.0, 540.0), 0.00014896322977011863)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(11, 12, 540.0, 600.0), 0.00036793050573151096)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(11, 12, 600.0, 660.0), 0.0003024749417379503)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(11, 12, 660.0, 720.0), 7.263766179594998e-05)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(11, 12, 720.0, 780.0), 7.737798495114381e-05)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(11, 12, 840.0, 1080.0), 7.360037219024495e-05)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(12, 13, 0.0, 30.0), 0.005442934607459622)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(12, 13, 30.0, 60.0), 0.0023099603288455053)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(12, 13, 60.0, 90.0), 0.0015476125810207045)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(12, 13, 90.0, 120.0), 0.0015690710859882222)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(12, 13, 120.0, 180.0), 0.003155552178314994)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(12, 13, 180.0, 240.0), 0.0024715148201473933)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(12, 13, 240.0, 300.0), 0.00214638868043489)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(12, 13, 300.0, 360.0), 0.0017134793037846727)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(12, 13, 360.0, 420.0), 0.0009684921868733149)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(12, 13, 420.0, 480.0), 0.0005519992558366529)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(12, 13, 480.0, 540.0), 0.0004441672064981391)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(12, 13, 540.0, 600.0), 0.00022332686365997108)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(12, 13, 600.0, 660.0), 0.00023780343565208111)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(12, 13, 660.0, 720.0), 0.00014898555439278127)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(13, 14, 0.0, 30.0), 0.0065652971880044205)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(13, 14, 30.0, 60.0), 0.0033645458423904226)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(13, 14, 60.0, 90.0), 0.002247264924524252)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(13, 14, 90.0, 120.0), 0.0021755851670695867)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(13, 14, 120.0, 180.0), 0.00292250684836152)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(13, 14, 180.0, 240.0), 0.0029939610328467135)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(13, 14, 240.0, 300.0), 0.0013771262994841458)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(13, 14, 300.0, 360.0), 0.0005929387919824101)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(13, 14, 360.0, 420.0), 0.0007299574379337656)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(13, 14, 420.0, 480.0), 0.00015161310680499916)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(13, 14, 480.0, 540.0), 0.00022326623210165028)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(13, 14, 540.0, 600.0), 0.00021908720500178134)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(14, 15, 0.0, 30.0), 0.004700575755513116)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(14, 15, 30.0, 60.0), 0.002876930233578738)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(14, 15, 60.0, 90.0), 0.0012326059557891803)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(14, 15, 90.0, 120.0), 0.001688513011030605)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(14, 15, 120.0, 180.0), 0.0024148215923521744)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(14, 15, 180.0, 240.0), 0.0009664823712470381)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(14, 15, 240.0, 300.0), 0.0008158516384741175)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(14, 15, 300.0, 360.0), 0.0005326476409500361)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(14, 15, 360.0, 420.0), 0.00037447250704764534)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(14, 15, 420.0, 480.0), 7.278074100962308e-05)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(14, 15, 480.0, 540.0), 0.00015460621875651884)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(14, 15, 540.0, 600.0), 0.00022625636961834557)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(14, 15, 840.0, 1080.0), 7.369704340227916e-05)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(15, 16, 0.0, 30.0), 0.005421542133242069)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(15, 16, 30.0, 60.0), 0.0028543297205245563)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(15, 16, 60.0, 90.0), 0.001320449445343739)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(15, 16, 90.0, 120.0), 0.0011372744623221703)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(15, 16, 120.0, 180.0), 0.0011175546229352943)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(15, 16, 180.0, 240.0), 0.0005212091408906178)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(15, 16, 240.0, 300.0), 0.00025063117439263165)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(15, 16, 300.0, 360.0), 0.0002906557976189996)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(15, 16, 360.0, 420.0), 6.934683987097806e-05)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(15, 16, 420.0, 480.0), 7.198332684426051e-05)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(16, 17, 0.0, 30.0), 0.005997678933359281)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(16, 17, 30.0, 60.0), 0.0014450238860978966)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(16, 17, 60.0, 90.0), 0.0008909835110546583)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(16, 17, 90.0, 120.0), 0.0008692603958852261)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(16, 17, 120.0, 180.0), 0.0004645626068627116)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(16, 17, 180.0, 240.0), 0.0005161866418057845)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(16, 17, 240.0, 300.0), 0.00047492492382272117)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(16, 17, 300.0, 360.0), 7.348989097075777e-05)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(16, 17, 360.0, 420.0), 0.0003000342936128893)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(17, 18, 0.0, 30.0), 0.004621906661329853)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(17, 18, 30.0, 60.0), 0.0015152391398060199)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(17, 18, 60.0, 90.0), 0.0006769045119123614)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(17, 18, 90.0, 120.0), 0.00044820275277284946)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(17, 18, 120.0, 180.0), 0.0007140653752077821)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(17, 18, 180.0, 240.0), 0.0001502672132808765)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(17, 18, 240.0, 300.0), 0.0003842231300012746)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(17, 18, 300.0, 360.0), 0.00021634404805889257)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(18, 19, 0.0, 30.0), 0.0034023082743939916)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(18, 19, 30.0, 60.0), 0.0006251774232962365)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(18, 19, 60.0, 90.0), 0.00022163965781205308)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(18, 19, 90.0, 120.0), 7.360037219024495e-05)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(18, 19, 120.0, 180.0), 0.00045934601255169126)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(18, 19, 180.0, 240.0), 7.511874968194916e-05)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(18, 19, 240.0, 300.0), 0.0001486019187134722)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(18, 19, 300.0, 360.0), 7.505084488366769e-05)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(18, 19, 420.0, 480.0), 7.594714627228585e-05)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(19, 24, 0.0, 30.0), 0.005137034953520923)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(19, 24, 30.0, 60.0), 0.0010774703023578233)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(19, 24, 60.0, 90.0), 0.00048539418673270443)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(19, 24, 90.0, 120.0), 0.0002988049182984063)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(19, 24, 120.0, 180.0), 0.00032644209078127245)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(19, 24, 180.0, 240.0), 0.0005357497395368892)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(19, 24, 240.0, 300.0), 0.0002944914928100358)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(19, 24, 300.0, 360.0), 0.00022851651374757815)); - } - else if (smallScaleCommercialTrafficType.equals(GenerateSmallScaleCommercialTrafficDemand.SmallScaleCommercialTrafficType.goodsTraffic.toString())) { + tourDistribution.put(GenerateSmallScaleCommercialTrafficDemand.SmallScaleCommercialTrafficType.commercialPersonTraffic.toString(), + new EnumeratedDistribution<>(rng, tourDurationProbabilityDistribution)); + tourDurationProbabilityDistribution.clear(); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 0.0, 30.0), 0.0002666800577200411)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 30.0, 60.0), 0.0006395055678719748)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 60.0, 90.0), 0.0007110769046958423)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 90.0, 120.0), 0.0006665961628449491)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 120.0, 180.0), 0.0023195866923785575)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 180.0, 240.0), 0.00261751319938476)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 240.0, 300.0), 0.0021430032453503087)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 300.0, 360.0), 0.0029303876579925905)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 360.0, 420.0), 0.00283576618143643)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 420.0, 480.0), 0.0027188265347502893)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 480.0, 540.0), 0.002597768116531099)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 540.0, 600.0), 0.002659151494701916)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 600.0, 660.0), 0.0021738406044924437)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 660.0, 720.0), 0.0021949848461843176)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 720.0, 780.0), 0.0021801193011023083)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 780.0, 840.0), 0.001746033717539671)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 840.0, 1080.0), 0.00350888397405923)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 0.0, 30.0), 0.0006845643884312735)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 30.0, 60.0), 0.0004003126952082357)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 60.0, 90.0), 0.0008155012585632697)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 90.0, 120.0), 0.0010930534970200114)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 120.0, 180.0), 0.0011760353713952051)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 180.0, 240.0), 0.0019364061980548415)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 240.0, 300.0), 0.002953452881036028)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 300.0, 360.0), 0.002589370165068672)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 360.0, 420.0), 0.0025604405819583055)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 420.0, 480.0), 0.0034319041631081476)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 480.0, 540.0), 0.0033480025727905907)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 540.0, 600.0), 0.002175717502193024)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 600.0, 660.0), 0.0028036478238686957)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 660.0, 720.0), 0.0028759635193342887)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 720.0, 780.0), 0.0017584406503249872)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 780.0, 840.0), 0.0016742001219093045)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 840.0, 1080.0), 0.0020658205220468245)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 0.0, 30.0), 0.0017247403950228777)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 30.0, 60.0), 0.003090998236080484)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 60.0, 90.0), 0.0015209554995803177)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 90.0, 120.0), 0.0016533392810110293)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 120.0, 180.0), 0.003732306124403562)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 180.0, 240.0), 0.004106247357091271)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 240.0, 300.0), 0.003188442431357427)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 300.0, 360.0), 0.005929370570550301)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 360.0, 420.0), 0.005992695595693005)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 420.0, 480.0), 0.006390572360276255)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 480.0, 540.0), 0.00993732232424166)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 540.0, 600.0), 0.007917613781985494)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 600.0, 660.0), 0.00753055040114282)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 660.0, 720.0), 0.004839531706746983)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 720.0, 780.0), 0.003571294178536547)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 780.0, 840.0), 0.0022261075091276465)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 840.0, 1080.0), 0.0020123396391017526)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 0.0, 30.0), 0.00553085745500388)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 30.0, 60.0), 0.005164301035284355)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 60.0, 90.0), 0.0034287284279468384)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 90.0, 120.0), 0.003359657704287739)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 120.0, 180.0), 0.005963896679549981)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 180.0, 240.0), 0.006376396116305889)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 240.0, 300.0), 0.011553162434249647)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 300.0, 360.0), 0.01216390369869719)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 360.0, 420.0), 0.015303642980241483)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 420.0, 480.0), 0.01894502604909179)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 480.0, 540.0), 0.026995818384739457)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 540.0, 600.0), 0.03735238580259259)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 600.0, 660.0), 0.02007351137947408)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 660.0, 720.0), 0.007579189226621267)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 720.0, 780.0), 0.003806896198418994)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 780.0, 840.0), 0.0020371212990837376)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 840.0, 1080.0), 0.00246729057836831)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 0.0, 30.0), 0.007834929725170775)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 30.0, 60.0), 0.007875284751511802)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 60.0, 90.0), 0.0056369706407995695)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 90.0, 120.0), 0.007252792818630801)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 120.0, 180.0), 0.011595289158181222)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 180.0, 240.0), 0.01584695155572567)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 240.0, 300.0), 0.019385993489144607)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 300.0, 360.0), 0.01804569113072999)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 360.0, 420.0), 0.020338168968415053)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 420.0, 480.0), 0.03244941203821404)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 480.0, 540.0), 0.046986423884473)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 540.0, 600.0), 0.026127574804977814)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 600.0, 660.0), 0.006859707180170414)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 660.0, 720.0), 0.004053368732850601)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 720.0, 780.0), 0.0017728320836715625)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 780.0, 840.0), 0.0008117046283836942)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 840.0, 1080.0), 0.0014889766393137468)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 0.0, 30.0), 0.008702611915372131)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 30.0, 60.0), 0.009703391735884857)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 60.0, 90.0), 0.00833249802530372)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 90.0, 120.0), 0.008160824294542027)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 120.0, 180.0), 0.014522058792957903)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 180.0, 240.0), 0.019189639247661674)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 240.0, 300.0), 0.022628081955363144)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 300.0, 360.0), 0.018168175275565253)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 360.0, 420.0), 0.01830766579908246)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 420.0, 480.0), 0.022414786327228577)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 480.0, 540.0), 0.015454698179801149)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 540.0, 600.0), 0.00743339793333549)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 600.0, 660.0), 0.0028959167218627997)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 660.0, 720.0), 0.0011608823477359163)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 720.0, 780.0), 0.0006126324367099846)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 780.0, 840.0), 0.0007090395380022889)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 840.0, 1080.0), 0.0009650931773638335)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 0.0, 30.0), 0.010532384705529854)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 30.0, 60.0), 0.010106787618396446)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 60.0, 90.0), 0.007305519187631069)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 90.0, 120.0), 0.0065298278976416635)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 120.0, 180.0), 0.012991661099288086)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 180.0, 240.0), 0.011082392048301831)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 240.0, 300.0), 0.013735041027849332)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 300.0, 360.0), 0.012921165569106639)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 360.0, 420.0), 0.010187951930469277)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 420.0, 480.0), 0.0070071162811467125)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 480.0, 540.0), 0.003478434072337058)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 540.0, 600.0), 0.002487434148850001)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 600.0, 660.0), 0.0007617139935295275)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 660.0, 720.0), 0.0004794259473854554)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 720.0, 780.0), 0.00011828408353297643)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 780.0, 840.0), 0.0009221448817170415)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 0.0, 30.0), 0.0053803765038808364)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 30.0, 60.0), 0.00748440387556175)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 60.0, 90.0), 0.003817044622559703)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 90.0, 120.0), 0.0042559767658946045)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 120.0, 180.0), 0.004633517730561146)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 180.0, 240.0), 0.0040156278424527785)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 240.0, 300.0), 0.004097425621422603)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 300.0, 360.0), 0.00534407493573042)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 360.0, 420.0), 0.002849425985304954)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 420.0, 480.0), 0.0024443772372422234)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 480.0, 540.0), 0.0011258612568464076)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 540.0, 600.0), 0.0005966047093584399)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 600.0, 660.0), 0.0005779388889435179)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 660.0, 720.0), 0.0004527621290439082)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 720.0, 780.0), 0.00011727646428602624)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 780.0, 840.0), 0.00011130198744577025)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(11, 12, 0.0, 30.0), 0.0025301846046864363)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(11, 12, 30.0, 60.0), 0.002932856090944951)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(11, 12, 60.0, 90.0), 0.0015297442159744696)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(11, 12, 90.0, 120.0), 0.0016816440829740813)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(11, 12, 120.0, 180.0), 0.0023140070407952395)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(11, 12, 180.0, 240.0), 0.0013768767086426792)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(11, 12, 240.0, 300.0), 0.0019019317686819275)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(11, 12, 300.0, 360.0), 0.0015577691125463963)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(11, 12, 360.0, 420.0), 0.001499121306916632)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(11, 12, 420.0, 480.0), 0.0007361366421130972)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(11, 12, 480.0, 540.0), 0.0007423049940853575)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(11, 12, 540.0, 600.0), 0.00011130198744577025)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(11, 12, 660.0, 720.0), 0.00024243947114654707)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(11, 12, 720.0, 780.0), 0.000261579996858755)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(12, 13, 0.0, 30.0), 0.0021669594044717543)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(12, 13, 30.0, 60.0), 0.0033993161916113994)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(12, 13, 60.0, 90.0), 0.001870484877697732)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(12, 13, 90.0, 120.0), 0.0008448185262884799)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(12, 13, 120.0, 180.0), 0.002024573233571085)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(12, 13, 180.0, 240.0), 0.0021888099857994042)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(12, 13, 240.0, 300.0), 0.0021657834323017752)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(12, 13, 300.0, 360.0), 0.0010623089332746248)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(12, 13, 360.0, 420.0), 0.0006268095760401356)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(12, 13, 420.0, 480.0), 0.0005094532977538987)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(12, 13, 480.0, 540.0), 0.0004744090926784203)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(12, 13, 540.0, 600.0), 0.00016487328572417658)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(12, 13, 660.0, 720.0), 0.0001162996982120756)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(13, 14, 0.0, 30.0), 0.0033401411497772818)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(13, 14, 30.0, 60.0), 0.002492685695459365)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(13, 14, 60.0, 90.0), 0.0027064477589805068)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(13, 14, 90.0, 120.0), 0.0018052297053924354)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(13, 14, 120.0, 180.0), 0.0027984509294891498)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(13, 14, 180.0, 240.0), 0.0022758505657711914)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(13, 14, 240.0, 300.0), 0.0003535503655144059)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(13, 14, 300.0, 360.0), 0.0005890430396050117)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(13, 14, 360.0, 420.0), 0.0002319134363595028)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(13, 14, 420.0, 480.0), 0.00011617748025141993)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(13, 14, 480.0, 540.0), 0.0003690064941818713)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(13, 14, 540.0, 600.0), 0.0001650495071007077)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(13, 14, 600.0, 660.0), 0.00023113252306835525)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(13, 14, 840.0, 1080.0), 0.00017239206443126303)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(14, 15, 0.0, 30.0), 0.003543871129770451)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(14, 15, 30.0, 60.0), 0.0018407982276338393)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(14, 15, 60.0, 90.0), 0.0010649270862293423)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(14, 15, 90.0, 120.0), 0.0009538696044712171)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(14, 15, 120.0, 180.0), 0.0021318639289119572)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(14, 15, 180.0, 240.0), 0.0019740243143620277)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(14, 15, 240.0, 300.0), 0.0006157677659961421)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(14, 15, 300.0, 360.0), 0.0004035374922773149)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(14, 15, 360.0, 420.0), 0.00011607019237524387)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(14, 15, 420.0, 480.0), 0.0003938282727195195)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(14, 15, 480.0, 540.0), 0.00011130198744577025)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(14, 15, 600.0, 660.0), 0.00011942109323430472)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(15, 16, 0.0, 30.0), 0.00254340964132742)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(15, 16, 30.0, 60.0), 0.0017847751078888892)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(15, 16, 60.0, 90.0), 0.000841891386995212)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(15, 16, 90.0, 120.0), 0.0003543852337006742)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(15, 16, 120.0, 180.0), 0.0013974221085794884)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(15, 16, 180.0, 240.0), 0.0006229273683665316)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(15, 16, 240.0, 300.0), 0.00020579571489011056)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(15, 16, 300.0, 360.0), 0.0004809214516599411)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(15, 16, 360.0, 420.0), 0.00022514291890117063)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(15, 16, 420.0, 480.0), 0.00014748146383900364)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(15, 16, 720.0, 780.0), 0.00011605559293173729)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(16, 17, 0.0, 30.0), 0.0019634787835054656)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(16, 17, 30.0, 60.0), 0.000860670737476427)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(16, 17, 60.0, 90.0), 0.0003550148096943092)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(16, 17, 90.0, 120.0), 0.000855728546868917)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(16, 17, 120.0, 180.0), 0.0009283998993093458)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(16, 17, 180.0, 240.0), 0.00022795178106384156)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(16, 17, 240.0, 300.0), 0.00024119874825349313)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(16, 17, 420.0, 480.0), 0.00023429279224671318)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(16, 17, 480.0, 540.0), 0.00011727269965059726)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(16, 17, 660.0, 720.0), 0.00011130198744577025)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(17, 18, 0.0, 30.0), 0.0017099830161073832)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(17, 18, 30.0, 60.0), 0.0006015092064895483)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(17, 18, 60.0, 90.0), 0.00011819436012345105)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(17, 18, 90.0, 120.0), 0.0002279569151752547)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(17, 18, 120.0, 180.0), 0.0006440525787748041)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(17, 18, 180.0, 240.0), 0.0003142746964600832)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(17, 18, 300.0, 360.0), 0.00022788575876606104)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(17, 18, 360.0, 420.0), 0.0004761806298753505)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(17, 18, 480.0, 540.0), 0.00011727269965059726)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(18, 19, 0.0, 30.0), 0.0020011795184968267)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(18, 19, 30.0, 60.0), 0.00023620950461199452)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(18, 19, 60.0, 90.0), 0.00011935825257957617)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(18, 19, 90.0, 120.0), 0.00011130198744577025)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(18, 19, 120.0, 180.0), 0.00012222981614916706)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(18, 19, 180.0, 240.0), 0.0002377005397786721)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(18, 19, 240.0, 300.0), 0.00026373526728965034)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(18, 19, 300.0, 360.0), 0.000256086036315955)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(18, 19, 360.0, 420.0), 0.00011394287938236544)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(19, 24, 0.0, 30.0), 0.0021116872169622083)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(19, 24, 30.0, 60.0), 0.0003681765715703113)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(19, 24, 60.0, 90.0), 0.0004137833254678062)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(19, 24, 90.0, 120.0), 0.00025108497234833097)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(19, 24, 120.0, 180.0), 0.0007576827338029722)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(19, 24, 180.0, 240.0), 0.0005180490039062906)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(19, 24, 240.0, 300.0), 0.0004944106124208977)); - tourDurationProbabilityDistribution.add(Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(19, 24, 300.0, 360.0), 0.0002278857587658224)); - } else - throw new IllegalArgumentException("Unknown small scale commercial traffic type: " + smallScaleCommercialTrafficType); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 0.0, 30.0), 0.0002666800577200411)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 30.0, 60.0), 0.0006395055678719748)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 60.0, 90.0), 0.0007110769046958423)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 90.0, 120.0), 0.0006665961628449491)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 120.0, 180.0), 0.0023195866923785575)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 180.0, 240.0), 0.00261751319938476)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 240.0, 300.0), 0.0021430032453503087)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 300.0, 360.0), 0.0029303876579925905)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 360.0, 420.0), 0.00283576618143643)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 420.0, 480.0), 0.0027188265347502893)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 480.0, 540.0), 0.002597768116531099)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 540.0, 600.0), 0.002659151494701916)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 600.0, 660.0), 0.0021738406044924437)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 660.0, 720.0), 0.0021949848461843176)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 720.0, 780.0), 0.0021801193011023083)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 780.0, 840.0), 0.001746033717539671)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(0, 4, 840.0, 1080.0), 0.00350888397405923)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 0.0, 30.0), 0.0006845643884312735)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 30.0, 60.0), 0.0004003126952082357)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 60.0, 90.0), 0.0008155012585632697)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 90.0, 120.0), 0.0010930534970200114)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 120.0, 180.0), 0.0011760353713952051)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 180.0, 240.0), 0.0019364061980548415)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 240.0, 300.0), 0.002953452881036028)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 300.0, 360.0), 0.002589370165068672)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 360.0, 420.0), 0.0025604405819583055)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 420.0, 480.0), 0.0034319041631081476)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 480.0, 540.0), 0.0033480025727905907)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 540.0, 600.0), 0.002175717502193024)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 600.0, 660.0), 0.0028036478238686957)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 660.0, 720.0), 0.0028759635193342887)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 720.0, 780.0), 0.0017584406503249872)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 780.0, 840.0), 0.0016742001219093045)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(4, 5, 840.0, 1080.0), 0.0020658205220468245)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 0.0, 30.0), 0.0017247403950228777)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 30.0, 60.0), 0.003090998236080484)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 60.0, 90.0), 0.0015209554995803177)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 90.0, 120.0), 0.0016533392810110293)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 120.0, 180.0), 0.003732306124403562)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 180.0, 240.0), 0.004106247357091271)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 240.0, 300.0), 0.003188442431357427)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 300.0, 360.0), 0.005929370570550301)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 360.0, 420.0), 0.005992695595693005)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 420.0, 480.0), 0.006390572360276255)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 480.0, 540.0), 0.00993732232424166)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 540.0, 600.0), 0.007917613781985494)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 600.0, 660.0), 0.00753055040114282)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 660.0, 720.0), 0.004839531706746983)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 720.0, 780.0), 0.003571294178536547)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 780.0, 840.0), 0.0022261075091276465)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(5, 6, 840.0, 1080.0), 0.0020123396391017526)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 0.0, 30.0), 0.00553085745500388)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 30.0, 60.0), 0.005164301035284355)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 60.0, 90.0), 0.0034287284279468384)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 90.0, 120.0), 0.003359657704287739)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 120.0, 180.0), 0.005963896679549981)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 180.0, 240.0), 0.006376396116305889)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 240.0, 300.0), 0.011553162434249647)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 300.0, 360.0), 0.01216390369869719)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 360.0, 420.0), 0.015303642980241483)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 420.0, 480.0), 0.01894502604909179)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 480.0, 540.0), 0.026995818384739457)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 540.0, 600.0), 0.03735238580259259)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 600.0, 660.0), 0.02007351137947408)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 660.0, 720.0), 0.007579189226621267)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 720.0, 780.0), 0.003806896198418994)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 780.0, 840.0), 0.0020371212990837376)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(6, 7, 840.0, 1080.0), 0.00246729057836831)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 0.0, 30.0), 0.007834929725170775)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 30.0, 60.0), 0.007875284751511802)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 60.0, 90.0), 0.0056369706407995695)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 90.0, 120.0), 0.007252792818630801)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 120.0, 180.0), 0.011595289158181222)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 180.0, 240.0), 0.01584695155572567)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 240.0, 300.0), 0.019385993489144607)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 300.0, 360.0), 0.01804569113072999)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 360.0, 420.0), 0.020338168968415053)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 420.0, 480.0), 0.03244941203821404)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 480.0, 540.0), 0.046986423884473)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 540.0, 600.0), 0.026127574804977814)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 600.0, 660.0), 0.006859707180170414)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 660.0, 720.0), 0.004053368732850601)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 720.0, 780.0), 0.0017728320836715625)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 780.0, 840.0), 0.0008117046283836942)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(7, 8, 840.0, 1080.0), 0.0014889766393137468)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 0.0, 30.0), 0.008702611915372131)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 30.0, 60.0), 0.009703391735884857)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 60.0, 90.0), 0.00833249802530372)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 90.0, 120.0), 0.008160824294542027)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 120.0, 180.0), 0.014522058792957903)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 180.0, 240.0), 0.019189639247661674)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 240.0, 300.0), 0.022628081955363144)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 300.0, 360.0), 0.018168175275565253)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 360.0, 420.0), 0.01830766579908246)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 420.0, 480.0), 0.022414786327228577)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 480.0, 540.0), 0.015454698179801149)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 540.0, 600.0), 0.00743339793333549)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 600.0, 660.0), 0.0028959167218627997)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 660.0, 720.0), 0.0011608823477359163)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 720.0, 780.0), 0.0006126324367099846)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 780.0, 840.0), 0.0007090395380022889)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(8, 9, 840.0, 1080.0), 0.0009650931773638335)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 0.0, 30.0), 0.010532384705529854)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 30.0, 60.0), 0.010106787618396446)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 60.0, 90.0), 0.007305519187631069)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 90.0, 120.0), 0.0065298278976416635)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 120.0, 180.0), 0.012991661099288086)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 180.0, 240.0), 0.011082392048301831)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 240.0, 300.0), 0.013735041027849332)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 300.0, 360.0), 0.012921165569106639)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 360.0, 420.0), 0.010187951930469277)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 420.0, 480.0), 0.0070071162811467125)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 480.0, 540.0), 0.003478434072337058)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 540.0, 600.0), 0.002487434148850001)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 600.0, 660.0), 0.0007617139935295275)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 660.0, 720.0), 0.0004794259473854554)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 720.0, 780.0), 0.00011828408353297643)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(9, 10, 780.0, 840.0), 0.0009221448817170415)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 0.0, 30.0), 0.0053803765038808364)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 30.0, 60.0), 0.00748440387556175)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 60.0, 90.0), 0.003817044622559703)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 90.0, 120.0), 0.0042559767658946045)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 120.0, 180.0), 0.004633517730561146)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 180.0, 240.0), 0.0040156278424527785)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 240.0, 300.0), 0.004097425621422603)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 300.0, 360.0), 0.00534407493573042)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 360.0, 420.0), 0.002849425985304954)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 420.0, 480.0), 0.0024443772372422234)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 480.0, 540.0), 0.0011258612568464076)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 540.0, 600.0), 0.0005966047093584399)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 600.0, 660.0), 0.0005779388889435179)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 660.0, 720.0), 0.0004527621290439082)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 720.0, 780.0), 0.00011727646428602624)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(10, 11, 780.0, 840.0), 0.00011130198744577025)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(11, 12, 0.0, 30.0), 0.0025301846046864363)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(11, 12, 30.0, 60.0), 0.002932856090944951)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(11, 12, 60.0, 90.0), 0.0015297442159744696)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(11, 12, 90.0, 120.0), 0.0016816440829740813)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(11, 12, 120.0, 180.0), 0.0023140070407952395)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(11, 12, 180.0, 240.0), 0.0013768767086426792)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(11, 12, 240.0, 300.0), 0.0019019317686819275)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(11, 12, 300.0, 360.0), 0.0015577691125463963)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(11, 12, 360.0, 420.0), 0.001499121306916632)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(11, 12, 420.0, 480.0), 0.0007361366421130972)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(11, 12, 480.0, 540.0), 0.0007423049940853575)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(11, 12, 540.0, 600.0), 0.00011130198744577025)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(11, 12, 660.0, 720.0), 0.00024243947114654707)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(11, 12, 720.0, 780.0), 0.000261579996858755)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(12, 13, 0.0, 30.0), 0.0021669594044717543)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(12, 13, 30.0, 60.0), 0.0033993161916113994)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(12, 13, 60.0, 90.0), 0.001870484877697732)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(12, 13, 90.0, 120.0), 0.0008448185262884799)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(12, 13, 120.0, 180.0), 0.002024573233571085)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(12, 13, 180.0, 240.0), 0.0021888099857994042)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(12, 13, 240.0, 300.0), 0.0021657834323017752)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(12, 13, 300.0, 360.0), 0.0010623089332746248)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(12, 13, 360.0, 420.0), 0.0006268095760401356)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(12, 13, 420.0, 480.0), 0.0005094532977538987)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(12, 13, 480.0, 540.0), 0.0004744090926784203)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(12, 13, 540.0, 600.0), 0.00016487328572417658)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(12, 13, 660.0, 720.0), 0.0001162996982120756)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(13, 14, 0.0, 30.0), 0.0033401411497772818)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(13, 14, 30.0, 60.0), 0.002492685695459365)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(13, 14, 60.0, 90.0), 0.0027064477589805068)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(13, 14, 90.0, 120.0), 0.0018052297053924354)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(13, 14, 120.0, 180.0), 0.0027984509294891498)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(13, 14, 180.0, 240.0), 0.0022758505657711914)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(13, 14, 240.0, 300.0), 0.0003535503655144059)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(13, 14, 300.0, 360.0), 0.0005890430396050117)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(13, 14, 360.0, 420.0), 0.0002319134363595028)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(13, 14, 420.0, 480.0), 0.00011617748025141993)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(13, 14, 480.0, 540.0), 0.0003690064941818713)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(13, 14, 540.0, 600.0), 0.0001650495071007077)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(13, 14, 600.0, 660.0), 0.00023113252306835525)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(13, 14, 840.0, 1080.0), 0.00017239206443126303)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(14, 15, 0.0, 30.0), 0.003543871129770451)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(14, 15, 30.0, 60.0), 0.0018407982276338393)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(14, 15, 60.0, 90.0), 0.0010649270862293423)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(14, 15, 90.0, 120.0), 0.0009538696044712171)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(14, 15, 120.0, 180.0), 0.0021318639289119572)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(14, 15, 180.0, 240.0), 0.0019740243143620277)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(14, 15, 240.0, 300.0), 0.0006157677659961421)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(14, 15, 300.0, 360.0), 0.0004035374922773149)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(14, 15, 360.0, 420.0), 0.00011607019237524387)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(14, 15, 420.0, 480.0), 0.0003938282727195195)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(14, 15, 480.0, 540.0), 0.00011130198744577025)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(14, 15, 600.0, 660.0), 0.00011942109323430472)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(15, 16, 0.0, 30.0), 0.00254340964132742)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(15, 16, 30.0, 60.0), 0.0017847751078888892)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(15, 16, 60.0, 90.0), 0.000841891386995212)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(15, 16, 90.0, 120.0), 0.0003543852337006742)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(15, 16, 120.0, 180.0), 0.0013974221085794884)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(15, 16, 180.0, 240.0), 0.0006229273683665316)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(15, 16, 240.0, 300.0), 0.00020579571489011056)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(15, 16, 300.0, 360.0), 0.0004809214516599411)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(15, 16, 360.0, 420.0), 0.00022514291890117063)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(15, 16, 420.0, 480.0), 0.00014748146383900364)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(15, 16, 720.0, 780.0), 0.00011605559293173729)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(16, 17, 0.0, 30.0), 0.0019634787835054656)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(16, 17, 30.0, 60.0), 0.000860670737476427)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(16, 17, 60.0, 90.0), 0.0003550148096943092)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(16, 17, 90.0, 120.0), 0.000855728546868917)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(16, 17, 120.0, 180.0), 0.0009283998993093458)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(16, 17, 180.0, 240.0), 0.00022795178106384156)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(16, 17, 240.0, 300.0), 0.00024119874825349313)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(16, 17, 420.0, 480.0), 0.00023429279224671318)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(16, 17, 480.0, 540.0), 0.00011727269965059726)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(16, 17, 660.0, 720.0), 0.00011130198744577025)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(17, 18, 0.0, 30.0), 0.0017099830161073832)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(17, 18, 30.0, 60.0), 0.0006015092064895483)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(17, 18, 60.0, 90.0), 0.00011819436012345105)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(17, 18, 90.0, 120.0), 0.0002279569151752547)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(17, 18, 120.0, 180.0), 0.0006440525787748041)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(17, 18, 180.0, 240.0), 0.0003142746964600832)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(17, 18, 300.0, 360.0), 0.00022788575876606104)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(17, 18, 360.0, 420.0), 0.0004761806298753505)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(17, 18, 480.0, 540.0), 0.00011727269965059726)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(18, 19, 0.0, 30.0), 0.0020011795184968267)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(18, 19, 30.0, 60.0), 0.00023620950461199452)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(18, 19, 60.0, 90.0), 0.00011935825257957617)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(18, 19, 90.0, 120.0), 0.00011130198744577025)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(18, 19, 120.0, 180.0), 0.00012222981614916706)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(18, 19, 180.0, 240.0), 0.0002377005397786721)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(18, 19, 240.0, 300.0), 0.00026373526728965034)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(18, 19, 300.0, 360.0), 0.000256086036315955)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(18, 19, 360.0, 420.0), 0.00011394287938236544)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(19, 24, 0.0, 30.0), 0.0021116872169622083)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(19, 24, 30.0, 60.0), 0.0003681765715703113)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(19, 24, 60.0, 90.0), 0.0004137833254678062)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(19, 24, 90.0, 120.0), 0.00025108497234833097)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(19, 24, 120.0, 180.0), 0.0007576827338029722)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(19, 24, 180.0, 240.0), 0.0005180490039062906)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(19, 24, 240.0, 300.0), 0.0004944106124208977)); + tourDurationProbabilityDistribution.add( + Pair.create(new GenerateSmallScaleCommercialTrafficDemand.TourStartAndDuration(19, 24, 300.0, 360.0), 0.0002278857587658224)); - return new EnumeratedDistribution<>(rng, tourDurationProbabilityDistribution); + tourDistribution.put(GenerateSmallScaleCommercialTrafficDemand.SmallScaleCommercialTrafficType.goodsTraffic.toString(), + new EnumeratedDistribution<>(rng, tourDurationProbabilityDistribution)); + return tourDistribution; } @Override diff --git a/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/data/GetGenerationRates.java b/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/data/GetGenerationRates.java new file mode 100644 index 00000000000..5ed6ab36660 --- /dev/null +++ b/contribs/small-scale-traffic-generation/src/main/java/org/matsim/smallScaleCommercialTrafficGeneration/data/GetGenerationRates.java @@ -0,0 +1,856 @@ +package org.matsim.smallScaleCommercialTrafficGeneration.data; + +import java.util.HashMap; +import java.util.Map; + +public interface GetGenerationRates { + /** + * Sets the generation rates based on the IVV 2005 + * + * @param smallScaleCommercialTrafficType used trafficType (freight or business traffic) + * @param generationType start or stop rates + */ + static Map> setGenerationRates(String smallScaleCommercialTrafficType, + String generationType) { + + Map> generationRates = new HashMap<>(); + Map ratesPerPurpose1 = new HashMap<>(); + Map ratesPerPurpose2 = new HashMap<>(); + Map ratesPerPurpose3 = new HashMap<>(); + Map ratesPerPurpose4 = new HashMap<>(); + Map ratesPerPurpose5 = new HashMap<>(); + Map ratesPerPurpose6 = new HashMap<>(); + if (smallScaleCommercialTrafficType.equals("commercialPersonTraffic")) { + if (generationType.equals("start")) { + ratesPerPurpose1.put("Inhabitants", 0.0); + ratesPerPurpose1.put("Employee", 0.0); + ratesPerPurpose1.put("Employee Primary Sector", 0.0); + ratesPerPurpose1.put("Employee Construction", 0.0); + ratesPerPurpose1.put("Employee Secondary Sector Rest", 0.059); + ratesPerPurpose1.put("Employee Retail", 0.0); + ratesPerPurpose1.put("Employee Traffic/Parcels", 0.0); + ratesPerPurpose1.put("Employee Tertiary Sector Rest", 0.0); + + ratesPerPurpose2.put("Inhabitants", 0.0); + ratesPerPurpose2.put("Employee", 0.029); + ratesPerPurpose2.put("Employee Primary Sector", 0.0); + ratesPerPurpose2.put("Employee Construction", 0.0); + ratesPerPurpose2.put("Employee Secondary Sector Rest", 0.045); + ratesPerPurpose2.put("Employee Retail", 0.0); + ratesPerPurpose2.put("Employee Traffic/Parcels", 0.0); + ratesPerPurpose2.put("Employee Tertiary Sector Rest", 0.0); + + ratesPerPurpose3.put("Inhabitants", 0.0); + ratesPerPurpose3.put("Employee", 0.021); + ratesPerPurpose3.put("Employee Primary Sector", 0.0); + ratesPerPurpose3.put("Employee Construction", 0.0); + ratesPerPurpose3.put("Employee Secondary Sector Rest", 0.0); + ratesPerPurpose3.put("Employee Retail", 0.0192); + ratesPerPurpose3.put("Employee Traffic/Parcels", 0.0); + ratesPerPurpose3.put("Employee Tertiary Sector Rest", 0.184); + + ratesPerPurpose4.put("Inhabitants", 0.0); + ratesPerPurpose4.put("Employee", 0.021); + ratesPerPurpose4.put("Employee Primary Sector", 0.0); + ratesPerPurpose4.put("Employee Construction", 0.0); + ratesPerPurpose4.put("Employee Secondary Sector Rest", 0.0); + ratesPerPurpose4.put("Employee Retail", 0.0); + ratesPerPurpose4.put("Employee Traffic/Parcels", 0.203); + ratesPerPurpose4.put("Employee Tertiary Sector Rest", 0.0); + + ratesPerPurpose5.put("Inhabitants", 0.0); + ratesPerPurpose5.put("Employee", 0.03); + ratesPerPurpose5.put("Employee Primary Sector", 0.0); + ratesPerPurpose5.put("Employee Construction", 0.29); + ratesPerPurpose5.put("Employee Secondary Sector Rest", 0.0); + ratesPerPurpose5.put("Employee Retail", 0.0); + ratesPerPurpose5.put("Employee Traffic/Parcels", 0.0); + ratesPerPurpose5.put("Employee Tertiary Sector Rest", 0.0); + } else if (generationType.equals("stop")) { + ratesPerPurpose1.put("Inhabitants", 0.0); + ratesPerPurpose1.put("Employee", 0.0); + ratesPerPurpose1.put("Employee Primary Sector", 0.0); + ratesPerPurpose1.put("Employee Construction", 0.0); + ratesPerPurpose1.put("Employee Secondary Sector Rest", 0.02); + ratesPerPurpose1.put("Employee Retail", 0.0); + ratesPerPurpose1.put("Employee Traffic/Parcels", 0.0); + ratesPerPurpose1.put("Employee Tertiary Sector Rest", 0.0); + + ratesPerPurpose2.put("Inhabitants", 0.002); + ratesPerPurpose2.put("Employee", 0.0); + ratesPerPurpose2.put("Employee Primary Sector", 0.029); + ratesPerPurpose2.put("Employee Construction", 0.029); + ratesPerPurpose2.put("Employee Secondary Sector Rest", 0.009); + ratesPerPurpose2.put("Employee Retail", 0.029); + ratesPerPurpose2.put("Employee Traffic/Parcels", 0.039); + ratesPerPurpose2.put("Employee Tertiary Sector Rest", 0.029); + + ratesPerPurpose3.put("Inhabitants", 0.025); + ratesPerPurpose3.put("Employee", 0.0); + ratesPerPurpose3.put("Employee Primary Sector", 0.0168); + ratesPerPurpose3.put("Employee Construction", 0.168); + ratesPerPurpose3.put("Employee Secondary Sector Rest", 0.0168); + ratesPerPurpose3.put("Employee Retail", 0.0168); + ratesPerPurpose3.put("Employee Traffic/Parcels", 0.097); + ratesPerPurpose3.put("Employee Tertiary Sector Rest", 0.168); + + ratesPerPurpose4.put("Inhabitants", 0.002); + ratesPerPurpose4.put("Employee", 0.0); + ratesPerPurpose4.put("Employee Primary Sector", 0.025); + ratesPerPurpose4.put("Employee Construction", 0.025); + ratesPerPurpose4.put("Employee Secondary Sector Rest", 0.025); + ratesPerPurpose4.put("Employee Retail", 0.025); + ratesPerPurpose4.put("Employee Traffic/Parcels", 0.075); + ratesPerPurpose4.put("Employee Tertiary Sector Rest", 0.025); + + ratesPerPurpose5.put("Inhabitants", 0.004); + ratesPerPurpose5.put("Employee", 0.0); + ratesPerPurpose5.put("Employee Primary Sector", 0.015); + ratesPerPurpose5.put("Employee Construction", 0.002); + ratesPerPurpose5.put("Employee Secondary Sector Rest", 0.015); + ratesPerPurpose5.put("Employee Retail", 0.015); + ratesPerPurpose5.put("Employee Traffic/Parcels", 0.02); + ratesPerPurpose5.put("Employee Tertiary Sector Rest", 0.015); + + } + } else if (smallScaleCommercialTrafficType.equals("goodsTraffic")) { + if (generationType.equals("start")) { + ratesPerPurpose1.put("Inhabitants", 0.0); + ratesPerPurpose1.put("Employee", 0.0); + ratesPerPurpose1.put("Employee Primary Sector", 0.0); + ratesPerPurpose1.put("Employee Construction", 0.0); + ratesPerPurpose1.put("Employee Secondary Sector Rest", 0.023); + ratesPerPurpose1.put("Employee Retail", 0.0); + ratesPerPurpose1.put("Employee Traffic/Parcels", 0.0); + ratesPerPurpose1.put("Employee Tertiary Sector Rest", 0.0); + + ratesPerPurpose2.put("Inhabitants", 0.0); + ratesPerPurpose2.put("Employee", 0.002); + ratesPerPurpose2.put("Employee Primary Sector", 0.0); + ratesPerPurpose2.put("Employee Construction", 0.0); + ratesPerPurpose2.put("Employee Secondary Sector Rest", 0.049); + ratesPerPurpose2.put("Employee Retail", 0.0); + ratesPerPurpose2.put("Employee Traffic/Parcels", 0.0); + ratesPerPurpose2.put("Employee Tertiary Sector Rest", 0.0); + + ratesPerPurpose3.put("Inhabitants", 0.0); + ratesPerPurpose3.put("Employee", 0.002); + ratesPerPurpose3.put("Employee Primary Sector", 0.0); + ratesPerPurpose3.put("Employee Construction", 0.0); + ratesPerPurpose3.put("Employee Secondary Sector Rest", 0.0); + ratesPerPurpose3.put("Employee Retail", 0.139); + ratesPerPurpose3.put("Employee Traffic/Parcels", 0.0); + ratesPerPurpose3.put("Employee Tertiary Sector Rest", 0.059); + + ratesPerPurpose4.put("Inhabitants", 0.0); + ratesPerPurpose4.put("Employee", 0.002); + ratesPerPurpose4.put("Employee Primary Sector", 0.0); + ratesPerPurpose4.put("Employee Construction", 0.0); + ratesPerPurpose4.put("Employee Secondary Sector Rest", 0.0); + ratesPerPurpose4.put("Employee Retail", 0.0); + ratesPerPurpose4.put("Employee Traffic/Parcels", 0.333); + ratesPerPurpose4.put("Employee Tertiary Sector Rest", 0.0); + + ratesPerPurpose5.put("Inhabitants", 0.0); + ratesPerPurpose5.put("Employee", 0.002); + ratesPerPurpose5.put("Employee Primary Sector", 0.0); + ratesPerPurpose5.put("Employee Construction", 0.220); + ratesPerPurpose5.put("Employee Secondary Sector Rest", 0.0); + ratesPerPurpose5.put("Employee Retail", 0.0); + ratesPerPurpose5.put("Employee Traffic/Parcels", 0.0); + ratesPerPurpose5.put("Employee Tertiary Sector Rest", 0.0); + + ratesPerPurpose6.put("Inhabitants", 0.009); + ratesPerPurpose6.put("Employee", 0.0); + ratesPerPurpose6.put("Employee Primary Sector", 0.0); + ratesPerPurpose6.put("Employee Construction", 0.0); + ratesPerPurpose6.put("Employee Secondary Sector Rest", 0.0); + ratesPerPurpose6.put("Employee Retail", 0.0); + ratesPerPurpose6.put("Employee Traffic/Parcels", 0.0); + ratesPerPurpose6.put("Employee Tertiary Sector Rest", 0.0); + + } else if (generationType.equals("stop")) { + ratesPerPurpose1.put("Inhabitants", 0.0); + ratesPerPurpose1.put("Employee", 0.0); + ratesPerPurpose1.put("Employee Primary Sector", 0.0); + ratesPerPurpose1.put("Employee Construction", 0.0); + ratesPerPurpose1.put("Employee Secondary Sector Rest", 0.031); + ratesPerPurpose1.put("Employee Retail", 0.0); + ratesPerPurpose1.put("Employee Traffic/Parcels", 0.0); + ratesPerPurpose1.put("Employee Tertiary Sector Rest", 0.0); + + ratesPerPurpose2.put("Inhabitants", 0.001); + ratesPerPurpose2.put("Employee", 0.0); + ratesPerPurpose2.put("Employee Primary Sector", 0.001); + ratesPerPurpose2.put("Employee Construction", 0.01); + ratesPerPurpose2.put("Employee Secondary Sector Rest", 0.011); + ratesPerPurpose2.put("Employee Retail", 0.021); + ratesPerPurpose2.put("Employee Traffic/Parcels", 0.001); + ratesPerPurpose2.put("Employee Tertiary Sector Rest", 0.001); + + ratesPerPurpose3.put("Inhabitants", 0.009); + ratesPerPurpose3.put("Employee", 0.0); + ratesPerPurpose3.put("Employee Primary Sector", 0.02); + ratesPerPurpose3.put("Employee Construction", 0.005); + ratesPerPurpose3.put("Employee Secondary Sector Rest", 0.029); + ratesPerPurpose3.put("Employee Retail", 0.055); + ratesPerPurpose3.put("Employee Traffic/Parcels", 0.02); + ratesPerPurpose3.put("Employee Tertiary Sector Rest", 0.02); + + ratesPerPurpose4.put("Inhabitants", 0.014); + ratesPerPurpose4.put("Employee", 0.0); + ratesPerPurpose4.put("Employee Primary Sector", 0.02); + ratesPerPurpose4.put("Employee Construction", 0.002); + ratesPerPurpose4.put("Employee Secondary Sector Rest", 0.11); + ratesPerPurpose4.put("Employee Retail", 0.154); + ratesPerPurpose4.put("Employee Traffic/Parcels", 0.02); + ratesPerPurpose4.put("Employee Tertiary Sector Rest", 0.02); + + ratesPerPurpose5.put("Inhabitants", 0.002); + ratesPerPurpose5.put("Employee", 0.0); + ratesPerPurpose5.put("Employee Primary Sector", 0.005); + ratesPerPurpose5.put("Employee Construction", 0.002); + ratesPerPurpose5.put("Employee Secondary Sector Rest", 0.01); + ratesPerPurpose5.put("Employee Retail", 0.01); + ratesPerPurpose5.put("Employee Traffic/Parcels", 0.005); + ratesPerPurpose5.put("Employee Tertiary Sector Rest", 0.005); + + ratesPerPurpose6.put("Inhabitants", 0.002); + ratesPerPurpose6.put("Employee", 0.0); + ratesPerPurpose6.put("Employee Primary Sector", 0.005); + ratesPerPurpose6.put("Employee Construction", 0.002); + ratesPerPurpose6.put("Employee Secondary Sector Rest", 0.01); + ratesPerPurpose6.put("Employee Retail", 0.01); + ratesPerPurpose6.put("Employee Traffic/Parcels", 0.005); + ratesPerPurpose6.put("Employee Tertiary Sector Rest", 0.005); + } + generationRates.put(6, ratesPerPurpose6); + } + generationRates.put(1, ratesPerPurpose1); + generationRates.put(2, ratesPerPurpose2); + generationRates.put(3, ratesPerPurpose3); + generationRates.put(4, ratesPerPurpose4); + generationRates.put(5, ratesPerPurpose5); + return generationRates; + } + + /** + * Sets the commitment rates based on the IVV 2005 for the goodsTraffic. The + * commitment rate for the commercialPersonTraffic is 1, because mode choice will be + * done in MATSim. + * + * @param smallScaleCommercialTrafficType used trafficType (freight or business traffic) + * @param commitmentType start or stop parameter + */ + static Map> setCommitmentRates(String smallScaleCommercialTrafficType, + String commitmentType) { + Map> commitmentRates = new HashMap<>(); + + if (smallScaleCommercialTrafficType.equals("goodsTraffic")) { + + // the first number is the purpose; second number the vehicle type + Map ratesPerPurpose1_1 = new HashMap<>(); + Map ratesPerPurpose1_2 = new HashMap<>(); + Map ratesPerPurpose1_3 = new HashMap<>(); + Map ratesPerPurpose1_4 = new HashMap<>(); + Map ratesPerPurpose1_5 = new HashMap<>(); + Map ratesPerPurpose2_1 = new HashMap<>(); + Map ratesPerPurpose2_2 = new HashMap<>(); + Map ratesPerPurpose2_3 = new HashMap<>(); + Map ratesPerPurpose2_4 = new HashMap<>(); + Map ratesPerPurpose2_5 = new HashMap<>(); + Map ratesPerPurpose3_1 = new HashMap<>(); + Map ratesPerPurpose3_2 = new HashMap<>(); + Map ratesPerPurpose3_3 = new HashMap<>(); + Map ratesPerPurpose3_4 = new HashMap<>(); + Map ratesPerPurpose3_5 = new HashMap<>(); + Map ratesPerPurpose4_1 = new HashMap<>(); + Map ratesPerPurpose4_2 = new HashMap<>(); + Map ratesPerPurpose4_3 = new HashMap<>(); + Map ratesPerPurpose4_4 = new HashMap<>(); + Map ratesPerPurpose4_5 = new HashMap<>(); + Map ratesPerPurpose5_1 = new HashMap<>(); + Map ratesPerPurpose5_2 = new HashMap<>(); + Map ratesPerPurpose5_3 = new HashMap<>(); + Map ratesPerPurpose5_4 = new HashMap<>(); + Map ratesPerPurpose5_5 = new HashMap<>(); + Map ratesPerPurpose6_1 = new HashMap<>(); + Map ratesPerPurpose6_2 = new HashMap<>(); + Map ratesPerPurpose6_3 = new HashMap<>(); + Map ratesPerPurpose6_4 = new HashMap<>(); + Map ratesPerPurpose6_5 = new HashMap<>(); + if (commitmentType.equals("start")) { + ratesPerPurpose1_1.put("Inhabitants", 0.0); + ratesPerPurpose1_1.put("Employee", 0.8); + ratesPerPurpose1_1.put("Employee Primary Sector", 0.0); + ratesPerPurpose1_1.put("Employee Construction", 0.0); + ratesPerPurpose1_1.put("Employee Secondary Sector Rest", 0.44); + ratesPerPurpose1_1.put("Employee Retail", 0.0); + ratesPerPurpose1_1.put("Employee Traffic/Parcels", 0.0); + ratesPerPurpose1_1.put("Employee Tertiary Sector Rest", 0.0); + + ratesPerPurpose1_2.put("Inhabitants", 0.0); + ratesPerPurpose1_2.put("Employee", 0.1); + ratesPerPurpose1_2.put("Employee Primary Sector", 0.0); + ratesPerPurpose1_2.put("Employee Construction", 0.0); + ratesPerPurpose1_2.put("Employee Secondary Sector Rest", 0.11); + ratesPerPurpose1_2.put("Employee Retail", 0.0); + ratesPerPurpose1_2.put("Employee Traffic/Parcels", 0.0); + ratesPerPurpose1_2.put("Employee Tertiary Sector Rest", 0.0); + + ratesPerPurpose1_3.put("Inhabitants", 0.0); + ratesPerPurpose1_3.put("Employee", 0.1); + ratesPerPurpose1_3.put("Employee Primary Sector", 0.0); + ratesPerPurpose1_3.put("Employee Construction", 0.0); + ratesPerPurpose1_3.put("Employee Secondary Sector Rest", 0.22); + ratesPerPurpose1_3.put("Employee Retail", 0.0); + ratesPerPurpose1_3.put("Employee Traffic/Parcels", 0.0); + ratesPerPurpose1_3.put("Employee Tertiary Sector Rest", 0.0); + + ratesPerPurpose1_4.put("Inhabitants", 0.0); + ratesPerPurpose1_4.put("Employee", 0.0); + ratesPerPurpose1_4.put("Employee Primary Sector", 0.0); + ratesPerPurpose1_4.put("Employee Construction", 0.0); + ratesPerPurpose1_4.put("Employee Secondary Sector Rest", 0.06); + ratesPerPurpose1_4.put("Employee Retail", 0.0); + ratesPerPurpose1_4.put("Employee Traffic/Parcels", 0.0); + ratesPerPurpose1_4.put("Employee Tertiary Sector Rest", 0.0); + + ratesPerPurpose1_5.put("Inhabitants", 0.0); + ratesPerPurpose1_5.put("Employee", 0.0); + ratesPerPurpose1_5.put("Employee Primary Sector", 0.0); + ratesPerPurpose1_5.put("Employee Construction", 0.0); + ratesPerPurpose1_5.put("Employee Secondary Sector Rest", 0.16); + ratesPerPurpose1_5.put("Employee Retail", 0.0); + ratesPerPurpose1_5.put("Employee Traffic/Parcels", 0.0); + ratesPerPurpose1_5.put("Employee Tertiary Sector Rest", 0.0); + + ratesPerPurpose2_1.put("Inhabitants", 0.0); + ratesPerPurpose2_1.put("Employee", 0.8); + ratesPerPurpose2_1.put("Employee Primary Sector", 0.0); + ratesPerPurpose2_1.put("Employee Construction", 0.0); + ratesPerPurpose2_1.put("Employee Secondary Sector Rest", 0.44); + ratesPerPurpose2_1.put("Employee Retail", 0.0); + ratesPerPurpose2_1.put("Employee Traffic/Parcels", 0.0); + ratesPerPurpose2_1.put("Employee Tertiary Sector Rest", 0.0); + + ratesPerPurpose2_2.put("Inhabitants", 0.0); + ratesPerPurpose2_2.put("Employee", 0.1); + ratesPerPurpose2_2.put("Employee Primary Sector", 0.0); + ratesPerPurpose2_2.put("Employee Construction", 0.0); + ratesPerPurpose2_2.put("Employee Secondary Sector Rest", 0.11); + ratesPerPurpose2_2.put("Employee Retail", 0.0); + ratesPerPurpose2_2.put("Employee Traffic/Parcels", 0.0); + ratesPerPurpose2_2.put("Employee Tertiary Sector Rest", 0.0); + + ratesPerPurpose2_3.put("Inhabitants", 0.0); + ratesPerPurpose2_3.put("Employee", 0.1); + ratesPerPurpose2_3.put("Employee Primary Sector", 0.0); + ratesPerPurpose2_3.put("Employee Construction", 0.0); + ratesPerPurpose2_3.put("Employee Secondary Sector Rest", 0.22); + ratesPerPurpose2_3.put("Employee Retail", 0.0); + ratesPerPurpose2_3.put("Employee Traffic/Parcels", 0.0); + ratesPerPurpose2_3.put("Employee Tertiary Sector Rest", 0.0); + + ratesPerPurpose2_4.put("Inhabitants", 0.0); + ratesPerPurpose2_4.put("Employee", 0.0); + ratesPerPurpose2_4.put("Employee Primary Sector", 0.0); + ratesPerPurpose2_4.put("Employee Construction", 0.0); + ratesPerPurpose2_4.put("Employee Secondary Sector Rest", 0.06); + ratesPerPurpose2_4.put("Employee Retail", 0.0); + ratesPerPurpose2_4.put("Employee Traffic/Parcels", 0.0); + ratesPerPurpose2_4.put("Employee Tertiary Sector Rest", 0.0); + + ratesPerPurpose2_5.put("Inhabitants", 0.0); + ratesPerPurpose2_5.put("Employee", 0.0); + ratesPerPurpose2_5.put("Employee Primary Sector", 0.0); + ratesPerPurpose2_5.put("Employee Construction", 0.0); + ratesPerPurpose2_5.put("Employee Secondary Sector Rest", 0.16); + ratesPerPurpose2_5.put("Employee Retail", 0.0); + ratesPerPurpose2_5.put("Employee Traffic/Parcels", 0.0); + ratesPerPurpose2_5.put("Employee Tertiary Sector Rest", 0.0); + + ratesPerPurpose3_1.put("Inhabitants", 0.0); + ratesPerPurpose3_1.put("Employee", 0.8); + ratesPerPurpose3_1.put("Employee Primary Sector", 0.0); + ratesPerPurpose3_1.put("Employee Construction", 0.0); + ratesPerPurpose3_1.put("Employee Secondary Sector Rest", 0.0); + ratesPerPurpose3_1.put("Employee Retail", 0.46); + ratesPerPurpose3_1.put("Employee Traffic/Parcels", 0.0); + ratesPerPurpose3_1.put("Employee Tertiary Sector Rest", 0.54); + + ratesPerPurpose3_2.put("Inhabitants", 0.0); + ratesPerPurpose3_2.put("Employee", 0.1); + ratesPerPurpose3_2.put("Employee Primary Sector", 0.0); + ratesPerPurpose3_2.put("Employee Construction", 0.0); + ratesPerPurpose3_2.put("Employee Secondary Sector Rest", 0.0); + ratesPerPurpose3_2.put("Employee Retail", 0.1); + ratesPerPurpose3_2.put("Employee Traffic/Parcels", 0.0); + ratesPerPurpose3_2.put("Employee Tertiary Sector Rest", 0.1); + + ratesPerPurpose3_3.put("Inhabitants", 0.0); + ratesPerPurpose3_3.put("Employee", 0.1); + ratesPerPurpose3_3.put("Employee Primary Sector", 0.0); + ratesPerPurpose3_3.put("Employee Construction", 0.0); + ratesPerPurpose3_3.put("Employee Secondary Sector Rest", 0.0); + ratesPerPurpose3_3.put("Employee Retail", 0.23); + ratesPerPurpose3_3.put("Employee Traffic/Parcels", 0.0); + ratesPerPurpose3_3.put("Employee Tertiary Sector Rest", 0.2); + + ratesPerPurpose3_4.put("Inhabitants", 0.0); + ratesPerPurpose3_4.put("Employee", 0.0); + ratesPerPurpose3_4.put("Employee Primary Sector", 0.0); + ratesPerPurpose3_4.put("Employee Construction", 0.0); + ratesPerPurpose3_4.put("Employee Secondary Sector Rest", 0.0); + ratesPerPurpose3_4.put("Employee Retail", 0.06); + ratesPerPurpose3_4.put("Employee Traffic/Parcels", 0.0); + ratesPerPurpose3_4.put("Employee Tertiary Sector Rest", 0.02); + + ratesPerPurpose3_5.put("Inhabitants", 0.0); + ratesPerPurpose3_5.put("Employee", 0.0); + ratesPerPurpose3_5.put("Employee Primary Sector", 0.0); + ratesPerPurpose3_5.put("Employee Construction", 0.0); + ratesPerPurpose3_5.put("Employee Secondary Sector Rest", 0.0); + ratesPerPurpose3_5.put("Employee Retail", 0.15); + ratesPerPurpose3_5.put("Employee Traffic/Parcels", 0.0); + ratesPerPurpose3_5.put("Employee Tertiary Sector Rest", 0.14); + + ratesPerPurpose4_1.put("Inhabitants", 0.009); + ratesPerPurpose4_1.put("Employee", 0.8); + ratesPerPurpose4_1.put("Employee Primary Sector", 0.0); + ratesPerPurpose4_1.put("Employee Construction", 0.0); + ratesPerPurpose4_1.put("Employee Secondary Sector Rest", 0.0); + ratesPerPurpose4_1.put("Employee Retail", 0.0); + ratesPerPurpose4_1.put("Employee Traffic/Parcels", 0.18); + ratesPerPurpose4_1.put("Employee Tertiary Sector Rest", 0.0); + + ratesPerPurpose4_2.put("Inhabitants", 0.0); + ratesPerPurpose4_2.put("Employee", 0.1); + ratesPerPurpose4_2.put("Employee Primary Sector", 0.0); + ratesPerPurpose4_2.put("Employee Construction", 0.0); + ratesPerPurpose4_2.put("Employee Secondary Sector Rest", 0.0); + ratesPerPurpose4_2.put("Employee Retail", 0.0); + ratesPerPurpose4_2.put("Employee Traffic/Parcels", 0.06); + ratesPerPurpose4_2.put("Employee Tertiary Sector Rest", 0.0); + + ratesPerPurpose4_3.put("Inhabitants", 0.0); + ratesPerPurpose4_3.put("Employee", 0.1); + ratesPerPurpose4_3.put("Employee Primary Sector", 0.0); + ratesPerPurpose4_3.put("Employee Construction", 0.0); + ratesPerPurpose4_3.put("Employee Secondary Sector Rest", 0.0); + ratesPerPurpose4_3.put("Employee Retail", 0.0); + ratesPerPurpose4_3.put("Employee Traffic/Parcels", 0.25); + ratesPerPurpose4_3.put("Employee Tertiary Sector Rest", 0.0); + + ratesPerPurpose4_4.put("Inhabitants", 0.0); + ratesPerPurpose4_4.put("Employee", 0.0); + ratesPerPurpose4_4.put("Employee Primary Sector", 0.0); + ratesPerPurpose4_4.put("Employee Construction", 0.0); + ratesPerPurpose4_4.put("Employee Secondary Sector Rest", 0.0); + ratesPerPurpose4_4.put("Employee Retail", 0.0); + ratesPerPurpose4_4.put("Employee Traffic/Parcels", 0.08); + ratesPerPurpose4_4.put("Employee Tertiary Sector Rest", 0.0); + + ratesPerPurpose4_5.put("Inhabitants", 0.0); + ratesPerPurpose4_5.put("Employee", 0.0); + ratesPerPurpose4_5.put("Employee Primary Sector", 0.0); + ratesPerPurpose4_5.put("Employee Construction", 0.0); + ratesPerPurpose4_5.put("Employee Secondary Sector Rest", 0.0); + ratesPerPurpose4_5.put("Employee Retail", 0.0); + ratesPerPurpose4_5.put("Employee Traffic/Parcels", 0.43); + ratesPerPurpose4_5.put("Employee Tertiary Sector Rest", 0.0); + + ratesPerPurpose5_1.put("Inhabitants", 0.0); + ratesPerPurpose5_1.put("Employee", 0.8); + ratesPerPurpose5_1.put("Employee Primary Sector", 0.0); + ratesPerPurpose5_1.put("Employee Construction", 0.25); + ratesPerPurpose5_1.put("Employee Secondary Sector Rest", 0.0); + ratesPerPurpose5_1.put("Employee Retail", 0.0); + ratesPerPurpose5_1.put("Employee Traffic/Parcels", 0.0); + ratesPerPurpose5_1.put("Employee Tertiary Sector Rest", 0.0); + + ratesPerPurpose5_2.put("Inhabitants", 0.0); + ratesPerPurpose5_2.put("Employee", 0.1); + ratesPerPurpose5_2.put("Employee Primary Sector", 0.0); + ratesPerPurpose5_2.put("Employee Construction", 0.2); + ratesPerPurpose5_2.put("Employee Secondary Sector Rest", 0.0); + ratesPerPurpose5_2.put("Employee Retail", 0.0); + ratesPerPurpose5_2.put("Employee Traffic/Parcels", 0.0); + ratesPerPurpose5_2.put("Employee Tertiary Sector Rest", 0.0); + + ratesPerPurpose5_3.put("Inhabitants", 0.0); + ratesPerPurpose5_3.put("Employee", 0.1); + ratesPerPurpose5_3.put("Employee Primary Sector", 0.0); + ratesPerPurpose5_3.put("Employee Construction", 0.25); + ratesPerPurpose5_3.put("Employee Secondary Sector Rest", 0.0); + ratesPerPurpose5_3.put("Employee Retail", 0.139); + ratesPerPurpose5_3.put("Employee Traffic/Parcels", 0.0); + ratesPerPurpose5_3.put("Employee Tertiary Sector Rest", 0.059); + + ratesPerPurpose5_4.put("Inhabitants", 0.0); + ratesPerPurpose5_4.put("Employee", 0.0); + ratesPerPurpose5_4.put("Employee Primary Sector", 0.0); + ratesPerPurpose5_4.put("Employee Construction", 0.02); + ratesPerPurpose5_4.put("Employee Secondary Sector Rest", 0.0); + ratesPerPurpose5_4.put("Employee Retail", 0.0); + ratesPerPurpose5_4.put("Employee Traffic/Parcels", 0.0); + ratesPerPurpose5_4.put("Employee Tertiary Sector Rest", 0.0); + + ratesPerPurpose5_5.put("Inhabitants", 0.0); + ratesPerPurpose5_5.put("Employee", 0.0); + ratesPerPurpose5_5.put("Employee Primary Sector", 0.0); + ratesPerPurpose5_5.put("Employee Construction", 0.28); + ratesPerPurpose5_5.put("Employee Secondary Sector Rest", 0.0); + ratesPerPurpose5_5.put("Employee Retail", 0.0); + ratesPerPurpose5_5.put("Employee Traffic/Parcels", 0.0); + ratesPerPurpose5_5.put("Employee Tertiary Sector Rest", 0.0); + + ratesPerPurpose6_1.put("Inhabitants", 0.0); + ratesPerPurpose6_1.put("Employee", 0.0); + ratesPerPurpose6_1.put("Employee Primary Sector", 0.0); + ratesPerPurpose6_1.put("Employee Construction", 0.0); + ratesPerPurpose6_1.put("Employee Secondary Sector Rest", 0.0); + ratesPerPurpose6_1.put("Employee Retail", 0.0); + ratesPerPurpose6_1.put("Employee Traffic/Parcels", 0.0); + ratesPerPurpose6_1.put("Employee Tertiary Sector Rest", 0.0); + + ratesPerPurpose6_2.put("Inhabitants", 0.29); + ratesPerPurpose6_2.put("Employee", 0.0); + ratesPerPurpose6_2.put("Employee Primary Sector", 0.0); + ratesPerPurpose6_2.put("Employee Construction", 0.0); + ratesPerPurpose6_2.put("Employee Secondary Sector Rest", 0.0); + ratesPerPurpose6_2.put("Employee Retail", 0.0); + ratesPerPurpose6_2.put("Employee Traffic/Parcels", 0.0); + ratesPerPurpose6_2.put("Employee Tertiary Sector Rest", 0.0); + + ratesPerPurpose6_3.put("Inhabitants", 0.63); + ratesPerPurpose6_3.put("Employee", 0.0); + ratesPerPurpose6_3.put("Employee Primary Sector", 0.0); + ratesPerPurpose6_3.put("Employee Construction", 0.0); + ratesPerPurpose6_3.put("Employee Secondary Sector Rest", 0.0); + ratesPerPurpose6_3.put("Employee Retail", 0.0); + ratesPerPurpose6_3.put("Employee Traffic/Parcels", 0.0); + ratesPerPurpose6_3.put("Employee Tertiary Sector Rest", 0.0); + + ratesPerPurpose6_4.put("Inhabitants", 0.07); + ratesPerPurpose6_4.put("Employee", 0.0); + ratesPerPurpose6_4.put("Employee Primary Sector", 0.0); + ratesPerPurpose6_4.put("Employee Construction", 0.0); + ratesPerPurpose6_4.put("Employee Secondary Sector Rest", 0.0); + ratesPerPurpose6_4.put("Employee Retail", 0.0); + ratesPerPurpose6_4.put("Employee Traffic/Parcels", 0.0); + ratesPerPurpose6_4.put("Employee Tertiary Sector Rest", 0.0); + + ratesPerPurpose6_5.put("Inhabitants", 0.001); + ratesPerPurpose6_5.put("Employee", 0.0); + ratesPerPurpose6_5.put("Employee Primary Sector", 0.0); + ratesPerPurpose6_5.put("Employee Construction", 0.2); + ratesPerPurpose6_5.put("Employee Secondary Sector Rest", 0.0); + ratesPerPurpose6_5.put("Employee Retail", 0.0); + ratesPerPurpose6_5.put("Employee Traffic/Parcels", 0.0); + ratesPerPurpose6_5.put("Employee Tertiary Sector Rest", 0.0); + } else if (commitmentType.equals("stop")) { + ratesPerPurpose1_1.put("Inhabitants", 0.0); + ratesPerPurpose1_1.put("Employee", 0.0); + ratesPerPurpose1_1.put("Employee Primary Sector", 0.0); + ratesPerPurpose1_1.put("Employee Construction", 0.0); + ratesPerPurpose1_1.put("Employee Secondary Sector Rest", 0.35); + ratesPerPurpose1_1.put("Employee Retail", 0.0); + ratesPerPurpose1_1.put("Employee Traffic/Parcels", 0.0); + ratesPerPurpose1_1.put("Employee Tertiary Sector Rest", 0.0); + + ratesPerPurpose1_2.put("Inhabitants", 0.0); + ratesPerPurpose1_2.put("Employee", 0.0); + ratesPerPurpose1_2.put("Employee Primary Sector", 0.0); + ratesPerPurpose1_2.put("Employee Construction", 0.0); + ratesPerPurpose1_2.put("Employee Secondary Sector Rest", 0.1); + ratesPerPurpose1_2.put("Employee Retail", 0.0); + ratesPerPurpose1_2.put("Employee Traffic/Parcels", 0.0); + ratesPerPurpose1_2.put("Employee Tertiary Sector Rest", 0.0); + + ratesPerPurpose1_3.put("Inhabitants", 0.0); + ratesPerPurpose1_3.put("Employee", 0.0); + ratesPerPurpose1_3.put("Employee Primary Sector", 0.0); + ratesPerPurpose1_3.put("Employee Construction", 0.0); + ratesPerPurpose1_3.put("Employee Secondary Sector Rest", 0.27); + ratesPerPurpose1_3.put("Employee Retail", 0.0); + ratesPerPurpose1_3.put("Employee Traffic/Parcels", 0.0); + ratesPerPurpose1_3.put("Employee Tertiary Sector Rest", 0.0); + + ratesPerPurpose1_4.put("Inhabitants", 0.0); + ratesPerPurpose1_4.put("Employee", 0.0); + ratesPerPurpose1_4.put("Employee Primary Sector", 0.0); + ratesPerPurpose1_4.put("Employee Construction", 0.0); + ratesPerPurpose1_4.put("Employee Secondary Sector Rest", 0.01); + ratesPerPurpose1_4.put("Employee Retail", 0.0); + ratesPerPurpose1_4.put("Employee Traffic/Parcels", 0.0); + ratesPerPurpose1_4.put("Employee Tertiary Sector Rest", 0.0); + + ratesPerPurpose1_5.put("Inhabitants", 0.0); + ratesPerPurpose1_5.put("Employee", 0.0); + ratesPerPurpose1_5.put("Employee Primary Sector", 0.0); + ratesPerPurpose1_5.put("Employee Construction", 0.0); + ratesPerPurpose1_5.put("Employee Secondary Sector Rest", 0.27); + ratesPerPurpose1_5.put("Employee Retail", 0.0); + ratesPerPurpose1_5.put("Employee Traffic/Parcels", 0.0); + ratesPerPurpose1_5.put("Employee Tertiary Sector Rest", 0.0); + + ratesPerPurpose2_1.put("Inhabitants", 0.55); + ratesPerPurpose2_1.put("Employee", 0.0); + ratesPerPurpose2_1.put("Employee Primary Sector", 0.46); + ratesPerPurpose2_1.put("Employee Construction", 0.46); + ratesPerPurpose2_1.put("Employee Secondary Sector Rest", 0.46); + ratesPerPurpose2_1.put("Employee Retail", 0.46); + ratesPerPurpose2_1.put("Employee Traffic/Parcels", 0.34); + ratesPerPurpose2_1.put("Employee Tertiary Sector Rest", 0.46); + + ratesPerPurpose2_2.put("Inhabitants", 0.09); + ratesPerPurpose2_2.put("Employee", 0.0); + ratesPerPurpose2_2.put("Employee Primary Sector", 0.09); + ratesPerPurpose2_2.put("Employee Construction", 0.09); + ratesPerPurpose2_2.put("Employee Secondary Sector Rest", 0.09); + ratesPerPurpose2_2.put("Employee Retail", 0.09); + ratesPerPurpose2_2.put("Employee Traffic/Parcels", 0.1); + ratesPerPurpose2_2.put("Employee Tertiary Sector Rest", 0.09); + + ratesPerPurpose2_3.put("Inhabitants", 0.21); + ratesPerPurpose2_3.put("Employee", 0.0); + ratesPerPurpose2_3.put("Employee Primary Sector", 0.22); + ratesPerPurpose2_3.put("Employee Construction", 0.22); + ratesPerPurpose2_3.put("Employee Secondary Sector Rest", 0.22); + ratesPerPurpose2_3.put("Employee Retail", 0.22); + ratesPerPurpose2_3.put("Employee Traffic/Parcels", 0.29); + ratesPerPurpose2_3.put("Employee Tertiary Sector Rest", 0.22); + + ratesPerPurpose2_4.put("Inhabitants", 0.06); + ratesPerPurpose2_4.put("Employee", 0.0); + ratesPerPurpose2_4.put("Employee Primary Sector", 0.06); + ratesPerPurpose2_4.put("Employee Construction", 0.06); + ratesPerPurpose2_4.put("Employee Secondary Sector Rest", 0.06); + ratesPerPurpose2_4.put("Employee Retail", 0.06); + ratesPerPurpose2_4.put("Employee Traffic/Parcels", 0.0); + ratesPerPurpose2_4.put("Employee Tertiary Sector Rest", 0.06); + + ratesPerPurpose2_5.put("Inhabitants", 0.1); + ratesPerPurpose2_5.put("Employee", 0.0); + ratesPerPurpose2_5.put("Employee Primary Sector", 0.17); + ratesPerPurpose2_5.put("Employee Construction", 0.17); + ratesPerPurpose2_5.put("Employee Secondary Sector Rest", 0.17); + ratesPerPurpose2_5.put("Employee Retail", 0.17); + ratesPerPurpose2_5.put("Employee Traffic/Parcels", 0.27); + ratesPerPurpose2_5.put("Employee Tertiary Sector Rest", 0.17); + + ratesPerPurpose3_1.put("Inhabitants", 0.489); + ratesPerPurpose3_1.put("Employee", 0.0); + ratesPerPurpose3_1.put("Employee Primary Sector", 0.538); + ratesPerPurpose3_1.put("Employee Construction", 0.538); + ratesPerPurpose3_1.put("Employee Secondary Sector Rest", 0.538); + ratesPerPurpose3_1.put("Employee Retail", 0.538); + ratesPerPurpose3_1.put("Employee Traffic/Parcels", 0.59); + ratesPerPurpose3_1.put("Employee Tertiary Sector Rest", 0.538); + + ratesPerPurpose3_2.put("Inhabitants", 0.106); + ratesPerPurpose3_2.put("Employee", 0.0); + ratesPerPurpose3_2.put("Employee Primary Sector", 0.092); + ratesPerPurpose3_2.put("Employee Construction", 0.092); + ratesPerPurpose3_2.put("Employee Secondary Sector Rest", 0.092); + ratesPerPurpose3_2.put("Employee Retail", 0.092); + ratesPerPurpose3_2.put("Employee Traffic/Parcels", 0.03); + ratesPerPurpose3_2.put("Employee Tertiary Sector Rest", 0.092); + + ratesPerPurpose3_3.put("Inhabitants", 0.26); + ratesPerPurpose3_3.put("Employee", 0.0); + ratesPerPurpose3_3.put("Employee Primary Sector", 0.19); + ratesPerPurpose3_3.put("Employee Construction", 0.19); + ratesPerPurpose3_3.put("Employee Secondary Sector Rest", 0.19); + ratesPerPurpose3_3.put("Employee Retail", 0.19); + ratesPerPurpose3_3.put("Employee Traffic/Parcels", 0.102); + ratesPerPurpose3_3.put("Employee Tertiary Sector Rest", 0.19); + + ratesPerPurpose3_4.put("Inhabitants", 0.033); + ratesPerPurpose3_4.put("Employee", 0.0); + ratesPerPurpose3_4.put("Employee Primary Sector", 0.032); + ratesPerPurpose3_4.put("Employee Construction", 0.032); + ratesPerPurpose3_4.put("Employee Secondary Sector Rest", 0.032); + ratesPerPurpose3_4.put("Employee Retail", 0.032); + ratesPerPurpose3_4.put("Employee Traffic/Parcels", 0.058); + ratesPerPurpose3_4.put("Employee Tertiary Sector Rest", 0.032); + + ratesPerPurpose3_5.put("Inhabitants", 0.112); + ratesPerPurpose3_5.put("Employee", 0.0); + ratesPerPurpose3_5.put("Employee Primary Sector", 0.147); + ratesPerPurpose3_5.put("Employee Construction", 0.147); + ratesPerPurpose3_5.put("Employee Secondary Sector Rest", 0.147); + ratesPerPurpose3_5.put("Employee Retail", 0.147); + ratesPerPurpose3_5.put("Employee Traffic/Parcels", 0.219); + ratesPerPurpose3_5.put("Employee Tertiary Sector Rest", 0.147); + + ratesPerPurpose4_1.put("Inhabitants", 0.37); + ratesPerPurpose4_1.put("Employee", 0.0); + ratesPerPurpose4_1.put("Employee Primary Sector", 0.14); + ratesPerPurpose4_1.put("Employee Construction", 0.14); + ratesPerPurpose4_1.put("Employee Secondary Sector Rest", 0.14); + ratesPerPurpose4_1.put("Employee Retail", 0.14); + ratesPerPurpose4_1.put("Employee Traffic/Parcels", 0.06); + ratesPerPurpose4_1.put("Employee Tertiary Sector Rest", 0.14); + + ratesPerPurpose4_2.put("Inhabitants", 0.05); + ratesPerPurpose4_2.put("Employee", 0.0); + ratesPerPurpose4_2.put("Employee Primary Sector", 0.07); + ratesPerPurpose4_2.put("Employee Construction", 0.07); + ratesPerPurpose4_2.put("Employee Secondary Sector Rest", 0.07); + ratesPerPurpose4_2.put("Employee Retail", 0.07); + ratesPerPurpose4_2.put("Employee Traffic/Parcels", 0.07); + ratesPerPurpose4_2.put("Employee Tertiary Sector Rest", 0.07); + + ratesPerPurpose4_3.put("Inhabitants", 0.4); + ratesPerPurpose4_3.put("Employee", 0.0); + ratesPerPurpose4_3.put("Employee Primary Sector", 0.21); + ratesPerPurpose4_3.put("Employee Construction", 0.21); + ratesPerPurpose4_3.put("Employee Secondary Sector Rest", 0.21); + ratesPerPurpose4_3.put("Employee Retail", 0.21); + ratesPerPurpose4_3.put("Employee Traffic/Parcels", 0.19); + ratesPerPurpose4_3.put("Employee Tertiary Sector Rest", 0.21); + + ratesPerPurpose4_4.put("Inhabitants", 0.13); + ratesPerPurpose4_4.put("Employee", 0.0); + ratesPerPurpose4_4.put("Employee Primary Sector", 0.05); + ratesPerPurpose4_4.put("Employee Construction", 0.05); + ratesPerPurpose4_4.put("Employee Secondary Sector Rest", 0.05); + ratesPerPurpose4_4.put("Employee Retail", 0.05); + ratesPerPurpose4_4.put("Employee Traffic/Parcels", 0.08); + ratesPerPurpose4_4.put("Employee Tertiary Sector Rest", 0.05); + + ratesPerPurpose4_5.put("Inhabitants", 0.05); + ratesPerPurpose4_5.put("Employee", 0.0); + ratesPerPurpose4_5.put("Employee Primary Sector", 0.54); + ratesPerPurpose4_5.put("Employee Construction", 0.54); + ratesPerPurpose4_5.put("Employee Secondary Sector Rest", 0.54); + ratesPerPurpose4_5.put("Employee Retail", 0.54); + ratesPerPurpose4_5.put("Employee Traffic/Parcels", 0.61); + ratesPerPurpose4_5.put("Employee Tertiary Sector Rest", 0.54); + + ratesPerPurpose5_1.put("Inhabitants", 0.16); + ratesPerPurpose5_1.put("Employee", 0.0); + ratesPerPurpose5_1.put("Employee Primary Sector", 0.4); + ratesPerPurpose5_1.put("Employee Construction", 0.4); + ratesPerPurpose5_1.put("Employee Secondary Sector Rest", 0.4); + ratesPerPurpose5_1.put("Employee Retail", 0.4); + ratesPerPurpose5_1.put("Employee Traffic/Parcels", 0.14); + ratesPerPurpose5_1.put("Employee Tertiary Sector Rest", 0.4); + + ratesPerPurpose5_2.put("Inhabitants", 0.55); + ratesPerPurpose5_2.put("Employee", 0.11); + ratesPerPurpose5_2.put("Employee Primary Sector", 0.11); + ratesPerPurpose5_2.put("Employee Construction", 0.11); + ratesPerPurpose5_2.put("Employee Secondary Sector Rest", 0.11); + ratesPerPurpose5_2.put("Employee Retail", 0.11); + ratesPerPurpose5_2.put("Employee Traffic/Parcels", 0.06); + ratesPerPurpose5_2.put("Employee Tertiary Sector Rest", 0.11); + + ratesPerPurpose5_3.put("Inhabitants", 0.22); + ratesPerPurpose5_3.put("Employee", 0.0); + ratesPerPurpose5_3.put("Employee Primary Sector", 0.17); + ratesPerPurpose5_3.put("Employee Construction", 0.17); + ratesPerPurpose5_3.put("Employee Secondary Sector Rest", 0.17); + ratesPerPurpose5_3.put("Employee Retail", 0.17); + ratesPerPurpose5_3.put("Employee Traffic/Parcels", 0.21); + ratesPerPurpose5_3.put("Employee Tertiary Sector Rest", 0.17); + + ratesPerPurpose5_4.put("Inhabitants", 0.0); + ratesPerPurpose5_4.put("Employee", 0.0); + ratesPerPurpose5_4.put("Employee Primary Sector", 0.04); + ratesPerPurpose5_4.put("Employee Construction", 0.04); + ratesPerPurpose5_4.put("Employee Secondary Sector Rest", 0.04); + ratesPerPurpose5_4.put("Employee Retail", 0.04); + ratesPerPurpose5_4.put("Employee Traffic/Parcels", 0.0); + ratesPerPurpose5_4.put("Employee Tertiary Sector Rest", 0.04); + + ratesPerPurpose5_5.put("Inhabitants", 0.06); + ratesPerPurpose5_5.put("Employee", 0.0); + ratesPerPurpose5_5.put("Employee Primary Sector", 0.28); + ratesPerPurpose5_5.put("Employee Construction", 0.28); + ratesPerPurpose5_5.put("Employee Secondary Sector Rest", 0.28); + ratesPerPurpose5_5.put("Employee Retail", 0.28); + ratesPerPurpose5_5.put("Employee Traffic/Parcels", 0.58); + ratesPerPurpose5_5.put("Employee Tertiary Sector Rest", 0.28); + + ratesPerPurpose6_1.put("Inhabitants", 0.0); + ratesPerPurpose6_1.put("Employee", 0.0); + ratesPerPurpose6_1.put("Employee Primary Sector", 0.0); + ratesPerPurpose6_1.put("Employee Construction", 0.0); + ratesPerPurpose6_1.put("Employee Secondary Sector Rest", 0.0); + ratesPerPurpose6_1.put("Employee Retail", 0.0); + ratesPerPurpose6_1.put("Employee Traffic/Parcels", 0.0); + ratesPerPurpose6_1.put("Employee Tertiary Sector Rest", 0.0); + + ratesPerPurpose6_2.put("Inhabitants", 0.85); + ratesPerPurpose6_2.put("Employee", 0.0); + ratesPerPurpose6_2.put("Employee Primary Sector", 0.21); + ratesPerPurpose6_2.put("Employee Construction", 0.21); + ratesPerPurpose6_2.put("Employee Secondary Sector Rest", 0.21); + ratesPerPurpose6_2.put("Employee Retail", 0.21); + ratesPerPurpose6_2.put("Employee Traffic/Parcels", 0.09); + ratesPerPurpose6_2.put("Employee Tertiary Sector Rest", 0.21); + + ratesPerPurpose6_3.put("Inhabitants", 0.15); + ratesPerPurpose6_3.put("Employee", 0.0); + ratesPerPurpose6_3.put("Employee Primary Sector", 0.58); + ratesPerPurpose6_3.put("Employee Construction", 0.58); + ratesPerPurpose6_3.put("Employee Secondary Sector Rest", 0.58); + ratesPerPurpose6_3.put("Employee Retail", 0.58); + ratesPerPurpose6_3.put("Employee Traffic/Parcels", 0.55); + ratesPerPurpose6_3.put("Employee Tertiary Sector Rest", 0.58); + + ratesPerPurpose6_4.put("Inhabitants", 0.0); + ratesPerPurpose6_4.put("Employee", 0.0); + ratesPerPurpose6_4.put("Employee Primary Sector", 0.21); + ratesPerPurpose6_4.put("Employee Construction", 0.21); + ratesPerPurpose6_4.put("Employee Secondary Sector Rest", 0.21); + ratesPerPurpose6_4.put("Employee Retail", 0.21); + ratesPerPurpose6_4.put("Employee Traffic/Parcels", 0.25); + ratesPerPurpose6_4.put("Employee Tertiary Sector Rest", 0.21); + + ratesPerPurpose6_5.put("Inhabitants", 0.0); + ratesPerPurpose6_5.put("Employee", 0.0); + ratesPerPurpose6_5.put("Employee Primary Sector", 0.0); + ratesPerPurpose6_5.put("Employee Construction", 0.0); + ratesPerPurpose6_5.put("Employee Secondary Sector Rest", 0.0); + ratesPerPurpose6_5.put("Employee Retail", 0.0); + ratesPerPurpose6_5.put("Employee Traffic/Parcels", 0.11); + ratesPerPurpose6_5.put("Employee Tertiary Sector Rest", 0.0); + } + commitmentRates.put("1_1", ratesPerPurpose1_1); + commitmentRates.put("1_2", ratesPerPurpose1_2); + commitmentRates.put("1_3", ratesPerPurpose1_3); + commitmentRates.put("1_4", ratesPerPurpose1_4); + commitmentRates.put("1_5", ratesPerPurpose1_5); + commitmentRates.put("2_1", ratesPerPurpose2_1); + commitmentRates.put("2_2", ratesPerPurpose2_2); + commitmentRates.put("2_3", ratesPerPurpose2_3); + commitmentRates.put("2_4", ratesPerPurpose2_4); + commitmentRates.put("2_5", ratesPerPurpose2_5); + commitmentRates.put("3_1", ratesPerPurpose3_1); + commitmentRates.put("3_2", ratesPerPurpose3_2); + commitmentRates.put("3_3", ratesPerPurpose3_3); + commitmentRates.put("3_4", ratesPerPurpose3_4); + commitmentRates.put("3_5", ratesPerPurpose3_5); + commitmentRates.put("4_1", ratesPerPurpose4_1); + commitmentRates.put("4_2", ratesPerPurpose4_2); + commitmentRates.put("4_3", ratesPerPurpose4_3); + commitmentRates.put("4_4", ratesPerPurpose4_4); + commitmentRates.put("4_5", ratesPerPurpose4_5); + commitmentRates.put("5_1", ratesPerPurpose5_1); + commitmentRates.put("5_2", ratesPerPurpose5_2); + commitmentRates.put("5_3", ratesPerPurpose5_3); + commitmentRates.put("5_4", ratesPerPurpose5_4); + commitmentRates.put("5_5", ratesPerPurpose5_5); + commitmentRates.put("6_1", ratesPerPurpose6_1); + commitmentRates.put("6_2", ratesPerPurpose6_2); + commitmentRates.put("6_3", ratesPerPurpose6_3); + commitmentRates.put("6_4", ratesPerPurpose6_4); + commitmentRates.put("6_5", ratesPerPurpose6_5); + } + return commitmentRates; + } +} diff --git a/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/test.output_events.xml.gz b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/test.output_events.xml.gz index 6934ebcecc0..4cac3132da0 100644 Binary files a/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/test.output_events.xml.gz and b/contribs/small-scale-traffic-generation/test/input/org/matsim/smallScaleCommercialTrafficGeneration/test.output_events.xml.gz differ diff --git a/contribs/sumo/src/main/java/org/matsim/contrib/sumo/SumoNetworkConverter.java b/contribs/sumo/src/main/java/org/matsim/contrib/sumo/SumoNetworkConverter.java index 378703db1eb..b563e1325d4 100644 --- a/contribs/sumo/src/main/java/org/matsim/contrib/sumo/SumoNetworkConverter.java +++ b/contribs/sumo/src/main/java/org/matsim/contrib/sumo/SumoNetworkConverter.java @@ -165,7 +165,10 @@ public void writeFeatures(SumoNetworkHandler handler, String output) { SumoNetworkFeatureExtractor props = new SumoNetworkFeatureExtractor(handler); try (CSVPrinter out = new CSVPrinter(IOUtils.getBufferedWriter(output), CSVFormat.DEFAULT)) { - out.printRecord(props.getHeader()); + List header = new ArrayList<>(props.getHeader()); + header.addAll(handler.attributes); + + out.printRecord(header); props.print(out); } catch (IOException e) { diff --git a/contribs/sumo/src/main/java/org/matsim/contrib/sumo/SumoNetworkFeatureExtractor.java b/contribs/sumo/src/main/java/org/matsim/contrib/sumo/SumoNetworkFeatureExtractor.java index ee8c9a45b87..91445ca7f33 100644 --- a/contribs/sumo/src/main/java/org/matsim/contrib/sumo/SumoNetworkFeatureExtractor.java +++ b/contribs/sumo/src/main/java/org/matsim/contrib/sumo/SumoNetworkFeatureExtractor.java @@ -274,6 +274,10 @@ public void print(CSVPrinter out, String linkId, SumoNetworkHandler.Edge edge) t out.print(numConnections.getInt('r')); out.print(numConnections.getInt('s')); + for (String attribute : handler.attributes) { + out.print(edge.attributes.getOrDefault(attribute, "")); + } + out.println(); } diff --git a/contribs/sumo/src/main/java/org/matsim/contrib/sumo/SumoNetworkHandler.java b/contribs/sumo/src/main/java/org/matsim/contrib/sumo/SumoNetworkHandler.java index 65de2df3a94..367be8f1827 100644 --- a/contribs/sumo/src/main/java/org/matsim/contrib/sumo/SumoNetworkHandler.java +++ b/contribs/sumo/src/main/java/org/matsim/contrib/sumo/SumoNetworkHandler.java @@ -47,6 +47,11 @@ public class SumoNetworkHandler extends DefaultHandler { */ final Map types = new HashMap<>(); + /** + * Attribute names that have been observed during parsing. + */ + Set attributes = new LinkedHashSet<>(); + /** * Stores current parsed edge. */ @@ -257,6 +262,14 @@ public void startElement(String uri, String localName, String qName, Attributes case "origTo": tmpEdge.origTo = value; break; + // Redundant attribute, that does not need to be stored + case "highway": + break; + default: + String attribute = attributes.getValue("key").intern(); + this.attributes.add(attribute); + tmpEdge.attributes.put(attribute, value); + break; } break; @@ -345,6 +358,8 @@ static final class Edge { @Nullable String origTo; + final Map attributes = new HashMap<>(); + public Edge(String id, String from, String to, String type, int priority, String name, String[] shape) { this.id = id; this.from = from; diff --git a/contribs/sumo/src/test/java/org/matsim/contrib/sumo/SumoNetworkConverterTest.java b/contribs/sumo/src/test/java/org/matsim/contrib/sumo/SumoNetworkConverterTest.java index 2bb89ec4caa..7a13bf4a440 100644 --- a/contribs/sumo/src/test/java/org/matsim/contrib/sumo/SumoNetworkConverterTest.java +++ b/contribs/sumo/src/test/java/org/matsim/contrib/sumo/SumoNetworkConverterTest.java @@ -1,6 +1,9 @@ package org.matsim.contrib.sumo; import com.google.common.io.Resources; +import org.apache.commons.csv.CSVFormat; +import org.apache.commons.csv.CSVParser; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.TransportMode; @@ -8,6 +11,8 @@ import org.matsim.api.core.v01.network.Network; import org.matsim.core.network.NetworkUtils; +import java.io.File; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardCopyOption; @@ -42,9 +47,16 @@ void convert() throws Exception { assert Files.exists(geometry) : "Geometries must exist"; - Path fts = Path.of(output.toString().replace(".xml", "-ft.csv")); + String csv = output.toString().replace(".xml", "-ft.csv"); + Path fts = Path.of(csv); assert Files.exists(fts) : "Features must exists"; + CSVParser parser = CSVParser.parse(new File(csv), StandardCharsets.UTF_8, CSVFormat.DEFAULT.builder().setHeader().setHeader().build()); + + List header = parser.getHeaderNames(); + Assertions.assertEquals("linkId", header.get(0)); + Assertions.assertEquals("highway_type", header.get(1)); + } } diff --git a/contribs/vsp/src/main/java/org/matsim/core/scoring/functions/PersonScoringParametersFromPersonAttributes.java b/contribs/vsp/src/main/java/org/matsim/core/scoring/functions/PersonScoringParametersFromPersonAttributes.java index 861a51c33c4..e5a805462bd 100644 --- a/contribs/vsp/src/main/java/org/matsim/core/scoring/functions/PersonScoringParametersFromPersonAttributes.java +++ b/contribs/vsp/src/main/java/org/matsim/core/scoring/functions/PersonScoringParametersFromPersonAttributes.java @@ -45,7 +45,7 @@ * which is an adoption of {@link org.matsim.core.scoring.functions.SubpopulationScoringParameters}. * This class additionaly allows for person-specific mode scoring parameters (for now ASC only) and marginalUtilityOfMoney. * In order to use this, you need to provide the respective attributes (otherwise default values for the subpopulation - * are used). For mode scoring parameters use .... TODO + * are used). The person specific mode parameters are interpreted as offset added to the subpopulation's parameters. * For marginalUtilityOfMoney an attribute {@link org.matsim.core.population.PersonUtils#getIncome(Person)} for persons that have a specific * income is used. Persons in the population, that have no attribute {@link org.matsim.core.population.PersonUtils#getIncome(Person)} will use the * default marginal utility set in their subpopulation's scoring parameters. @@ -160,9 +160,11 @@ public ScoringParameters getScoringParameters(Person person) { Map personalScoringModeConstants = PersonUtils.getModeConstants(person); if (personalScoringModeConstants != null) { for (Map.Entry entry: personalScoringModeConstants.entrySet()) { - ModeUtilityParameters.Builder modeUtilityParamsBuilder = new ModeUtilityParameters.Builder(); + ScoringConfigGroup.ModeParams subpopulationModeParams = subpopulationScoringParams.getModes().get(entry.getKey()); + ModeUtilityParameters.Builder modeUtilityParamsBuilder = new ModeUtilityParameters.Builder(); try { - modeUtilityParamsBuilder.setConstant(Double.parseDouble(entry.getValue())); + modeUtilityParamsBuilder.setConstant(Double.parseDouble(entry.getValue()) + + subpopulationModeParams.getConstant()); } catch (NumberFormatException e) { log.error("PersonalScoringModeConstants from person attribute could not be parsed for person " + person.getId().toString() + "."); @@ -170,7 +172,6 @@ public ScoringParameters getScoringParameters(Person person) { } // copy other params from subpopulation config - ScoringConfigGroup.ModeParams subpopulationModeParams = subpopulationScoringParams.getModes().get(entry.getKey()); modeUtilityParamsBuilder.setMarginalUtilityOfTraveling_s(subpopulationModeParams.getMarginalUtilityOfTraveling()); modeUtilityParamsBuilder.setMarginalUtilityOfDistance_m(subpopulationModeParams.getMarginalUtilityOfDistance()); modeUtilityParamsBuilder.setMonetaryDistanceRate(subpopulationModeParams.getMonetaryDistanceRate()); diff --git a/contribs/vsp/src/main/java/org/matsim/freight/carriers/analysis/CarrierPlanAnalysis.java b/contribs/vsp/src/main/java/org/matsim/freight/carriers/analysis/CarrierPlanAnalysis.java deleted file mode 100644 index 4b57935373a..00000000000 --- a/contribs/vsp/src/main/java/org/matsim/freight/carriers/analysis/CarrierPlanAnalysis.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * *********************************************************************** * - * project: org.matsim.* - * *********************************************************************** * - * * - * copyright : (C) by the members listed in the COPYING, * - * LICENSE and WARRANTY file. * - * email : info at matsim dot org * - * * - * *********************************************************************** * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * See also COPYING, LICENSE and WARRANTY file * - * * - * *********************************************************************** - * - */ - -package org.matsim.freight.carriers.analysis; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.matsim.api.core.v01.Id; -import org.matsim.core.utils.misc.Time; -import org.matsim.freight.carriers.Carrier; -import org.matsim.freight.carriers.Carriers; -import org.matsim.freight.carriers.CarriersUtils; - -import java.io.BufferedWriter; -import java.io.FileWriter; -import java.io.IOException; -import java.util.TreeMap; - -/** - * Some basic analysis / data collection for {@link Carriers}(files) - *

- * For all carriers it writes out the: - * - score of the selected plan - * - number of tours (= vehicles) of the selected plan - * - number of Services (input) - * - number of shipments (input) - * to a tsv-file. - * @author Kai Martins-Turner (kturner) - */ -public class CarrierPlanAnalysis { - - private static final Logger log = LogManager.getLogger(CarrierPlanAnalysis.class); - - Carriers carriers; - - public CarrierPlanAnalysis(Carriers carriers) { - this.carriers = carriers; - } - - public void runAnalysisAndWriteStats(String analysisOutputDirectory) throws IOException { - log.info("Writing out carrier analysis ..."); - //Load per vehicle - String fileName = analysisOutputDirectory + "Carrier_stats.tsv"; - - BufferedWriter bw1 = new BufferedWriter(new FileWriter(fileName)); - - //Write headline: - bw1.write("carrierId \t MATSimScoreSelectedPlan \t jSpritScoreSelectedPlan \t nuOfTours \t nuOfShipments(input) \t nuOfServices(input) \t jspritComputationTime[HH:mm:ss]"); - bw1.newLine(); - - final TreeMap, Carrier> sortedCarrierMap = new TreeMap<>(carriers.getCarriers()); - - for (Carrier carrier : sortedCarrierMap.values()) { - bw1.write(carrier.getId().toString()); - bw1.write("\t" + carrier.getSelectedPlan().getScore()); - bw1.write("\t" + carrier.getSelectedPlan().getJspritScore()); - bw1.write("\t" + carrier.getSelectedPlan().getScheduledTours().size()); - bw1.write("\t" + carrier.getShipments().size()); - bw1.write("\t" + carrier.getServices().size()); - if (CarriersUtils.getJspritComputationTime(carrier) != Integer.MIN_VALUE) - bw1.write("\t" + Time.writeTime(CarriersUtils.getJspritComputationTime(carrier), Time.TIMEFORMAT_HHMMSS)); - else - bw1.write("\t" + "null"); - - bw1.newLine(); - } - - bw1.close(); - log.info("Output written to " + fileName); - } -} diff --git a/contribs/vsp/src/main/java/org/matsim/freight/carriers/analysis/RunFreightAnalysisEventBased.java b/contribs/vsp/src/main/java/org/matsim/freight/carriers/analysis/RunFreightAnalysisEventBased.java deleted file mode 100644 index 44374d18dd7..00000000000 --- a/contribs/vsp/src/main/java/org/matsim/freight/carriers/analysis/RunFreightAnalysisEventBased.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * *********************************************************************** * - * project: org.matsim.* - * *********************************************************************** * - * * - * copyright : (C) by the members listed in the COPYING, * - * LICENSE and WARRANTY file. * - * email : info at matsim dot org * - * * - * *********************************************************************** * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * See also COPYING, LICENSE and WARRANTY file * - * * - * *********************************************************************** - * - */ - -package org.matsim.freight.carriers.analysis; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.matsim.api.core.v01.Scenario; -import org.matsim.freight.carriers.FreightCarriersConfigGroup; -import org.matsim.freight.carriers.CarriersUtils; -import org.matsim.freight.carriers.events.CarrierEventsReaders; -import org.matsim.core.api.experimental.events.EventsManager; -import org.matsim.core.config.Config; -import org.matsim.core.config.ConfigUtils; -import org.matsim.core.events.EventsUtils; -import org.matsim.core.events.MatsimEventsReader; -import org.matsim.core.scenario.ScenarioUtils; - -import java.io.File; -import java.io.IOException; - - -/** - * A first approach for some analysis based on the freight events introduced in 2022/23. - * This class comes from teaching SimGV in the winter term 2022/23. - *

- * This class should get extended and prepared as a standardized analysis for freight output. - * This should also get aligned with the current development in Simwrapper. - * Todo: Add some tests. - * - * @author kturner (Kai Martins-Turner) - */ -public class RunFreightAnalysisEventBased { - - private static final Logger log = LogManager.getLogger(RunFreightAnalysisEventBased.class); - - //Were is your simulation output, that should be analysed? - private final String SIM_OUTPUT_PATH ; - private final String ANALYSIS_OUTPUT_PATH; - private final String GLOBAL_CRS; - - /** - * @param simOutputPath The output directory of the simulation run - * @param analysisOutputPath The directory where the result of the analysis should go to - * @param globalCrs - */ - public RunFreightAnalysisEventBased(String simOutputPath, String analysisOutputPath, String globalCrs) { - this.SIM_OUTPUT_PATH = simOutputPath; - this.ANALYSIS_OUTPUT_PATH = analysisOutputPath; - this.GLOBAL_CRS = globalCrs; - } - - public void runAnalysis() throws IOException { - - Config config = ConfigUtils.createConfig(); - config.vehicles().setVehiclesFile(SIM_OUTPUT_PATH + "output_allVehicles.xml.gz"); - config.network().setInputFile(SIM_OUTPUT_PATH + "output_network.xml.gz"); - config.global().setCoordinateSystem(GLOBAL_CRS); - config.plans().setInputFile(null); - config.eventsManager().setNumberOfThreads(null); - config.eventsManager().setEstimatedNumberOfEvents(null); - config.global().setNumberOfThreads(1); - //freight settings - FreightCarriersConfigGroup freightCarriersConfigGroup = ConfigUtils.addOrGetModule( config, FreightCarriersConfigGroup.class ) ; - freightCarriersConfigGroup.setCarriersFile( SIM_OUTPUT_PATH + "output_carriers.xml.gz"); - freightCarriersConfigGroup.setCarriersVehicleTypesFile(SIM_OUTPUT_PATH + "output_carriersVehicleTypes.xml.gz"); - - //Were to store the analysis output? - String analysisOutputDirectory = ANALYSIS_OUTPUT_PATH; - if (!analysisOutputDirectory.endsWith("/")) { - analysisOutputDirectory = analysisOutputDirectory + "/"; - } - File folder = new File(analysisOutputDirectory); - folder.mkdirs(); - - final String eventsFile = SIM_OUTPUT_PATH + "output_events.xml.gz"; - - Scenario scenario = ScenarioUtils.loadScenario(config); - - //load carriers according to freight config - CarriersUtils.loadCarriersAccordingToFreightConfig( scenario ); - - - // CarrierPlanAnalysis - CarrierPlanAnalysis carrierPlanAnalysis = new CarrierPlanAnalysis(CarriersUtils.getCarriers(scenario)); - carrierPlanAnalysis.runAnalysisAndWriteStats(analysisOutputDirectory); - - // Prepare eventsManager - start of event based Analysis; - EventsManager eventsManager = EventsUtils.createEventsManager(); - - FreightTimeAndDistanceAnalysisEventsHandler freightTimeAndDistanceAnalysisEventsHandler = new FreightTimeAndDistanceAnalysisEventsHandler(scenario); - eventsManager.addHandler(freightTimeAndDistanceAnalysisEventsHandler); - - CarrierLoadAnalysis carrierLoadAnalysis = new CarrierLoadAnalysis(CarriersUtils.getCarriers(scenario)); - eventsManager.addHandler(carrierLoadAnalysis); - - eventsManager.initProcessing(); - MatsimEventsReader matsimEventsReader = CarrierEventsReaders.createEventsReader(eventsManager); - - matsimEventsReader.readFile(eventsFile); - eventsManager.finishProcessing(); - - log.info("Analysis completed."); - log.info("Writing output..."); - freightTimeAndDistanceAnalysisEventsHandler.writeTravelTimeAndDistancePerVehicle(analysisOutputDirectory, scenario); - freightTimeAndDistanceAnalysisEventsHandler.writeTravelTimeAndDistancePerVehicleType(analysisOutputDirectory, scenario); - carrierLoadAnalysis.writeLoadPerVehicle(analysisOutputDirectory, scenario); - } - -} diff --git a/contribs/vsp/src/test/java/org/matsim/core/scoring/functions/PersonScoringParametersFromPersonAttributesNoSubpopulationTest.java b/contribs/vsp/src/test/java/org/matsim/core/scoring/functions/PersonScoringParametersFromPersonAttributesNoSubpopulationTest.java index 395990c6a8c..9934ec2f088 100644 --- a/contribs/vsp/src/test/java/org/matsim/core/scoring/functions/PersonScoringParametersFromPersonAttributesNoSubpopulationTest.java +++ b/contribs/vsp/src/test/java/org/matsim/core/scoring/functions/PersonScoringParametersFromPersonAttributesNoSubpopulationTest.java @@ -22,7 +22,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.TransportMode; import org.matsim.api.core.v01.population.*; @@ -50,8 +49,6 @@ */ public class PersonScoringParametersFromPersonAttributesNoSubpopulationTest { - @RegisterExtension - private MatsimTestUtils utils = new MatsimTestUtils(); private PersonScoringParametersFromPersonAttributes personScoringParams; private Population population; @@ -144,7 +141,7 @@ void testPersonWithLowIncomeLowCarAsc(){ Id id = Id.createPersonId("lowIncomeLowCarAsc"); ScoringParameters params = personScoringParams.getScoringParameters(population.getPersons().get(id)); makeAssertMarginalUtilityOfMoneyAndPtWait(params, 0.5d, 0.5d); - Assertions.assertEquals(-0.1d, params.modeParams.get(TransportMode.car).constant, MatsimTestUtils.EPSILON); + Assertions.assertEquals(-1.0d -0.1d, params.modeParams.get(TransportMode.car).constant, MatsimTestUtils.EPSILON); Assertions.assertEquals(-0.001d, params.modeParams.get(TransportMode.car).marginalUtilityOfTraveling_s, MatsimTestUtils.EPSILON); } @@ -153,7 +150,7 @@ void testPersonWithHighIncomeLowCarAsc(){ Id id = Id.createPersonId("highIncomeLowCarAsc"); ScoringParameters params = personScoringParams.getScoringParameters(population.getPersons().get(id)); makeAssertMarginalUtilityOfMoneyAndPtWait(params, 1.5d, 0.5d); - Assertions.assertEquals(-0.1d, params.modeParams.get(TransportMode.car).constant, MatsimTestUtils.EPSILON); + Assertions.assertEquals(-1.0d -0.1d, params.modeParams.get(TransportMode.car).constant, MatsimTestUtils.EPSILON); Assertions.assertEquals(-0.001d, params.modeParams.get(TransportMode.car).marginalUtilityOfTraveling_s, MatsimTestUtils.EPSILON); } @@ -162,8 +159,8 @@ void testPersonWithMediumIncomeHighCarAsc(){ Id id = Id.createPersonId("mediumIncomeHighCarAsc"); ScoringParameters params = personScoringParams.getScoringParameters(population.getPersons().get(id)); makeAssertMarginalUtilityOfMoneyAndPtWait(params, 1d, 0.5d); - Assertions.assertEquals(-2.1d, params.modeParams.get(TransportMode.car).constant, MatsimTestUtils.EPSILON); - Assertions.assertEquals(-50.0d, params.modeParams.get(TransportMode.bike).constant, MatsimTestUtils.EPSILON); + Assertions.assertEquals(-1.0d -2.1d, params.modeParams.get(TransportMode.car).constant, MatsimTestUtils.EPSILON); + Assertions.assertEquals(-0.55d -50.0d, params.modeParams.get(TransportMode.bike).constant, MatsimTestUtils.EPSILON); Assertions.assertEquals(-0.001d, params.modeParams.get(TransportMode.car).marginalUtilityOfTraveling_s, MatsimTestUtils.EPSILON); } @@ -189,12 +186,12 @@ void testPersonSpecificAscScoring(){ Leg carLegZeroDistanceTenSeconds = createLeg(TransportMode.car, 0.0d, 10.0d ); legScoringRichCarLeg.handleLeg(carLegZeroDistanceTenSeconds); - Assertions.assertEquals(-0.1d -0.001d * 10 -7.5*1./1.5 -0.3, legScoringRichCarLeg.getScore(), MatsimTestUtils.EPSILON, "for the rich person with low car asc, a 0 meter and 10s car trip should be equal to a score of "); + Assertions.assertEquals(-1.0d -0.1d -0.001d * 10 -7.5*1./1.5 -0.3, legScoringRichCarLeg.getScore(), MatsimTestUtils.EPSILON, "for the rich person with low car asc, a 0 meter and 10s car trip should be equal to a score of "); ScoringParameters paramsMediumIncomeHighCarAsc = personScoringParams.getScoringParameters(population.getPersons().get(Id.createPersonId("mediumIncomeHighCarAsc"))); CharyparNagelLegScoring legScoringMediumIncomeHighCarAsc = new CharyparNagelLegScoring(paramsMediumIncomeHighCarAsc, NetworkUtils.createNetwork(), Set.of(TransportMode.pt)); legScoringMediumIncomeHighCarAsc.handleLeg(carLegZeroDistanceTenSeconds); - Assertions.assertEquals(-2.1d -0.001d * 10 -7.5*1./1.0 -0.3, legScoringMediumIncomeHighCarAsc.getScore(), MatsimTestUtils.EPSILON, "for the medium person with high car asc, a 0 meter and 10s car trip should be equal to a score of "); + Assertions.assertEquals(-1.0d -2.1d -0.001d * 10 -7.5*1./1.0 -0.3, legScoringMediumIncomeHighCarAsc.getScore(), MatsimTestUtils.EPSILON, "for the medium person with high car asc, a 0 meter and 10s car trip should be equal to a score of "); // bike has no person specific asc for high income person and is not affected CharyparNagelLegScoring legScoringRichBikeLeg = new CharyparNagelLegScoring(paramsRich, NetworkUtils.createNetwork(), Set.of(TransportMode.pt)); @@ -205,7 +202,7 @@ void testPersonSpecificAscScoring(){ // bike has a person specific asc for the medium income person CharyparNagelLegScoring legScoringMediumIncomeBikeLeg = new CharyparNagelLegScoring(paramsMediumIncomeHighCarAsc, NetworkUtils.createNetwork(), Set.of(TransportMode.pt)); legScoringMediumIncomeBikeLeg.handleLeg(bikeLegZeroDistanceZeroSeconds); - Assertions.assertEquals(-50.0d, legScoringMediumIncomeBikeLeg.getScore(), MatsimTestUtils.EPSILON, "for the medium income person with high car asc, a 0 meter and 0s bike trip should be equal to a score of "); + Assertions.assertEquals(-0.55d -50.0d, legScoringMediumIncomeBikeLeg.getScore(), MatsimTestUtils.EPSILON, "for the medium income person with high car asc, a 0 meter and 0s bike trip should be equal to a score of "); } private static Leg createLeg(String mode, double distance, double travelTime) { diff --git a/contribs/vsp/src/test/java/org/matsim/core/scoring/functions/PersonScoringParametersFromPersonAttributesTest.java b/contribs/vsp/src/test/java/org/matsim/core/scoring/functions/PersonScoringParametersFromPersonAttributesTest.java index 72f00ce92ef..2ef25ce7dea 100644 --- a/contribs/vsp/src/test/java/org/matsim/core/scoring/functions/PersonScoringParametersFromPersonAttributesTest.java +++ b/contribs/vsp/src/test/java/org/matsim/core/scoring/functions/PersonScoringParametersFromPersonAttributesTest.java @@ -22,7 +22,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.TransportMode; import org.matsim.api.core.v01.population.*; @@ -50,8 +49,6 @@ */ public class PersonScoringParametersFromPersonAttributesTest { - @RegisterExtension - private MatsimTestUtils utils = new MatsimTestUtils(); private PersonScoringParametersFromPersonAttributes personScoringParams; private Population population; @@ -166,7 +163,7 @@ void testPersonWithLowIncomeLowCarAsc(){ Id id = Id.createPersonId("lowIncomeLowCarAsc"); ScoringParameters params = personScoringParams.getScoringParameters(population.getPersons().get(id)); makeAssertMarginalUtilityOfMoneyAndPtWait(params, 0.5d, 0.5d); - Assertions.assertEquals(-0.1d, params.modeParams.get(TransportMode.car).constant, MatsimTestUtils.EPSILON); + Assertions.assertEquals(-1.0d -0.1d, params.modeParams.get(TransportMode.car).constant, MatsimTestUtils.EPSILON); Assertions.assertEquals(-0.001d, params.modeParams.get(TransportMode.car).marginalUtilityOfTraveling_s, MatsimTestUtils.EPSILON); } @@ -175,7 +172,7 @@ void testPersonWithHighIncomeLowCarAsc(){ Id id = Id.createPersonId("highIncomeLowCarAsc"); ScoringParameters params = personScoringParams.getScoringParameters(population.getPersons().get(id)); makeAssertMarginalUtilityOfMoneyAndPtWait(params, 1.5d, 0.5d); - Assertions.assertEquals(-0.1d, params.modeParams.get(TransportMode.car).constant, MatsimTestUtils.EPSILON); + Assertions.assertEquals(-1.0d -0.1d, params.modeParams.get(TransportMode.car).constant, MatsimTestUtils.EPSILON); Assertions.assertEquals(-0.001d, params.modeParams.get(TransportMode.car).marginalUtilityOfTraveling_s, MatsimTestUtils.EPSILON); } @@ -184,8 +181,8 @@ void testPersonWithMediumIncomeHighCarAsc(){ Id id = Id.createPersonId("mediumIncomeHighCarAsc"); ScoringParameters params = personScoringParams.getScoringParameters(population.getPersons().get(id)); makeAssertMarginalUtilityOfMoneyAndPtWait(params, 1d, 0.5d); - Assertions.assertEquals(-2.1d, params.modeParams.get(TransportMode.car).constant, MatsimTestUtils.EPSILON); - Assertions.assertEquals(-50.0d, params.modeParams.get(TransportMode.bike).constant, MatsimTestUtils.EPSILON); + Assertions.assertEquals(-1.0d -2.1d, params.modeParams.get(TransportMode.car).constant, MatsimTestUtils.EPSILON); + Assertions.assertEquals(-0.55d -50.0d, params.modeParams.get(TransportMode.bike).constant, MatsimTestUtils.EPSILON); Assertions.assertEquals(-0.001d, params.modeParams.get(TransportMode.car).marginalUtilityOfTraveling_s, MatsimTestUtils.EPSILON); } @@ -229,12 +226,12 @@ void testPersonSpecificAscScoring(){ Leg carLegZeroDistanceTenSeconds = createLeg(TransportMode.car, 0.0d, 10.0d ); legScoringRichCarLeg.handleLeg(carLegZeroDistanceTenSeconds); - Assertions.assertEquals(-0.1d -0.001d * 10 -7.5*1./1.5 -0.3, legScoringRichCarLeg.getScore(), MatsimTestUtils.EPSILON, "for the rich person with low car asc, a 0 meter and 10s car trip should be equal to a score of "); + Assertions.assertEquals(-1.0d -0.1d -0.001d * 10 -7.5*1./1.5 -0.3, legScoringRichCarLeg.getScore(), MatsimTestUtils.EPSILON, "for the rich person with low car asc, a 0 meter and 10s car trip should be equal to a score of "); ScoringParameters paramsMediumIncomeHighCarAsc = personScoringParams.getScoringParameters(population.getPersons().get(Id.createPersonId("mediumIncomeHighCarAsc"))); CharyparNagelLegScoring legScoringMediumIncomeHighCarAsc = new CharyparNagelLegScoring(paramsMediumIncomeHighCarAsc, NetworkUtils.createNetwork(), Set.of(TransportMode.pt)); legScoringMediumIncomeHighCarAsc.handleLeg(carLegZeroDistanceTenSeconds); - Assertions.assertEquals(-2.1d -0.001d * 10 -7.5*1./1.0 -0.3, legScoringMediumIncomeHighCarAsc.getScore(), MatsimTestUtils.EPSILON, "for the medium person with high car asc, a 0 meter and 10s car trip should be equal to a score of "); + Assertions.assertEquals(-1.0d -2.1d -0.001d * 10 -7.5*1./1.0 -0.3, legScoringMediumIncomeHighCarAsc.getScore(), MatsimTestUtils.EPSILON, "for the medium person with high car asc, a 0 meter and 10s car trip should be equal to a score of "); // bike has no person specific asc for high income person and is not affected CharyparNagelLegScoring legScoringRichBikeLeg = new CharyparNagelLegScoring(paramsRich, NetworkUtils.createNetwork(), Set.of(TransportMode.pt)); @@ -245,7 +242,7 @@ void testPersonSpecificAscScoring(){ // bike has a person specific asc for the medium income person CharyparNagelLegScoring legScoringMediumIncomeBikeLeg = new CharyparNagelLegScoring(paramsMediumIncomeHighCarAsc, NetworkUtils.createNetwork(), Set.of(TransportMode.pt)); legScoringMediumIncomeBikeLeg.handleLeg(bikeLegZeroDistanceZeroSeconds); - Assertions.assertEquals(-50.0d, legScoringMediumIncomeBikeLeg.getScore(), MatsimTestUtils.EPSILON, "for the medium income person with high car asc, a 0 meter and 0s bike trip should be equal to a score of "); + Assertions.assertEquals(-0.55d -50.0d, legScoringMediumIncomeBikeLeg.getScore(), MatsimTestUtils.EPSILON, "for the medium income person with high car asc, a 0 meter and 0s bike trip should be equal to a score of "); } private static Leg createLeg(String mode, double distance, double travelTime) { diff --git a/contribs/vsp/test/input/org/matsim/freight/carriers/analysis/FreightAnalysisEventBasedTest/runFreightAnalysisEventBasedTest/Carrier_stats.tsv b/contribs/vsp/test/input/org/matsim/freight/carriers/analysis/FreightAnalysisEventBasedTest/runFreightAnalysisEventBasedTest/Carrier_stats.tsv index d9ee80ea968..fc9ba4ea543 100644 --- a/contribs/vsp/test/input/org/matsim/freight/carriers/analysis/FreightAnalysisEventBasedTest/runFreightAnalysisEventBasedTest/Carrier_stats.tsv +++ b/contribs/vsp/test/input/org/matsim/freight/carriers/analysis/FreightAnalysisEventBasedTest/runFreightAnalysisEventBasedTest/Carrier_stats.tsv @@ -1,2 +1,2 @@ -carrierId MATSimScoreSelectedPlan jSpritScoreSelectedPlan nuOfTours nuOfShipments(input) nuOfServices(input) jspritComputationTime[HH:mm:ss] -carrier1 -263.4 null 2 0 7 null +carrierId MATSimScoreSelectedPlan jSpritScoreSelectedPlan nuOfTours nuOfShipments(input) nuOfShipments(handled) nuOfServices(input) nuOfServices(handled) nuOfPlanedDemandSize nuOfHandledDemandSize jspritComputationTime[HH:mm:ss] +carrier1 -263.4 null 2 0 0 7 7 7 7 null diff --git a/examples/scenarios/freight-chessboard-9x9/singleCarrierFiveActivities_Shipments.xml b/examples/scenarios/freight-chessboard-9x9/singleCarrierFiveActivities_Shipments.xml new file mode 100644 index 00000000000..1e6b969acaf --- /dev/null +++ b/examples/scenarios/freight-chessboard-9x9/singleCarrierFiveActivities_Shipments.xml @@ -0,0 +1,76 @@ + + + + + + 0.12 + 50 + + + + + + + + + + + + + + + + + -215.4666666666667 + + + + + + + + + + + + + + + + + + + + + + + + + i(1,0) i(2,0) i(3,0) j(3,1) j(3,2) i(4,2) i(5,2) i(6,2) j(6,2)R + + + + i(7,0) i(8,0) i(9,0) j(9,1) + + + + j(9,3) j(9,4) j(9,5) j(9,6) + + + + i(9,7)R i(8,7)R i(7,7)R i(6,7)R i(5,7)R j(4,7)R + + + + i(6,6) j(6,6)R i(6,5)R i(5,5)R j(4,5)R j(4,4)R j(4,3)R + + + + i(4,1)R i(3,1)R i(2,1)R i(1,1)R + + + + + + + \ No newline at end of file diff --git a/matsim/pom.xml b/matsim/pom.xml index e5c689b9261..76d07182ba5 100644 --- a/matsim/pom.xml +++ b/matsim/pom.xml @@ -118,7 +118,7 @@ org.apache.maven.plugins maven-surefire-report-plugin - 3.3.1 + 3.5.0 diff --git a/matsim/src/main/java/org/matsim/analysis/IterationTravelStatsControlerListener.java b/matsim/src/main/java/org/matsim/analysis/IterationTravelStatsControlerListener.java index 483f282480c..f0807fbe07e 100644 --- a/matsim/src/main/java/org/matsim/analysis/IterationTravelStatsControlerListener.java +++ b/matsim/src/main/java/org/matsim/analysis/IterationTravelStatsControlerListener.java @@ -94,15 +94,17 @@ private boolean isWriteGraph(IterationEndsEvent event){ return config.controller().getCreateGraphsInterval() > 0 && event.getIteration() % config.controller().getCreateGraphsInterval() == 0; } - private boolean isWriteTripsAndLegs(IterationEndsEvent event){ - if (config.controller().getWriteTripsInterval() <= 0) { - return false; - } + private boolean isWriteTripsAndLegs(IterationEndsEvent event) { - if (event.getIteration() == 0 || event.isLastIteration()){ - return true; + // This uses the same logic as in PlansDumpingImpl + int writeTripsInterval = config.controller().getWriteTripsInterval(); + final boolean writingTripsAtAll = writeTripsInterval > 0; + final boolean earlyIteration = event.getIteration() <= config.controller().getWritePlansInterval() ; + + if (!writingTripsAtAll) { + return false; } - return event.getIteration() % config.controller().getWriteTripsInterval() == 0; + return earlyIteration || event.isLastIteration() || event.getIteration() % writeTripsInterval == 0; } } diff --git a/matsim/src/main/java/org/matsim/core/config/consistency/VspConfigConsistencyCheckerImpl.java b/matsim/src/main/java/org/matsim/core/config/consistency/VspConfigConsistencyCheckerImpl.java index 901d5da4b5c..9fd9e5045b7 100644 --- a/matsim/src/main/java/org/matsim/core/config/consistency/VspConfigConsistencyCheckerImpl.java +++ b/matsim/src/main/java/org/matsim/core/config/consistency/VspConfigConsistencyCheckerImpl.java @@ -495,6 +495,19 @@ private static boolean checkControlerConfigGroup( Config config, Level lvl, bool case SpeedyALT: break; } + + if ( config.controller().getWritePlansInterval() <= 0 ) { + problem = true ; + System.out.flush() ; + log.log( lvl, "found writePlansInterval==0. vsp default is to write plans at least once (for simwrapper).") ; + } + + if ( config.controller().getWriteTripsInterval() <= 0 ) { + problem = true ; + System.out.flush() ; + log.log( lvl, "found writeTripsInterval==0. vsp default is to write trips at least once (for simwrapper).") ; + } + return problem; } diff --git a/matsim/src/main/java/org/matsim/core/controler/AbstractController.java b/matsim/src/main/java/org/matsim/core/controler/AbstractController.java index a1c008e31ba..6775c0fc998 100644 --- a/matsim/src/main/java/org/matsim/core/controler/AbstractController.java +++ b/matsim/src/main/java/org/matsim/core/controler/AbstractController.java @@ -79,7 +79,7 @@ protected final void run(final Config config) { public void run() throws MatsimRuntimeModifications.UnexpectedShutdownException { loadCoreListeners(); controlerListenerManagerImpl.fireControlerStartupEvent(); - ControlerUtils.checkConfigConsistencyAndWriteToLog(config, "config dump before iterations start"); + ControllerUtils.checkConfigConsistencyAndWriteToLog(config, "config dump before iterations start" ); prepareForSim(); doIterations(config); } diff --git a/matsim/src/main/java/org/matsim/core/controler/Controler.java b/matsim/src/main/java/org/matsim/core/controler/Controler.java index bc7fbdc47da..22279357ada 100755 --- a/matsim/src/main/java/org/matsim/core/controler/Controler.java +++ b/matsim/src/main/java/org/matsim/core/controler/Controler.java @@ -65,7 +65,7 @@ * * @author mrieser */ -public final class Controler implements ControlerI, MatsimServices, AllowsConfiguration{ +public final class Controler implements Controller, ControlerI, MatsimServices, AllowsConfiguration{ // yyyy Design thoughts: // * Seems to me that we should try to get everything here final. Flexibility is provided by the ability to set or add factories. If this is // not sufficient, people should use AbstractController. kai, jan'13 diff --git a/matsim/src/main/java/org/matsim/core/controler/ControlerUtils.java b/matsim/src/main/java/org/matsim/core/controler/ControlerUtils.java index 490076578e5..be978146879 100644 --- a/matsim/src/main/java/org/matsim/core/controler/ControlerUtils.java +++ b/matsim/src/main/java/org/matsim/core/controler/ControlerUtils.java @@ -1,103 +1,30 @@ -/* *********************************************************************** * - * project: org.matsim.* * - * * - * *********************************************************************** * - * * - * copyright : (C) 2008 by the members listed in the COPYING, * - * LICENSE and WARRANTY file. * - * email : info at matsim dot org * - * * - * *********************************************************************** * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * See also COPYING, LICENSE and WARRANTY file * - * * - * *********************************************************************** */ package org.matsim.core.controler; -import java.io.PrintWriter; -import java.io.StringWriter; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; +import com.google.inject.Injector; import org.matsim.api.core.v01.Scenario; import org.matsim.core.config.Config; -import org.matsim.core.config.ConfigWriter; -import org.matsim.core.controler.corelisteners.ControlerDefaultCoreListenersModule; -import org.matsim.core.scenario.ScenarioByInstanceModule; /** - * @author nagel - * + * @deprecated -- use class and methods with double l. */ -public final class ControlerUtils { - private static final Logger log = LogManager.getLogger( ControlerUtils.class ) ; +@Deprecated +public class ControlerUtils { + private ControlerUtils(){} // namespace only; do not instantiate + /** - * This is meant for creating the matsim injector if one does not need/want {@link Controler}. Technical reason is that {@link Controler} creates - * the injector in the run method, and then it is too late to extract material in a direct way. - * - * @param config * @param scenario * @return + * @deprecated -- use controller methods with double l */ - public static com.google.inject.Injector createAdhocInjector( Config config, Scenario scenario ){ - return Injector.createInjector( config, new AbstractModule(){ - @Override public void install(){ - install( new NewControlerModule() ); - install( new ControlerDefaultCoreListenersModule() ); - install( new ControlerDefaultsModule() ); - install( new ScenarioByInstanceModule( scenario ) ); - } - } ); - } - - private ControlerUtils() {} // namespace for static methods only should not be instantiated - - /** - * Design decisions: - *

    - *
  • I extracted this method since it is now called twice: once - * directly after reading, and once before the iterations start. The second - * call seems more important, but I wanted to leave the first one there in - * case the program fails before that config dump. Might be put into the - * "unexpected shutdown hook" instead. kai, dec'10 - * - * Removed the first call for now, because I am now also checking for - * consistency with loaded controler modules. If still desired, we can - * put it in the shutdown hook.. michaz aug'14 - * - *
- * - * @param config TODO - * @param message the message that is written just before the config dump - */ - public static final void checkConfigConsistencyAndWriteToLog(Config config, - final String message) { - log.info(message); - String newline = System.lineSeparator();// use native line endings for logfile - StringWriter writer = new StringWriter(); - new ConfigWriter(config).writeStream(new PrintWriter(writer), newline); - log.info(newline + newline + writer.getBuffer().toString()); - log.info("Complete config dump done."); - log.info("Checking consistency of config..."); - config.checkConsistency(); - log.info("Checking consistency of config done."); - } - - @Deprecated // use OutputDirectoryLogging.catchLogEntries() directly. kai, mar'18 - public static final void initializeOutputLogging() { - OutputDirectoryLogging.catchLogEntries(); + @Deprecated + public Controler createControler( Scenario scenario ) { + return (Controler) ControllerUtils.createController( scenario ); } - public static void catchLogEntries() { - OutputDirectoryLogging.catchLogEntries(); + public Injector createAdhocInjector( Config config, Scenario scenario ) { + return ControllerUtils.createAdhocInjector( config, scenario ); } - - public Controler createControler( Scenario scenario ) { - return new Controler( scenario ); + public Injector createAdhocInjector( Scenario scenario ) { + return ControllerUtils.createAdhocInjector( scenario ); } - } diff --git a/matsim/src/main/java/org/matsim/core/controler/Controller.java b/matsim/src/main/java/org/matsim/core/controler/Controller.java new file mode 100644 index 00000000000..17dc747424f --- /dev/null +++ b/matsim/src/main/java/org/matsim/core/controler/Controller.java @@ -0,0 +1,7 @@ +package org.matsim.core.controler; + +/** + * This is an attempt to allow a syntax that spells controller with double l. + */ +public interface Controller extends MatsimServices, AllowsConfiguration, Runnable { +} diff --git a/matsim/src/main/java/org/matsim/core/controler/ControllerUtils.java b/matsim/src/main/java/org/matsim/core/controler/ControllerUtils.java new file mode 100644 index 00000000000..05665604a40 --- /dev/null +++ b/matsim/src/main/java/org/matsim/core/controler/ControllerUtils.java @@ -0,0 +1,121 @@ +/* *********************************************************************** * + * project: org.matsim.* * + * * + * *********************************************************************** * + * * + * copyright : (C) 2008 by the members listed in the COPYING, * + * LICENSE and WARRANTY file. * + * email : info at matsim dot org * + * * + * *********************************************************************** * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * See also COPYING, LICENSE and WARRANTY file * + * * + * *********************************************************************** */ +package org.matsim.core.controler; + +import java.io.PrintWriter; +import java.io.StringWriter; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.matsim.api.core.v01.Scenario; +import org.matsim.core.config.Config; +import org.matsim.core.config.ConfigWriter; +import org.matsim.core.controler.corelisteners.ControlerDefaultCoreListenersModule; +import org.matsim.core.scenario.ScenarioByInstanceModule; + +/** + * @author nagel + * + */ +public final class ControllerUtils{ + private static final Logger log = LogManager.getLogger( ControllerUtils.class ) ; + /** + * This is meant for creating the matsim injector if one does not need/want {@link Controler}. Technical reason is that {@link Controler} creates + * the injector in the run method, and then it is too late to extract material in a direct way. + * + * @param config + * @param scenario + * @return + */ + public static com.google.inject.Injector createAdhocInjector( Config config, Scenario scenario ){ + return Injector.createInjector( config, new AbstractModule(){ + @Override public void install(){ + install( new NewControlerModule() ); + install( new ControlerDefaultCoreListenersModule() ); + install( new ControlerDefaultsModule() ); + install( new ScenarioByInstanceModule( scenario ) ); + } + } ); + } + /** + * This is meant for creating the matsim injector if one does not need/want {@link Controler}. + * Technical reason is that {@link Controler} creates + * the injector in the run method, and then it is too late to extract material in a direct way. + * + * @param scenario + * @return + */ + public static com.google.inject.Injector createAdhocInjector( Scenario scenario ){ + return Injector.createInjector( scenario.getConfig(), new AbstractModule(){ + @Override public void install(){ + install( new NewControlerModule() ); + install( new ControlerDefaultCoreListenersModule() ); + install( new ControlerDefaultsModule() ); + install( new ScenarioByInstanceModule( scenario ) ); + } + } ); + } + + private ControllerUtils() {} // namespace for static methods only should not be instantiated + + /** + * Design decisions: + *
    + *
  • I extracted this method since it is now called twice: once + * directly after reading, and once before the iterations start. The second + * call seems more important, but I wanted to leave the first one there in + * case the program fails before that config dump. Might be put into the + * "unexpected shutdown hook" instead. kai, dec'10 + * + * Removed the first call for now, because I am now also checking for + * consistency with loaded controler modules. If still desired, we can + * put it in the shutdown hook.. michaz aug'14 + * + *
+ * + * @param config TODO + * @param message the message that is written just before the config dump + */ + public static final void checkConfigConsistencyAndWriteToLog(Config config, + final String message) { + log.info(message); + String newline = System.lineSeparator();// use native line endings for logfile + StringWriter writer = new StringWriter(); + new ConfigWriter(config).writeStream(new PrintWriter(writer), newline); + log.info(newline + newline + writer.getBuffer().toString()); + log.info("Complete config dump done."); + log.info("Checking consistency of config..."); + config.checkConsistency(); + log.info("Checking consistency of config done."); + } + + @Deprecated // use OutputDirectoryLogging.catchLogEntries() directly. kai, mar'18 + public static final void initializeOutputLogging() { + OutputDirectoryLogging.catchLogEntries(); + } + + public static void catchLogEntries() { + OutputDirectoryLogging.catchLogEntries(); + } + + public static Controller createController( Scenario scenario ) { + return new Controler( scenario ); + } + +} diff --git a/matsim/src/main/java/org/matsim/core/mobsim/qsim/agents/PopulationAgentSource.java b/matsim/src/main/java/org/matsim/core/mobsim/qsim/agents/PopulationAgentSource.java index 0d5260068b6..54a862f8fd4 100644 --- a/matsim/src/main/java/org/matsim/core/mobsim/qsim/agents/PopulationAgentSource.java +++ b/matsim/src/main/java/org/matsim/core/mobsim/qsim/agents/PopulationAgentSource.java @@ -155,7 +155,7 @@ private void insertVehicles(Person person) { } // find the link ID of where to place the vehicle: - Id vehicleLinkId = findVehicleLink(person); + Id vehicleLinkId = findVehicleLink(person, vehicle); // Checking if the vehicle has been seen before: Id result = this.seenVehicleIds.get( vehicleId ) ; @@ -190,7 +190,15 @@ private void insertVehicles(Person person) { * than to ask agent.getCurrentLinkId() after creation. * @param person TODO */ - private Id findVehicleLink(Person person ) { + private Id findVehicleLink(Person person, Vehicle vehicle) { + /* + * Manual case: the initial link id of the vehicle is saved as an attribute + */ + Id initialLinkId = VehicleUtils.getInitialLinkId(vehicle); + if (initialLinkId != null) { + return initialLinkId; + } + /* Cases that come to mind: * (1) multiple persons share car located at home, but possibly brought to different place by someone else. * This is treated by the following algo. diff --git a/matsim/src/main/java/org/matsim/core/mobsim/qsim/qnetsimengine/QueueWithBuffer.java b/matsim/src/main/java/org/matsim/core/mobsim/qsim/qnetsimengine/QueueWithBuffer.java index 741763e4c87..947b2faa2a6 100644 --- a/matsim/src/main/java/org/matsim/core/mobsim/qsim/qnetsimengine/QueueWithBuffer.java +++ b/matsim/src/main/java/org/matsim/core/mobsim/qsim/qnetsimengine/QueueWithBuffer.java @@ -40,7 +40,6 @@ import org.matsim.core.config.groups.QSimConfigGroup.LinkDynamics; import org.matsim.core.config.groups.QSimConfigGroup.TrafficDynamics; import org.matsim.core.gbl.Gbl; -import org.matsim.core.gbl.MatsimRandom; import org.matsim.core.mobsim.framework.MobsimDriverAgent; import org.matsim.core.mobsim.qsim.interfaces.MobsimVehicle; import org.matsim.core.mobsim.qsim.interfaces.SignalGroupState; @@ -63,8 +62,8 @@ * Separating out the "lane" functionality from the "link" functionality. *

* Design thoughts:
    - *
  • In fast capacity update, the flows are not accumulated in every time step, - * rather updated only if an agent wants to enter the link or an agent is added to buffer. + *
  • In fast capacity update, the flows are not accumulated in every time step, + * rather updated only if an agent wants to enter the link or an agent is added to buffer. * Improvement of 15-20% in the computational performance is observed. amit feb'16 * (I seem to recall that in the end that statement was not consistently correct. kai, feb'18)
  • *
  • Currently (feb'18), the design is such that (possibly time-dep) flowCap and nEffectiveLanes are "pushed" into the @@ -90,7 +89,7 @@ public final void addFromWait(final QVehicle veh) { addToBuffer(veh); } - + /** * Stores the accumulated fractional parts of the flow capacity. See also * flowCapFraction. @@ -189,7 +188,7 @@ private void addValue(double value1, double now) { private double effectiveNumberOfLanesUsedInQsim = Double.POSITIVE_INFINITY ; private double accumulatedInflowCap = 1. ; - + private final FlowEfficiencyCalculator flowEfficiencyCalculator; private QueueWithBuffer(AbstractQLink.QLinkInternalInterface qlink, final VehicleQ vehicleQueue, Id laneId, @@ -198,7 +197,7 @@ private QueueWithBuffer(AbstractQLink.QLinkInternalInterface qlink, final Vehicl // the general idea is to give this object no longer access to "everything". Objects get back pointers (here qlink), but they // do not present the back pointer to the outside. In consequence, this object can go up to qlink, but not any further. kai, mar'16 // Now I am even trying to get rid of the full qLink back pointer (since it allows, e.g., going back to Link). kai, feb'18 - + // log.setLevel(Level.DEBUG); this.flowEfficiencyCalculator = flowEfficiencyCalculator; @@ -328,7 +327,7 @@ private void updateFastFlowAccumulation(){ double now = context.getSimTimer().getTimeOfDay() ; double remainingFlowCapThisTimeStep = subtractConsumptionOfVehiclesThatAreAlreadyInTheBuffer(); - + if( this.flowcap_accumulate.getTimeStep() < now && this.flowcap_accumulate.getValue() < remainingFlowCapThisTimeStep){ @@ -344,7 +343,7 @@ private void updateFastFlowAccumulation(){ private void updateSlowFlowAccumulation(){ double remainingFlowCapThisTimeStep = subtractConsumptionOfVehiclesThatAreAlreadyInTheBuffer(); - + if (this.thisTimeStepGreen && this.flowcap_accumulate.getValue() < remainingFlowCapThisTimeStep){ double newFlowCap = Math.min(flowcap_accumulate.getValue() + flowCapacityPerTimeStep, @@ -372,15 +371,15 @@ public final void initBeforeSimStep() { private void calculateFlowCapacity() { // the following is not looking at time because it simply assumes that the lookups are "now". kai, feb'18 // I am currently not sure if this statement is correct. kai, feb'18 - + // we need the flow capacity per sim-tick and multiplied with flowCapFactor flowCapacityPerTimeStep = unscaledFlowCapacity_s * context.qsimConfig.getTimeStepSize() * context.qsimConfig.getFlowCapFactor() ; inverseFlowCapacityPerTimeStep = 1.0 / flowCapacityPerTimeStep; - + // start with the base assumption, might be adjusted below depending on the traffic dynamics this.effectiveNumberOfLanesUsedInQsim = this.effectiveNumberOfLanes; this.maxInflowUsedInQsim = this.flowCapacityPerTimeStep; - + switch (context.qsimConfig.getTrafficDynamics()) { case queue: case withHoles: @@ -391,10 +390,10 @@ private void calculateFlowCapacity() { // equal: rho * (vmax + vhole) = vhole * rhojam // rho(qmax) = vhole * rhojam / (vmax + vhole) // qmax = vmax * rho(qmax) = rhojam / (1/vhole + 1/vmax) ; - + // yyyyyy this should possibly be getFreespeed(now). But if that's the case, then maxFlowFromFdiag would // also have to be re-computed with each freespeed change. kai, feb'18 - + final double maxFlowFromFdiag = (this.effectiveNumberOfLanes/context.effectiveCellSize) / ( 1./(HOLE_SPEED_KM_H/3.6) + 1/this.qLinkInternalInterface.getFreespeed() ) ; final double minimumNumberOfLanesFromFdiag = this.flowCapacityPerTimeStep * context.effectiveCellSize * ( 1./(HOLE_SPEED_KM_H/3.6) + 1/this.qLinkInternalInterface.getFreespeed() ); @@ -455,19 +454,19 @@ private void calculateFlowCapacity() { } } break; - + default: throw new RuntimeException("The traffic dynamics "+context.qsimConfig.getTrafficDynamics()+" is not implemented yet."); } // log.debug( "linkId=" + this.qLink.getLink().getId() + "; flowCapPerTimeStep=" + flowCapacityPerTimeStep + // "; invFlowCapPerTimeStep=" + inverseFlowCapacityPerTimeStep + "; maxFlowFromFdiag=" + maxFlowFromFdiag ) ; - + } private void calculateStorageCapacity() { // The following is not adjusted for time-dependence!! kai, apr'16 // No, I think that it simply assumes that the lookups are "now". kai, feb'18 // double now = context.getSimTimer().getTimeOfDay() ; - + // first guess at storageCapacity: storageCapacity = this.length * this.effectiveNumberOfLanesUsedInQsim / context.effectiveCellSize * context.qsimConfig.getStorageCapFactor() ; // storageCapacity = this.length * this.qLink.getLink().getNumberOfLanes(now) / context.effectiveCellSize * context.qsimConfig.getStorageCapFactor() ; @@ -489,7 +488,7 @@ private void calculateStorageCapacity() { if (Double.isNaN(freespeedTravelTime)) { throw new IllegalStateException("Double.NaN is not a valid freespeed travel time for a link. Please check the attributes length and freespeed!"); } - + //this assumes that vehicles have the flowEfficiencyFactor of 1.0; the actual flow can be different double tempStorageCapacity = freespeedTravelTime * unscaledFlowCapacity_s * context.qsimConfig.getFlowCapFactor(); // yy note: freespeedTravelTime may be Inf. In this case, storageCapacity will also be set to Inf. This can still be @@ -505,7 +504,7 @@ private void calculateStorageCapacity() { QueueWithBuffer.spaceCapWarningCount++; } storageCapacity = tempStorageCapacity; - + // write out the modified qsim behavior as link attribute qLinkInternalInterface.getLink().getAttributes().putAttribute("storageCapacityUsedInQsim", storageCapacity ); } @@ -514,7 +513,7 @@ private void calculateStorageCapacity() { * () uncongested branch is q(rho) = rho * v_max * () congested branch is q(rho) = (rho - rho_jam) * v_holes * () rho_maxflow is where these two meet, resulting in rho_maxflow = v_holes * rho_jam / ( v_holes + v_max ) - * () max flow is q(rho_maxflow), resulting in v_max * v_holes * rho_jam / ( v_holes + v_max ) + * () max flow is q(rho_maxflow), resulting in v_max * v_holes * rho_jam / ( v_holes + v_max ) * () Since everything else is given, rho_jam needs to be large enough so that q(rho_maxflow) can reach capacity, resulting in * rho_jam >= capacity * (v_holes + v_max) / (v_max * v_holes) ; * () In consequence, storage capacity needs to be larger than curved_length * rho_jam . @@ -554,7 +553,7 @@ private void calculateStorageCapacity() { } private double getBufferStorageCapacity() { - return flowCapacityPerTimeStep;//this assumes that vehicles have the flowEfficiencyFactor of 1.0 + return flowCapacityPerTimeStep;//this assumes that vehicles have the flowEfficiencyFactor of 1.0 } @Override @@ -664,7 +663,6 @@ private void removeVehicleFromQueue(final QVehicle veh2Remove) { case withHoles: case kinematicWaves: QueueWithBuffer.Hole hole = new QueueWithBuffer.Hole() ; - double ttimeOfHoles = length*3600./HOLE_SPEED_KM_H/1000. ; // double offset = this.storageCapacity/this.flowCapacityPerTimeStep ; /* NOTE: Start with completely full link, i.e. N_storageCap cells filled. Now make light at end of link green, discharge with @@ -680,7 +678,12 @@ private void removeVehicleFromQueue(final QVehicle veh2Remove) { // double nLanes = 2. * flowCapacityPerTimeStep ; // pseudo-lanes // double ttimeOfHoles = 0.1 * this.storageCapacity/this.flowCapacityPerTimeStep/nLanes ; - hole.setEarliestLinkExitTime( now + 1.0*ttimeOfHoles + 0.0*MatsimRandom.getRandom().nextDouble()*ttimeOfHoles ) ; + // The calculation of the earliest exit time looked like the formula below. It looks like someone tried to include some randomness, + // but the random part was multiplied with zero, therefore I removed it. Janek oct' 24 + // now + 1.0*ttimeOfHoles + 0.0*MatsimRandom.getRandom().nextDouble()*ttimeOfHoles + var holeTravelTime = length * 3.6 / HOLE_SPEED_KM_H; + var earliestExitTime = now + holeTravelTime; + hole.setEarliestLinkExitTime(earliestExitTime) ; hole.setSizeInEquivalents(veh2Remove.getSizeInEquivalents()); holes.add( hole ) ; break; @@ -747,9 +750,9 @@ public void recalcTimeVariantAttributes() { // not speed, since that is looked up anyways. // yy might also make flow and storage self-detecting changes (not really that // much more expensive). kai, feb'18 - + // log.debug("just entered recalcTimeVariantAttributes; now=" + this.context.getSimTimer().getTimeOfDay() ) ; - + calculateFlowCapacity(); calculateStorageCapacity(); flowcap_accumulate.setValue(flowCapacityPerTimeStep); @@ -916,7 +919,7 @@ public final double getLastMovementTimeOfFirstVehicle() { public final void addTransitSlightlyUpstreamOfStop( final QVehicle veh) { this.vehQueue.addFirst(veh) ; } - + @Override public final void setSignalized( final boolean isSignalized) { qSignalizedItem = new DefaultSignalizeableItem( qLinkInternalInterface.getToNode().getOutLinks().keySet()); @@ -1020,7 +1023,7 @@ void setVisInfo(Coord upstreamCoord, Coord downstreamCoord) { this.downstreamCoord = downstreamCoord; } } - + private int noOfSeepModeBringFwd = 0; private QVehicle peekFromVehQueue(){ diff --git a/matsim/src/main/java/org/matsim/core/trafficmonitoring/TravelTimeCalculatorModule.java b/matsim/src/main/java/org/matsim/core/trafficmonitoring/TravelTimeCalculatorModule.java index 687cc456271..577f57583ce 100644 --- a/matsim/src/main/java/org/matsim/core/trafficmonitoring/TravelTimeCalculatorModule.java +++ b/matsim/src/main/java/org/matsim/core/trafficmonitoring/TravelTimeCalculatorModule.java @@ -26,7 +26,8 @@ import com.google.inject.Key; import com.google.inject.Singleton; import com.google.inject.name.Names; - +import jakarta.inject.Inject; +import jakarta.inject.Provider; import org.matsim.api.core.v01.network.Network; import org.matsim.core.api.experimental.events.EventsManager; import org.matsim.core.config.groups.TravelTimeCalculatorConfigGroup; @@ -35,8 +36,7 @@ import org.matsim.core.router.util.TravelTime; import org.matsim.core.utils.collections.CollectionUtils; -import jakarta.inject.Inject; -import jakarta.inject.Provider; +import java.util.Set; /** @@ -55,28 +55,42 @@ public void install() { if (getConfig().travelTimeCalculator().isCalculateLinkToLinkTravelTimes()) { throw new RuntimeException("separate modes together with link2link routing currently not implemented. doesn't look difficult, " - + "but I cannot say if it would be picked up correctly by downstream modules. kai, nov'16") ; + + "but I cannot say if it would be picked up correctly by downstream modules. kai, nov'16"); } + + Set analyzedModes = getConfig().travelTimeCalculator().getAnalyzedModes(); + // go through all modes: // for (final String mode : CollectionUtils.stringToSet(getConfig().travelTimeCalculator().getAnalyzedModesAsString() )) { - for (final String mode : getConfig().routing().getNetworkModes() ) { + for (final String mode : getConfig().routing().getNetworkModes()) { - // generate and bind the observer: - bind(TravelTimeCalculator.class).annotatedWith(Names.named(mode)).toProvider(new SingleModeTravelTimeCalculatorProvider(mode)).in(Singleton.class); + if (analyzedModes.contains(mode)) { + // generate and bind the observer: + bind(TravelTimeCalculator.class).annotatedWith(Names.named(mode)).toProvider(new SingleModeTravelTimeCalculatorProvider(mode)).in(Singleton.class); - // bind the observer to travel time provider (for router): - addTravelTimeBinding(mode).toProvider(new Provider() { - @Inject Injector injector; - @Override public TravelTime get() { - return injector.getInstance( Key.get( TravelTimeCalculator.class, Names.named( mode ) ) ).getLinkTravelTimes(); - } + // bind the observer to travel time provider (for router): + addTravelTimeBinding(mode).toProvider(new Provider() { + @Inject + Injector injector; - // the following is not there yet (leads to NPE). Presumably, the collection into the underlying multi-binder is - // done later, and until then it is only available per annotation (as above)? kai, nov'19 + @Override + public TravelTime get() { + return injector.getInstance(Key.get(TravelTimeCalculator.class, Names.named(mode))).getLinkTravelTimes(); + } + + // the following is not there yet (leads to NPE). Presumably, the collection into the underlying multi-binder is + // done later, and until then it is only available per annotation (as above)? kai, nov'19 // @Inject Map travelTimes ; // @Override public TravelTime get() { return travelTimes.get( mode ) ; } - }).in( Singleton.class ); - // (This used to be without "Singleton". I think that with Singleton it makes more sense, but don't know ramifications. kai, nov'19) + }).in(Singleton.class); + // (This used to be without "Singleton". I think that with Singleton it makes more sense, but don't know ramifications. kai, nov'19) + } else { + + // For modes that are not analyzed, no travel time calculator is bound + // however, travel time is still provided + addTravelTimeBinding(mode).to(FreeSpeedTravelTime.class).in(Singleton.class); + + } } } else { @@ -88,7 +102,7 @@ public void install() { // bind the TravelTime objects. In this case, this just passes on the same information from TravelTimeCalculator to each individual mode: if (getConfig().travelTimeCalculator().isCalculateLinkTravelTimes()) { // for (String mode : CollectionUtils.stringToSet(getConfig().travelTimeCalculator().getAnalyzedModesAsString() )) { - for ( String mode : getConfig().routing().getNetworkModes() ) { + for (String mode : getConfig().routing().getNetworkModes()) { addTravelTimeBinding(mode).toProvider(ObservedLinkTravelTimes.class); } } @@ -101,9 +115,12 @@ public void install() { private static class SingleModeTravelTimeCalculatorProvider implements Provider { - @Inject TravelTimeCalculatorConfigGroup config; - @Inject EventsManager eventsManager; - @Inject Network network; + @Inject + TravelTimeCalculatorConfigGroup config; + @Inject + EventsManager eventsManager; + @Inject + Network network; private String mode; @@ -117,17 +134,17 @@ public TravelTimeCalculator get() { // config.isCalculateLinkTravelTimes(), config.isCalculateLinkToLinkTravelTimes(), true, CollectionUtils.stringToSet(mode)); // eventsManager.addHandler(calculator); // return TravelTimeCalculator.configure(calculator, config, network); - TravelTimeCalculator.Builder builder = new TravelTimeCalculator.Builder( network ); - builder.setTimeslice( config.getTraveltimeBinSize() ); - builder.setMaxTime( config.getMaxTime() ); - builder.setCalculateLinkTravelTimes( config.isCalculateLinkTravelTimes() ); - builder.setCalculateLinkToLinkTravelTimes( config.isCalculateLinkToLinkTravelTimes() ); - builder.setFilterModes( true ); // no point asking the config since we are in "separateModes" anyways. - builder.setAnalyzedModes( CollectionUtils.stringToSet( mode ) ); - builder.configure( config ); + TravelTimeCalculator.Builder builder = new TravelTimeCalculator.Builder(network); + builder.setTimeslice(config.getTraveltimeBinSize()); + builder.setMaxTime(config.getMaxTime()); + builder.setCalculateLinkTravelTimes(config.isCalculateLinkTravelTimes()); + builder.setCalculateLinkToLinkTravelTimes(config.isCalculateLinkToLinkTravelTimes()); + builder.setFilterModes(true); // no point asking the config since we are in "separateModes" anyways. + builder.setAnalyzedModes(CollectionUtils.stringToSet(mode)); + builder.configure(config); TravelTimeCalculator calculator = builder.build(); - eventsManager.addHandler( calculator ); - return calculator ; + eventsManager.addHandler(calculator); + return calculator; } } diff --git a/matsim/src/main/java/org/matsim/pt/utils/TransitScheduleValidator.java b/matsim/src/main/java/org/matsim/pt/utils/TransitScheduleValidator.java index cfd96dbe88f..5f05825abc1 100644 --- a/matsim/src/main/java/org/matsim/pt/utils/TransitScheduleValidator.java +++ b/matsim/src/main/java/org/matsim/pt/utils/TransitScheduleValidator.java @@ -20,17 +20,12 @@ package org.matsim.pt.utils; import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Set; +import java.util.*; import javax.xml.parsers.ParserConfigurationException; +import it.unimi.dsi.fastutil.doubles.DoubleArrayList; +import it.unimi.dsi.fastutil.doubles.DoubleList; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.network.Link; import org.matsim.api.core.v01.network.Network; @@ -39,13 +34,9 @@ import org.matsim.core.population.routes.NetworkRoute; import org.matsim.core.scenario.MutableScenario; import org.matsim.core.scenario.ScenarioUtils; -import org.matsim.pt.transitSchedule.api.MinimalTransferTimes; -import org.matsim.pt.transitSchedule.api.TransitLine; -import org.matsim.pt.transitSchedule.api.TransitRoute; -import org.matsim.pt.transitSchedule.api.TransitRouteStop; -import org.matsim.pt.transitSchedule.api.TransitSchedule; -import org.matsim.pt.transitSchedule.api.TransitScheduleReader; -import org.matsim.pt.transitSchedule.api.TransitStopFacility; +import org.matsim.core.utils.geometry.CoordUtils; +import org.matsim.core.utils.geometry.GeometryUtils; +import org.matsim.pt.transitSchedule.api.*; import org.xml.sax.SAXException; /** @@ -248,6 +239,135 @@ public static ValidationResult validateTransfers(final TransitSchedule schedule) return result; } + public static ValidationResult validateDepartures(TransitSchedule schedule) { + ValidationResult result = new ValidationResult(); + for (TransitLine line : schedule.getTransitLines().values()) { + for (TransitRoute route : line.getRoutes().values()) { + if (route.getDepartures().isEmpty()) + result.addError("No departures defined for line %s, route %s".formatted(line.getId(), route.getId())); + + } + } + + return result; + } + + /** + * Validate if coordinates of stops and given travel times are plausible. + */ + public static ValidationResult validateStopCoordinates(final TransitSchedule schedule) { + + ValidationResult result = new ValidationResult(); + + // List of stops to the collected suspicious stops + Map suspiciousStops = new TreeMap<>(Comparator.comparing(TransitStopFacility::getName)); + + for (TransitLine line : schedule.getTransitLines().values()) { + + for (TransitRoute route : line.getRoutes().values()) { + + List routeStops = route.getStops(); + + // For too short routes, we can not detect outliers + if (routeStops.size() <= 4) + continue; + + double lastDepartureOffset = routeStops.getFirst().getDepartureOffset().or(routeStops.getFirst().getArrivalOffset()).seconds(); + + DoubleList speeds = new DoubleArrayList(); + DoubleList dists = new DoubleArrayList(); + + for (int i = 1; i < routeStops.size(); i++) { + TransitRouteStop routeStop = routeStops.get(i); + + if (routeStop.getStopFacility().getCoord() == null) + break; + + double departureOffset = routeStop.getArrivalOffset().or(routeStop.getDepartureOffset()).orElse(0); + double travelTime = departureOffset - lastDepartureOffset; + double length = CoordUtils.calcEuclideanDistance(routeStop.getStopFacility().getCoord(), + routeStops.get(i - 1).getStopFacility().getCoord()); + + dists.add(length); + + // Short distances are not checked, because here high speeds are not so problematic and arise from few seconds difference + if (length <= 20) { + speeds.add(-1); + continue; + } + + if (travelTime == 0) { + speeds.add(Double.POSITIVE_INFINITY); + continue; + } + + double speed = length / travelTime; + speeds.add(speed); + lastDepartureOffset = departureOffset; + } + + // If all speeds are valid, the stops and speeds can be checked + if (speeds.size() == routeStops.size() - 1) { + + // First check for suspicious stops + // These are stops with very high speed, and also high distance between stops + for (int i = 0; i < speeds.size() - 1; i++) { + TransitRouteStop stop = routeStops.get(i + 1); + double toStop = speeds.getDouble(i); + double fromStop = speeds.getDouble(i + 1); + + double both = (toStop + fromStop) / 2; + + double dist = (dists.getDouble(i) + dists.getDouble(i + 1)) / 2; + + // Only if the distance is large, we assume a mapping error might have occurred + if (dist < 5_000) + continue; + + // Remove the considered speeds from the calculation + DoubleList copy = new DoubleArrayList(speeds); + copy.removeDouble(i); + copy.removeDouble(i); + copy.removeIf(s -> s == -1 || s == Double.POSITIVE_INFINITY); + + double mean = copy.doubleStream().average().orElse(-1); + + // If no mean is known, use a high value to avoid false positives + if (mean == -1) { + mean = 70; + } + + // Some hard coded rules to detect suspicious stops, these are speed m/s, so quite high values + if (((toStop > 3 * mean && both > 50) || toStop > 120) && (((fromStop > 3 * mean && both > 50) || fromStop > 120))) { + DoubleList suspiciousSpeeds = suspiciousStops.computeIfAbsent(stop.getStopFacility(), (k) -> new DoubleArrayList()); + suspiciousSpeeds.add(toStop); + suspiciousSpeeds.add(fromStop); + } + } + + // Then check for implausible travel times + for (int i = 0; i < speeds.size(); i++) { + double speed = speeds.getDouble(i); + TransitStopFacility from = routeStops.get(i).getStopFacility(); + TransitStopFacility to = routeStops.get(i + 1).getStopFacility(); + if (speed > 230) { + result.addWarning("Suspicious high speed from stop %s (%s) to %s (%s) on line %s, route %s, index: %d: %.2f m/s, %.2fm" + .formatted(from.getName(), from.getId(), to.getName(), to.getId(), line.getId(), route.getId(), i, speed, dists.getDouble(i))); + } + } + } + } + } + + for (Map.Entry e : suspiciousStops.entrySet()) { + TransitStopFacility stop = e.getKey(); + double speed = e.getValue().doubleStream().average().orElse(-1); + result.addWarning("Suspicious location for stop %s (%s) at stop area %s: %s, avg. speed: %.2f m/s".formatted(stop.getName(), stop.getId(), stop.getStopAreaId(), stop.getCoord(), speed)); + } + + return result; + } + public static ValidationResult validateAll(final TransitSchedule schedule, final Network network) { ValidationResult v = validateUsedStopsHaveLinkId(schedule); v.add(validateNetworkRoutes(schedule, network)); @@ -259,6 +379,8 @@ public static ValidationResult validateAll(final TransitSchedule schedule, final v.add(validateAllStopsExist(schedule)); v.add(validateOffsets(schedule)); v.add(validateTransfers(schedule)); + v.add(validateStopCoordinates(schedule)); + v.add(validateDepartures(schedule)); return v; } diff --git a/matsim/src/main/java/org/matsim/vehicles/VehicleUtils.java b/matsim/src/main/java/org/matsim/vehicles/VehicleUtils.java index 70027f8a0b5..aac3e537da9 100644 --- a/matsim/src/main/java/org/matsim/vehicles/VehicleUtils.java +++ b/matsim/src/main/java/org/matsim/vehicles/VehicleUtils.java @@ -20,17 +20,18 @@ package org.matsim.vehicles; +import java.util.HashMap; +import java.util.Map; + import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.Scenario; +import org.matsim.api.core.v01.network.Link; import org.matsim.api.core.v01.population.Person; import org.matsim.core.gbl.Gbl; import org.matsim.utils.objectattributes.attributable.AttributesUtils; -import java.util.HashMap; -import java.util.Map; - /** * @author nagel @@ -57,6 +58,7 @@ public final class VehicleUtils { private static final String COST_PER_SECOND_WAITING = "costsPerSecondWaiting"; private static final String COST_PER_SECOND_INSERVICE = "costsPerSecondInService"; private static final String FUEL_TYPE = "fuelType"; + private static final String INITIAL_LINK_ID = "initialLinkId"; public static VehicleType createVehicleType( Id typeId ){ return new VehicleType( typeId ); @@ -432,4 +434,13 @@ public static void writeVehicles( Vehicles vehicles, String filename ) { new MatsimVehicleWriter( vehicles ).writeFile( filename ); } + + public static Id getInitialLinkId(Vehicle vehicle) { + String attribute = (String) vehicle.getAttributes().getAttribute(INITIAL_LINK_ID); + return attribute == null ? null : Id.createLinkId(attribute); + } + + public static void setInitialLinkId(Vehicle vehicle, Id initialLinkId) { + vehicle.getAttributes().putAttribute(INITIAL_LINK_ID, initialLinkId.toString()); + } } diff --git a/matsim/src/main/resources/dtd/plans_v4.dtd b/matsim/src/main/resources/dtd/plans_v4.dtd index 3fa4889d1b8..258030b9b7d 100755 --- a/matsim/src/main/resources/dtd/plans_v4.dtd +++ b/matsim/src/main/resources/dtd/plans_v4.dtd @@ -38,15 +38,15 @@ - - - - - - + + + + + + @@ -71,7 +71,7 @@ id CDATA #REQUIRED x CDATA #IMPLIED y CDATA #IMPLIED - freq CDATA #IMPLIED + freq CDATA #IMPLIED isPrimary (yes|no) "no"> @@ -96,7 +96,7 @@ type CDATA #REQUIRED x CDATA #IMPLIED y CDATA #IMPLIED - link CDATA #IMPLIED + link CDATA #IMPLIED facility CDATA #IMPLIED start_time CDATA #IMPLIED end_time CDATA #IMPLIED diff --git a/matsim/src/test/java/org/matsim/core/mobsim/qsim/qnetsimengine/QueueWithBufferTest.java b/matsim/src/test/java/org/matsim/core/mobsim/qsim/qnetsimengine/QueueWithBufferTest.java new file mode 100644 index 00000000000..244f51b1246 --- /dev/null +++ b/matsim/src/test/java/org/matsim/core/mobsim/qsim/qnetsimengine/QueueWithBufferTest.java @@ -0,0 +1,199 @@ +package org.matsim.core.mobsim.qsim.qnetsimengine; + +import org.junit.jupiter.api.Test; +import org.matsim.api.core.v01.Coord; +import org.matsim.api.core.v01.Id; +import org.matsim.core.api.experimental.events.EventsManager; +import org.matsim.core.config.Config; +import org.matsim.core.config.ConfigUtils; +import org.matsim.core.config.groups.QSimConfigGroup; +import org.matsim.core.mobsim.framework.MobsimDriverAgent; +import org.matsim.core.mobsim.framework.MobsimTimer; +import org.matsim.core.mobsim.qsim.interfaces.AgentCounter; +import org.matsim.core.network.NetworkUtils; +import org.matsim.vehicles.VehicleType; +import org.matsim.vehicles.VehicleUtils; +import org.matsim.vis.snapshotwriters.SnapshotLinkWidthCalculator; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.mock; + +/** + * This suite of unit tests is not exhaustive! I wrote these tests, because I wanted to understand what is happening when the QueueWithBuffer is operated + * with config::qsim.trafficDynamics = 'kinematicWaves'. + */ +class QueueWithBufferTest { + + @Test + void initLinkQueue() { + + var config = ConfigUtils.createConfig(); + var context = createNetsimeEngineContext(config, new MobsimTimer()); + var link = createQLink(10, 2, 5400, context, config); + + assertEquals(1, link.getOfferingQLanes().size()); + assertEquals(link.getAcceptingQLane(), link.getOfferingQLanes().getFirst()); + QueueWithBuffer qwb = (QueueWithBuffer) link.getAcceptingQLane(); + assertEquals(1.5, qwb.getSimulatedFlowCapacityPerTimeStep()); + assertEquals(2 * 2, qwb.getStorageCapacity()); + } + + @Test + void initLinkKinematicWaves() { + + var config = ConfigUtils.createConfig(); + config.qsim().setTrafficDynamics(QSimConfigGroup.TrafficDynamics.kinematicWaves); + var context = createNetsimeEngineContext(config, new MobsimTimer()); + var link = createQLink(10, 2, 5400, context, config); + + assertEquals(1, link.getOfferingQLanes().size()); + assertEquals(link.getAcceptingQLane(), link.getOfferingQLanes().getFirst()); + QueueWithBuffer qwb = (QueueWithBuffer) link.getAcceptingQLane(); + assertEquals(1.5, qwb.getSimulatedFlowCapacityPerTimeStep()); + + var vHole = 15 / 3.6; + // according to https://doi.org/10.1080/23249935.2017.1364802 equation 7 + var expectedStorageCap = link.getSimulatedFlowCapacityPerTimeStep() * link.getLink().getLength() * ( 1 / link.getLink().getFreespeed() + 1 / vHole); + assertEquals(expectedStorageCap, qwb.getStorageCapacity(), 0.001); + } + + @Test + void freeStorageQueue() { + var config = ConfigUtils.createConfig(); + var timer = new MobsimTimer(); + var context = createNetsimeEngineContext(config, timer); + var link = createQLink(10, 1, 1800, context, config); + var driver = mock(MobsimDriverAgent.class); + var vehicle1 = createVehicle("vehicle-1", driver, 10,1); + var vehicle2 = createVehicle("vehicle-2", driver, 10,1); + + // the link should accept vehicles until the storage capacity is exhausted + assertTrue(link.getAcceptingQLane().isAcceptingFromUpstream()); + link.getAcceptingQLane().addFromUpstream(vehicle1); + assertTrue(link.getAcceptingQLane().isAcceptingFromUpstream()); + link.getAcceptingQLane().addFromUpstream(vehicle2); + assertFalse(link.getAcceptingQLane().isAcceptingFromUpstream()); + + // this should move one vehicle into the buffer, and free one pcu in the queue immediately + timer.setTime(1); + link.doSimStep(); + + // test that capacity is available at the upstream end of the queue + assertTrue(link.getAcceptingQLane().isAcceptingFromUpstream()); + + // test that only one vehicle was moved into the buffer. Remove the first vehicle, and then the link should not offer more vehicles + assertEquals(vehicle1.getId(), link.getOfferingQLanes().getFirst().popFirstVehicle().getId()); + // this double negation is so terrible! + assertTrue(link.getOfferingQLanes().getFirst().isNotOfferingVehicle()); + } + + @Test + void freeStorageKinematicWaves() { + var config = ConfigUtils.createConfig(); + config.qsim().setTrafficDynamics(QSimConfigGroup.TrafficDynamics.kinematicWaves); + var timer = new MobsimTimer(); + var context = createNetsimeEngineContext(config, timer); + var link = createQLink(15, 1, 1800, context, config); + var driver = mock(MobsimDriverAgent.class); + var vehicle1 = createVehicle("vehicle-1", driver, 10,2); + var vehicle2 = createVehicle("vehicle-2", driver, 1, 1); + link.doSimStep(); + + // the link should accept vehicles according to its max inflow capacity + // vehicle consumes 2pcu. Max inflow should be: 1/cellSize / (1/vHole + 1/vMax) = 0.588... + // the queue with buffer seems to increase the accumulated inflow per 'doSimStep' regardless of the time between invocations. This works, because + // in the simulation 'doSimStep' is invoked every timestep. We need 3 'doSimStep's to increase the accumulated inflow to a value over 1. + assertTrue(link.getAcceptingQLane().isAcceptingFromUpstream()); + link.getAcceptingQLane().addFromUpstream(vehicle1); + // acc inflow is -1.422 + assertFalse(link.getAcceptingQLane().isAcceptingFromUpstream()); + link.doSimStep(); + // acc inflow is -0.842 + assertFalse(link.getAcceptingQLane().isAcceptingFromUpstream()); + link.doSimStep(); + // acc inflow is -0.236 + assertFalse(link.getAcceptingQLane().isAcceptingFromUpstream()); + link.doSimStep(); + // acc inflow is +0.352 > 0 + assertTrue(link.getAcceptingQLane().isAcceptingFromUpstream()); + link.getAcceptingQLane().addFromUpstream(vehicle2); + assertFalse(link.getAcceptingQLane().isAcceptingFromUpstream()); + + // this should move one vehicle into the buffer, and start a backwards travelling hole + timer.setTime(1); + link.doSimStep(); + + // now, one vehicle should be in the buffer and one vehicle should be in the queue. + // The link has free storage capacity, but it is not freed yet, because the leaving vehicle has sent a backwards travelling hole on its way. + // the earliest exit time of that hole should be: now + length / vHole -> 1 + 15 * 3.6 / 15km/h = 4.6s + assertFalse(link.getAcceptingQLane().isAcceptingFromUpstream()); + // remove the first vehicle from the buffer and asser that it was the only vehicle in the buffer + assertEquals(vehicle1.getId(), link.getOfferingQLanes().getFirst().popFirstVehicle().getId()); + assertTrue(link.getOfferingQLanes().getFirst().isNotOfferingVehicle()); + + // pretend we are doing 5 sim steps. I think we need to do this, as the inflow capacity accumulates per 'doSimStep' and does not keep track + // of the last update time. + timer.setTime(2); + link.doSimStep(); + assertFalse(link.getAcceptingQLane().isAcceptingFromUpstream()); + assertTrue(link.getOfferingQLanes().getFirst().isNotOfferingVehicle()); + timer.setTime(3); + link.doSimStep(); + assertFalse(link.getAcceptingQLane().isAcceptingFromUpstream()); + assertTrue(link.getOfferingQLanes().getFirst().isNotOfferingVehicle()); + timer.setTime(4); + link.doSimStep(); + assertFalse(link.getAcceptingQLane().isAcceptingFromUpstream()); + assertTrue(link.getOfferingQLanes().getFirst().isNotOfferingVehicle()); + timer.setTime(5); // 5 > 4.6: 4.6 is the arrival time of the backwards travelling hole. + link.doSimStep(); + assertTrue(link.getAcceptingQLane().isAcceptingFromUpstream()); + assertTrue(link.getOfferingQLanes().getFirst().isNotOfferingVehicle()); + } + + private static NetsimEngineContext createNetsimeEngineContext(Config config, MobsimTimer timer) { + return new NetsimEngineContext( + mock(EventsManager.class), + 5, + mock(AgentCounter.class), + mock(AbstractAgentSnapshotInfoBuilder.class), + config.qsim(), + timer, + mock(SnapshotLinkWidthCalculator.class) + ); + } + + QLinkImpl createQLink(double length, double lanes, double cap, NetsimEngineContext context, Config config) { + var net = NetworkUtils.createNetwork(); + var n1 = net.getFactory().createNode(Id.createNodeId("n1"), new Coord(0, 0)); + var n2 = net.getFactory().createNode(Id.createNodeId("n2"), new Coord(0, 100)); + net.addNode(n1); + net.addNode(n2); + var link = net.getFactory().createLink(Id.createLinkId("test"), n1, n2); + link.setCapacity(cap); + link.setFreespeed(10); + link.setLength(length); + link.setNumberOfLanes(lanes); + + var internalInterface = mock(QNetsimEngineI.NetsimInternalInterface.class); + QNodeImpl qNode = new QNodeImpl.Builder(internalInterface, context, config.qsim()).build(n2); + qNode.setNetElementActivationRegistry(mock(NetElementActivationRegistry.class)); + var b = new QLinkImpl.Builder(context, internalInterface); + b.setLinkSpeedCalculator(new DefaultLinkSpeedCalculator()); + var l = b.build(link, qNode); + l.setNetElementActivationRegistry(mock(NetElementActivationRegistry.class)); + return l; + } + + QVehicle createVehicle(String id, MobsimDriverAgent driver, double maxV, double pcu) { + + var type = VehicleUtils.createVehicleType(Id.create("type", VehicleType.class)); + type.setMaximumVelocity(10); + type.setPcuEquivalents(pcu); + type.setMaximumVelocity(maxV); + var vehicle = VehicleUtils.createVehicle(Id.createVehicleId(id), type); + var result = new QVehicleImpl(vehicle); + result.setDriver(driver); + return result; + } + } diff --git a/matsim/src/test/java/org/matsim/core/router/NetworkRoutingInclAccessEgressModuleTest.java b/matsim/src/test/java/org/matsim/core/router/NetworkRoutingInclAccessEgressModuleTest.java index 6781d0872d2..0b4cc89e381 100644 --- a/matsim/src/test/java/org/matsim/core/router/NetworkRoutingInclAccessEgressModuleTest.java +++ b/matsim/src/test/java/org/matsim/core/router/NetworkRoutingInclAccessEgressModuleTest.java @@ -189,6 +189,7 @@ void calcRoute_modeVehiclesFromVehiclesData_differentTypesTakeDifferentRoutes() config.qsim().setVehiclesSource(QSimConfigGroup.VehiclesSource.modeVehicleTypesFromVehiclesData); config.qsim().setMainModes(modes); config.routing().setNetworkModes(modes); + config.travelTimeCalculator().setAnalyzedModes(new HashSet<>(modes)); ScoringConfigGroup scoring = config.scoring(); ScoringConfigGroup.ModeParams slowParams = new ScoringConfigGroup.ModeParams(SLOW_MODE); diff --git a/matsim/src/test/java/org/matsim/core/trafficmonitoring/TravelTimeCalculatorModuleTest.java b/matsim/src/test/java/org/matsim/core/trafficmonitoring/TravelTimeCalculatorModuleTest.java index ae05592d528..356fc5c1cff 100644 --- a/matsim/src/test/java/org/matsim/core/trafficmonitoring/TravelTimeCalculatorModuleTest.java +++ b/matsim/src/test/java/org/matsim/core/trafficmonitoring/TravelTimeCalculatorModuleTest.java @@ -97,9 +97,10 @@ public void install() { void testOneTravelTimeCalculatorPerMode() { Config config = ConfigUtils.createConfig(); -// config.travelTimeCalculator().setAnalyzedModesAsString("car,bike" ); + config.travelTimeCalculator().setAnalyzedModesAsString("car,bike"); config.routing().setNetworkModes( new LinkedHashSet<>( Arrays.asList( TransportMode.car, TransportMode.bike ) ) ); // (this is now newly taken from the router network modes. kai, feb'19) + // analyzed modes still need to be set correctly now, because these two settings can differ rakow, oct'24 config.travelTimeCalculator().setSeparateModes(true); Scenario scenario = ScenarioUtils.createScenario(config); diff --git a/matsim/src/test/java/org/matsim/examples/simple/PtScoringTest.java b/matsim/src/test/java/org/matsim/examples/simple/PtScoringTest.java index 8954e969fe7..9169ff96e92 100644 --- a/matsim/src/test/java/org/matsim/examples/simple/PtScoringTest.java +++ b/matsim/src/test/java/org/matsim/examples/simple/PtScoringTest.java @@ -54,7 +54,7 @@ public class PtScoringTest { @ParameterizedTest @EnumSource(TypicalDurationScoreComputation.class) void test_PtScoringLineswitch(TypicalDurationScoreComputation typicalDurationScoreComputation) { - Config config = this.utils.loadConfig(IOUtils.extendUrl(ExamplesUtils.getTestScenarioURL("pt-simple-lineswitch"), "config.xml")); + Config config = this.utils.loadConfig(IOUtils.extendUrl(ExamplesUtils.getTestScenarioURL("pt-simple-lineswitch"), "config.xml"), MatsimTestUtils.TestMethodType.Parameterized); ScoringConfigGroup pcs = config.scoring() ; if(typicalDurationScoreComputation.equals(TypicalDurationScoreComputation.uniform)){ @@ -208,7 +208,7 @@ void test_PtScoringLineswitch(TypicalDurationScoreComputation typicalDurationSco @ParameterizedTest @EnumSource(TypicalDurationScoreComputation.class) void test_PtScoringLineswitchAndPtConstant(TypicalDurationScoreComputation typicalDurationScoreComputation) { - Config config = this.utils.loadConfig(IOUtils.extendUrl(ExamplesUtils.getTestScenarioURL("pt-simple-lineswitch"), "config.xml")); + Config config = this.utils.loadConfig(IOUtils.extendUrl(ExamplesUtils.getTestScenarioURL("pt-simple-lineswitch"), "config.xml"), MatsimTestUtils.TestMethodType.Parameterized); ScoringConfigGroup pcs = config.scoring() ; if(typicalDurationScoreComputation.equals(TypicalDurationScoreComputation.uniform)) @@ -365,7 +365,7 @@ void test_PtScoringLineswitchAndPtConstant(TypicalDurationScoreComputation typic @ParameterizedTest @EnumSource(TypicalDurationScoreComputation.class) void test_PtScoring_Wait(TypicalDurationScoreComputation typicalDurationScoreComputation) { - Config config = this.utils.loadConfig(IOUtils.extendUrl(ExamplesUtils.getTestScenarioURL("pt-simple"), "config.xml")); + Config config = this.utils.loadConfig(IOUtils.extendUrl(ExamplesUtils.getTestScenarioURL("pt-simple"), "config.xml"), MatsimTestUtils.TestMethodType.Parameterized); ScoringConfigGroup pcs = config.scoring(); if(typicalDurationScoreComputation.equals(TypicalDurationScoreComputation.uniform)){ @@ -452,7 +452,7 @@ void test_PtScoring_Wait(TypicalDurationScoreComputation typicalDurationScoreCom @ParameterizedTest @EnumSource(TypicalDurationScoreComputation.class) void test_PtScoring(TypicalDurationScoreComputation typicalDurationScoreComputation) { - Config config = this.utils.loadConfig(IOUtils.extendUrl(ExamplesUtils.getTestScenarioURL("pt-simple"), "config.xml")); + Config config = this.utils.loadConfig(IOUtils.extendUrl(ExamplesUtils.getTestScenarioURL("pt-simple"), "config.xml"), MatsimTestUtils.TestMethodType.Parameterized); ScoringConfigGroup pcs = config.scoring() ; if(typicalDurationScoreComputation.equals(TypicalDurationScoreComputation.uniform)) diff --git a/pom.xml b/pom.xml index 6dbd5f639cc..f811ec6d8e5 100644 --- a/pom.xml +++ b/pom.xml @@ -205,7 +205,7 @@ com.google.errorprone error_prone_annotations - 2.29.2 + 2.33.0 @@ -321,7 +321,7 @@ org.mockito mockito-core - 5.12.0 + 5.13.0 test @@ -358,7 +358,7 @@ net.bytebuddy byte-buddy - 1.14.18 + 1.15.1 test @@ -420,7 +420,7 @@ org.apache.maven.plugins maven-surefire-plugin - 3.3.1 + 3.5.0 org.apache.maven.plugins