Skip to content

Commit

Permalink
Merge branch 'master' into german-freight-minor-update
Browse files Browse the repository at this point in the history
  • Loading branch information
luchengqi7 authored Jul 30, 2024
2 parents ca7c246 + e1783db commit 1cd36bb
Show file tree
Hide file tree
Showing 184 changed files with 2,493 additions and 2,004 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ private void runCommand(Class<? extends MATSimAppCommand> clazz, Path input) thr
MATSimAppCommand command = clazz.getDeclaredConstructor().newInstance();
String[] args = this.args.get(clazz);
args = ArrayUtils.addAll(args, createArgs(clazz, args, input));
log.info("Running {} with arguments: {}", clazz, Arrays.toString(args));
log.info("Running {} with arguments: {}", clazz, String.join(" ", args));

command.execute(args);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,22 @@ final class TripByGroupAnalysis {
}
}

// Norm shares per instance of each group to sum of 1
for (Group group : this.groups) {

String norm = group.columns.get(0);
if (group.columns.size() > 1)
throw new UnsupportedOperationException("Multiple columns not supported yet");

Table df = group.data;
for (String label : df.stringColumn(norm).asSet()) {
DoubleColumn dist_group = df.doubleColumn("share");
Selection sel = df.stringColumn(norm).isEqualTo(label);
double total = dist_group.where(sel).sum();
if (total > 0)
dist_group.set(sel, dist_group.divide(total));
}
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -667,18 +667,25 @@ else if (samplingOption.equals("changeDemandOnLocation")) {
int demandForThisLink = calculateDemandBasedOnLinkLength(countOfLinks, distributedDemand, demandToDistribute, possibleLinksForService.size(),
sumOfPossibleLinkLength, link);
countOfLinks++;
double serviceTime = newDemandInformationElement.getFirstJobElementTimePerUnit()
* demandForThisLink;
Id<CarrierService> idNewService = Id.create(
Carrier thisCarrier = CarriersUtils.getCarriers(scenario).getCarriers()
.get(Id.create(newDemandInformationElement.getCarrierName(), Carrier.class));
int numberOfJobsForDemand = calculateNumberOfJobsForDemand(thisCarrier, demandForThisLink);
for (int i = 0; i < numberOfJobsForDemand; i++) {
int singleDemandForThisLink = demandForThisLink / numberOfJobsForDemand;
if (i == numberOfJobsForDemand - 1)
singleDemandForThisLink = demandForThisLink - (numberOfJobsForDemand - 1) * singleDemandForThisLink;
double serviceTime = newDemandInformationElement.getFirstJobElementTimePerUnit()
* singleDemandForThisLink;
Id<CarrierService> idNewService = Id.create(
createJobId(scenario, newDemandInformationElement, link.getId(), null),
CarrierService.class);
if (demandToDistribute > 0 && demandForThisLink > 0) {
CarrierService thisService = CarrierService.Builder.newInstance(idNewService, link.getId())
.setCapacityDemand(demandForThisLink).setServiceDuration(serviceTime)
if (demandToDistribute > 0 && singleDemandForThisLink > 0) {
CarrierService thisService = CarrierService.Builder.newInstance(idNewService, link.getId())
.setCapacityDemand(singleDemandForThisLink).setServiceDuration(serviceTime)
.setServiceStartTimeWindow(newDemandInformationElement.getFirstJobElementTimeWindow())
.build();
CarriersUtils.getCarriers(scenario).getCarriers().values().iterator().next().getServices()
.put(thisService.getId(), thisService);
thisCarrier.getServices().put(thisService.getId(), thisService);
}
}
distributedDemand = distributedDemand + demandForThisLink;
}
Expand All @@ -705,24 +712,31 @@ else if (samplingOption.equals("changeDemandOnLocation")) {
.skip(rand.nextInt(usedServiceLocations.size() - 1)).findFirst().get()));
}
int demandForThisLink = calculateDemandForThisLink(demandToDistribute, numberOfJobs, distributedDemand, i);
Carrier thisCarrier = CarriersUtils.getCarriers(scenario).getCarriers()
.get(Id.create(newDemandInformationElement.getCarrierName(), Carrier.class));
int numberOfJobsForDemand = calculateNumberOfJobsForDemand(thisCarrier, demandForThisLink);
for (int j = 0; j < numberOfJobsForDemand; j++) {
int singleDemandForThisLink = demandForThisLink / numberOfJobsForDemand;
if (j == numberOfJobsForDemand - 1)
singleDemandForThisLink = demandForThisLink - (numberOfJobsForDemand - 1) * singleDemandForThisLink;
double serviceTime;
if (singleDemandForThisLink == 0)
serviceTime = newDemandInformationElement.getFirstJobElementTimePerUnit();
else
serviceTime = newDemandInformationElement.getFirstJobElementTimePerUnit() * demandForThisLink;
usedServiceLocations.add(link.getId().toString());

double serviceTime;
if (demandToDistribute == 0)
serviceTime = newDemandInformationElement.getFirstJobElementTimePerUnit();
else
serviceTime = newDemandInformationElement.getFirstJobElementTimePerUnit() * demandForThisLink;
usedServiceLocations.add(link.getId().toString());

Id<CarrierService> idNewService = Id.create(
Id<CarrierService> idNewService = Id.create(
createJobId(scenario, newDemandInformationElement, link.getId(), null), CarrierService.class);
if ((demandToDistribute > 0 && demandForThisLink > 0) || demandToDistribute == 0) {
CarrierService thisService = CarrierService.Builder.newInstance(idNewService, link.getId())
.setCapacityDemand(demandForThisLink).setServiceDuration(serviceTime)
if ((demandToDistribute > 0 && singleDemandForThisLink > 0) || demandToDistribute == 0) {
CarrierService thisService = CarrierService.Builder.newInstance(idNewService, link.getId())
.setCapacityDemand(singleDemandForThisLink).setServiceDuration(serviceTime)
.setServiceStartTimeWindow(newDemandInformationElement.getFirstJobElementTimeWindow())
.build();
CarriersUtils.getCarriers(scenario).getCarriers()
CarriersUtils.getCarriers(scenario).getCarriers()
.get(Id.create(newDemandInformationElement.getCarrierName(), Carrier.class)).getServices()
.put(thisService.getId(), thisService);
}
}
distributedDemand = distributedDemand + demandForThisLink;
}
Expand Down Expand Up @@ -1007,29 +1021,56 @@ else if (numberOfPickupLocations != null) {
private static void createSingleShipment(Scenario scenario, DemandInformationElement newDemandInformationElement,
Link linkPickup, Link linkDelivery, int demandForThisLink) {

Id<CarrierShipment> idNewShipment = Id.create(createJobId(scenario, newDemandInformationElement,
linkPickup.getId(), linkDelivery.getId()), CarrierShipment.class);
Carrier thisCarrier = CarriersUtils.getCarriers(scenario).getCarriers()
.get(Id.create(newDemandInformationElement.getCarrierName(), Carrier.class));
int numberOfJobsForDemand = calculateNumberOfJobsForDemand(thisCarrier, demandForThisLink);

TimeWindow timeWindowPickup = newDemandInformationElement.getFirstJobElementTimeWindow();
TimeWindow timeWindowDelivery = newDemandInformationElement.getSecondJobElementTimeWindow();

double serviceTimePickup;
double serviceTimeDelivery;
if (demandForThisLink == 0) {
serviceTimePickup = newDemandInformationElement.getFirstJobElementTimePerUnit();
serviceTimeDelivery = newDemandInformationElement.getSecondJobElementTimePerUnit();
} else {
serviceTimePickup = newDemandInformationElement.getFirstJobElementTimePerUnit() * demandForThisLink;
serviceTimeDelivery = newDemandInformationElement.getSecondJobElementTimePerUnit() * demandForThisLink;
for (int i = 0; i < numberOfJobsForDemand; i++) {
Id<CarrierShipment> idNewShipment = Id.create(createJobId(scenario, newDemandInformationElement,
linkPickup.getId(), linkDelivery.getId()), CarrierShipment.class);
double serviceTimePickup;
double serviceTimeDelivery;
int singleDemandForThisLink = Math.round ((float) demandForThisLink / numberOfJobsForDemand);
if (i == numberOfJobsForDemand - 1)
singleDemandForThisLink = demandForThisLink - (numberOfJobsForDemand - 1) * singleDemandForThisLink;
if (singleDemandForThisLink == 0) {
serviceTimePickup = newDemandInformationElement.getFirstJobElementTimePerUnit();
serviceTimeDelivery = newDemandInformationElement.getSecondJobElementTimePerUnit();
} else {
serviceTimePickup = newDemandInformationElement.getFirstJobElementTimePerUnit() * singleDemandForThisLink;
serviceTimeDelivery = newDemandInformationElement.getSecondJobElementTimePerUnit() * singleDemandForThisLink;
}
CarrierShipment thisShipment = CarrierShipment.Builder
.newInstance(idNewShipment, linkPickup.getId(), linkDelivery.getId(), singleDemandForThisLink)
.setPickupServiceTime(serviceTimePickup).setPickupTimeWindow(timeWindowPickup)
.setDeliveryServiceTime(serviceTimeDelivery).setDeliveryTimeWindow(timeWindowDelivery)
.build();
thisCarrier.getShipments().put(thisShipment.getId(), thisShipment);
}
}

/**
* Method calculates the number of jobs for a demand on one link based on the largest vehicle capacity of the carrier.
*
* @param thisCarrier the carrier of a job
* @param demandForThisLink Demand for this link
* @return Number of jobs for this demand
*/
private static int calculateNumberOfJobsForDemand(Carrier thisCarrier, int demandForThisLink) {
double largestVehicleCapacity = 0;
for (CarrierVehicle vehicle : thisCarrier.getCarrierCapabilities().getCarrierVehicles().values()) {
if (vehicle.getType().getCapacity().getOther() > largestVehicleCapacity) {
largestVehicleCapacity = vehicle.getType().getCapacity().getOther();
}
}
if (demandForThisLink > largestVehicleCapacity) {
log.info("Demand {} is larger than the largest vehicle capacity ({}). Splitting demand into multiple jobs.", demandForThisLink, largestVehicleCapacity);
return (int) Math.ceil((double) demandForThisLink / largestVehicleCapacity);
}
CarrierShipment thisShipment = CarrierShipment.Builder
.newInstance(idNewShipment, linkPickup.getId(), linkDelivery.getId(), demandForThisLink)
.setPickupServiceTime(serviceTimePickup).setPickupTimeWindow(timeWindowPickup)
.setDeliveryServiceTime(serviceTimeDelivery).setDeliveryTimeWindow(timeWindowDelivery)
.build();
CarriersUtils.getCarriers(scenario).getCarriers()
.get(Id.create(newDemandInformationElement.getCarrierName(), Carrier.class)).getShipments()
.put(thisShipment.getId(), thisShipment);
return 1;
}

/**
Expand Down Expand Up @@ -1086,7 +1127,7 @@ private static int calculateDemandForThisLink(int demandToDistribute, int number
} else {
roundingError = roundingError
+ ((double) demandForThisLink - ((double) demandToDistribute / (double) numberOfJobs));
if (roundingError > 1) {
if (roundingError >= 1) {
demandForThisLink = demandForThisLink - 1;
roundingError = roundingError - 1;
}
Expand All @@ -1113,7 +1154,7 @@ private static int calculateDemandBasedOnLinkLength(int countOfLinks, int distri
.ceil(link.getLength() / sumOfPossibleLinkLength * (double) demandToDistribute);
roundingError = roundingError + ((double) demandForThisLink
- (link.getLength() / sumOfPossibleLinkLength * (double) demandToDistribute));
if (roundingError > 1) {
if (roundingError >= 1) {
demandForThisLink = demandForThisLink - 1;
roundingError = roundingError - 1;
}
Expand Down Expand Up @@ -1265,7 +1306,7 @@ private static HashMap<Id<Link>, Link> findAllPossibleLinks(Scenario scenario,
crsTransformationNetworkAndShape);
if (!possibleLinks.containsKey(newPossibleLink.getId()))
possibleLinks.put(newPossibleLink.getId(), newPossibleLink);
if (nearestLinkPerPerson.size() == possiblePersons.size())
if (!possiblePersons.isEmpty() && nearestLinkPerPerson.size() == possiblePersons.size())
break;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,13 @@ private void createDemand(DemandGenerationOptions selectedDemandGenerationOption
*/
FreightDemandGenerationUtils.preparePopulation(population, sampleSizeInputPopulation,
upSamplePopulationTo, "changeDemandOnLocation");
case noPopulationSampling ->
/*
* If the demand sample is equal to the population sample, the demand is created
* based on the given population and the set input population sampleSize
*/
FreightDemandGenerationUtils.preparePopulation(population, sampleSizeInputPopulation,
sampleSizeInputPopulation, "noPopulationSampling");
default -> throw new RuntimeException("No valid sampling option selected!");
}
switch (selectedPopulationOption) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,12 @@
import org.matsim.core.utils.geometry.CoordinateTransformation;
import org.matsim.core.utils.geometry.transformations.TransformationFactory;

import java.util.*;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
* @author nkuehnel / MOIA
Expand All @@ -39,41 +43,38 @@ public H3ZoneSystem(String crs, int resolution, Network network, Predicate<Zone>
this.resolution = resolution;
this.network = network;
this.filter = filter;
this.network.getLinks().values().forEach(l -> getZoneForCoord(l.getToNode().getCoord()));
init();
}


@Override
public Optional<Zone> getZoneForCoord(Coord coord) {

long h3Address = getH3Cell(coord);
Id<Zone> zoneId = Id.create(h3Address, Zone.class);

if(zones.containsKey(zoneId)) {
return Optional.of(zones.get(zoneId));
} else {
Optional<Zone> zone = H3Utils.createZone(h3Address, fromLatLong);
if(zone.isPresent() && filter.test(zone.get())) {
initZone(zone.get(), h3Address);
return zone;
} else {
return Optional.empty();
}
private void init() {
Map<Long, List<Link>> linksToH3 =
this.network.getLinks().values()
.stream()
.collect(Collectors.groupingBy(link -> getH3Cell(link.getToNode().getCoord())));
for (Map.Entry<Long, List<Link>> linksH3 : linksToH3.entrySet()) {
Optional<Zone> maybeZone = createZone(linksH3.getKey());
maybeZone.ifPresent(z -> {
zones.put(z.getId(), z);
zoneToLinksMap.put(z.getId(), linksH3.getValue());
});
}
}

private void initZone(Zone zone, long h3Address) {
if(filter.test(zone)) {
zones.put(zone.getId(), zone);
for (Link link : network.getLinks().values()) {
long linkH3Address = getH3Cell(link.getToNode().getCoord());

if (linkH3Address == h3Address) {
List<Link> links = zoneToLinksMap.computeIfAbsent(zone.getId(), id -> new ArrayList<>());
links.add(link);
}
}
private Optional<Zone> createZone(Long h3) {
Optional<Zone> zone = H3Utils.createZone(h3, fromLatLong);
if(zone.isPresent() && filter.test(zone.get())) {
return zone;
}
return Optional.empty();
}

@Override
public Optional<Zone> getZoneForCoord(Coord coord) {
long h3Address = getH3Cell(coord);
Id<Zone> zoneId = Id.create(h3Address, Zone.class);
// create new zone if absent, should not be linked to existing links in the network,
// as all of them are covered in the init() phase.
return Optional.ofNullable(zones.computeIfAbsent(zoneId, id -> createZone(h3Address).orElse(null)));
}

private long getH3Cell(Coord coord) {
Expand Down Expand Up @@ -106,4 +107,4 @@ public List<Link> getLinksForZoneId(Id<Zone> zone) {
public Map<Id<Zone>, Zone> getZones() {
return Collections.unmodifiableMap(zones);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,11 @@ public SquareGridZoneSystem(Network network, double cellSize, Predicate<Zone> zo
}
public SquareGridZoneSystem(Network network, double cellSize, boolean filterByNetwork, Predicate<Zone> zoneFilter) {
this.zoneFilter = zoneFilter;
Preconditions.checkArgument(!network.getNodes().isEmpty(), "Cannot create SquareGrid if no nodes");

this.network = network;
this.cellSize = cellSize;

Preconditions.checkArgument(!network.getNodes().isEmpty(), "Cannot create SquareGrid if no nodes");

initBounds();

this.rows = Math.max(1, (int) Math.ceil((maxY - minY) / cellSize));
Expand Down
Loading

0 comments on commit 1cd36bb

Please sign in to comment.