{"_id":"56a96dfd8791090d00113bac","project":"56a83b979ec7660d002e07be","parentDoc":null,"user":"56a83a6070a9440d00ef5ef8","version":{"_id":"56a83b989ec7660d002e07c1","project":"56a83b979ec7660d002e07be","__v":9,"createdAt":"2016-01-27T03:38:00.333Z","releaseDate":"2016-01-27T03:38:00.333Z","categories":["56a83b989ec7660d002e07c2","56a83c282036420d002d21e1","56a96de8f834950d0037b35a","56a9706013a69a0d00a778c3","56a970ec2d8fd90d0036eec7","56a971a62bb3910d000ee934","56a973372d8fd90d0036eece","56a978dc2bb3910d000ee93f","571d5ae118b3c10e003e55cd"],"is_deprecated":false,"is_hidden":false,"is_beta":false,"is_stable":true,"codename":"Beta","version_clean":"1.0.0","version":"1.0"},"__v":24,"githubsync":"","category":{"_id":"56a96de8f834950d0037b35a","__v":2,"pages":["56a96dfd8791090d00113bac","56a974842bb3910d000ee93a"],"version":"56a83b989ec7660d002e07c1","project":"56a83b979ec7660d002e07be","sync":{"url":"","isSync":false},"reference":false,"createdAt":"2016-01-28T01:24:56.870Z","from_sync":false,"order":2,"slug":"configuration","title":"Configuration"},"updates":[],"next":{"pages":[],"description":""},"createdAt":"2016-01-28T01:25:17.047Z","link_external":false,"link_url":"","sync_unique":"","hidden":false,"api":{"results":{"codes":[]},"settings":"","auth":"required","params":[],"url":""},"isReference":false,"order":1,"body":"<div class=\"corner-ribbon top-left sticky blue\"><a style=\"color: white;\" href=\"https://pathfinder.readme.io/blog/pathfinder-now-in-public-beta\">Public Beta!</a></div>\n\nObjective 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.\n\nNote 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](doc:objective-function-dsl-1).\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Concepts and Terminology\"\n}\n[/block]\nAn 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.\n\n## Sense\nThis is the instruction to either minimize or maximize the function.\n\n## Context\nSince 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.\n\nFor 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\".\n\nAlternatively, 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.\n\n## Quantity\nThis 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.\n\nThe 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.\n\n\n# Syntax\n\nThe Pathfinder DSL is a (very small) subset of YAML. Every objective function has the form\n\n    sense: <Sense>\n    context:\n        method: <Method>\n        for: <Entity Dictionary>\n    quantity:\n        <Expression>\n        \n\n### Sense\n    Sense = min | max\n\n### Context\n    Method = sum | min | max\n    Entity Dictionary =\n        <name1>: commodity | transport\n        <name2>: commodity | transport\n        <name3>: commodity | transport\n        \n\n### Quantity\n    Expression = Value | Evaluation\n    \n    Evaluation =\n        <Function>:\n            - Quantity Expression\n            ...\n    Value = Constant | <entity name>.<Property>\n    Constant = <Number> | <Global Keyword>\n    Property = <Entity Keyword> | <Parameter> \n    Function = absolute_value | add | subtract | multiply | divide\n\n#### Global Keywords\n\n- `now` - UTC timestamp when the route is calculated\n\n#### Transport Keywords\n- `distance` - The route length for the transport\n- `duration` - The route duration for the transport\n\n#### Commodity Keywords\n- `request_time` - The UTC timestamp for when the commodity was first set to `Waiting` status\n- `pickup_time` - The UTC timestamp for when the commodity will be picked up in the route\n- `dropoff_time` - The UTC timestamp for when the commodity will be dropped off in the route\n- `distance` - The distance that the commodity will travel according to the route\n\n#### Parameters\n\nThese 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.\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Examples\"\n}\n[/block]\nFor those who prefer concrete examples to context free grammars.\n\n### Minimize total transport distance\n    sense: min\n    context:\n        method: sum\n        for:\n            t: transport\n    quantity: t.distance\n\n###  Minimize total transport time\n    sense: min\n    context:\n        method: sum\n        for:\n            t: transport\n    quantity: t.duration\n\n### Minimize max transport distance\n    sense: min\n    context:\n        method: max\n        for:\n            t: transport\n    quantity: t.distance\n\n### Minimize max transport route duration\n    sense: min\n    context:\n        method: max\n        for:\n            t: transport\n    quantity: t.duration\n\n### Minimize max time until passenger pickup\n    sense: min\n    context:\n        method: max\n        for:\n            c: commodity\n    quantity: c.pickup_time\n\n### Minimize max fuel used by a transport\n    sense: min\n    context:\n        method: sum\n        for:\n            t: transport\n    quantity:\n        divide:\n            - t.distance\n            - t.mpg            \n\n### Minimize total fuel used by transports\n    sense: min\n    context:\n        method: sum\n        for:\n            t: transport\n    quantity:\n        divide:\n            - t.distance\n            - t.mpg\n\n### Minimize max time until passenger dropoff\n    sense: min\n    context:\n        - method: max\n        - for:\n            c: commodity\n    quantity:\n        subtract:\n            - c.dropoff_time\n            - now\n\n### Minimize maximum time until dropoff including past wait time\n    sense: min\n    context:\n        - method: max\n        - for:\n            c: commodity\n    quantity:\n        subtract:\n            - c.dropoff_time\n            - c.request_time\n\n### Minimize time until pickup weighted by customer priority\n    sense: min\n    context:\n        method: sum\n        for:\n            c: commodity\n    quantity:\n        multiply:\n            - subtract:\n                - c.pickup_time\n                - now\n            - c.priority                \n\n### Minimize total time from now until drop off weighted by customer priority\n    sense: min\n    context:\n        method: sum\n        for:\n            c: commodity\n    quantity:\n        multiply:\n            - substract:\n                - c.dropoff_time\n                - now\n            - c.priority\n\n### Minimize maximum distance traveled by commodity\n        sense: min\n        context:\n            method: max\n            for:\n                c: commodity\n        quantity: c.distance\n\n### Minimize maximum difference between passenger total wait times\n    sense: min\n    context:\n        method: max\n        for:\n            c1: commodity\n            c2: commodity\n    quantity:\n        absolute_value:\n            subtract:\n                - subtract:\n                    - c1.dropoff_time\n                    - c1.request_time\n                - subtract:\n                    - c2.dropoff_time\n                    - c2.dropoff_time\n\n### Minimize sum of differences between passenger total wait times\n    sense: min\n    context:\n        method: sum\n        for:\n            c1: commodity\n            c2: commodity\n    quantity:\n        absolute_value:\n            - subtract:\n                - subtract:\n                    - c1.dropoff_time\n                    - c1.request_time\n                - subtract:\n                    - c2.dropoff_time\n                    - c2.request_time","excerpt":"","slug":"objective-function-dsl","type":"basic","title":"Objective Function DSL"}

Objective Function DSL


<div class="corner-ribbon top-left sticky blue"><a style="color: white;" href="https://pathfinder.readme.io/blog/pathfinder-now-in-public-beta">Public Beta!</a></div> 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](doc:objective-function-dsl-1). [block:api-header] { "type": "basic", "title": "Concepts and Terminology" } [/block] 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 transport - `duration` - The route duration for the transport #### Commodity Keywords - `request_time` - The UTC timestamp for when the commodity was first set to `Waiting` status - `pickup_time` - The UTC timestamp for when the commodity will be picked up in the route - `dropoff_time` - The UTC timestamp for when the commodity will be dropped off in the route - `distance` - 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. [block:api-header] { "type": "basic", "title": "Examples" } [/block] 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