All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.opentripplanner.raptor.api.request.MultiCriteriaRequest Maven / Gradle / Ivy

The newest version!
package org.opentripplanner.raptor.api.request;

import java.util.List;
import java.util.Objects;
import java.util.Optional;
import javax.annotation.Nullable;
import org.opentripplanner.framework.tostring.ToStringBuilder;
import org.opentripplanner.raptor.api.model.RaptorTripSchedule;
import org.opentripplanner.raptor.api.model.RelaxFunction;

/**
 * Parameters to configure the multi-criteria search.
 * 

* @param The TripSchedule type defined by the user of the raptor API. */ public class MultiCriteriaRequest { private final RelaxFunction relaxC1; @Nullable private final RaptorTransitGroupPriorityCalculator transitPriorityCalculator; private final List passThroughPoints; @Nullable private final Double relaxCostAtDestination; private MultiCriteriaRequest() { this.relaxC1 = RelaxFunction.NORMAL; this.transitPriorityCalculator = null; this.passThroughPoints = List.of(); this.relaxCostAtDestination = null; } public MultiCriteriaRequest(Builder builder) { this.relaxC1 = Objects.requireNonNull(builder.relaxC1()); this.transitPriorityCalculator = builder.transitPriorityCalculator(); this.passThroughPoints = builder.passThroughPoints(); this.relaxCostAtDestination = builder.relaxCostAtDestination(); } public static Builder of() { return new Builder(new MultiCriteriaRequest<>()); } public Builder copyOf() { return new Builder<>(this); } /** * Whether to accept non-optimal trips if they are close enough with respect to * c1(generalized-cost). In other words this relaxes the pareto comparison at * each stop and at the destination. *

* Let {@code c} be the existing minimum pareto optimal cost to beat. Then a trip * with cost {@code c'} is accepted if the following is true: *

   * c' < RelaxFunction.relax(c)
   * 
* The default is {@link RelaxFunction#NORMAL}. */ public RelaxFunction relaxC1() { return relaxC1; } public Optional transitPriorityCalculator() { return Optional.ofNullable(transitPriorityCalculator); } public boolean hasPassThroughPoints() { return !passThroughPoints.isEmpty(); } public List passThroughPoints() { return passThroughPoints; } /** * Whether to accept non-optimal trips if they are close enough - if and only if they represent * an optimal path for their given iteration. In other words this slack only relaxes the pareto * comparison at the destination. *

* Let {@code c} be the existing minimum pareto optimal cost to beat. Then a trip with cost * {@code c'} is accepted if the following is true: *

   * c' < Math.round(c * relaxCostAtDestination)
   * 
* If the value is less than 1.0 a normal '<' comparison is performed. *

* The default is not set. *

* @deprecated This parameter only relax the cost at the destination, not at each stop. This * is replaced by {@link #relaxC1()}. This parameter is ignored if {@link #relaxC1()} exist. */ @Deprecated @Nullable public Double relaxCostAtDestination() { return relaxCostAtDestination; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; MultiCriteriaRequest that = (MultiCriteriaRequest) o; return ( Objects.equals(relaxC1, that.relaxC1) && Objects.equals(transitPriorityCalculator, that.transitPriorityCalculator) && Objects.equals(passThroughPoints, that.passThroughPoints) && Objects.equals(relaxCostAtDestination, that.relaxCostAtDestination) ); } @Override public int hashCode() { return Objects.hash( relaxC1, transitPriorityCalculator, passThroughPoints, relaxCostAtDestination ); } @Override public String toString() { return ToStringBuilder .of(MultiCriteriaRequest.class) .addObj("relaxC1", relaxC1, RelaxFunction.NORMAL) .addObj("transitPriorityCalculator", transitPriorityCalculator) .addObj("passThroughPoints", passThroughPoints) .addNum("relaxCostAtDestination", relaxCostAtDestination) .toString(); } public boolean includeC2() { return hasPassThroughPoints() || transitPriorityCalculator != null; } public static class Builder { private final MultiCriteriaRequest original; private RelaxFunction relaxC1; private RaptorTransitGroupPriorityCalculator transitPriorityCalculator; private List passThroughPoints; private Double relaxCostAtDestination; public Builder(MultiCriteriaRequest original) { this.original = original; this.relaxC1 = original.relaxC1; this.passThroughPoints = original.passThroughPoints; this.transitPriorityCalculator = original.transitPriorityCalculator; this.relaxCostAtDestination = original.relaxCostAtDestination; } @Nullable public RelaxFunction relaxC1() { return relaxC1; } public Builder withRelaxC1(RelaxFunction relaxC1) { this.relaxC1 = relaxC1; return this; } @Nullable public RaptorTransitGroupPriorityCalculator transitPriorityCalculator() { return transitPriorityCalculator; } public Builder withTransitPriorityCalculator(RaptorTransitGroupPriorityCalculator value) { transitPriorityCalculator = value; return this; } public List passThroughPoints() { return passThroughPoints; } @Nullable public Builder withPassThroughPoints(List points) { // Prevent setting this to an empty list - here we use null to represent NOT_SET passThroughPoints = (points == null || points.isEmpty()) ? List.of() : points; return this; } @Nullable @Deprecated public Double relaxCostAtDestination() { return relaxCostAtDestination; } @Deprecated public Builder withRelaxCostAtDestination(Double value) { relaxCostAtDestination = value; return this; } public MultiCriteriaRequest build() { var newInstance = new MultiCriteriaRequest(this); return original.equals(newInstance) ? original : newInstance; } @Override public String toString() { return ToStringBuilder .of(MultiCriteriaRequest.Builder.class) .addObj("relaxC1", relaxC1) .addObj("transitPriorityCalculator", transitPriorityCalculator) .addObj("passThroughPoints", passThroughPoints) .addNum("relaxCostAtDestination", relaxCostAtDestination) .toString(); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy