Giraffe.Graph.Directed (giraffe v0.2.1)

Implementation of a directed graph with weighted edges. Vertices can be any term, and edges have numeric weights.

Examples

iex> graph = Giraffe.Graph.Directed.new()
...> graph = graph |> Giraffe.Graph.Directed.add_edge(:a, :b, 1)
...> graph |> Giraffe.Graph.Directed.edges()
[{:a, :b, 1}]

Summary

Functions

Adds a weighted edge between two vertices in the graph. The vertices will be added to the graph if they don't already exist.

Adds a vertex to the graph with an optional label.

Finds shortest paths using Bellman-Ford algorithm

Finds all maximal cliques in the graph. A clique is a subset of vertices where every vertex is connected to every other vertex. Only considers bidirectional edges.

Gets the shortest path between a and b using Dijkstra's algorithm

Returns a list of all edges in the graph as tuples of {from, to, weight}.

Returns a list of all edges for a specific vertex.

Gets the label associated with a vertex.

Finds all possible paths between two vertices. Returns a list of tuples containing the path and its total weight.

Finds the shortest path between two vertices using Dijkstra's algorithm. Returns {:ok, path, total_weight} if a path exists, or :no_path if no path exists.

Returns true if the given vertex exists in the graph.

Checks if the graph is acyclic.

Checks if the graph is cyclic.

Returns a sorted list of all vertices that are neighbors of the given vertex. Includes both incoming and outgoing edges.

Creates a new empty graph.

Returns the number of edges in the graph

Returns the number of vertices in the graph

Returns vertices in post-order DFS traversal order.

Returns a list of all vertices reachable from the given starting vertices.

Sets a label for an existing vertex. Returns unchanged graph if vertex doesn't exist.

Finds the shortest paths from a source vertex to all other vertices using the Bellman-Ford algorithm.

Returns the label for the given vertex

Returns a list of all vertices in the graph.

Types

edge()

@type edge() :: {vertex(), vertex(), weight()}

t()

@type t() :: %Giraffe.Graph.Directed{
  edges: %{required(vertex()) => %{required(vertex()) => weight()}},
  labels: map(),
  vertices: MapSet.t()
}

vertex()

@type vertex() :: any()

weight()

@type weight() :: number()

Functions

add_edge(graph, v1, v2, opts_or_weight \\ 1)

@spec add_edge(t(), vertex(), vertex(), number() | keyword()) :: t()

Adds a weighted edge between two vertices in the graph. The vertices will be added to the graph if they don't already exist.

Examples

iex> graph = Giraffe.Graph.Directed.new()
...> graph = Giraffe.Graph.Directed.add_edge(graph, :a, :b, 1)
...> Giraffe.Graph.Directed.edges(graph)
[{:a, :b, 1}]

add_vertex(graph, vertex, labels \\ [])

@spec add_vertex(t(), vertex(), [any()]) :: t()

Adds a vertex to the graph with an optional label.

Examples

iex> graph = Giraffe.Graph.Directed.new()
iex> Giraffe.Graph.Directed.add_vertex(graph, :a, "vertex A")
%Giraffe.Graph.Directed{vertices: MapSet.new([:a]), edges: %{}, labels: %{a: "vertex A"}}

bellman_ford(graph, source)

@spec bellman_ford(t(), vertex()) :: %{required(vertex()) => number()} | nil

Finds shortest paths using Bellman-Ford algorithm

cliques(directed)

@spec cliques(t()) :: [[vertex()]]

Finds all maximal cliques in the graph. A clique is a subset of vertices where every vertex is connected to every other vertex. Only considers bidirectional edges.

Examples

iex> graph = Giraffe.Graph.Directed.new()
...> graph = graph |> Giraffe.Graph.Directed.add_edge(:a, :b, 1)
...> graph = graph |> Giraffe.Graph.Directed.add_edge(:b, :a, 1)
...> Giraffe.Graph.Directed.cliques(graph)
[[:a, :b]]

dijkstra(graph, a, b)

@spec dijkstra(t(), vertex(), vertex()) :: {:ok, [vertex()], number()} | :no_path

Gets the shortest path between a and b using Dijkstra's algorithm

edges(directed)

@spec edges(t()) :: [{vertex(), vertex(), number()}]

Returns a list of all edges in the graph as tuples of {from, to, weight}.

Examples

iex> graph = Giraffe.Graph.Directed.new()
...> graph = Giraffe.Graph.Directed.add_edge(graph, :a, :b, 1)
...> Giraffe.Graph.Directed.edges(graph)
[{:a, :b, 1}]

edges(directed, vertex)

@spec edges(t(), vertex()) :: [{vertex(), vertex(), number()}]

Returns a list of all edges for a specific vertex.

Examples

iex> graph = Giraffe.Graph.Directed.new()
...> graph = Giraffe.Graph.Directed.add_edge(graph, :a, :b, 1)
...> Giraffe.Graph.Directed.edges(graph, :a)
[{:a, :b, 1}]

get_label(graph, vertex)

@spec get_label(t(), vertex()) :: any() | nil

Gets the label associated with a vertex.

Examples

iex> graph = Giraffe.Graph.Directed.new() |> Giraffe.Graph.Directed.add_vertex(:a, "vertex A")
iex> Giraffe.Graph.Directed.get_label(graph, :a)
"vertex A"

get_paths(graph, start, finish)

@spec get_paths(t(), vertex(), vertex()) :: [{[vertex()], weight()}]

Finds all possible paths between two vertices. Returns a list of tuples containing the path and its total weight.

Examples

iex> graph = Giraffe.Graph.Directed.new()
...> graph = graph |> Giraffe.Graph.Directed.add_edge(:a, :b, 1)
...> Giraffe.Graph.Directed.get_paths(graph, :a, :b)
[{[:a, :b], 1.0}]

get_shortest_path(directed, start, finish)

@spec get_shortest_path(t(), vertex(), vertex()) ::
  {:ok, [vertex()], weight()} | :no_path

Finds the shortest path between two vertices using Dijkstra's algorithm. Returns {:ok, path, total_weight} if a path exists, or :no_path if no path exists.

Examples

iex> graph = Giraffe.Graph.Directed.new()
...> graph = graph |> Giraffe.Graph.Directed.add_edge(:a, :b, 1)
...> Giraffe.Graph.Directed.get_shortest_path(graph, :a, :b)
{:ok, [:a, :b], 1}

has_vertex?(graph, vertex)

@spec has_vertex?(t(), vertex()) :: boolean()

Returns true if the given vertex exists in the graph.

is_acyclic?(directed)

@spec is_acyclic?(t()) :: boolean()

Checks if the graph is acyclic.

Examples

iex> graph = Giraffe.Graph.Directed.new()
...> graph = graph |> Giraffe.Graph.Directed.add_edge(:a, :b, 1)
...> Giraffe.Graph.Directed.is_acyclic?(graph)
true

is_cyclic?(graph)

@spec is_cyclic?(t()) :: boolean()

Checks if the graph is cyclic.

Examples

iex> graph = Giraffe.Graph.Directed.new()
...> graph = graph |> Giraffe.Graph.Directed.add_edge(:a, :b, 1)
...> graph = graph |> Giraffe.Graph.Directed.add_edge(:b, :a, 1)
...> Giraffe.Graph.Directed.is_cyclic?(graph)
true

neighbors(directed, vertex)

@spec neighbors(t(), vertex()) :: [vertex()]

Returns a sorted list of all vertices that are neighbors of the given vertex. Includes both incoming and outgoing edges.

Examples

iex> graph = Giraffe.Graph.Directed.new()
...> graph = graph |> Giraffe.Graph.Directed.add_edge(:a, :b, 1)
...> Giraffe.Graph.Directed.neighbors(graph, :a)
[:b]

new(opts \\ [])

@spec new(keyword()) :: t()

Creates a new empty graph.

Examples

iex> Giraffe.Graph.Directed.new()
%Giraffe.Graph.Directed{vertices: MapSet.new(), edges: %{}, labels: %{}}

num_edges(graph)

@spec num_edges(t()) :: non_neg_integer()

Returns the number of edges in the graph

num_vertices(graph)

@spec num_vertices(t()) :: non_neg_integer()

Returns the number of vertices in the graph

postorder(directed)

@spec postorder(t()) :: [vertex()]

Returns vertices in post-order DFS traversal order.

Examples

iex> graph = Giraffe.Graph.Directed.new()
...> |> Giraffe.Graph.Directed.add_edge(:a, :b, 1)
...> |> Giraffe.Graph.Directed.add_edge(:b, :c, 1)
iex> Giraffe.Graph.Directed.postorder(graph)
[:c, :b, :a]

reachable(graph, vertices)

@spec reachable(t(), [vertex()]) :: [vertex()]

Returns a list of all vertices reachable from the given starting vertices.

Examples

iex> graph = Giraffe.Graph.Directed.new()
...> |> Giraffe.Graph.Directed.add_edge(:a, :b, 1)
...> |> Giraffe.Graph.Directed.add_edge(:b, :c, 1)
iex> Giraffe.Graph.Directed.reachable(graph, [:a])
[:a, :b, :c]

set_label(graph, vertex, label)

@spec set_label(t(), vertex(), label :: any()) :: t()

Sets a label for an existing vertex. Returns unchanged graph if vertex doesn't exist.

Examples

iex> graph = Giraffe.Graph.Directed.new() |> Giraffe.Graph.Directed.add_vertex(:a)
iex> Giraffe.Graph.Directed.set_label(graph, :a, "new label")
%Giraffe.Graph.Directed{vertices: MapSet.new([:a]), edges: %{}, labels: %{a: "new label"}}

shortest_paths(graph, source)

@spec shortest_paths(t(), vertex()) ::
  {:ok, %{required(vertex()) => weight()}} | {:error, :negative_cycle}

Finds the shortest paths from a source vertex to all other vertices using the Bellman-Ford algorithm.

Examples

iex> graph = Giraffe.Graph.Directed.new()
...> graph = graph |> Giraffe.Graph.Directed.add_edge(:a, :b, 1)
...> Giraffe.Graph.Directed.shortest_paths(graph, :a)
{:ok, %{a: 0, b: 1}}

vertex_labels(graph, vertex)

@spec vertex_labels(t(), vertex()) :: [any()]

Returns the label for the given vertex

vertices(directed)

@spec vertices(t()) :: [vertex()]

Returns a list of all vertices in the graph.

Examples

iex> graph = Giraffe.Graph.Directed.new() |> Giraffe.Graph.Directed.add_vertex(:a)
iex> Giraffe.Graph.Directed.vertices(graph)
[:a]