4. Decision Models
The Decision Model is at the heart of both the Decision Intelligence paradigm, and World Modeler Server’s capabilities. Most of World Modeler Server’s functions exist either to support the management of Decision Models, or to utilize them in various ways. Therefore, understanding how the API handles them is a pre-requisite to effectively using most of the API’s operations.
Introduction to Decision Models
If you are already familiar with Decision Models, in particular the “Action to Outcomes” paradigm on which Quantellia’s Decision Models are based, you may skip this section. If you are new to Decision Models, or wish to brush up your knowledge, then this section provides an introductory overview and if you wish to explore the subject in more depth, then consult the following resources:*
What are Decision Models for?
You are most likely familiar with the concept of a Data Model. The purpose of a Data Model is to define a set of information-storing entities (such as tables in a relational database, documents in a document repository, etc.), a description of the information stored in each of them (such as columns of tables, keywords for documents, etc.), and the way these objects are related to one another. The purpose of the relationships is to allow navigation through the data model. For example, in a simple student database, there is a table of students and a table of courses. The relationship “student is enrolled in course” is represented by a third table, each row of which is a student ID and the ID of a course they are enrolled in. Using entities and the relationships between them, a well-designed data model can answer many useful questions for the organization it is built to serve. In our students and courses example the model can answer “What courses is student X enrolled in?”, or “Which students are enrolled in course Y?”. Data models allow data to be joined, filtered, and aggregated so that information relevant to the questions being asked by the user can be extracted and presented in a way that is understandable to them.
But there are some questions Data Models cannot answer. Considering the above students and courses example again, no Data Model can help with the question “What course should student X enroll in?”. Data Models can provide raw facts, but the facts alone cannot determine decisions since some vital pieces of the decision-making process are missing. These are:
- What are the outcomes or goals the decision-maker is trying to achieve?
- What actions can the decision-maker take to achieve those goals?
- How does a given action affect the goals?
- What factors not under the decision-maker’s control also affect the outcomes?
The purpose of a Decision Model is to create and digitally store a representation of the information needed to answer the questions specifically related to decision making. It integrates with traditional Data Models, but adds new types of information that Data Models typically don’t capture.
Elements of a Decision Model
Decision Models are composed of elements that are assigned one of the following Roles:
- Actions
- These represent the things a decision-maker can change and which are under their control.
- Outcomes
- These represent the things that the decision-maker is ultimately trying to achieve. In particular, producing outcomes that are within a specified range is what is meant by a “goal” (e.g. the outcome “Profit” is greater than zero).
- Externals
- These represent other factors on which the Outcomes may depend, but are not under the control of the decision-maker (for example, the sales of an ice-cream truck depend on the weather).
- Intermediates
- It is rarely the case that the immediate consequences of the Actions a decision-maker can take are the Outcomes they are trying to achieve. Instead, Actions (and Externals) have direct consequences, which in turn have other consequences, and so on, until the Outcomes are reached. The elements that map out the causal chain between the Actions and External, and the Outcomes are called Intermediates.
- Constraints
- Most decisions are made within a set of limitations. Budgets, timeframes, and other resources are bounded and any decision that requires one of the elements to exceed its bounds needs to be excluded from consideration. To detect such conditions, Decision Models also contain Constraints. Each Constraint is a conditional expression that must be satisfied for the decision to be valid (for example ProjectBudget <= BudgetLimit )
- Dependencies
- Dependencies link Decision Model elements together in a way that represents the “chain-of-thought reasoning” process. From a quantitative perspective, element A has a direct dependency on element B if the value of B is one of the input arguments to element A.
In summary Decision Models are like Data models in that they contain elements that represent information in a structured way. However, unlike Data Models:
- Elements are labelled to reflect the role they play in the decision-making process
- Relationships between elements do not represent navigability, but dependency.
- Since Decision Models have well-defined Inputs (Actions and Externals), Outputs (Outcomes), and quantitative relationships that ultimately link these together, a Decision Model can be evaluated (or “executed”). Outcomes can be calculated by supplying a set of values to each of the Inputs and propagating these through the dependencies.
- Because Actions and Outcomes are identified as such, a Decision Model can be used to optimize a decision by finding the Actions yielding the Outcomes that are closest to the goal. This is often done using simulation.
Visualizing Decision Models using Causal Decision Diagrams (CDDs)
Many design disciplines in the information sciences include a formal diagramming notation. Entity-relation models (ERM) are represented visually using entity-relation diagrams (ERD), for example, and object-oriented designs (OOD) are commonly represented in Universal Modeling Language (UML) diagrams. Decision Modeling is no different in this regard, with Decision Models represented in Causal Decision Diagrams (CDDs). An example of a CDD is shown below. This CDD considers a product whose wholesale price varies rapidly, and compares the net earnings that a retailer will achieve if they hold the retail price fixed, vs holding the margin fixed and letting the retail price vary with the wholesale price.
Calculating the value of a Decision Model Element
The diagrammatic representation of the reasoning process employed in making a decision is often very useful in and of itself. However, the full power of using Decision Models in World Modeler Server is unleashed when the speed of a computer is leveraged to retrieve data from the sources associated with the decision model, and run the decision reasoning process from Actions to Outcomes (which we collectively refer to as the Decision Model’s inputs). Given how quickly a computer can do this, many different Actions and their Outcomes can be calculated in a short time and presented for decision-makers to consider. This will be covered in detail in section 6, Simulation.
Expressions and code blocks
For a computer to be able to perform the calculations required to determine the Outcomes that result from each set of Inputs, the value of each element in the dependency chain that links the Inputs to the Outputs must be calculated using the values of the elements on which it depends. Once calculated, each element’s value is then passed on to the elements that depend on it, and so on, until the Outcome elements are calculated. Therefore, for a Decision Model to be executable (or evaluable), every element must define the calculation that defines its value. In the current version of World Modeler Server, the calculations are defined as fragments of JavaScript code.
Expressions
For example, suppose a Decision Model has two inputs, Revenue and Cost and a single Output, Profit which is defined as the difference between Revenue and Cost. The value of the Revenue and Cost elements are obtained from outside the model. Perhaps they are entered manually by the user through a UI, or are read from a database or other data source. Either way, the value of the Profit element is specified by a string with the following syntax:
Revenue – Cost;
The above snippet of code—a single calculation with no embedded control flow logic—is referred to as an Expression. Expressions can reference any element of the Decision Model either by its short name, or its Fully Qualified Name, along with references to the standard JavaScript run-time library. For example, suppose we need to allow for the fact that the actual profit we make is influenced by fluctuations in the currency exchange rate, and we represent this as a random ±5% fluctuation in the above profit calculation. So profit could now be represented as:
(0.95 + Math.random() * 0.1) * (Revenue – Cost);
Note that the above expression makes use of the JavaScript library function Math.random(). Code Blocks Sometimes, the calculation required to compute the value of a Decision Model Element is too complicated to be achievable as a single expression. In this case, a Code Block can be used. A Code Block is essentially the body of a function that returns the desired value and can access the value of all other elements in the model as if they were global variables. Just as with normal JavaScript functions, local variables can be declared and used, and the calculated value is output using a return statement. To indicate that the source syntax is a code block, rather than a simple expression, the first non-whitespace or comment character must be an opening brace { . The body of the code block follows, ending in a return statement and a closing brace }. Consider the following example which calculates the Cost element as a sliding scale depending on the time of year (before or after June) and the number of units purchased, defined in the model as an element named OrderSize.
{ // This is a code block that calculates cost based on:
// - whether the goods are ordered before or after June
// - the size of the order
let is_before_june = ((new Date()).getUTCMonth() + 1 <= 6 ) ? true : false;
let cost = null;
// Use the pre-June cost schedule
if (is_before_june)
{
if (OrderSize < 1000) cost = 25;
else if (OrderSize < 10000) cost = 18;
else if (OrderSize < 50000) cost = 15;
else cost = 12;
}
// Use the post-Jone cost schedule
else
{
if (OrderSize < 1000) cost = 30;
else if (OrderSize < 10000) cost = 22;
else if (OrderSize < 50000) cost = 20;
else cost = 15;
}
return cost;
}
math library
In addition to native Javascript Math library, both expressions and code blocks can also include more advanced mathematical functions defined in the math.js library. See the math.js online documentation.
Open DI Representation of a Decision Model in JSON
When sending or receiving Decision Models and their elements to or from World Modeler Server, the JSON representation defined by the Open DI standard is used. JSON strings are sent to World Modeler Server API as the body of POST and PUT requests, and are returned to the caller as the value field of the RESTRespose object in the response body of each API call (see Section 2, above). The Open DI object model for Decision Models is shown below as a UML diagram.
The Decision Model includes a collection of Decision Model Elements. This collection, named elements, includes both the model elements that define the model’s entities and logic (these are referred to as evaluable elements and are usually of the Open DI type DIVariable), and the diagrams, if any, used to visualize the model. The graphical elements of each diagram are also stored in the elements collection. We will discuss this in more detail below.Representing a Decision Model in JSON
Recall from Lazy Loading and “collection” vs “instance” queries in section 2 that when Decision Models are returned from the API as members of a collection, their internal collections are not fully populated. In this form, the JSON representing a decision Model is shown below.
“Lazy” JSON for returning Decision Models in a collection:
{
"ownerID": "027668E9-3239-4FF2-B1E5-52104AAEC713",
"ownerType": "Quantellia.WMServer.Auth.WMUser",
"name": "Pricing Model",
"summary": "Short summary of Decision Model",
"documentation": "Long description of Decision Model",
"documentationMIMEType": "MIME type of documentation",
"id": "6027bcb9-553d-4625-bdbf-01307132e2de"
}
By contrast, when a single decision model is returned, it includes the element collection (shown) and the diagrams collection (not shown to save space). “Complete” JSON for returning a single Decision Model instance:
{
"elements": [
{
"parent": null,
"expression": "UnitCost * ProductionRun",
"role": "External",
"value": null,
"defaultvalue": "DIVariable",
"type": null,
"id": "00981101-9fdd-4aca-a1a9-33f671b04984",
"name": "TotalCost",
"summary": "string",
"documentation": "string",
"documentationMIMEType": "string",
"properties": {}
},
{
"parent": null,
"expression": "1000000",
"role": "External",
"value": null,
"defaultvalue": null,
"type": "DIVariable",
"id": "2b03dbda-0246-4713-bc79-7d1cc10cab5f",
"name": "MarketSize",
"summary": "string",
"documentation": "string",
"documentationMIMEType": "string",
"properties": {}
},
{
"parent": null,
"expression": "DemandCurve * MarketSize",
"role": "Intermediate",
"value": null,
"defaultvalue": null,
"type": "DIVariable",
"id": "4e6bcc5f-77d8-4c98-8797-f6e765cf9b0c",
"name": "UnitsSold",
"summary": "string",
"documentation": "string",
"documentationMIMEType": "string",
"properties": {}
},
{
"parent": null,
"expression": "{ if (ProductionRun < 50000) return 8.0;
else if (ProductionRun < 150000) return 6.0;
else return 4.0;
}",
"role": "External",
"value": null,
"defaultvalue": null,
"type": "DIVariable",
"id": "50202eb2-18cb-49d0-ae4b-511d2f394ebf",
"name": "UnitCost",
"summary": "string",
"documentation": "string",
"documentationMIMEType": "string",
"properties": {}
},
// ... etc
{
"parent": null,
"expression": "120000",
"role": "Intermediate",
"value": null,
"defaultvalue": null,
"type": "DIVariable",
"id": "f99abeea-6d07-4734-91f7-141d6bd7e9f1",
"name": "ProductionRun",
"summary": "string",
"documentation": "string",
"documentationMIMEType": "string",
"properties": {}
}
],
"id": "6027bcb9-553d-4625-bdbf-01307132e2de",
"name": "Pricing Model",
"summary": "string",
"documentation": "string",
"documentationMIMEType": "string",
"properties": {
"OwnerID": "027668E9-3239-4FF2-B1E5-52104AAEC713",
"OwnerType": "Quantellia.WMServer.Auth.WMUser"
}
}
Note that the string supplying the value of the expression property can be either an Expression or a Code Block.
Representing a Decision Model Element in JSON
Decision Model Elements do not have separate “lazy” and “complete” forms because they do not generally have internal collections within them, so the cost of querying a Decision Model Element is low, and the JSON string representing it is quite small. The DIDecisionModelDiagram element type (the type that stores a CDD in the Decision Model) may seem like an exception to this, since each diagram contains a collection of graphical objects. However, the JSON implementation of this does not represent diagram elements as collections inside the diagrams that own them. Instead, both diagrams and their contents are peers in the “flat” elements collection, since they are all elements of the same decision model. The hierarchical relationship between them within the Decision Model is implemented by:
- The parent field of each diagram element, that points to the DIDecisionModelDiagram that is its parent.
- The elementRef field of each diagram element that points to the evaluable DIVariable that it represents, or is null if the diagram element is a pure graphical annotation.
This is shown in the pair of diagrams below.
Logical representation of the relationships between evaluable DIVariable elements in a Decision Model, DIDecisionModelDiagram elements,
and the DIDeicisionModelDiagramElement instances they contain.
|
Physical layout of the Decision Model’s elements collection corresponding to the logical representation (left) as a flat list.
Note the following:
|
{
"parent": null,
"expression": "UnitCost * ProductionRun",
"role": "External",
"value": null,
"defaultvalue": null,
"type": "DIVariable",
"id": "00981101-9fdd-4aca-a1a9-33f671b04984",
"name": "ProductionCost",
"summary": "Short summary of the Decision Model Element",
"documentation": "string",
"documentationMIMEType": "string",
"properties": {}
}
Storing user-defined values in the properties field
The Open DI standard defines the JSON object structures for the types of elements in manages. However, most applications will require additional information to be stored with Decision Intelligence objects that is not defined in the standard. To support this extensibility, the Open DI standard defines a field named properties that may be included in each Decision Model and Decision Model Element. The value of the properties field is an object whose internal values can store whatever information the particular application needs. Note that: • To avoid namespace conflicts in the properties object, applications should adhere to the convention of storing their custom data inside a single sub-object object whose name is unique to the application. World Modeler Server, when utilizing the properties field, stores its data inside an object named “wm”. For example:
"properties": {
"wm": {
"OwnerID": "027668E9-3239-4FF2-B1E5-52104AAEC713",
"OwnerType": "Quantellia.WMServer.Auth.WMUser"
}
}
Decision Model API
The World Modeler Server API provides a set of operations for retrieving and managing Decision Models. These are:
Method | Operation | Description |
GET | /decisionModel/{id} | Retrieve information without making any changes to the data on the World Modeler server. GET requests cannot have any payload in their body. |
GET | /decisionModel | Gets the Decision Model instance with the specified ID. GET requests cannot have any payload in their body. |
POST | /decisionModel | Creates a new instance of a Decision Model and populates it with the details specified in the body of the request. |
POST | /decisionModel/{id}/elements | Updates the Decision Model whose details are specified in the body of the request |
PUT | /decisionModel | Updates the Decision Model whose details are specified in the body of the request. |
DELETE | /decisionModel/{id} | Deletes the Decision Model with the specified ID. |
⇦ Prev: 3. Authentication and authorization Next: 5. Evaluating Decision Models ⇨