Yog.IO.List (YogEx v0.97.1)

Copy Markdown View Source

Adjacency list import/export for graph serialization.

Adjacency lists are a compact way to represent sparse graphs where each node stores only its neighbors. This format is commonly used in:

  • Algorithm competitions and textbooks
  • Graph database exports
  • Network analysis tools
  • Configuration files

Format

Each line represents one node and its neighbors:

node_id: neighbor1 neighbor2 neighbor3...

For weighted graphs, neighbors include weights:

node_id: neighbor1,weight1 neighbor2,weight2...

Examples

Simple unweighted adjacency list:

1: 2 3
2: 3 4
3: 4
4:

Weighted adjacency list:

1: 2,5 3,10
2: 3,2
3: 4,7

Limitations

This format is intended for simple graphs where:

  • Node IDs are integers or strings.
  • Edge weights are numbers or maps with a "weight" key.

For graphs with complex node IDs (like tuples) or rich metadata, use Yog.IO.JSON or Yog.IO.GEXF instead.

Use Cases

  • Importing graphs from text files and databases
  • Human-readable graph representation
  • Sparse graph serialization
  • Algorithm competition input format
  • Adjacency matrix conversion

See Also

Summary

Types

Adjacency list entry: {node_id, [{neighbor_id, weight}]}

Functions

Creates a graph from an adjacency list.

Creates a graph from a string representation of an adjacency list.

Exports a graph to an adjacency list representation.

Exports a graph to a string representation of an adjacency list.

Types

adjacency_entry()

@type adjacency_entry() :: {Yog.node_id(), [{Yog.node_id(), number()}]}

Adjacency list entry: {node_id, [{neighbor_id, weight}]}

Functions

from_list(type, entries)

@spec from_list(:directed | :undirected, [adjacency_entry()]) :: Yog.graph()

Creates a graph from an adjacency list.

Parameters

  • type - :directed or :undirected
  • entries - List of {node_id, neighbors} tuples where neighbors is a list of {neighbor_id, weight} tuples. For unweighted graphs, use weight 1.

Examples

iex> # Unweighted adjacency list
...> entries = [
...>   {1, [{2, 1}, {3, 1}]},
...>   {2, [{3, 1}]},
...>   {3, []}
...> ]
iex> graph = Yog.IO.List.from_list(:undirected, entries)
iex> Yog.Model.order(graph)
3
iex> Yog.Model.edge_count(graph)
3

iex> # Weighted adjacency list
...> weighted = [
...>   {1, [{2, 5}, {3, 10}]},
...>   {2, [{3, 2}]},
...>   {3, []}
...> ]
iex> digraph = Yog.IO.List.from_list(:directed, weighted)
iex> Yog.Model.edge_count(digraph)
3

Notes

  • For undirected graphs, edges are added in both directions automatically
  • Nodes with empty neighbor lists are still added to the graph
  • Duplicate edges are handled by the underlying graph structure

from_string(type, string, opts \\ [])

@spec from_string(:directed | :undirected, String.t(), keyword()) :: Yog.graph()

Creates a graph from a string representation of an adjacency list.

Parses a string in the format:

node_id: neighbor1 neighbor2...

Parameters

  • type - :directed or :undirected
  • string - Multiline string with adjacency list format
  • opts - Options:
    • :weighted - true to parse weighted edges (format: "neighbor,weight")
    • :delimiter - Delimiter between node and neighbors (default: ":")

Examples

iex> text = """
...> 1: 2 3
...> 2: 3
...> 3:
...> """
iex> graph = Yog.IO.List.from_string(:undirected, text)
iex> Yog.Model.order(graph)
3

iex> # Weighted format
iex> weighted_text = """
...> 1: 2,5 3,10
...> 2: 3,2
...> """
iex> graph = Yog.IO.List.from_string(:directed, weighted_text, weighted: true)
iex> Yog.Model.edge_count(graph)
3

to_list(graph)

@spec to_list(Yog.graph()) :: [adjacency_entry()]

Exports a graph to an adjacency list representation.

Returns a list of {node_id, neighbors} tuples where neighbors is a list of {neighbor_id, weight} tuples.

Examples

iex> graph = Yog.undirected()
...>   |> Yog.add_node(1, nil)
...>   |> Yog.add_node(2, nil)
...>   |> Yog.add_node(3, nil)
...>   |> Yog.add_edge_ensure(from: 1, to: 2, with: 5)
...>   |> Yog.add_edge_ensure(from: 2, to: 3, with: 7)
iex> entries = Yog.IO.List.to_list(graph)
iex> entries
[{1, [{2, 5}]}, {2, [{1, 5}, {3, 7}]}, {3, [{2, 7}]}]

Notes

  • Node order is deterministic (sorted by node ID)
  • For undirected graphs, each edge appears twice (once for each direction)
  • Isolated nodes have empty neighbor lists

to_string(graph, opts \\ [])

@spec to_string(
  Yog.graph(),
  keyword()
) :: String.t()

Exports a graph to a string representation of an adjacency list.

Options

  • weighted - true to include weights (format: "neighbor,weight")
  • delimiter - Delimiter between node and neighbors (default: ":")
  • node_formatter - Function to convert node IDs to strings (default: &Kernel.to_string/1)
  • weight_formatter - Function to convert edge weights to strings (default: &Yog.Utils.to_weight_label/1)

Examples

iex> graph = Yog.undirected()
...>   |> Yog.add_edge_ensure(from: 1, to: 2, with: 5)
...>   |> Yog.add_edge_ensure(from: 2, to: 3, with: 7)
iex> Yog.IO.List.to_string(graph)
"1: 2\n2: 1 3\n3: 2"

iex> # Using custom formatters for complex types
iex> graph = Yog.undirected()
...>   |> Yog.add_edge_with({1, 2}, {3, 4}, [weight: 10], & &1)
iex> Yog.IO.List.to_string(graph,
...>   node_formatter: fn {a, b} -> "#{a}_#{b}" end,
...>   weight_formatter: fn [weight: w] -> "w#{w}" end,
...>   weighted: true
...> )
"1_2: 3_4,w10\n3_4: 1_2,w10"