Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal: move all probabilities in edges #4

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# StochasticProgram.jl
# StochOptInterface.jl
A generic package to write stochastic programs easily
8 changes: 5 additions & 3 deletions src/StochasticProgram.jl → src/StochOptInterface.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
# An interface for Stochastic Optimization in Julia
################################################################################

module StochasticProgram
module StochOptInterface

using LightGraphs


export AbstractStochasticProgram, stochasticprogram
export AbstractStochasticProgram, stochasticprogram, AbstractStochasticProgramSolver


"""
Expand All @@ -35,8 +35,10 @@ Write the StochasticProgram `sp` inside `filename`.
function write end


include("graph.jl")
include("node.jl")
include("edges.jl")
include("graph.jl")
include("valuefunction.jl")
include("solvers.jl")

end
59 changes: 59 additions & 0 deletions src/edges.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Edges utilities
# Edge stores
# - an id corresponding to index in graph
# - a noise, or a collection of noise (for stagewise noise)
# - an optimization problem (implemented with JuMP or MOI)

abstract type AbstractEdge end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't already defined as LightGraphs.AbstractEdge ? We need to decide whether we want to implement LightGraphs interface or create a new one.
In LightGraph, an edge is just Edge(src, dst). In this case, we need to do e.g.

sync!(sp::AbstractStochasticProgram, edge)

instead of

sync!(edge)

because the edge only contains the incoming and outgoing edge and the rest is stored in the stochastic program.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes presumably all these methods should take sp as the first argument.

Copy link
Member Author

@frapac frapac Dec 4, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, it seems that I do not have the same vision as yours :p But you are right concerning sp.

Concerning Lightgraphs, the arguments would be:

Pros

  • we would be able to use already existing methods in a lightweight package
  • able also to plot easily our graphs!

Cons

  • We have to find a proper (and efficient) way to overwrap Lightgraphs (for instance, how to loop easily on a node's outgoing edges?)

What do you think?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might miss some of the argument, but why not use MetaGraphs ? As far as I know it's a very light package building on LightGraph allowing to attach to an edge or nodes any object.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have to find a proper (and efficient) way to overwrap Lightgraphs (for instance, how to loop easily on a node's outgoing edges?)

The existing functionality out_neighbors is not efficient?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

out_neighbors allows to loop upon outgoing nodes, and not outgoing edges. I do not find a proper function to loop upon outgoing edges, but I am not an expert on Lightgraphs ...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@frapac The function out_edges has been removed, I think we now need to do Edge.(u, out_neighbors(g, u)) instead of out_edges(g, u).
@leclere I initially wanted to use MetaGraphs in StructDualDynProg but when you look at it here and here, it seems inefficient because all properties are stored in a Dict{Symbol, Any}. MetaGraphs cannot really do better at his abstract level (or maybe using macros as we do in MathOptInterfaceUtilities :-P) but we can do faster by storing dictionnaries like proba::Dict{SimpleEdge{Int}, Float64} which will be typed.


"""
sync!(edge::AbstractEdge)

Synchronize state in `edge` with parent node.
"""
function sync! end


"""
set!(edge::AbstractEdge, x)

Set current state in `edge` problem.

set!(edge::AbstractEdge, noise)

Set current noise in `edge` problem.
"""
function set! end


"""
rand(edge::AbstractEdge)

Draw a random realization of edge's noise (in the case that `edge` stores a
collection of noises).
"""
function rand end


"""
build!(edge::AbstractEdge)

Build optimization model in `edge` with model stored in AbstractNode parent.
"""
function build! end


"""
reload!(edge:AbstractEdge)

Reload optimization model in `edge`
"""
function reload! end


"""
size(edges)

Return number of noises in `edges`.
"""
function size end
14 changes: 11 additions & 3 deletions src/graph.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Graph utilities
# Graph and edges utilities

"""
getmaster(sp::AbstractStochasticProgram)
Expand All @@ -17,11 +17,11 @@ function probability end


"""
setchildx!(sp::AbstractStochasticProgram, node, child, sol)
setchildstate!(sp::AbstractStochasticProgram, node::AbstractNode, child::AbstractNode, sol::AbstractSolution)

Sets the parent solution of `child` as `sol`, the solution obtained at `node`.
"""
function setchildx! end
function setchildstate! end


"""
Expand All @@ -30,3 +30,11 @@ function setchildx! end
Sets the probability to take the edge `edge` in the stochastic problem `sp` to `probability`.
"""
function setprobability! end


"""
edges(sp::AbstractStochasticProgram, node::AbstractNode)

Returns iterable of outgoing edges in `node`.
"""
function edges end
28 changes: 21 additions & 7 deletions src/node.jl
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
# Nodes utilities
# Node stores:
# - an index in the graph, and a stage
# - an optimization model (with objective, dynamics and constraints)
# - a value function
# - a list of outgoing edges


abstract type AbstractNode end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, in LightGraphs a node is just an Int.



"""
solve!(sp::AbstractStochasticProgram, node)
solve!(node::AbstractNode, edge)

Solves the program at node `node` in `sp` and returns the solution.
Solves the problem starting at `node` and stored inside `edge`, and
returns a AbstractSolution object.
"""
function solve! end

Expand Down Expand Up @@ -37,11 +43,19 @@ function statedim end


"""
set(node::AbstractNode, state::AbstractState)
set!(node::AbstractNode, state::AbstractState)

Set state inside `node`.
Set state inside `node` and update out-going edges.

set!(node::AbstractNode, vf::AbstractValueFunction)

Set value function inside `node`.

set!(node::AbstractNode, cut::Cuts)

Add new cuts inside `node` and udpate in-going edges.
"""
function set end
function set! end


"""
Expand All @@ -53,9 +67,9 @@ numberofpaths(sp::AbstractStochasticProgram, len) = numberofpaths(sp, getmaster(


"""
sample(node::AbstractNode, npaths)
sample(node::AbstractNode, npaths::Int)

Sample `npaths` path starting from `node`.
Sample `npaths` edges outgoing `node` and return a list.
"""
function sample end

Expand Down
57 changes: 57 additions & 0 deletions src/solution.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
abstract type AbstractSolution end

"""
feasibility_cut(sol::AbstractSolution)

Returns the tuple `(a, α)` representing the feasibility cut ``⟨a, x⟩ ≧ α`` certified by this solution.
"""
function feasibility_cut end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor point, but none of the other methods have _ so we should just be consistent with feasibilitycut.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am ok with renaming it feasibilitycut :)


"""
optimality_cut(sol::AbstractSolution)

Returns the tuple `(a, α)` representing the optimality cut ``⟨a, x⟩ + θ ≧ α`` certified by this solution.
"""
function optimality_cut end

"""
getstatus(sol::AbstractSolution)

Returns the status of the solution `sol`.
"""
function getstatus end

"""
getobjectivevalue(sol::AbstractSolution)

Returns the objective value of the solution `sol` *including* the part of the objective depending on `θ`.
"""
function getobjectivevalue end

"""
getstateobjectivevalue(sol::AbstractSolution)

Returns the objective value of the solution `sol` *excluding* the part of the objective depending on `θ`.
"""
function getstateobjectivevalue end


"""
getstatevalue(sol::AbstractSolution)

Returns the value of the state of solution `sol`.
"""
function getstatevalue end

"""
getbellmanvalue(sp::AbstractStochasticProgram, node, child, sol::AbstractSolution)

Returns the value of the θ in the solution `sol` of node `node` for its child `child`.
This assumes that `node` is using `MultiCutGenerator`.

getbellmanvalue(sp::AbstractStochasticProgram, node, sol::AbstractSolution)

Returns the value of the θ in the solution `sol` of node `node`.
This assumes that `node` is using `AvgCutGenerator`.
"""
function getbellmanvalue end
2 changes: 1 addition & 1 deletion src/solvers.jl
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# Solver utilities

abstract type AbstractStochasticProgrammingSolver end
abstract type AbstractStochasticProgramSolver end
11 changes: 11 additions & 0 deletions src/valuefunction.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Abstraction to define value functions

abstract type AbstractValueFunction end


"""
getvalue(vf::AbstractValueFunction, x)

Get cost-to-go at point `x`.
"""
function getvalue end