DecisionProgramming.CompatiblePathsType
CompatiblePaths(diagram::InfluenceDiagram, Z::DecisionStrategy, fixed::FixedPath=Dict{Node, State}())

CompatiblePaths outer construction function. Interface for iterating over paths that are compatible and active given influence diagram and decision strategy.

1. Initialize path s of length n
2. Fill chance states s[C] by generating subpaths paths(C)
3. Fill decision states s[D] by decision strategy Z and path s

Examples

for s in CompatiblePaths(diagram, Z)
...
end
DecisionProgramming.DecisionStrategyMethod
DecisionStrategy(z::DecisionVariables)

Extract values for decision variables from solved decision model.

Examples

Z = DecisionStrategy(z)
DecisionProgramming.DecisionVariablesMethod
DecisionVariables(model::Model,  diagram::InfluenceDiagram; names::Bool=false, name::String="z")

Create decision variables and constraints.

Arguments

• model::Model: JuMP model into which variables are added.
• diagram::InfluenceDiagram: Influence diagram structure.
• names::Bool: Use names or have JuMP variables be anonymous.
• name::String: Prefix for predefined decision variable naming convention.

Examples

z = DecisionVariables(model, diagram)
DecisionProgramming.DefaultPathProbabilityType
struct DefaultPathProbability <: AbstractPathProbability

Path probability obtained as a product of the probability values corresponding to path s in each chance node.

Examples

julia> C = [2]
1-element Array{Int64,1}:
2

julia> I_j = [[1]]
1-element Array{Array{Int64,1},1}:
[1]

julia> X = [Probabilities(Node(2), [0.5 0.5; 0.2 0.8])]
1-element Array{Probabilities{2},1}:
[0.5 0.5; 0.2 0.8]

julia> P = DefaultPathProbability(C, I_j, X)
DefaultPathProbability(Int16[2], Array{Int16,1}[[1]], Probabilities[[0.5 0.5; 0.2 0.8]])

julia> s = Path((1, 2))
(1, 2)

julia> P(s)
0.5
DecisionProgramming.DefaultPathUtilityType
struct DefaultPathUtility <: AbstractPathUtility

Default path utility obtained as a sum of the utility values corresponding to path s in each value node.

Examples

julia> vals = Utility.([1.0 -2.0; 3.0 4.0])
2×2 Array{Float32,2}:
1.0  -2.0
3.0   4.0

julia> Y = [Utilities(Node(3), vals)]
1-element Array{Utilities{2},1}:
[1.0 -2.0; 3.0 4.0]

julia> I_3 = [[1,2]]
1-element Array{Array{Int64,1},1}:
[1, 2]

julia> U = DefaultPathUtility(I_3, Y)
DefaultPathUtility(Array{Int16,1}[[1, 2]], Utilities[[1.0 -2.0; 3.0 4.0]])

julia> s = Path((1, 2))
(1, 2)

julia> U(s)
-2.0f0

julia> t = Utility(-100.0)

julia> U(s, t)
-102.0f0
DecisionProgramming.FixedPathType
const FixedPath = Dict{Node, State}

FixedPath type.

Examples

julia> FixedPath(Dict(1=>1, 2=>3))
Dict{Int16,Int16} with 2 entries:
2 => 3
1 => 1
DecisionProgramming.FixedPathMethod
function FixedPath(diagram::InfluenceDiagram, fixed::Dict{Name, Name})

FixedPath outer construction function. Create FixedPath variable.

Arguments

• diagram::InfluenceDiagram: Influence diagram structure
• fixed::Dict{Name, Name}: Dictionary of nodes and their fixed states. Order is node=>state, and both are idefied with their names.

Example

julia> fixedpath = FixedPath(diagram, Dict("O" => "lemon"))
Dict{Int16,Int16} with 1 entry:
1 => 1

julia> vec(collect(paths(states, fixedpath)))
3-element Array{Tuple{Int16,Int16},1}:
(1, 1)
(1, 2)
(1, 3)

DecisionProgramming.ForbiddenPathType
const ForbiddenPath = Tuple{Vector{Node}, Set{Path}}

ForbiddenPath type.

Examples

julia> ForbiddenPath(([1, 2], Set([(1, 2)])))
(Int16[1, 2], Set(Tuple{Vararg{Int16,N}} where N[(1, 2)])

julia> ForbiddenPath[
([1, 2], Set([(1, 2)])),
([3, 4, 5], Set([(1, 2, 3), (3, 4, 5)]))
]
2-element Array{Tuple{Array{Int16,1},Set{Tuple{Vararg{Int16,N}} where N}},1}:
([1, 2], Set([(1, 2)]))
([3, 4, 5], Set([(1, 2, 3), (3, 4, 5)]))
DecisionProgramming.ForbiddenPathMethod
function ForbiddenPath(diagram::InfluenceDiagram, nodes::Vector{Name}, paths::Vector{NTuple{N, Name}}) where N

ForbiddenPath outer construction function. Create ForbiddenPath variable.

Arguments

• diagram::InfluenceDiagram: Influence diagram structure
• nodes::Vector{Name}: Vector of nodes involved in forbidden paths. Identified by their names.
• paths::Vector{NTuple{N, Name}}: Vector of tuples defining the forbidden combinations of states. States identified by their names.

Example

ForbiddenPath(diagram, ["R1", "R2"], [("high", "low"), ("low", "high")])
DecisionProgramming.InfluenceDiagramType
mutable struct InfluenceDiagram
Nodes::Vector{AbstractNode}
Names::Vector{Name}
I_j::Vector{Vector{Node}}
States::Vector{Vector{Name}}
S::States
C::Vector{Node}
D::Vector{Node}
V::Vector{Node}
X::Vector{Probabilities}
Y::Vector{Utilities}
P::AbstractPathProbability
U::AbstractPathUtility
translation::Utility
function InfluenceDiagram()
new(Vector{AbstractNode}())
end
end

Hold all information related to the influence diagram.

Fields

• Nodes::Vector{AbstractNode}: Vector of added abstract nodes.
• Names::Vector{Name}: Names of nodes in order of their indices.
• I_j::Vector{Vector{Node}}: Information sets of nodes in order of their indices. Nodes of information sets identified by their indices.
• States::Vector{Vector{Name}}: States of each node in order of their indices.
• S::States: Vector showing the number of states each node has.
• C::Vector{Node}: Indices of chance nodes in ascending order.
• D::Vector{Node}: Indices of decision nodes in ascending order.
• V::Vector{Node}: Indices of value nodes in ascending order.
• X::Vector{Probabilities}: Probability matrices of chance nodes in order of chance nodes in C.
• Y::Vector{Utilities}: Utility matrices of value nodes in order of value nodes in V.
• P::AbstractPathProbability: Path probabilities.
• U::AbstractPathUtility: Path utilities.
• translation::Utility: Utility translation for storing the positive or negative utility translation.

Examples

diagram = InfluenceDiagram()
DecisionProgramming.LocalDecisionStrategyMethod
function LocalDecisionStrategy(rng::AbstractRNG, diagram::InfluenceDiagram, d::Node)

Generate random decision strategy for decision node d.

Examples

rng = MersenneTwister(3)
diagram = InfluenceDiagram()
random_diagram!(rng, diagram, 5, 2, 3, 2, 2, rand(rng, [2,3], 5))
LocalDecisionStrategy(rng, diagram, diagram.D[1])
DecisionProgramming.PathCompatibilityVariablesMethod
PathCompatibilityVariables(model::Model,
diagram::InfluenceDiagram,
z::DecisionVariables;
names::Bool=false,
name::String="x",
forbidden_paths::Vector{ForbiddenPath}=ForbiddenPath[],
fixed::FixedPath=Dict{Node, State}(),
probability_cut::Bool=true,
probability_scale_factor::Float64=1.0)

Create path compatibility variables and constraints.

Arguments

• model::Model: JuMP model into which variables are added.
• diagram::InfluenceDiagram: Influence diagram structure.
• z::DecisionVariables: Decision variables from DecisionVariables function.
• names::Bool: Use names or have JuMP variables be anonymous.
• name::String: Prefix for predefined decision variable naming convention.
• forbidden_paths::Vector{ForbiddenPath}: The forbidden subpath structures. Path compatibility variables will not be generated for paths that include forbidden subpaths.
• fixed::FixedPath: Path compatibility variable will not be generated for paths which do not include these fixed subpaths.
• probability_cut Includes probability cut constraint in the optimisation model.
• probability_scale_factor::Float64: Adjusts conditional value at risk model to be compatible with the expected value expression if the probabilities were scaled there.

Examples

x_s = PathCompatibilityVariables(model, diagram; probability_cut = false)
DecisionProgramming.ProbabilitiesType
struct Probabilities{N} <: AbstractArray{Float64, N}

Construct and validate stage probabilities (probabilities for a single node).

Examples

julia> data = [0.5 0.5 ; 0.2 0.8]
2×2 Array{Float64,2}:
0.5  0.5
0.2  0.8

julia> X = Probabilities(Node(2), data)
2×2 Probabilities{2}:
0.5  0.5
0.2  0.8

julia> s = (1, 2)
(1, 2)

julia> X(s)
0.5
DecisionProgramming.ProbabilityMatrixType
struct ProbabilityMatrix{N} <: AbstractArray{Float64, N}
nodes::Vector{Name}
indices::Vector{Dict{Name, Int}}
matrix::Array{Float64, N}
end

Construct probability matrix.

DecisionProgramming.ProbabilityMatrixMethod
function ProbabilityMatrix(diagram::InfluenceDiagram, node::Name)

Initialise a probability matrix for a given chance node. The matrix is initialised with zeros.

Examples

julia> X_O = ProbabilityMatrix(diagram, "O")
2-element ProbabilityMatrix{1}:
0.0
0.0
DecisionProgramming.StateProbabilitiesMethod
StateProbabilities(diagram::InfluenceDiagram, Z::DecisionStrategy, node::Node, state::State, prior_probabilities::StateProbabilities)

Associate each node with array of conditional probabilities for each of its states occuring in compatible paths given fixed states and prior probability. Fix node and state using their indices.

Examples

# Prior probabilities
prior_probabilities = StateProbabilities(diagram, Z)
StateProbabilities(diagram, Z, Node(2), State(1), prior_probabilities)
DecisionProgramming.StateProbabilitiesMethod
StateProbabilities(diagram::InfluenceDiagram, Z::DecisionStrategy, node::Name, state::Name, prior_probabilities::StateProbabilities)

Associate each node with array of conditional probabilities for each of its states occuring in compatible paths given fixed states and prior probability. Fix node and state using their names.

Examples

# Prior probabilities
prior_probabilities = StateProbabilities(diagram, Z)

# Select node and fix its state
node = "R"
state = "no test"
StateProbabilities(diagram, Z, node, state, prior_probabilities)
DecisionProgramming.StateProbabilitiesMethod
StateProbabilities(diagram::InfluenceDiagram, Z::DecisionStrategy)

Associate each node with array of probabilities for each of its states occuring in compatible paths.

Examples

StateProbabilities(diagram, Z)
DecisionProgramming.StatesType
struct States <: AbstractArray{State, 1}

States type. Works like Vector{State}.

Examples

julia> S = States(State.([2, 3, 2, 4]))
4-element States:
2
3
2
4
DecisionProgramming.UtilitiesType
struct Utilities{N} <: AbstractArray{Utility, N}

State utilities.

Examples

julia> vals = Utility.([1.0 -2.0; 3.0 4.0])
2×2 Array{Float32,2}:
1.0  -2.0
3.0   4.0

julia> Y = Utilities(Node(3), vals)
2×2 Utilities{2}:
1.0  -2.0
3.0   4.0

julia> s = Path((1, 2))
(1, 2)

julia> Y(s)
-2.0f0
DecisionProgramming.UtilityDistributionMethod
UtilityDistribution(diagram::InfluenceDiagram, Z::DecisionStrategy)

Construct the probability mass function for path utilities on paths that are compatible with given decision strategy.

Examples

UtilityDistribution(diagram, Z)
DecisionProgramming.UtilityMatrixType
struct UtilityMatrix{N} <: AbstractArray{Utility, N}
I_v::Vector{Name}
indices::Vector{Dict{Name, Int}}
matrix::Array{Utility, N}
end

Construct utility matrix.

DecisionProgramming.UtilityMatrixMethod
function UtilityMatrix(diagram::InfluenceDiagram, node::Name)

Initialise a utility matrix for a value node. The matrix is initialised with Inf values.

Examples

julia> Y_V3 = UtilityMatrix(diagram, "V3")
2×3 UtilityMatrix{2}:
Inf  Inf  Inf
Inf  Inf  Inf
DecisionProgramming.add_node!Method
function add_node!(diagram::InfluenceDiagram, node::AbstractNode)

Add node to influence diagram structure.

Examples

julia> add_node!(diagram, ChanceNode("O", [], ["lemon", "peach"]))
1-element Array{AbstractNode,1}:
ChanceNode("O", String[], ["lemon", "peach"])
DecisionProgramming.add_probabilities!Method
function add_probabilities!(diagram::InfluenceDiagram, node::Name, probabilities::AbstractArray{Float64, N}) where N

Add probability matrix to influence diagram, specifically to its X vector.

Examples

julia> X_O = ProbabilityMatrix(diagram, "O")
2-element ProbabilityMatrix{1}:
0.0
0.0

julia> X_O["lemon"] = 0.2
0.2

ERROR: DomainError with Probabilities should sum to one.:

julia> X_O["peach"] = 0.8
0.2

1-element Array{Probabilities,1}:
[0.2, 0.8]
Note

The function generate_arcs! must be called before probabilities or utilities can be added to the influence diagram.

DecisionProgramming.add_utilities!Method
function add_utilities!(diagram::InfluenceDiagram, node::Name, utilities::AbstractArray{T, N}) where {N,T<:Real}

Add utility matrix to influence diagram, specifically to its Y vector.

Examples

julia> Y_V3 = UtilityMatrix(diagram, "V3")
2×3 UtilityMatrix{2}:
Inf  Inf  Inf
Inf  Inf  Inf

julia> Y_V3["peach", :] = [-40, -20, 0]
3-element Array{Int64,1}:
-40
-20
0

julia> Y_V3["lemon", :] = [-200, 0, 0]
3-element Array{Int64,1}:
-200
0
0

1-element Array{Utilities,1}:
[-200.0 0.0 0.0; -40.0 -20.0 0.0]

2-element Array{Utilities,1}:
[-200.0 0.0 0.0; -40.0 -20.0 0.0]
[0.0, -25.0]
Note

The function generate_arcs! must be called before probabilities or utilities can be added to the influence diagram.

DecisionProgramming.conditional_value_at_riskMethod
conditional_value_at_risk(model::Model,
diagram,
x_s::PathCompatibilityVariables{N},
α::Float64;
probability_scale_factor::Float64=1.0) where N

Create a conditional value-at-risk (CVaR) objective.

Arguments

• model::Model: JuMP model into which variables are added.
• diagram::InfluenceDiagram: Influence diagram structure.
• x_s::PathCompatibilityVariables: Path compatibility variables.
• α::Float64: Probability level at which conditional value-at-risk is optimised.
• probability_scale_factor::Float64: Adjusts conditional value at risk model to be compatible with the expected value expression if the probabilities were scaled there.

Examples

α = 0.05  # Parameter such that 0 ≤ α ≤ 1
CVaR = conditional_value_at_risk(model, x_s, U, P, α)
CVaR = conditional_value_at_risk(model, x_s, U, P, α; probability_scale_factor = 10.0)
DecisionProgramming.expected_valueMethod
expected_value(model::Model,
diagram::InfluenceDiagram,
x_s::PathCompatibilityVariables)

Create an expected value objective.

Arguments

• model::Model: JuMP model into which variables are added.
• diagram::InfluenceDiagram: Influence diagram structure.
• x_s::PathCompatibilityVariables: Path compatibility variables.

Examples

EV = expected_value(model, diagram, x_s)
DecisionProgramming.generate_arcs!Method
function generate_arcs!(diagram::InfluenceDiagram)

Generate arc structures using nodes added to influence diagram, by ordering nodes, giving them indices and generating correct values for the vectors Names, I_j, states, S, C, D, V in the influence digram. Abstraction is created and the names of the nodes and states are only used in the user interface from here on.

Examples

generate_arcs!(diagram)
DecisionProgramming.generate_diagram!Method
function generate_diagram!(diagram::InfluenceDiagram;
default_probability::Bool=true,
default_utility::Bool=true,
positive_path_utility::Bool=false,
negative_path_utility::Bool=false)

Generate complete influence diagram with probabilities and utilities as well.

Arguments

• default_probability::Bool=true: Choice to use default path probabilities.
• default_utility::Bool=true: Choice to use default path utilities.
• positive_path_utility::Bool=false: Choice to use a positive path utility translation.
• negative_path_utility::Bool=false: Choice to use a negative path utility translation.

Examples

generate_diagram!(diagram)
Note

The influence diagram must be generated after probabilities and utilities are added but before creating the decision model.

Note

If the default probabilities and utilities are not used, define AbstractPathProbability and AbstractPathUtility structures and define P(s), U(s) and U(s, t) functions for them. Add the AbstractPathProbability and AbstractPathUtility structures to the influence diagram fields P and U.

DecisionProgramming.index_ofMethod
function index_of(diagram::InfluenceDiagram, node::Name)

Get the index of a given node.

Example

julia> idx_O = index_of(diagram, "O")
1
DecisionProgramming.lazy_probability_cutMethod
lazy_probability_cut(model::Model, diagram::InfluenceDiagram, x_s::PathCompatibilityVariables)

Add a probability cut to the model as a lazy constraint.

Examples

lazy_probability_cut(model, diagram, x_s)
Note

Remember to set lazy constraints on in the solver parameters, unless your solver does this automatically. Note that Gurobi does this automatically.

DecisionProgramming.num_statesMethod
function num_states(diagram::InfluenceDiagram, node::Name)

Get the number of states in a given node.

Example

julia> NS_O = num_states(diagram, "O")
2
DecisionProgramming.pathsMethod
function paths(states::AbstractVector{State}, fixed::FixedPath)

Iterate over paths with fixed states in lexicographical order.

Examples

julia> states = States(State.([2, 3]))
2-element States:
2
3

julia> vec(collect(paths(states, Dict(Node(1) => State(2)))))
3-element Array{Tuple{Int16,Int16},1}:
(2, 1)
(2, 2)
(2, 3)
DecisionProgramming.pathsMethod
function paths(states::AbstractVector{State})

Iterate over paths in lexicographical order.

Examples

julia> states = States(State.([2, 3]))
2-element States:
2
3

julia> vec(collect(paths(states)))
6-element Array{Tuple{Int16,Int16},1}:
(1, 1)
(2, 1)
(1, 2)
(2, 2)
(1, 3)
(2, 3)
DecisionProgramming.print_decision_strategyMethod
print_decision_strategy(diagram::InfluenceDiagram, Z::DecisionStrategy, state_probabilities::StateProbabilities; show_incompatible_states::Bool = false)

Print decision strategy.

Arguments

• diagram::InfluenceDiagram: Influence diagram structure.
• Z::DecisionStrategy: Decision strategy structure with optimal decision strategy.
• state_probabilities::StateProbabilities: State probabilities structure corresponding to optimal decision strategy.
• show_incompatible_states::Bool: Choice to print rows also for incompatible states.

Examples

print_decision_strategy(diagram, Z, S_probabilities)
DecisionProgramming.print_state_probabilitiesMethod
print_state_probabilities(diagram::InfluenceDiagram, state_probabilities::StateProbabilities, nodes::Vector{Name}; prob_fmt="%f")

Print state probabilities with fixed states.

Examples

S_probabilities = StateProbabilities(diagram, Z)
print_state_probabilities(S_probabilities, ["R"])
print_state_probabilities(S_probabilities, ["A"])
DecisionProgramming.print_utility_distributionMethod
print_utility_distribution(U_distribution::UtilityDistribution; util_fmt="%f", prob_fmt="%f")

Print utility distribution.

Examples

U_distribution = UtilityDistribution(diagram, Z)
print_utility_distribution(U_distribution)
DecisionProgramming.randomStrategyMethod
randomStrategy(diagram::InfluenceDiagram)

Generates a random decision strategy for the problem. Returns the strategy as well as the expected utility of the strategy and the paths that are compatible with the strategy.

Arguments

• diagram::InfluenceDiagram: Influence diagram structure.
Warning

This function does not exclude forbidden paths: the strategy returned by this function might be forbidden if the diagram has forbidden state combinations.

Examples

objval, Z, S_active = randomStrategy(diagram)
DecisionProgramming.random_diagram!Method
random_diagram!(rng::AbstractRNG, diagram::InfluenceDiagram, n_C::Int, n_D::Int, n_V::Int, m_C::Int, m_D::Int, states::Vector{Int})

Generate random decision diagram with n_C chance nodes, n_D decision nodes, and n_V value nodes. Parameter m_C and m_D are the upper bounds for the size of the information set.

Arguments

• rng::AbstractRNG: Random number generator.
• diagram::InfluenceDiagram: The (empty) influence diagram structure that is filled by this function
• n_C::Int: Number of chance nodes.
• n_D::Int: Number of decision nodes.
• n_V::Int: Number of value nodes.
• m_C::Int: Upper bound for size of information set for chance nodes.
• m_D::Int: Upper bound for size of information set for decision nodes.
• states::Vector{State}: The number of states for each chance and decision node is randomly chosen from this set of numbers.

Examples

rng = MersenneTwister(3)
diagram = InfluenceDiagram()
random_diagram!(rng, diagram, 5, 2, 3, 2, 2, [2,3])
DecisionProgramming.random_probabilities!Method
function random_probabilities!(rng::AbstractRNG, diagram::InfluenceDiagram, c::Node; n_inactive::Int=0)

Generate random probabilities for chance node c.

Examples

rng = MersenneTwister(3)
diagram = InfluenceDiagram()
random_diagram!(rng, diagram, 5, 2, 3, 2, 2, [2,3])
c = diagram.C[1]
random_probabilities!(rng, diagram, c)
DecisionProgramming.random_utilities!Method
function random_utilities!(rng::AbstractRNG, diagram::InfluenceDiagram, v::Node; low::Float64=-1.0, high::Float64=1.0)

Generate random utilities between low and high for value node v.

Examples

rng = MersenneTwister(3)
diagram = InfluenceDiagram()
random_diagram!(rng, diagram, 5, 2, 3, 2, 2, [2,3])
v = diagram.V[1]
random_utilities!(rng, diagram, v)
DecisionProgramming.singlePolicyUpdateMethod
singlePolicyUpdate(diagram::InfluenceDiagram, model::Model)

Finds a feasible solution using single policy update and sets the model start values to that solution. Returns a vector of tuples consisting of the value of each improved solution starting from a random policy, time (in milliseconds) since the function call and the decision strategy that gave the improved value. The purpose of all this output is to allow us to examine how fast the method finds good solutions.

Arguments

• diagram::InfluenceDiagram: Influence diagram structure.
• model::Model: The decision model, modelled in JuMP
• z::DecisionVariables: The decision variables
• x_s::PathCompatibilityVariables: The path compatibility variables
Warning

This function does not exclude forbidden paths: the strategies explored by this function might be forbidden if the diagram has forbidden state combinations.

Examples

solutionhistory = singlePolicyUpdate(diagram, model)`