Objective Function DSL
Objective functions are the criteria used to optimize routes. Under the hood, Pathfinder uses complex mathematics to determine the optimal route at any given time. However, to use Pathfinder it is not required to understand the underlying model. Instead, objective functions are specified using a Domain Specific Language (DSL). If this seems too complicated, don't fret! The Pathfinder dashboard contains two predefined objective functions that cover common use cases: minimizing distance and minimizing time.
Note that the "objective functions" described by this document are strictly speaking not objective functions. If you're interested in how Pathfinder transforms this DSL into mathematical expressions, you can read more about the DSL Compiler.
Concepts and Terminology
An objective function is a function from some variables to a real number and an instruction to either minimize or maximize that number. For Pathfinder, routes are calculated with cluster-granularity. The input to the objective function is the "route" for the cluster for the snapshot in time when it is calculated. There are three parts to a Pathfinder objective function: sense, context and quantity.
Sense
This is the instruction to either minimize or maximize the function.
Context
Since the input to the objective function is all of the routes for transports in the cluster, every objective function will involve iterating over the transports, the commodities or some Cartesian product of those sets. An expression is computed during the iteration and then either a sum, min or max is computed. This is essentially a "foreach loop" from most familiar programming languages.
For instance, I may want to minimize the maximum distance traveled by any transports. In this case, Pathfinder iterates over the set of transports and evaluates a maximum. "max" is referred to as the "method" and transports is referred to as the "entities".
Alternatively, I may want to minimize the total difference between commodity wait times. In this case, Pathfinder iterates over the set of all pairs of commodities and evaluates a sum. The method is "sum" and the entities are the Cartesian product of commodities with commodities.
Quantity
This is the value that will be computed for each iteration of the context. It is an algebraic combination of route variables, a few Pathfinder specific keyword quantities and parameters that are configured for your application and passed in via the metadata of transports and commodities.
The currently supported operations are absolute value, add, subtract, multiply and divide. This list is admittedly limited, however that is due to the need for the expression to be representable by a "linear combination" for Pathfinder's optimizer to function correctly.
Syntax
The Pathfinder DSL is a (very small) subset of YAML. Every objective function has the form
sense: <Sense>
context:
method: <Method>
for: <Entity Dictionary>
quantity:
<Expression>
Sense
Sense = min | max
Context
Method = sum | min | max
Entity Dictionary =
<name1>: commodity | transport
<name2>: commodity | transport
<name3>: commodity | transport
Quantity
Expression = Value | Evaluation
Evaluation =
<Function>:
- Quantity Expression
...
Value = Constant | <entity name>.<Property>
Constant = <Number> | <Global Keyword>
Property = <Entity Keyword> | <Parameter>
Function = absolute_value | add | subtract | multiply | divide
Global Keywords
now- UTC timestamp when the route is calculated
Transport Keywords
distance- The route length for the transportduration- The route duration for the transport
Commodity Keywords
request_time- The UTC timestamp for when the commodity was first set toWaitingstatuspickup_time- The UTC timestamp for when the commodity will be picked up in the routedropoff_time- The UTC timestamp for when the commodity will be dropped off in the routedistance- The distance that the commodity will travel according to the route
Parameters
These must be configured via the Pathfinder dashboard and included in the metadata for commodity or transports when they are created and updated via the SDKs. If the parameters are not present in the metadata, Pathfinder will make intelligent guesses (MAX_INT, MIN_INT, 0) based on your objective function. However, this is strongly discouraged.
Examples
For those who prefer concrete examples to context free grammars.
Minimize total transport distance
sense: min
context:
method: sum
for:
t: transport
quantity: t.distance
Minimize total transport time
sense: min
context:
method: sum
for:
t: transport
quantity: t.duration
Minimize max transport distance
sense: min
context:
method: max
for:
t: transport
quantity: t.distance
Minimize max transport route duration
sense: min
context:
method: max
for:
t: transport
quantity: t.duration
Minimize max time until passenger pickup
sense: min
context:
method: max
for:
c: commodity
quantity: c.pickup_time
Minimize max fuel used by a transport
sense: min
context:
method: sum
for:
t: transport
quantity:
divide:
- t.distance
- t.mpg
Minimize total fuel used by transports
sense: min
context:
method: sum
for:
t: transport
quantity:
divide:
- t.distance
- t.mpg
Minimize max time until passenger dropoff
sense: min
context:
- method: max
- for:
c: commodity
quantity:
subtract:
- c.dropoff_time
- now
Minimize maximum time until dropoff including past wait time
sense: min
context:
- method: max
- for:
c: commodity
quantity:
subtract:
- c.dropoff_time
- c.request_time
Minimize time until pickup weighted by customer priority
sense: min
context:
method: sum
for:
c: commodity
quantity:
multiply:
- subtract:
- c.pickup_time
- now
- c.priority
Minimize total time from now until drop off weighted by customer priority
sense: min
context:
method: sum
for:
c: commodity
quantity:
multiply:
- substract:
- c.dropoff_time
- now
- c.priority
Minimize maximum distance traveled by commodity
sense: min
context:
method: max
for:
c: commodity
quantity: c.distance
Minimize maximum difference between passenger total wait times
sense: min
context:
method: max
for:
c1: commodity
c2: commodity
quantity:
absolute_value:
subtract:
- subtract:
- c1.dropoff_time
- c1.request_time
- subtract:
- c2.dropoff_time
- c2.dropoff_time
Minimize sum of differences between passenger total wait times
sense: min
context:
method: sum
for:
c1: commodity
c2: commodity
quantity:
absolute_value:
- subtract:
- subtract:
- c1.dropoff_time
- c1.request_time
- subtract:
- c2.dropoff_time
- c2.request_time
Updated less than a minute ago