gograph

package module
v0.4.0 Latest Latest
Warning

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

Go to latest
Published: Apr 6, 2023 License: Apache-2.0 Imports: 1 Imported by: 2

README

build Go Report Card codecov Go Reference Mentioned in Awesome Go

gograph

golang generic graph package

GoGraph is a Golang generic graph library that provides mathematical graph theory and algorithms. It can be used as an external library in production.

In addition, it is a helpful resource for those who want to prepare for interviews.




Table of Contents

Install

Use go get command to get the latest version of the gograph:

go get github.com/hmdsefi/gograph

Then you can use import the gograph to your code:

package main

import "github.com/hmdsefi/gograph"

How to Use

Graph

gograph contains the Graph[T comparable] interface that provides all needed APIs to manage a graph. All the supported graph types in gograph library implemented this interface.

type Graph[T comparable] interface {
GraphType

AddEdge(from, to *Vertex[T], options ...EdgeOptionFunc) (*Edge[T], error)
GetAllEdges(from, to *Vertex[T]) []*Edge[T]
GetEdge(from, to *Vertex[T]) *Edge[T]
EdgesOf(v *Vertex[T]) []*Edge[T]
RemoveEdges(edges ...*Edge[T])
AddVertexByLabel(label T, options ...VertexOptionFunc) *Vertex[T]
AddVertex(v *Vertex[T])
GetVertexByID(label T) *Vertex[T]
GetAllVerticesByID(label ...T) []*Vertex[T]
GetAllVertices() []*Vertex[T]
RemoveVertices(vertices ...*Vertex[T])
ContainsEdge(from, to *Vertex[T]) bool
ContainsVertex(v *Vertex[T]) bool
}

The generic type of the T in Graph interface represents the vertex label. The type of T should be comparable. You cannot use slices and function types for T.

Directed

directed-graph

graph := New[int](gograph.Directed())

graph.AddEdge(gograph.NewVertex(1), gograph.NewVertex(2))
graph.AddEdge(gograph.NewVertex(1), gograph.NewVertex(3))
graph.AddEdge(gograph.NewVertex(2), gograph.NewVertex(2))
graph.AddEdge(gograph.NewVertex(3), gograph.NewVertex(4))
graph.AddEdge(gograph.NewVertex(4), gograph.NewVertex(5))
graph.AddEdge(gograph.NewVertex(5), gograph.NewVertex(6))
Acyclic

acyclic-graph

graph := New[int](gograph.Directed())

graph.AddEdge(gograph.NewVertex(1), gograph.NewVertex(2))
graph.AddEdge(gograph.NewVertex(2), gograph.NewVertex(3))
_, err := graph.AddEdge(gograph.NewVertex(3), gograph.NewVertex(1))
if err != nil {
// do something
}
Undirected

undirected-graph

// by default graph is undirected
graph := New[string]()

graph.AddEdge(gograph.NewVertex("A"), gograph.NewVertex("B"))
graph.AddEdge(gograph.NewVertex("A"), gograph.NewVertex("D"))
graph.AddEdge(gograph.NewVertex("B"), gograph.NewVertex("C"))
graph.AddEdge(gograph.NewVertex("B"), gograph.NewVertex("D"))
Weighted

weighted-edge

graph := New[string]()

vA := gograph.AddVertexByLabel("A")
vB := gograph.AddVertexByLabel("B")
vC := gograph.AddVertexByLabel("C")
vD := gograph.AddVertexByLabel("D")

graph.AddEdge(vA, vB, gograph.WithEdgeWeight(4))
graph.AddEdge(vA, vD, gograph.WithEdgeWeight(3))
graph.AddEdge(vB, vC, gograph.WithEdgeWeight(3))
graph.AddEdge(vB, vD, gograph.WithEdgeWeight(1))
graph.AddEdge(vC, vD, gograph.WithEdgeWeight(2))

weighted-vertex

graph := New[string]()
vA := gograph.AddVertexByLabel("A", gograph.WithVertexWeight(3))
vB := gograph.AddVertexByLabel("B", gograph.WithVertexWeight(2))
vC := gograph.AddVertexByLabel("C", gograph.WithVertexWeight(4))

graph.AddEdge(vA, vB)
graph.AddEdge(vB, vC)
Traverse

Traverse package provides the iterator interface that guarantees all the algorithm export the same APIs:

type Iterator[T comparable] interface {
	HasNext() bool
	Next() *gograph.Vertex[T]
	Iterate(func(v *gograph.Vertex[T]) error) error
	Reset()
}

This package contains the following iterators:

License

Apache License, please see LICENSE for details.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrNilVertices        = errors.New("vertices are nil")
	ErrVertexDoesNotExist = errors.New("vertex does not exist")
	ErrEdgeAlreadyExists  = errors.New("edge already exists")
	ErrDAGCycle           = errors.New("edges would create cycle")
	ErrDAGHasCycle        = errors.New("the graph contains a cycle")
)

Functions

This section is empty.

Types

type Edge

type Edge[T comparable] struct {
	// contains filtered or unexported fields
}

Edge represents an edges in a graph. It contains start and end points.

func NewEdge

func NewEdge[T comparable](source *Vertex[T], dest *Vertex[T], options ...EdgeOptionFunc) *Edge[T]

func (Edge[T]) Destination added in v0.2.0

func (e Edge[T]) Destination() *Vertex[T]

Destination returns edge dest vertex

func (*Edge[T]) OtherVertex added in v0.2.0

func (e *Edge[T]) OtherVertex(v T) *Vertex[T]

OtherVertex accepts the label of one the vertices of the edge and returns the other one. If the input label doesn't match to either of the vertices, returns nil.

func (Edge[T]) Source added in v0.2.0

func (e Edge[T]) Source() *Vertex[T]

Source returns edge source vertex

func (*Edge[T]) Weight

func (e *Edge[T]) Weight() float64

Weight returns the weight of the edge.

type EdgeOptionFunc

type EdgeOptionFunc func(properties *EdgeProperties)

EdgeOptionFunc represent an alias of function type that modifies the specified edge properties.

func WithEdgeWeight

func WithEdgeWeight(weight float64) EdgeOptionFunc

WithEdgeWeight sets the edge weight for the specified edge properties in the returned EdgeOptionFunc.

type EdgeProperties

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

EdgeProperties represents the properties of an edge.

type Graph

type Graph[T comparable] interface {
	GraphType

	// AddEdge adds an edge from the vertex with the 'from' label to
	// the vertex with the 'to' label by appending the 'to' vertex to the
	// 'neighbors' slice of the 'from' vertex, in directed graph.
	//
	// In undirected graph, it also adds an edge from the vertex with
	// the 'to' label to the vertex with the 'from' label by appending
	// the 'from' vertex to the 'neighbors' slice of the 'to' vertex. it
	// means that it create the edges in both direction between the specified
	// vertices.
	//
	// This method accepts additional edge options such as weight and adds
	// them to the new edge.
	//
	//
	// It creates the input vertices if they don't exist in the graph.
	// If any of the specified vertices is nil, returns nil.
	// If edge already exist, returns error.
	AddEdge(from, to *Vertex[T], options ...EdgeOptionFunc) (*Edge[T], error)

	// GetAllEdges returns a slice of all edges connecting source vertex to
	// target vertex if such vertices exist in this graph.
	//
	// In directed graph, it returns a single edge.
	//
	// If any of the specified vertices is nil, returns nil.
	// If any of the vertices does not exist, returns nil.
	// If both vertices exist but no edges found, returns an empty set.
	GetAllEdges(from, to *Vertex[T]) []*Edge[T]

	// GetEdge returns an edge connecting source vertex to target vertex
	// if such vertices and such edge exist in this graph.
	//
	// In undirected graph, returns only the edge from the "from" vertex to
	// the "to" vertex.
	//
	// If any of the specified vertices is nil, returns nil.
	// If edge does not exist, returns nil.
	GetEdge(from, to *Vertex[T]) *Edge[T]

	// EdgesOf returns a slice of all edges touching the specified vertex.
	// If no edges are touching the specified vertex returns an empty slice.
	//
	// If the input vertex is nil, returns nil.
	// If the input vertex does not exist, returns nil.
	EdgesOf(v *Vertex[T]) []*Edge[T]

	// RemoveEdges removes input edges from the graph from the specified
	// slice of edges, if they exist. In undirected graph, removes edges
	// in both directions.
	RemoveEdges(edges ...*Edge[T])

	// AddVertexByLabel adds a new vertex with the given label to the graph.
	// Label of the vertex is a comparable type. This method also accepts the
	// vertex properties such as weight.
	//
	// If there is a vertex with the same label in the graph, returns nil.
	// Otherwise, returns the created vertex.
	AddVertexByLabel(label T, options ...VertexOptionFunc) *Vertex[T]

	// AddVertex adds the input vertex to the graph. It doesn't add
	// vertex to the graph if the input vertex label is already exists
	// in the graph.
	AddVertex(v *Vertex[T])

	// GetVertexByID returns the vertex with the input label.
	//
	// If vertex doesn't exist, returns nil.
	GetVertexByID(label T) *Vertex[T]

	// GetAllVerticesByID returns a slice of vertices with the specified label list.
	//
	// If vertex doesn't exist, doesn't add nil to the output list.
	GetAllVerticesByID(label ...T) []*Vertex[T]

	// GetAllVertices returns a slice of all existing vertices in the graph.
	GetAllVertices() []*Vertex[T]

	// RemoveVertices removes all the specified vertices from this graph including
	// all its touching edges if present.
	RemoveVertices(vertices ...*Vertex[T])

	// ContainsEdge returns 'true' if and only if this graph contains an edge
	// going from the source vertex to the target vertex.
	//
	// If any of the specified vertices does not exist in the graph, or if is nil,
	// returns 'false'.
	ContainsEdge(from, to *Vertex[T]) bool

	// ContainsVertex returns 'true' if this graph contains the specified vertex.
	//
	// If the specified vertex is nil, returns 'false'.
	ContainsVertex(v *Vertex[T]) bool
}

Graph defines methods for managing a graph with vertices and edges. It is the base interface in the graph hierarchy. Each graph object contains a set of vertices and edges.

Through generics, a graph can be typed to specific classes for vertices' label T.

func New

func New[T comparable](options ...GraphOptionFunc) Graph[T]

New creates a new instance of base graph that implemented the Graph interface.

type GraphOptionFunc

type GraphOptionFunc func(properties *GraphProperties)

GraphOptionFunc represent an alias of function type that modifies the specified graph properties.

func Acyclic

func Acyclic() GraphOptionFunc

Acyclic returns a GraphOptionFunc that modifies the specified graph properties. It sets the isAcyclic and isDirected to true. Only direct graph can be acyclic.

func Directed

func Directed() GraphOptionFunc

Directed returns a GraphOptionFunc that modifies the specified graph properties. It sets the isDirected to true.

func Weighted

func Weighted() GraphOptionFunc

Weighted returns a GraphOptionFunc that modifies the specified graph properties. It sets the isWeighted to true.

type GraphProperties

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

GraphProperties represents the properties of a graph.

type GraphType

type GraphType interface {
	// IsDirected returns true if the graph is directed, false otherwise.
	IsDirected() bool

	// IsAcyclic returns true if the graph is acyclic, false otherwise.
	IsAcyclic() bool

	// IsWeighted returns true if the graph is weighted, false otherwise.
	IsWeighted() bool
}

GraphType defines methods to determine the type of graph. A graph can have multiple types. e.g., a directed graph can be a weighted or acyclic.

type Vertex

type Vertex[T comparable] struct {
	// contains filtered or unexported fields
}

Vertex represents a node or point in a graph

func NewVertex

func NewVertex[T comparable](label T, options ...VertexOptionFunc) *Vertex[T]

func TopologySort

func TopologySort[T comparable](g Graph[T]) ([]*Vertex[T], error)

TopologySort performs a topological sort of the graph using Kahn's algorithm. If the sorted list of vertices does not contain all vertices in the graph, it means there is a cycle in the graph.

It returns error if it finds a cycle in the graph.

func (*Vertex[T]) Degree added in v0.2.0

func (v *Vertex[T]) Degree() int

Degree returns the total degree of the vertex which is the sum of in and out degrees.

func (*Vertex[T]) HasNeighbor

func (v *Vertex[T]) HasNeighbor(vertex *Vertex[T]) bool

HasNeighbor checks if the input vertex is the neighbor of the current node or not. It returns 'true' if it finds the input in the neighbors. Otherwise, returns 'false'.

func (*Vertex[T]) InDegree

func (v *Vertex[T]) InDegree() int

InDegree returns the number of incoming edges to the current vertex.

func (*Vertex[T]) Label

func (v *Vertex[T]) Label() T

Label returns vertex label.

func (*Vertex[T]) NeighborByLabel

func (v *Vertex[T]) NeighborByLabel(label T) *Vertex[T]

NeighborByLabel iterates over the neighbor slice and returns the vertex which its label is equal to the input label.

It returns nil if there is no neighbor with that label.

func (*Vertex[T]) Neighbors

func (v *Vertex[T]) Neighbors() []*Vertex[T]

Neighbors returns a copy of neighbor slice. If the caller changed the result slice, it won't impact the graph or the vertex.

func (*Vertex[T]) OutDegree

func (v *Vertex[T]) OutDegree() int

OutDegree returns the number of outgoing edges to the current vertex.

func (*Vertex[T]) Weight

func (v *Vertex[T]) Weight() float64

Weight returns vertex label.

type VertexOptionFunc

type VertexOptionFunc func(properties *VertexProperties)

VertexOptionFunc represent an alias of function type that modifies the specified vertex properties.

func WithVertexWeight

func WithVertexWeight(weight float64) VertexOptionFunc

WithVertexWeight sets the edge weight for the specified vertex properties in the returned VertexOptionFunc.

type VertexProperties

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

VertexProperties represents the properties of an edge.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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