Skip to content

Choice Models

ChoiceModel module-attribute

ChoiceModel = Annotated[
    PodsChoiceModel | LogitChoiceModel,
    Field(discriminator="kind"),
]

Two types of choice models are available in PassengerSim.

Use the kind key to select which kind of choice model you wish to parameterize.

TwoFloats module-attribute

TwoFloats = SerializeAsAny[tuple[float, float] | None]

CommonChoiceModel

Bases: Named

A common base class for choice models.

Defines restrictions and other parameters that are common to all choice models.

Source code in passengersim/config/choice_model.py
class CommonChoiceModel(Named, extra="forbid"):
    """A common base class for choice models.

    Defines restrictions and other parameters that are common to all
    choice models."""

    restrictions: dict[str, float] | None = None

    @property
    def r1(self):
        """Restriction 1.

        This is deprecated in favor of the `restrictions` dictionary."""
        return self.restrictions.get("r1", None)

    @r1.setter
    def r1(self, value: float):
        self.restrictions["r1"] = value

    @property
    def r2(self):
        """Restriction 2.

        This is deprecated in favor of the `restrictions` dictionary."""
        return self.restrictions.get("r2", None)

    @r2.setter
    def r2(self, value: float):
        self.restrictions["r2"] = value

    @property
    def r3(self):
        """Restriction 3.

        This is deprecated in favor of the `restrictions` dictionary."""
        return self.restrictions.get("r3", None)

    @r3.setter
    def r3(self, value: float):
        self.restrictions["r3"] = value

    @property
    def r4(self):
        """Restriction 4.

        This is deprecated in favor of the `restrictions` dictionary."""
        return self.restrictions.get("r4", None)

    @r4.setter
    def r4(self, value: float):
        self.restrictions["r4"] = value

    @model_validator(mode="before")
    @classmethod
    def _named_restrictions(cls, data: Any) -> Any:
        restricts = data.get("restrictions", {})
        if "r1" in data:
            restricts["r1"] = data.pop("r1")
        if "r2" in data:
            restricts["r2"] = data.pop("r2")
        if "r3" in data:
            restricts["r3"] = data.pop("r3")
        if "r4" in data:
            restricts["r4"] = data.pop("r4")
        data["restrictions"] = restricts
        return data

r1 property writable

r1

Restriction 1.

This is deprecated in favor of the restrictions dictionary.

r2 property writable

r2

Restriction 2.

This is deprecated in favor of the restrictions dictionary.

r3 property writable

r3

Restriction 3.

This is deprecated in favor of the restrictions dictionary.

r4 property writable

r4

Restriction 4.

This is deprecated in favor of the restrictions dictionary.

restrictions class-attribute instance-attribute

restrictions: dict[str, float] | None = None

LogitChoiceModel

Bases: CommonChoiceModel

Source code in passengersim/config/choice_model.py
class LogitChoiceModel(CommonChoiceModel, extra="forbid"):
    kind: Literal["logit"]

    emult: float | None = None
    """Using for WTP, a bit of a quick and dirty until we have a better approach"""

    anc1_relevance: float | None = None
    anc2_relevance: float | None = None
    anc3_relevance: float | None = None
    anc4_relevance: float | None = None

    intercept: float = 0
    """This is the alternative specific constant for the no-purchase alternative."""

    nonstop: float = 0
    duration: float = 0
    price: float = 0
    """This is the parameter for the price of each alternative."""

    tod_sin2p: float = 0
    r"""Schedule parameter.

    If $t$ is departure time (in minutes after midnight local time) divided
    by 1440, this parameter is multiplied by $sin( 2 \pi t)$ and the result is
    added to the utility of the particular alternative."""

    tod_sin4p: float = 0
    r"""Schedule parameter.

    If $t$ is departure time (in minutes after midnight local time) divided
    by 1440, this parameter is multiplied by $sin( 4 \pi t)$ and the result is
    added to the utility of the particular alternative."""

    tod_sin6p: float = 0
    tod_cos2p: float = 0
    tod_cos4p: float = 0
    tod_cos6p: float = 0
    free_bag: float = 0
    early_boarding: float = 0
    same_day_change: float = 0

anc1_relevance class-attribute instance-attribute

anc1_relevance: float | None = None

anc2_relevance class-attribute instance-attribute

anc2_relevance: float | None = None

anc3_relevance class-attribute instance-attribute

anc3_relevance: float | None = None

anc4_relevance class-attribute instance-attribute

anc4_relevance: float | None = None

duration class-attribute instance-attribute

duration: float = 0

early_boarding class-attribute instance-attribute

early_boarding: float = 0

emult class-attribute instance-attribute

emult: float | None = None

Using for WTP, a bit of a quick and dirty until we have a better approach

free_bag class-attribute instance-attribute

free_bag: float = 0

intercept class-attribute instance-attribute

intercept: float = 0

This is the alternative specific constant for the no-purchase alternative.

kind instance-attribute

kind: Literal['logit']

nonstop class-attribute instance-attribute

nonstop: float = 0

price class-attribute instance-attribute

price: float = 0

This is the parameter for the price of each alternative.

same_day_change class-attribute instance-attribute

same_day_change: float = 0

tod_cos2p class-attribute instance-attribute

tod_cos2p: float = 0

tod_cos4p class-attribute instance-attribute

tod_cos4p: float = 0

tod_cos6p class-attribute instance-attribute

tod_cos6p: float = 0

tod_sin2p class-attribute instance-attribute

tod_sin2p: float = 0

Schedule parameter.

If \(t\) is departure time (in minutes after midnight local time) divided by 1440, this parameter is multiplied by \(sin( 2 \pi t)\) and the result is added to the utility of the particular alternative.

tod_sin4p class-attribute instance-attribute

tod_sin4p: float = 0

Schedule parameter.

If \(t\) is departure time (in minutes after midnight local time) divided by 1440, this parameter is multiplied by \(sin( 4 \pi t)\) and the result is added to the utility of the particular alternative.

tod_sin6p class-attribute instance-attribute

tod_sin6p: float = 0

PodsChoiceModel

Bases: CommonChoiceModel

Source code in passengersim/config/choice_model.py
class PodsChoiceModel(CommonChoiceModel, extra="forbid"):
    kind: Literal["pods"]

    emult: float | None = None

    basefare_mult: float | None = None
    basefare_mult2: float | None = 1.0
    connect_disutility: float | None = None
    path_quality: TwoFloats = None
    airline_pref_pods: TwoFloats = None
    airline_pref_hhi: TwoFloats = None
    airline_pref_seat_share: TwoFloats = None
    elapsed_time: TwoFloats = None
    buffer_threshold: int | None = None
    buffer_time: TwoFloats = None
    tolerance: float | None = None
    non_stop_multiplier: float | None = None
    connection_multiplier: float | None = None

    # DWM info
    todd_curve: str | None = None
    early_dep: dict | None = None
    late_arr: dict | None = None
    replanning: TwoFloats = None

    # Ancillaries
    anc1_relevance: float | None = None
    anc2_relevance: float | None = None
    anc3_relevance: float | None = None
    anc4_relevance: float | None = None

airline_pref_hhi class-attribute instance-attribute

airline_pref_hhi: TwoFloats = None

airline_pref_pods class-attribute instance-attribute

airline_pref_pods: TwoFloats = None

airline_pref_seat_share class-attribute instance-attribute

airline_pref_seat_share: TwoFloats = None

anc1_relevance class-attribute instance-attribute

anc1_relevance: float | None = None

anc2_relevance class-attribute instance-attribute

anc2_relevance: float | None = None

anc3_relevance class-attribute instance-attribute

anc3_relevance: float | None = None

anc4_relevance class-attribute instance-attribute

anc4_relevance: float | None = None

basefare_mult class-attribute instance-attribute

basefare_mult: float | None = None

basefare_mult2 class-attribute instance-attribute

basefare_mult2: float | None = 1.0

buffer_threshold class-attribute instance-attribute

buffer_threshold: int | None = None

buffer_time class-attribute instance-attribute

buffer_time: TwoFloats = None

connect_disutility class-attribute instance-attribute

connect_disutility: float | None = None

connection_multiplier class-attribute instance-attribute

connection_multiplier: float | None = None

early_dep class-attribute instance-attribute

early_dep: dict | None = None

elapsed_time class-attribute instance-attribute

elapsed_time: TwoFloats = None

emult class-attribute instance-attribute

emult: float | None = None

kind instance-attribute

kind: Literal['pods']

late_arr class-attribute instance-attribute

late_arr: dict | None = None

non_stop_multiplier class-attribute instance-attribute

non_stop_multiplier: float | None = None

path_quality class-attribute instance-attribute

path_quality: TwoFloats = None

replanning class-attribute instance-attribute

replanning: TwoFloats = None

todd_curve class-attribute instance-attribute

todd_curve: str | None = None

tolerance class-attribute instance-attribute

tolerance: float | None = None