graph

package
v0.0.0-...-e471070 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 25, 2021 License: GPL-3.0 Imports: 4 Imported by: 0

Documentation

Overview

Package graph provides data structures to manipulate a set of vertices and a collection of edges that each connect a pair of vertices.

Depth-first search (DFS) and breadth-first search (BFS) start from source vertex and perform the following steps until the data structure is empty:

  • take the next unmarked vertex v from the data structure and mark it,
  • put onto the data structure all unmarked vertices that are adjacent to v.

The algorithms differ only in the rule used to take the next vertex: most recently added for DFS (stack), least recently added for BFS (queue).

DFS explores the graph by looking for new vertices far away from the start point, taking closer vertices only when dead ends are encountered.

BFS completely covers the area close to the starting point, moving farther away only when everything nearby has been examined.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func DepthFirstSearch

func DepthFirstSearch(g *AdjacencyList, source int) []int

DepthFirstSearch is a method to find the vertices connected to the source. It is similar to searching through the maze by using a string that guarantees you can always find a way out and the passage marks guarantee that you avoid exploring any passage or intersection twice. To search a graph, a recursive method is used that visits all of graph's vertices and edges.

Depth-first search marks all the vertices connected to a given source in time proportional to the sum of their degrees. A degree of vertex v is a count of its adjacent vertices.

func HasCycle

func HasCycle(g *AdjacencyList) bool

HasCycle reports whether a given graph has a cycle (path with at least one edge whose first and last vertices are the same). It assumes no self-loops or parallel edges.

Example
g := NewAdjacencyList(5)
g.Add(1, 0)
g.Add(0, 2)
g.Add(0, 3)
g.Add(3, 4)

fmt.Println(HasCycle(g))
g.Add(2, 1)
fmt.Println(HasCycle(g))
Output:

false
true

func IsBipartite

func IsBipartite(g *AdjacencyList) bool

IsBipartite returns true if a graph whose vertices we can divide into two sets such that all edges connect a vertex in one set (colored red) with a vertex in the other set (colored black). In other words, can the vertices of a given graph be assigned one of two colors in such a way that no edge connects vertices of the same color? Graph is two-colorable if and only if it contains no odd-length cycle.

For example, IMDB can be defined as a graph with movies and performers as vertices and each line defining the adjacency list of edges connecting each movie to its performers. The graph is bipartite — there are no edges connecting performers to performers or movies to movies.

Types

type AdjacencyList

type AdjacencyList struct {
	// contains filtered or unexported fields
}

AdjacencyList maintains a vertex-indexed array of lists of the vertices adjacent to each vertex. Every edge appears twice: if an edge connects v and w, then w appears in v's list and v appears in w's list. Space usage is proportional to number of vertices + edges. A new edge is added in constant time and iteration through adjacent vertices is constant time per adjacent vertex.

func NewAdjacencyList

func NewAdjacencyList(vertices int) *AdjacencyList

NewAdjacencyList creates a graph represented as an array of adjacency lists.

func (*AdjacencyList) Add

func (g *AdjacencyList) Add(v, w int)

Add adds a new edge connecting v and w vertices.

func (*AdjacencyList) Adjacent

func (g *AdjacencyList) Adjacent(v int) []int

Adjacent returns vertices adjacent to the vertex v.

func (*AdjacencyList) String

func (g *AdjacencyList) String() string

String returns a string representation of the graph's adjacency lists.

type BreadthFirstPath

type BreadthFirstPath struct {
	// contains filtered or unexported fields
}

BreadthFirstPath uses breadth-first search to find paths in a graph with the fewest number of edges from the source vertex. The algorithm is based on maintaining a queue of all vertices that have been marked but whose adjacency lists have not been checked. It puts the source vertex onto the queue, then does the following steps until the queue is empty:

  • remove the next vertex v from the queue,
  • put onto the queue all unmarked vertices that are adjacent to v and mark them.

BFS takes time proportional to number of edges + number of vertices in the worst case.

func NewBreadthFirstPath

func NewBreadthFirstPath(g *AdjacencyList, source int) *BreadthFirstPath

NewBreadthFirstPath creates BreadthFirstPath to look up shortest paths from the source vertex.

func (*BreadthFirstPath) To

func (bfs *BreadthFirstPath) To(v int) []int

To searches a shortest path from source to the connected vertex v.

type ConnectedComponent

type ConnectedComponent struct {
	// contains filtered or unexported fields
}

ConnectedComponent uses depth-first search to find connected components in a graph.

func NewConnectedComponent

func NewConnectedComponent(g *AdjacencyList) *ConnectedComponent

NewConnectedComponent finds the connected components of a graph. It uses marked array to find a vertex to serve as the starting point for a depth-first search in each component. Firstly it marks all vertices connected to 0. Then in a loop it looks for an unmarked vertex and marks all vertices connected to that vertex.

DFS uses preprocessing time and space proportional to E+V (number of edges plus vertices) to support constant-time connectivity queries in a graph. In theory DFS is faster than union-find algorithm, because it provides a constant-time guarantee. In practise, the difference is negligible, and union-find is faster because it doesn't have to build a full representation of the graph.

func (*ConnectedComponent) Count

func (cc *ConnectedComponent) Count() int

Count returns number of components.

func (*ConnectedComponent) ID

func (cc *ConnectedComponent) ID(v int) int

ID returns component identifier (between 0 and count-1) for vertex v.

func (*ConnectedComponent) IsConnected

func (cc *ConnectedComponent) IsConnected(v, w int) bool

IsConnected tells whether v and w are in the same component by checking if site identifiers are equal.

type DepthFirstPath

type DepthFirstPath struct {
	// contains filtered or unexported fields
}

DepthFirstPath uses depth-first search to find paths to all the vertices in a graph that are connected to a given start vertex s. To save known paths to each vertex, it maintains a vertex-indexed array.

func NewDepthFirstPath

func NewDepthFirstPath(g *AdjacencyList, source int) *DepthFirstPath

NewDepthFirstPath creates DepthFirstPath to look up paths connected to source vertex.

func (*DepthFirstPath) To

func (dfs *DepthFirstPath) To(v int) []int

To searches a path from source to the connected vertex v.

type SymbolGraph

type SymbolGraph struct {
	// contains filtered or unexported fields
}

SymbolGraph is a graph whose vertices are strings (city, movie), not integer indices.

Example
package main

import (
	"bytes"
	"fmt"
	"log"

	"github.com/marselester/alg/graph"
)

const routes = `
JFK MCO
ORD DEN
ORD HOU
DFW PHX
JFK ATL
ORD DFW
ORD PHX
ATL HOU
DEN PHX
PHX LAX
JFK ORD
DEN LAS
DFW HOU
ORD ATL
LAS LAX
ATL MCO
HOU MCO
LAS PHX
`

func main() {
	sg, err := graph.NewSymbolGraph(bytes.NewReader([]byte(routes)), " ")
	if err != nil {
		log.Fatalf("flight: graph creation failed: %v", err)
	}

	v, ok := sg.Index("JFK")
	if !ok {
		log.Fatalf("flight: airport not found")
	}
	for _, v := range sg.Adjacent(v) {
		fmt.Println(sg.Name(v))
	}
}
Output:

ORD
ATL
MCO

func NewSymbolGraph

func NewSymbolGraph(in io.ReadSeeker, sep string) (*SymbolGraph, error)

NewSymbolGraph constructs a symbol graph. It uses two passes through the data to build underlying indices. Note, one pass would be sufficient if a graph used a hash table implementation (extra log V factor, V is number of vertices) instead of a linked list.

func (*SymbolGraph) Adjacent

func (sg *SymbolGraph) Adjacent(v int) []int

Adjacent returns vertices adjacent to the vertex v.

func (*SymbolGraph) Graph

func (sg *SymbolGraph) Graph() *AdjacencyList

Graph returns an underlying graph.

func (*SymbolGraph) Index

func (sg *SymbolGraph) Index(key string) (int, bool)

Index returns a vertex index associated with a key (vertex name).

func (*SymbolGraph) Name

func (sg *SymbolGraph) Name(v int) string

Name returns a vertex name associated with index v. Empty string indicates that vertex doesn't exist.

Directories

Path Synopsis
Package mst computes minimum spanning tree for undirected edge-weighted graph.
Package mst computes minimum spanning tree for undirected edge-weighted graph.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL