Skip to content

Commit

Permalink
Updated interfaces
Browse files Browse the repository at this point in the history
  • Loading branch information
MicheleCeresoli committed Nov 23, 2023
1 parent 70f8efe commit 1f309e3
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 56 deletions.
36 changes: 19 additions & 17 deletions src/SMDGraphs.jl
Original file line number Diff line number Diff line change
@@ -1,29 +1,31 @@
module SMDGraphs

using JSMDInterfaces.Interface: @interface
using JSMDInterfaces.Interface

import JSMDInterfaces:
import JSMDInterfaces.Graph:
AbstractJSMDGraphNode,
AbstractJSMDGraph
AbstractJSMDGraph,
add_edge!,
add_vertex!,
edges,
edgetype,
get_path,
has_vertex,
has_edge,
has_path,
inneighbors,
is_directed,
ne,
nv,
outneighbors,
vertices

import Graphs:
AbstractGraph
AbstractGraph,
SimpleGraph,
SimpleDiGraph,
add_edge!,
add_vertex!,
dijkstra_shortest_paths,
edges,
edgetype,
enumerate_paths,
has_edge,
has_path,
has_vertex,
is_directed,
ne,
nv,
vertices

enumerate_paths

include("graphs/MappedGraphs.jl")

Expand Down
78 changes: 42 additions & 36 deletions src/graphs/MappedGraphs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Get the mapped-id of an `AbstractJSMDGraphNode`.


"""
MappedNodeGraph{N, G}
MappedNodeGraph{N, G} <: AbstractJSMDGraph{Int}
Create a graph with mapped nodes.
Expand Down Expand Up @@ -66,6 +66,13 @@ Get the mappedid associated with a node.
"""
@inline get_mappedid(g::MappedNodeGraph, node::Int) = g.mid[node]

"""
get_outerid(g::MappedNodeGraph, id::Int)
Return the id of the node associated to the mapped id `id`.
"""
@inline get_outerid(g::MappedNodeGraph, id::Int) = get_node_id(g.nodes[id])

"""
get_mappednode(g::MappedNodeGraph, mid::Int)
Expand All @@ -83,32 +90,46 @@ Get the node associated with a node index.
Base.isempty(g::MappedNodeGraph) = Base.isempty(g.nodes)


# JSMD Interfaces
# Graphs Interfaces
# =======================

# TODO: change this functions to use mapped IDs as inputs!

has_vertex(g::MappedNodeGraph, node::Int) = haskey(g.mid, node)
has_edge(g::MappedNodeGraph, from::Int, to::Int) = has_edge(g.graph, from, to)

edges(g::MappedNodeGraph) = edges(g.graph)
function has_edge(g::MappedNodeGraph, from::Int, to::Int)
# Check whether from and to are registered in the graph
(!haskey(g.mid, from) || !haskey(g.mid, to)) && return false

fid = get_mappedid(g, from)
tid = get_mappedid(g, to)

has_edge(g.graph, fid, tid)
end

function edges(g::MappedNodeGraph)
map(e->Graphs.SimpleEdge(get_outer_id(e.src), get_outer_id(e.dst)), edges(g.graph))
end

edgetype(g::MappedNodeGraph) = edgetype(g.graph)

inneighbors(g::MappedNodeGraph) = inneighbors(g.graph)
is_directed(g::MappedNodeGraph) = is_directed(g.graph)

ne(g::MappedNodeGraph) = ne(g.graph)
nv(g::MappedNodeGraph) = nv(g.graph)

outneighbors(g::MappedNodeGraph) = outneighbors(g.graph)
function inneighbors(g::MappedNodeGraph, node::Int)
map(get_outerid, inneighbors(g.graph, node))
end

vertices(g::MappedNodeGraph) = vertices(g.graph)
function outneighbors(g::MappedNodeGraph, node::Int)
map(get_outerid, outneighbors(g.graph, node))
end

vertices(g::MappedNodeGraph) = map(get_node_id, g.nodes)

"""
add_vertex!(g, node)

Add `node` to the graph `g`.
"""
# JSMD Interfaces
# =======================

function add_vertex!(g::MappedNodeGraph{T}, node::T) where {T<:AbstractJSMDGraphNode}
nodeid = get_node_id(node)
has_vertex(g, nodeid) && return nothing
Expand All @@ -125,12 +146,6 @@ function add_vertex!(g::MappedNodeGraph{T}, node::T) where {T<:AbstractJSMDGraph
return nothing
end

"""
add_edge!(g::MappedNodeGraph, from::Int, to::Int, [cost])
Add an edge between `from` and `to` to `g`.
Optionally assign a `cost` to the edge.
"""
function add_edge!(g::MappedNodeGraph{T}, from::Int, to::Int, cost::Int=0) where {T}
# ensure the two vertexes already exist in the graph
if !(has_vertex(g, from) && has_vertex(g, to))
Expand All @@ -148,16 +163,18 @@ function add_edge!(g::MappedNodeGraph{T}, from::Int, to::Int, cost::Int=0) where
return nothing
end


"""
has_path(g, from, to)
Return true if there is a path between `from` and `to` in the graph `g`.
"""
function has_path(g::MappedNodeGraph, from::Int, to::Int)
return has_path(g.graph, get_mappedid(g, from), get_mappedid(g, to))
end

function get_path(g::MappedNodeGraph{T}, from::Int, to::Int) where {T}
(has_vertex(g, from) && has_vertex(g, to)) || return Int[]
return g.paths[from][to]
end


# Internal routines
# =======================

"""
add_edge_cost!(g::MappedNodeGraph, fid::Int, tid::Int, cost::Int)
Expand Down Expand Up @@ -211,17 +228,6 @@ function compute_paths!(g::MappedNodeGraph{T}) where {T}
return nothing
end

"""
get_path(g::MappedNodeGraph, from::Int, to::Int)
Get the nodes on the path between and including `from` and `to`. Returns an empty array if
either `from` or `to` are not a part of `g` or if there is no path between them.
"""
function get_path(g::MappedNodeGraph{T}, from::Int, to::Int) where {T}
(has_vertex(g, from) && has_vertex(g, to)) || return Int[]
return g.paths[from][to]
end

"""
get_edgecosts(g::MappedNodeGraph, from::Int, to::Int)
Expand Down
8 changes: 5 additions & 3 deletions test/runtests.jl
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
using SMDGraphs
using Graphs
using Test

using Graphs

import JSMDInterfaces.Graph as jGraph
import SMDGraphs: MappedGraph, MappedDiGraph, MappedNodeGraph

# Simple Node graph for testing purposes
struct IntNode <: SMDGraphs.AbstractGraphNode
struct IntNode <: jGraph.AbstractJSMDGraphNode
id::Int
end

struct FakeNode <: SMDGraphs.AbstractGraphNode
struct FakeNode <: jGraph.AbstractJSMDGraphNode
id::Int
end

Expand Down

0 comments on commit 1f309e3

Please sign in to comment.