The problem envelope
The problem envelope is a common structure to all modelling API calls. Models are placed inside the envelope container and shipped as a single payload to the API. The advantage to this is that there are fewer end-points that you need to work with and the specification of what you want done actually moves into the envelope itself.
The submitting of models to the API follows a common process. Starting with whichever model you’re working with (such as the TSP, CVRP or IVR). This is represented by the block on the left labelled Model Definition. This model definition is serialised and placed in the content section of the problem envelope. If you’re unable to serialise the model, then you’re missing a required field which needs to be specified in the model definition.
Once you’ve set up the content of the Problem Envelope (the middle block), you will need to specify that this model is an input model (the default is input) and provide the model name. The model name is the unique identifier of the model, such as tsp-mcvfz472gty6
. This tells the API how it should handle the payload on the server. Lastly, the whole problem envelope is serialised again into binary format and provided as the content in the http post.
If you’re thinking that this sounds like two independent serialisation steps, you’re correct! To summarise:
- model -> envelope
- envelope -> http body
The same process applies, but in reverse for retrieving a solution to a problem.
First the content from the http get request is deserialised into a problem envelope. You’ll find that the sub-type field has already been set to 1
as this is an output payload. Next, you can deserialise the content of the problem envelope into the corresponding response payload for the model you’re working with. So the retrieval process is again, a two step process:
- http body -> envelope
- envelope -> model response
You can then work with the model response in the domain of your problem.
If you’re keen to get your hands dirty at this point with some concrete examples feel free to check out the examples repo which has implementations of this logic across a few languages such as R, Python, Java and C#.
Problem Envelope
A problem envelope
is used as a container for submitting a particular model to the API. The envelope contains the serialised model and requires that the model type field be set on the envelope. This allows the API to unpack the model using the type that was submitted. If you use the wrong type field for a particular model you’ll receive a serialisation error from the API.
Schema definition
message ProblemEnvelope {
enum SubType {
INPUT = 0;
OUTPUT = 1;
}
required string type = 1;
required SubType subType = 2 [default = INPUT];
optional bytes content = 3;
}
Fields
- type
- The model type being sent to the API. The model unique identifier is provided in the schema definitions available here. A standard format for model names is used by the API which is
<service class>-<id>
. An example of this is the tsp which istsp-mcvfz472gty6
. If a blank type field, an invalid model name or a valid but incorrect model name with respect to the content field is provided, an error is returned by the API. - subType
- The subtype is used to differentiate between incoming and outgoing problem envelopes (if you are using a serivce-bus internally). Problem envelopes submitted to the API should use the default INPUT type. A POST request to the API will return a request ID in json format. A GET request (with a valid request id) will return a problem envelope with the
subType = OUTPUT
. This output payload is the output from the solver and typically contains the solution corresponding to the model submitted. - content
- In the context of an
INPUT
problem envelope this is the serialised model content. The process of creating serialised content is language dependent and we suggest seeing the implementations provided in a few languages on the examples repo. In the context of anOUTPUT
problem envelope (i.e. a response from a GET request to the API), this field contains aSolverResponse
which can be deserialised accordingly. The solver response contains log messages (with potential errors detected by the API in parsing the input model), an overall status as well as a solution when the solve is complete (which can be deserialised into the corresponding response model type).
Examples
The following example illustrates how to configure a simple input problem envelope which specifies a TSP model should be solved. The type is set to tsp-mcvfz472gty6
and the subType to INPUT
. The content is a simple TSP model with three points which has been serialised into the content field. This could now be submitted via a POST request to the API and a request id will be returned in json.
type: "tsp-mcvfz472gty6"
subType: INPUT
content: "\n[\n\037\n\023The Oval Bar Dublin\025XT\310\300\035\323dUB\n\036\n\022
The Confession Box\025\326D\310\300\035\300fUB\n\026\n\nKehoes Pub\025>M\310\300\035Y]UB\020\001"
The next sample is an example of a response corresponding to a GET request using the above request id:
type: "tsp-mcvfz472gty6"
subType: OUTPUT
content: "\n\026\010\336\361\360\370\005\022\014Model Queued\030\000\n2\010\336\361\360\370\005\022(Successfully parsed solve request ...
The content field above can be deserialised using the SolverResponse
type to gain access to the solution and solver logs for the model submitted.
Solver Info
A Solver Info
is a common object used to provide logs and (where successful) a solution to a submitted model. This object is returned for all model type submissions, allowing for a standard handling of responses, only modifying the deserialisation type for the solution content.
Schema definition
message SolverInfo {
required int64 unixDateTime = 1;
required string infoMessage = 2;
enum SolverMessageType {
INFO = 0;
WARNING = 1;
ERROR = 2;
}
required SolverMessageType type = 3; // The type of the particular message returned.
}}
Fields
- unixDateTime
- The time in seconds (UTC) the message was created.
- infoMessage
- A string message containing a human-readable description. I.e. “Solve successful”, or “Error, Location IDs should be unique”.
- SolverMessageType
- The type of message generated in the log. Will be either
Info
,Warning
orError
. Warning messages are typically used to indicate possible modelling error conditions which the solver has detected. This is a function of the model being employed. There will only be one error message in a log as the solver will not continue if an error is detected.
Solver Response
A Solver Response
is a common object used to provide logs and (where successful) a solution to a submitted model. This object is returned for all model type submissions, allowing for a standard handling of responses, only modifying the deserialisation type for the solution content.
Schema definition
message SolverResponse {
repeated SolverInfo logs = 1;
enum SolveState {
WIP = 0; // Work In Progress
COMPLETED = 1; // The solve is complete
FAILED = 2; // The solve has failed
}
required SolveState state = 2; // The current state of the solve-process
optional bytes solution = 3; // If a solution is available, it is returned here.
}
Fields
- logs
- A list of log messages provided by the solver. Each log message conforms to the
Solver Info
type described above. - state
- The current state of the solve. Will be one of three possible values, either work in progress (WIP), completed (COMPLETED) or failed (FAILED).
- solution
- In the instance where a solve has completed (without an error as the last message in the logs), the solution will be populated with a serialised model response, corresponding to the output type of the model submitted.
Examples
This example illustrates the detailed feedback provided by the solver. A collection of log messages (truncated) as well as a serialised TSP solution response (also truncated).
logs {
unixDateTime: 1595685086
infoMessage: "Model Queued"
type: INFO
}
logs {
unixDateTime: 1595685086
infoMessage: "Successfully parsed solve request for IVR"
type: INFO
}
...
logs {
unixDateTime: 1595685086
infoMessage: "Solve done"
type: INFO
}
state: COMPLETED
solution: "\n\023The Oval Bar Dublin\n\022The Confession Box\n\nKehoes Pub\n\023
The Oval Bar Dublin\022\306\006\n\023The Oval Bar Dublin... truncated
The solution field above can be deserialised using the corresponding output model type. In this particular case, the solution can be deserialised using the TSP.SolutionResponse
object. Most models make use of the SolutionResponse
as a naming standard for the return type object name.