graph.go 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. // Copyright ©2014 The gonum Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package graph
  5. // Node is a graph node. It returns a graph-unique integer ID.
  6. type Node interface {
  7. ID() int
  8. }
  9. // Edge is a graph edge. In directed graphs, the direction of the
  10. // edge is given from -> to, otherwise the edge is semantically
  11. // unordered.
  12. type Edge interface {
  13. From() Node
  14. To() Node
  15. Weight() float64
  16. }
  17. // Graph is a generalized graph.
  18. type Graph interface {
  19. // Has returns whether the node exists within the graph.
  20. Has(Node) bool
  21. // Nodes returns all the nodes in the graph.
  22. Nodes() []Node
  23. // From returns all nodes that can be reached directly
  24. // from the given node.
  25. From(Node) []Node
  26. // HasEdgeBeteen returns whether an edge exists between
  27. // nodes x and y without considering direction.
  28. HasEdgeBetween(x, y Node) bool
  29. // Edge returns the edge from u to v if such an edge
  30. // exists and nil otherwise. The node v must be directly
  31. // reachable from u as defined by the From method.
  32. Edge(u, v Node) Edge
  33. }
  34. // Undirected is an undirected graph.
  35. type Undirected interface {
  36. Graph
  37. // EdgeBetween returns the edge between nodes x and y.
  38. EdgeBetween(x, y Node) Edge
  39. }
  40. // Directed is a directed graph.
  41. type Directed interface {
  42. Graph
  43. // HasEdgeFromTo returns whether an edge exists
  44. // in the graph from u to v.
  45. HasEdgeFromTo(u, v Node) bool
  46. // To returns all nodes that can reach directly
  47. // to the given node.
  48. To(Node) []Node
  49. }
  50. // Weighter defines graphs that can report edge weights.
  51. type Weighter interface {
  52. // Weight returns the weight for the edge between
  53. // x and y if Edge(x, y) returns a non-nil Edge.
  54. // If x and y are the same node or there is no
  55. // joining edge between the two nodes the weight
  56. // value returned is implementation dependent.
  57. // Weight returns true if an edge exists between
  58. // x and y or if x and y have the same ID, false
  59. // otherwise.
  60. Weight(x, y Node) (w float64, ok bool)
  61. }
  62. // NodeAdder is an interface for adding arbitrary nodes to a graph.
  63. type NodeAdder interface {
  64. // NewNodeID returns a new unique arbitrary ID.
  65. NewNodeID() int
  66. // Adds a node to the graph. AddNode panics if
  67. // the added node ID matches an existing node ID.
  68. AddNode(Node)
  69. }
  70. // NodeRemover is an interface for removing nodes from a graph.
  71. type NodeRemover interface {
  72. // RemoveNode removes a node from the graph, as
  73. // well as any edges attached to it. If the node
  74. // is not in the graph it is a no-op.
  75. RemoveNode(Node)
  76. }
  77. // EdgeSetter is an interface for adding edges to a graph.
  78. type EdgeSetter interface {
  79. // SetEdge adds an edge from one node to another.
  80. // If the graph supports node addition the nodes
  81. // will be added if they do not exist, otherwise
  82. // SetEdge will panic.
  83. // If the IDs returned by e.From and e.To are
  84. // equal, SetEdge will panic.
  85. SetEdge(e Edge)
  86. }
  87. // EdgeRemover is an interface for removing nodes from a graph.
  88. type EdgeRemover interface {
  89. // RemoveEdge removes the given edge, leaving the
  90. // terminal nodes. If the edge does not exist it
  91. // is a no-op.
  92. RemoveEdge(Edge)
  93. }
  94. // Builder is a graph that can have nodes and edges added.
  95. type Builder interface {
  96. NodeAdder
  97. EdgeSetter
  98. }
  99. // UndirectedBuilder is an undirected graph builder.
  100. type UndirectedBuilder interface {
  101. Undirected
  102. Builder
  103. }
  104. // DirectedBuilder is a directed graph builder.
  105. type DirectedBuilder interface {
  106. Directed
  107. Builder
  108. }
  109. // Copy copies nodes and edges as undirected edges from the source to the destination
  110. // without first clearing the destination. Copy will panic if a node ID in the source
  111. // graph matches a node ID in the destination.
  112. //
  113. // If the source is undirected and the destination is directed both directions will
  114. // be present in the destination after the copy is complete.
  115. //
  116. // If the source is a directed graph, the destination is undirected, and a fundamental
  117. // cycle exists with two nodes where the edge weights differ, the resulting destination
  118. // graph's edge weight between those nodes is undefined. If there is a defined function
  119. // to resolve such conflicts, an Undirect may be used to do this.
  120. func Copy(dst Builder, src Graph) {
  121. nodes := src.Nodes()
  122. for _, n := range nodes {
  123. dst.AddNode(n)
  124. }
  125. for _, u := range nodes {
  126. for _, v := range src.From(u) {
  127. dst.SetEdge(src.Edge(u, v))
  128. }
  129. }
  130. }