Skip to content

Commit

Permalink
wip: doc updates
Browse files Browse the repository at this point in the history
  • Loading branch information
jalving committed Jul 6, 2024
1 parent 0c20aff commit 1610047
Show file tree
Hide file tree
Showing 6 changed files with 535 additions and 86 deletions.
47 changes: 33 additions & 14 deletions docs/src/documentation/api_docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ OptiEdge
@optinode
@linkconstraint
@nodevariables
set_to_node_objectives
graph_backend
graph_index
source_graph
Expand All @@ -23,16 +24,23 @@ all_nodes
collect_nodes
num_local_nodes
num_nodes
num_local_variables
add_edge
get_edge
get_edge_by_index
Plasmo.has_edge
local_edges
all_edges
num_local_edges
num_edges
num_local_link_constraints
num_linkconstraints
num_link_constraints
local_link_constraints
all_link_constraints
num_local_constraints
local_constraints
local_elements
all_elements
Base.getindex(::OptiGraph, ::Int)
```

Expand All @@ -43,35 +51,47 @@ set_jump_model

## Extended Methods
```@docs
JuMP.all_variables
JuMP.set_optimizer
JuMP.optimize!
JuMP.objective_function
JuMP.name
JuMP.set_name
JuMP.index
JuMP.backend
JuMP.value
JuMP.dual
JuMP.num_variables
JuMP.num_constraints
JuMP.object_dictionary
JuMP.add_variable
JuMP.num_variables
JuMP.all_variables
JuMP.start_value
JuMP.set_start_value
JuMP.add_constraint
JuMP.list_of_constraint_types
JuMP.num_constraints
JuMP.all_constraints
JuMP.objective_value
JuMP.dual_objective_value
JuMP.objective_sense
JuMP.objective_function
JuMP.objective_function_type
JuMP.objective_bound
JuMP.set_objective
JuMP.set_objective_function
JuMP.set_objective_sense
JuMP.set_objective_coefficient
JuMP.set_optimizer
JuMP.add_nonlinear_operator
JuMP.optimize!
JuMP.termination_status
JuMP.primal_status
JuMP.dual_status
JuMP.relative_gap
JuMP.constraint_ref_with_index
JuMP.object_dictionary
```

## Graph Projections
```@docs
hyper_projection
edge_hyper_projection
clique_projection
edge_projection
edge_clique_projection
edge_hyper_projection
bipartite_projection
```

Expand All @@ -95,8 +115,7 @@ identify_nodes
expand
```

## Plotting
```@docs
<!-- ```@docs
PlasmoPlots.layout_plot
PlasmoPlots.matrix_plot
```
``` -->
2 changes: 2 additions & 0 deletions src/Plasmo.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ using Reexport
@reexport using JuMP

export OptiGraph,
OptiNode,
OptiEdge,
NodeVariableRef,
graph_backend,
graph_index,
Expand Down
27 changes: 23 additions & 4 deletions src/core_types.jl
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
abstract type AbstractOptiGraph <: JuMP.AbstractModel end

abstract type AbstractNode <: JuMP.AbstractModel end
abstract type AbstractOptiNode <: JuMP.AbstractModel end

abstract type AbstractEdge <: JuMP.AbstractModel end
abstract type AbstractOptiEdge <: JuMP.AbstractModel end

struct NodeIndex
value::Symbol
Expand All @@ -13,13 +13,32 @@ end
# NOTE: We parameterize nodes and edges on the graph type itself. This may instead
# become a special type that denotes whether we have a standard optigraph, or a
# distributed memory optigraph in the future.
struct OptiNode{GT<:AbstractOptiGraph} <: AbstractNode

"""
OptiNode{GT<:AbstractOptiGraph} <: AbstractOptiNode
A data structure meant to encapsulate variables, constraints, an objective function, and
other model data. An optinode is "lightweight" in the sense that it does not directly
contain model data, but instead acts as an interface that maps to a backend where
the model data is stored. This avoids the need to generate memory overhead through
container structures in cases when a node contains very little model data.
"""
struct OptiNode{GT<:AbstractOptiGraph} <: AbstractOptiNode
source_graph::Base.RefValue{<:GT}
idx::NodeIndex
label::Symbol
end

struct OptiEdge{GT<:AbstractOptiGraph} <: AbstractEdge
"""
OptiEdge{GT<:AbstractOptiGraph} <: AbstractOptiEdge
A data structure meant to encapsulate linking constraints other model data. An optiedge
is "lightweight" in the sense that it does not directly contain model data, but instead acts
as an interface that maps to a backend where the model data is stored. This avoids the need
to generate memory overhead through container structures in cases when a node contains very
little model data.
"""
struct OptiEdge{GT<:AbstractOptiGraph} <: AbstractOptiEdge
source_graph::Base.RefValue{<:GT}
label::Symbol
nodes::OrderedSet{OptiNode}
Expand Down
95 changes: 48 additions & 47 deletions src/graph_functions/projections.jl
Original file line number Diff line number Diff line change
Expand Up @@ -86,15 +86,15 @@ struct HyperGraphProjectionType <: AbstractProjectionType end
Retrieve a hypergraph representation of the optigraph `graph`. Returns a [`HyperGraph`](@ref) object, as well as a dictionary
that maps hypernodes and hyperedges to the original optinodes and optiedges.
"""
function hyper_projection(optigraph::OptiGraph)
function hyper_projection(graph::OptiGraph)
hypergraph = GOI.HyperGraph()
projection = GraphProjection(optigraph, hypergraph, HyperGraphProjectionType())
for node in all_nodes(optigraph)
projection = GraphProjection(graph, hypergraph, HyperGraphProjectionType())
for node in all_nodes(graph)
hypernode = Graphs.add_vertex!(hypergraph)
projection[hypernode] = node
projection[node] = hypernode
end
for edge in all_edges(optigraph)
for edge in all_edges(graph)
nodes = all_nodes(edge)
hypernodes = Base.getindex.(projection, nodes)
@assert length(hypernodes) >= 2
Expand All @@ -110,29 +110,30 @@ end
struct CliqueGraphProjectionType <: AbstractProjectionType end

"""
build_clique_graph(graph::OptiGraph)
clique_projection(graph::OptiGraph)
Retrieve a standard graph representation of the optigraph `graph`. Returns a `LightGraphs.Graph` object, as well as a dictionary
that maps vertices and edges to the optinodes and optiedges.
Retrieve a standard graph representation of `graph`. The projection contains a standard
`Graphs.Graph` and a mapping between its elements and the given optigraph. This projection
works by creating an edge for each pair of nodes in each hyperedge.
"""
function clique_projection(optigraph::OptiGraph)
graph = Graphs.Graph()
projection = GraphProjection(optigraph, graph, CliqueGraphProjectionType())
for optinode in all_nodes(optigraph)
Graphs.add_vertex!(graph)
vertex = nv(graph)
function clique_projection(graph::OptiGraph)
clique_graph = Graphs.Graph()
projection = GraphProjection(graph, clique_graph, CliqueGraphProjectionType())
for optinode in all_nodes(graph)
Graphs.add_vertex!(clique_graph)
vertex = nv(clique_graph)
projection[vertex] = optinode
projection[optinode] = vertex
end
for edge in all_edges(optigraph)
for edge in all_edges(graph)
nodes = edge.nodes
edge_vertices = [projection[optinode] for optinode in nodes]
for i in 1:length(edge_vertices)
vertex_from = edge_vertices[i]
other_vertices = edge_vertices[(i + 1):end]
for j in 1:length(other_vertices)
vertex_to = other_vertices[j]
inserted = Graphs.add_edge!(graph, vertex_from, vertex_to)
inserted = Graphs.add_edge!(clique_graph, vertex_from, vertex_to)
end
end
end
Expand All @@ -144,28 +145,28 @@ end
struct EdgeGraphProjectionType <: AbstractProjectionType end

"""
edge_graph(optigraph::OptiGraph)
edge_clique_projection(graph::OptiGraph)
Retrieve the edge-graph representation of `optigraph`. This is sometimes called the line graph of a hypergraph.
Returns a `GraphProjection`.
Retrieve the edge-graph representation of optigraph `graph`. This is sometimes called the
line graph of a hypergraph.
"""
function edge_clique_projection(optigraph::OptiGraph)
graph = Graphs.Graph()
projection = GraphProjection(optigraph, graph, EdgeGraphProjectionType())
for optiedge in all_edges(optigraph)
Graphs.add_vertex!(graph)
vertex = nv(graph)
function edge_clique_projection(graph::OptiGraph)
edge_graph = Graphs.Graph()
projection = GraphProjection(graph, edge_graph, EdgeGraphProjectionType())
for optiedge in all_edges(graph)
Graphs.add_vertex!(edge_graph)
vertex = nv(edge_graph)
projection[vertex] = optiedge
projection[optiedge] = vertex
end
edge_array = all_edges(optigraph)
edge_array = all_edges(graph)
n_edges = length(edge_array)
for i in 1:(n_edges - 1)
for j in (i + 1):n_edges
e1 = edge_array[i]
e2 = edge_array[j]
if !isempty(intersect(e1.nodes, e2.nodes))
Graphs.add_edge!(graph, projection[e1], projection[e2])
Graphs.add_edge!(edge_graph, projection[e1], projection[e2])
end
end
end
Expand All @@ -176,24 +177,24 @@ end
struct EdgeHyperGraphProjectionType <: AbstractProjectionType end

"""
edge_hyper_graph(graph::OptiGraph)
edge_hyper_projection(graph::OptiGraph)
Retrieve an edge-hypergraph representation of the optigraph `graph`. Returns a [`GraphProjection`](@ref) object, as well as a dictionary
that maps hypernodes and hyperedges to the original optinodes and optiedges. This is also called the dual-hypergraph representation of a hypergraph.
Retrieve an edge-hypergraph representation of the optigraph `graph`. This is sometimes
called the dual-hypergraph representation of a hypergraph.
"""
function edge_hyper_projection(optigraph::OptiGraph)
function edge_hyper_projection(graph::OptiGraph)
# create a primal hypergraph first. we need to do this to get the node --> edge mapping
primal_map = hyper_projection(optigraph)
primal_map = hyper_projection(graph)

# build the edge hypergraph
hypergraph = GOI.HyperGraph()
projection = GraphProjection(optigraph, hypergraph, EdgeHyperGraphProjectionType())
for edge in all_edges(optigraph)
projection = GraphProjection(graph, hypergraph, EdgeHyperGraphProjectionType())
for edge in all_edges(graph)
hypernode = Graphs.add_vertex!(hypergraph)
projection[hypernode] = edge
projection[edge] = hypernode
end
for node in all_nodes(optigraph)
for node in all_nodes(graph)
hyperedges = incident_edges(primal_map, node)
dual_nodes = Base.getindex.(projection, hyperedges)
# NOTE: a hypergraph may not always have a valid edge projection; we only
Expand All @@ -212,29 +213,29 @@ end
struct BipartiteGraphProjectionType <: AbstractProjectionType end

"""
bipartite_graph(optigraph::OptiGraph)
bipartite_graph(graph::OptiGraph)
Create a bipartite graph representation from `optigraph`.
The bipartite graph contains two sets of vertices corresponding to optinodes and optiedges respectively.
Create a bipartite graph representation from `graph`. The bipartite graph contains two
sets of vertices corresponding to optinodes and optiedges respectively.
"""
function bipartite_projection(optigraph::OptiGraph)
graph = GOI.BipartiteGraph()
projection = GraphProjection(optigraph, graph, BipartiteGraphProjectionType())
for optinode in all_nodes(optigraph)
Graphs.add_vertex!(graph; bipartite=1)
node_vertex = nv(graph)
function bipartite_projection(graph::OptiGraph)
bipartite_graph = GOI.BipartiteGraph()
projection = GraphProjection(graph, bipartite_graph, BipartiteGraphProjectionType())
for optinode in all_nodes(graph)
Graphs.add_vertex!(bipartite_graph; bipartite=1)
node_vertex = nv(bipartite_graph)
projection[node_vertex] = optinode
projection[optinode] = node_vertex
end
for edge in all_edges(optigraph)
Graphs.add_vertex!(graph; bipartite=2)
edge_vertex = nv(graph)
for edge in all_edges(graph)
Graphs.add_vertex!(bipartite_graph; bipartite=2)
edge_vertex = nv(bipartite_graph)
projection[edge] = edge_vertex
projection[edge_vertex] = edge
nodes = edge.nodes
edge_vertices = [projection[optinode] for optinode in nodes]
for node_vertex in edge_vertices
Graphs.add_edge!(graph, edge_vertex, node_vertex)
Graphs.add_edge!(bipartite_graph, edge_vertex, node_vertex)
end
end
return projection
Expand Down
Loading

0 comments on commit 1610047

Please sign in to comment.