Introduction to RASON
About RASON Models and the RASON Server
Rason Subscriptions
Rason Web IDE
Creating and Running a Decision Flow
Defining Your Optimization Model
Defining Your Simulation Model
Performing Sensitivity Analysis
Defining Your Stochastic Optimization Model
Defining Your Data Science Model
Defining Custom Types
Defining Custom Functions
Defining Your Decision Table
Defining Contexts
Using the REST API
REST API Quick Call Endpoints
REST API Endpoints
Decision Flow REST API Endpoints
OData Endpoints
OData Service for Decision Flows
Creating Your Own Application
Using Arrays, For, Loops and Tables
Organization Accounts

A Project Selection Model

Our next example is a capital budgeting problem, where the projects being considered for funding have uncertain future cash flows. First, we will use simulation optimization to find a solution to the model using the Evolutionary Engine. Afterwards, we will use calls to the RASON Interpreter to analyze the structure of the model, transform the model into a linear model and solve again using the LP/Quadratic engine.

In this example, eight different capital projects are proposed for funding. Each one has a known initial investment. Each project has a 90% chance of success, and if a project succeeds, it will have an uncertain (but positive) future cash flow. Funding all eight projects would require a total initial investment of $2.5 million, but our capital budget is only $1.5 million. Hence, we must choose a subset of the projects to fund that will maximize our expected total future cash flow, while ensuring that our total initial investment doesn't exceed our $1.5 million budget.

To model the uncertainty in this problem, we use PSI functions that define uncertain variables with probability distributions within the uncertainVariables section. To model the cash flow if a project is successful, we first create the uncertain variable successCashFlow with 8 elements then populate this array using the PsiTriangular() function, specifying a minimum, most likely and maximum cash flow for each of the 8 projects.

The x array will hold our 0-1 (binary) decision variables. If a variable is set to 1, the project is selected. If a variable is set to 0, the project is not selected.

To model the chance of success we create the variable successProbability (within formulas) using the probability distribution, =PsiBinomial(1,0.9). On each trial, this distribution returns 1 with probability 90% and 0 with probability 10%.

In formulas, cash multiplies the net cash flow from each project, expected cash flow minus the initial investment, by the x array which holds our binary decision variables. Inside constraints, invest calculates the constraint that ensures that the total initial investment does not exceed $1,500,000, (initialInvest multiplied by the 0-1 decision variables in the x array).

The objective maximizes the expected mean of cash using the Psi Statistic function, PsiMean(). Alternatively, we could have calculated cash in the objective and set the chanceType property to ExpVal. This alternative formulation would allow us to skip the intermediate calculation of cash in formulas.

objective: { 
   total: {type: "maximize",formula: "sumproduct(successCashFlow * successProbability - initialInvest, x)", chanceType: "ExpVal", 
   finalValue: [] } 
}

Inside of modelSettings we set simulationOptimization: True.

modelSettings: { simulationOptimization: true, numTrials: 1000, randomSeed: 1 },

When the model option simulationOptimization is set to True, the Evolutionary engine will be used to solve the model. The idea behind simulation optimization is straightforward: For each set of values for the decision variables considered by the optimizer, we perform one simulation, a compute user-specified summary measure - such as PsiMean(cash) in the Project Selection model - for the constraints and/or objective that depend on uncertainty. The optimizer uses these summary measures to decide what set of values it should try next for the decision variables - and the process is repeated. The great strength of simulation optimization is its generality - but this is also its weakness: It requires a new simulation at each step of the optimization, and because the method assumes no structure in the model, in general the number of steps can grow exponentially with the number of variables and constraints.

Note that modelType is set to "optimization", rather than "simulation". I modelType=simulation and POST rason.net/api/model/{nameorid}/simulate is called to solve a stochastic optimization model, the workflow engine will run a simulation, only. In order to solve the model using stochastic optimization, you must specify "modelType" = "optimization.

This model formulation will find the best combination of projects - by finding 0 or 1 values for the selection variables in the x array - to maximize the expected value of total net cash flow, subject to the constraint that the total initial investment doesn't exceed our $1.5 million budget. The full model formulation is below.


  {
  modelName: "UGProjectSelect0",
  modelType: "optimization",
  modelSettings: { simulationOptimization: true,numTrials: 1000,randomSeed: 1},
 variables: { 
    x: { dimensions: [8], type: "binary", finalValue: [] } 
 },
 uncertainVariables: {
    successCashFlow: {dimensions: [8] },
    "successCashFlow[1]": { formula: "PsiTriangular(400000, 500000, 900000)" },
    "successCashFlow[2]": {formula: "PsiTriangular(500000, 750000, 1250000)"},
    "successCashFlow[3]": {formula: "PsiTriangular(500000, 1000000,1500000)"},
    "successCashFlow[4]": {formula: "PsiTriangular(400000, 600000, 900000)"},
    "successCashFlow[5]": {formula: "PsiTriangular(250000, 500000, 750000)"},
    "successCashFlow[6]": {formula: "PsiTriangular(300000, 500000, 600000)"},
    "successCashFlow[7]": {formula: "PsiTriangular(200000, 450000, 700000)"},
    "successCashFlow[8]": {formula: "PsiTriangular(400000, 500000, 700000)"},
    successProbability: { dimensions: [8],formula: "PsiBinomial(1, 0.9)"}}, 
    formulas: { initialInvest: {value: [325000, 450000, 550000, 300000, 150000, 250000, 150000, 325000]}, 
    cash: { formula: "sumproduct(successCashFlow * successProbability - initialInvest, x)"  } 
 }, 
 constraints: {
    invest: { formula: "sumproduct(initialInvest, x)", upper: 1500000 } 
 },
 objective: { 
    total: { type: "maximize",formula: cash, chanceType: ExpVal, finalValue: [] } 
 }
}
Back to Defining a Stochastic Optimization Model