Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integrate "demand generation of parcel delivery" (based on master thesis) in matsim-libs #3665

Merged
merged 53 commits into from
Jan 20, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
059e82b
Matsim Advanced
May 14, 2024
3044f4e
Matsim Advanced - Small fixes
May 14, 2024
2e49324
Matsim Advanced - Small fixes 2
May 14, 2024
83a2671
Merge branch 'matsim-org:master' into master
AnaUeb May 24, 2024
dde8994
Masterarbeit 1
May 24, 2024
f566eda
Merge branch 'master' of https://github.com/AnaUeb/matsim-libs
May 24, 2024
5d4c0c2
Merge branch 'matsim-org:master' into master
AnaUeb May 24, 2024
7a8fd39
DemandPerAge - MA
Jun 5, 2024
2100fda
DemandPerAge - MA 2
Jun 7, 2024
ba55915
DemandPerAge - MA 3
Jun 11, 2024
8368088
MA - Erros
Jun 21, 2024
bf3029c
Modify freight demand generation tool
Jun 22, 2024
6921cf3
Changes 2
Jun 25, 2024
5c4307d
Packages per Person
Jun 25, 2024
09f38a6
Stop time
Jul 16, 2024
6e19035
Presentation day
Aug 6, 2024
6a3974e
Code merge-conflicts day
Aug 9, 2024
d99b43e
merge in upstream master from matsim-libs
kt86 Aug 9, 2024
be0c562
auto indent lines. no changes in behaviour
kt86 Aug 9, 2024
65ab468
First run after merge
Aug 13, 2024
f794d0e
PLZ-runs
Oct 2, 2024
67cf249
poisson
Oct 9, 2024
c83fb61
commit MA
Dec 8, 2024
1b21f54
commit MA 2
Dec 9, 2024
754049b
marge in matsim-libs/master and resolve conflicts
kt86 Dec 10, 2024
8744950
fix compile error
kt86 Dec 10, 2024
faf938c
test was already removed, after class itself was removed.
kt86 Dec 11, 2024
7052e39
add data for new column in CarrierLoadAnalysis
kt86 Dec 11, 2024
97aaafd
add check for null
kt86 Dec 11, 2024
e1db475
Revert "add check for null" -- because it leads to an infinty running...
kt86 Dec 11, 2024
0e25410
update FreightDemandGeneration by adding functionality for specific u…
rewertvsp Jan 7, 2025
aeb2b1f
add implementation for parcel delivery
rewertvsp Jan 7, 2025
c6d3953
rename method and extend java doc
rewertvsp Jan 7, 2025
0f8e4ee
add demand information to ageGroup file 1
rewertvsp Jan 7, 2025
65a6a84
move stuff into brackets
rewertvsp Jan 9, 2025
8a82a1e
revert renaming
rewertvsp Jan 9, 2025
ff95066
add tests
rewertvsp Jan 9, 2025
0f2b841
rename test input files
rewertvsp Jan 10, 2025
8591463
add java doc
rewertvsp Jan 10, 2025
dc9e722
Merge remote-tracking branch 'refs/remotes/upstream/master' into upda…
rewertvsp Jan 13, 2025
2533395
rename to related object
rewertvsp Jan 13, 2025
6797c6a
fix controller
rewertvsp Jan 13, 2025
e0eb2f2
Merge pull request #4 from AnaUeb/updateAna2-by-Ricardo
rewertvsp Jan 13, 2025
6be7865
Merge branch 'matsim-org:master' into ana2
kt86 Jan 13, 2025
01ecf5b
move link finding for persons to more effective place
rewertvsp Jan 14, 2025
2a45de0
Merge remote-tracking branch 'upstream/master' into ana2
rewertvsp Jan 15, 2025
eae01d8
use recent Builder for services
rewertvsp Jan 15, 2025
e7486a3
Merge branch 'master' into ana2
rewertvsp Jan 15, 2025
0fc834f
Merge remote-tracking branch 'upstream/master' into ana2
rewertvsp Jan 20, 2025
4b1a0e6
Merge remote-tracking branch 'upstream/master' into ana2
rewertvsp Jan 20, 2025
7f1785e
mark Freight analysis in vsp contrib as deprecated, but make it runab…
rewertvsp Jan 20, 2025
6e56d39
delete unneeded test files
rewertvsp Jan 20, 2025
2db78f7
Some cleanup (#5)
kt86 Jan 20, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
merge in upstream master from matsim-libs
  • Loading branch information
kt86 committed Aug 9, 2024
commit d99b43e5e2f7828797a90d51b6239b3818301cbf
Original file line number Diff line number Diff line change
Expand Up @@ -305,11 +305,11 @@ else if (!record.get("fleetSize").isBlank())
/**
* Checks if the read carrier information is consistent.
*
* @param allNewCarrierInformation Set of CarrierInformationElements
* * @param freightCarriersConfigGroup FreightCarriersConfigGroup
* * @param scenario Scenario
* * @param indexShape ShpOptions.Index for the shape file
* * @param shapeCategory Column name in the shape file for the data connection in the csv files
* @param allNewCarrierInformation Set of CarrierInformationElements
* @param freightCarriersConfigGroup FreightCarriersConfigGroup
* @param scenario Scenario
* @param indexShape ShpOptions.Index for the shape file
* @param shapeCategory Column name in the shape file for the data connection in the csv files
*/
static void checkNewCarrier(Set<CarrierInformationElement> allNewCarrierInformation,
FreightCarriersConfigGroup freightCarriersConfigGroup, Scenario scenario, ShpOptions.Index indexShape, String shapeCategory) {
Expand Down Expand Up @@ -347,9 +347,9 @@ static void checkNewCarrier(Set<CarrierInformationElement> allNewCarrierInformat
"If a vehicle type is selected in the input file, numberOfDepots or selectedVehicleDepots should be set. Please check carrier "
+ carrierElement.getName());
if ((carrierElement.getVehicleDepots() != null
&& (carrierElement.getNumberOfDepotsPerType() > carrierElement.getVehicleDepots().size())
&& carrierElement.getAreaOfAdditionalDepots() == null) || (carrierElement.getVehicleDepots() == null && (carrierElement.getNumberOfDepotsPerType() > 0)
&& carrierElement.getAreaOfAdditionalDepots() == null))
&& (carrierElement.getNumberOfDepotsPerType() > carrierElement.getVehicleDepots().size())
&& carrierElement.getAreaOfAdditionalDepots() == null) || (carrierElement.getVehicleDepots() == null && (carrierElement.getNumberOfDepotsPerType() > 0)
&& carrierElement.getAreaOfAdditionalDepots() == null))
log.warn("No possible area for additional depot given. Random choice in the hole network of a possible position");
if (carrierElement.getAreaOfAdditionalDepots() != null) {
if (indexShape == null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
import org.matsim.core.utils.geometry.CoordinateTransformation;
import org.matsim.freight.carriers.*;


import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
Expand Down Expand Up @@ -415,7 +414,7 @@ static Set<DemandInformationElement> readDemandInformation(Path csvLocationDeman
Double.parseDouble(record.get("shareOfPopulationWithSecondJobElement")));
if (!record.get("areasSecondJobElement").isBlank())
builder.setAreasSecondJobElement(record.get("areasSecondJobElement").split(";"));
if (!record.get("numberOfSecondJobElementLocations").isBlank())
if (!record.get("numberOfSecondJobElementLocations").isBlank())
builder.setNumberOfSecondJobElementLocations(
Integer.parseInt(record.get("numberOfSecondJobElementLocations")));
if (!record.get("locationsOfSecondJobElement").isBlank())
Expand Down Expand Up @@ -699,11 +698,18 @@ else if (samplingOption.equals("changeDemandOnLocation")) {
double sumOfPossibleLinkLength = possibleLinksForService.values().stream().mapToDouble(Link::getLength).sum();
for (Link link : possibleLinksForService.values()) {
int demandForThisLink = calculateDemandBasedOnLinkLength(countOfLinks, distributedDemand, demandToDistribute, possibleLinksForService.size(),
sumOfPossibleLinkLength, link);
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 && singleDemandForThisLink > 0) {
Expand Down Expand Up @@ -739,12 +745,19 @@ else if (samplingOption.equals("changeDemandOnLocation")) {
.skip(rand.nextInt(usedServiceLocations.size() - 1)).findFirst().get()));
}
int demandForThisLink = calculateDemandForThisLink(demandToDistribute, numberOfJobs, distributedDemand, i);
double serviceTime;
if (demandToDistribute == 0)
serviceTime = newDemandInformationElement.getFirstJobElementTimePerUnit();
else
serviceTime = newDemandInformationElement.getFirstJobElementTimePerUnit() * demandForThisLink;
usedServiceLocations.add(link.getId().toString());
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());

Id<CarrierService> idNewService = Id.create(
createJobId(scenario, newDemandInformationElement, link.getId(), null), CarrierService.class);
Expand Down Expand Up @@ -799,10 +812,9 @@ private static void createShipments(Scenario scenario, DemandInformationElement
HashMap<Id<Person>, HashMap<Double, String>> nearestLinkPerPersonPickup = new HashMap<>();
HashMap<Id<Person>, HashMap<Double, String>> nearestLinkPerPersonDelivery = new HashMap<>();


// set number of jobs
if (shareOfPopulationWithThisPickup == null && shareOfPopulationWithThisDelivery == null)
numberOfJobs = newDemandInformationElement.getNumberOfJobs();
numberOfJobs = newDemandInformationElement.getNumberOfJobs();
else if (population == null)
throw new RuntimeException(
"No population found although input parameter <ShareOfPopulationWithThisDemand> is set");
Expand Down Expand Up @@ -894,7 +906,7 @@ else if (population == null)
numberPossibleJobsDelivery = numberOfJobs;
//ERROR: If no shareOfPopulationWithThisPickup is selected
if (shareOfPopulationWithThisPickup != null) //NEW
numberPossibleJobsPickup = (int) Math
numberPossibleJobsPickup = (int) Math
.round(shareOfPopulationWithThisPickup * numberPossibleJobsPickup);
} else if (samplingOption.equals("changeNumberOfLocationsWithDemand")) {
numberOfJobs = sampledNumberPossibleJobsDelivery;
Expand Down Expand Up @@ -1026,11 +1038,10 @@ else if (population == null)
if (!usedDeliveryLocations.contains(linkDelivery.getId().toString()))
usedDeliveryLocations.add(linkDelivery.getId().toString());
//NEW: package creation to use other parameters
if(demandDistributionOption =="") {
if(Objects.equals(demandDistributionOption, "")) {
createSingleShipment(scenario, newDemandInformationElement, linkPickup, linkDelivery,
demandForThisLink);
}
else {
} else {
createSinglePackageShipment(scenario, newDemandInformationElement, linkPickup, linkDelivery,
demandForThisLink, (Double) population.getAttributes().getAttribute("sampleSize"));
}
Expand Down Expand Up @@ -1067,7 +1078,7 @@ else if (numberOfPickupLocations != null) {
}
for (Link demandBasedLink : demandBasesLinks.values()) {
int demandForThisLink = calculateDemandBasedOnLinkLength(countOfLinks, distributedDemand, demandToDistribute, demandBasesLinks.size(), sumOfDemandBasedLinks,
demandBasedLink);
demandBasedLink);
if (pickupIsDemandBase) {
linkPickup = demandBasedLink;
while (linkDelivery == null || usedDeliveryLocations.contains(linkDelivery.getId().toString())) {
Expand Down Expand Up @@ -1102,17 +1113,14 @@ else if (numberOfPickupLocations != null) {
if(demandDistributionOption =="" && demandForThisLink > 0) {
createSingleShipment(scenario, newDemandInformationElement, linkPickup, linkDelivery,
demandForThisLink);
}
else if (demandForThisLink > 0) {
} else if (demandForThisLink > 0) {
createSinglePackageShipment(scenario, newDemandInformationElement, linkPickup, linkDelivery,
demandForThisLink, (Double) population.getAttributes().getAttribute("sampleSize"));
}
distributedDemand = distributedDemand + demandForThisLink;
}
}
} else
// if a certain number of shipments is selected
{
} else { // if a certain number of shipments is selected
log.info("Number of jobs: "+numberOfJobs);

//ERROR: Verschoben vor die for-Schleife
Expand Down Expand Up @@ -1168,12 +1176,12 @@ else if (demandForThisLink > 0) {
//NEW: create Package
if(demandDistributionOption !="") {
createSingleShipment(scenario, newDemandInformationElement, linkPickup, linkDelivery,
demandForThisLink);
demandForThisLink);
distributedDemand = distributedDemand + demandForThisLink;
}else {
if(demandForThisLink != 0) {
createSinglePackageShipment(scenario, newDemandInformationElement, linkPickup, linkDelivery,
demandForThisLink, (Double) population.getAttributes().getAttribute("sampleSize"));
demandForThisLink, (Double) population.getAttributes().getAttribute("sampleSize"));
distributedDemand = distributedDemand + demandForThisLink;
}
}
Expand All @@ -1193,6 +1201,14 @@ else if (demandForThisLink > 0) {
reduceNumberOfJobsIfSameCharacteristics(scenario, newDemandInformationElement);
}









/** Creates a single shipment.
* @param scenario Scenario
* @param newDemandInformationElement single DemandInformationElement
Expand All @@ -1203,32 +1219,63 @@ else if (demandForThisLink > 0) {
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;

}
CarrierShipment thisShipment = CarrierShipment.Builder
.newInstance(idNewShipment, linkPickup.getId(), linkDelivery.getId(), 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();
CarriersUtils.getCarriers(scenario).getCarriers()
.get(Id.create(newDemandInformationElement.getCarrierName(), Carrier.class)).getShipments()
.put(thisShipment.getId(), thisShipment);
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);
}
return 1;
}


/** Creates a single shipment for packages. //NEW METHOD
* @param scenario Scenario
Expand All @@ -1240,10 +1287,10 @@ private static void createSingleShipment(Scenario scenario, DemandInformationEle
*/

private static void createSinglePackageShipment(Scenario scenario, DemandInformationElement newDemandInformationElement,
Link linkPickup, Link linkDelivery, int demandForThisLink, double sampleSize) {
Link linkPickup, Link linkDelivery, int demandForThisLink, double sampleSize) {

Id<CarrierShipment> idNewShipment = Id.create(createJobId(scenario, newDemandInformationElement,
linkPickup.getId(), linkDelivery.getId()), CarrierShipment.class);
linkPickup.getId(), linkDelivery.getId()), CarrierShipment.class);

TimeWindow timeWindowPickup = newDemandInformationElement.getFirstJobElementTimeWindow();
TimeWindow timeWindowDelivery = newDemandInformationElement.getSecondJobElementTimeWindow();
Expand All @@ -1258,13 +1305,13 @@ private static void createSinglePackageShipment(Scenario scenario, DemandInforma
serviceTimeDelivery = newDemandInformationElement.getSecondJobElementTimePerUnit() * stops;

CarrierShipment thisShipment = CarrierShipment.Builder
.newInstance(idNewShipment, linkPickup.getId(), linkDelivery.getId(), demandForThisLink)
.setPickupServiceTime(serviceTimePickup).setPickupTimeWindow(timeWindowPickup)
.setDeliveryServiceTime(serviceTimeDelivery).setDeliveryTimeWindow(timeWindowDelivery)
.build();
.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);
.get(Id.create(newDemandInformationElement.getCarrierName(), Carrier.class)).getShipments()
.put(thisShipment.getId(), thisShipment);

}
}
Expand Down Expand Up @@ -1323,7 +1370,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 @@ -1350,7 +1397,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 @@ -1555,9 +1602,9 @@ private static HashMap<Id<Link>, Link> findAllPossibleLinks(Scenario scenario,
crsTransformationNetworkAndShape);
if (!possibleLinks.containsKey(newPossibleLink.getId())){
possibleLinks.put(newPossibleLink.getId(), newPossibleLink);
if (possiblePersons.size() == possibleLinks.size())
break;
}
if (!possiblePersons.isEmpty() && nearestLinkPerPerson.size() == possiblePersons.size())
break;
}
}
}
return possibleLinks;
Expand Down Expand Up @@ -1611,10 +1658,11 @@ private static Link findNextUsedLink(Scenario scenario, ShpOptions.Index indexSh
* @return HashMap with all possible persons
*/
private static HashMap<Id<Person>, Person> findPossiblePersons(Population population,
String[] areasForJobElementLocations, ShpOptions.Index indexShape,
CoordinateTransformation crsTransformationNetworkAndShape) {
String[] areasForJobElementLocations, ShpOptions.Index indexShape,
CoordinateTransformation crsTransformationNetworkAndShape) {

HashMap<Id<Person>, Person> possiblePersons = new HashMap<>();

for (Person person : population.getPersons().values()) {
Coord coord = getHomeCoord(person);
if (crsTransformationNetworkAndShape != null)
Expand Down Expand Up @@ -1742,7 +1790,7 @@ private static Link findPossibleLinkForDemand(HashMap<Id<Link>, Link> possibleLi
.skip(rand.nextInt(scenario.getNetwork().getLinks().size())).findFirst().get();
else {
newLink = getNewLinkForPerson(possiblePersons, nearestLinkPerPerson, scenario);
}
}
}
} else {
if (possiblePersons.isEmpty()) {
Expand Down
Loading
You are viewing a condensed version of this merge commit. You can view the full changes here.