aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/soniakeys/graph/fromlist.go
diff options
context:
space:
mode:
authorPetter Rasmussen2016-04-17 13:11:19 +0200
committerPetter Rasmussen2016-04-17 13:11:19 +0200
commit97981f7fd205353907135eacfc0e0ade24b88269 (patch)
tree1fdb61a7138642a1612bb201434e8ebda141cc8a /vendor/github.com/soniakeys/graph/fromlist.go
parent8de8e05c483c6b5f23b14742315f1860211dcef7 (diff)
parentb5eb2866cfceb69b0d4dd4948273d679a884fbb2 (diff)
downloadgdrive-97981f7fd205353907135eacfc0e0ade24b88269.tar.bz2
Merge pull request #140 from paulz/godep
add Go dependencies by godep
Diffstat (limited to 'vendor/github.com/soniakeys/graph/fromlist.go')
-rw-r--r--vendor/github.com/soniakeys/graph/fromlist.go418
1 files changed, 418 insertions, 0 deletions
diff --git a/vendor/github.com/soniakeys/graph/fromlist.go b/vendor/github.com/soniakeys/graph/fromlist.go
new file mode 100644
index 0000000..31d41fa
--- /dev/null
+++ b/vendor/github.com/soniakeys/graph/fromlist.go
@@ -0,0 +1,418 @@
+// Copyright 2014 Sonia Keys
+// License MIT: http://opensource.org/licenses/MIT
+
+package graph
+
+// FromList represents a rooted tree (or forest) where each node is associated
+// with a half arc identifying an arc "from" another node.
+//
+// Other terms for this data structure include "parent list",
+// "predecessor list", "in-tree", "inverse arborescence", and
+// "spaghetti stack."
+//
+// The Paths member represents the tree structure. Leaves and MaxLen are
+// not always needed. Where Leaves is used it serves as a bitmap where
+// Leaves.Bit(n) == 1 for each leaf n of the tree. Where MaxLen is used it is
+// provided primarily as a convenience for functions that might want to
+// anticipate the maximum path length that would be encountered traversing
+// the tree.
+//
+// Various graph search methods use a FromList to returns search results.
+// For a start node of a search, From will be -1 and Len will be 1. For other
+// nodes reached by the search, From represents a half arc in a path back to
+// start and Len represents the number of nodes in the path. For nodes not
+// reached by the search, From will be -1 and Len will be 0.
+//
+// A single FromList can also represent a forest. In this case paths from
+// all leaves do not return to a single root node, but multiple root nodes.
+//
+// While a FromList generally encodes a tree or forest, it is technically
+// possible to encode a cyclic graph. A number of FromList methods require
+// the receiver to be acyclic. Graph methods documented to return a tree or
+// forest will never return a cyclic FromList. In other cases however,
+// where a FromList is not known to by cyclic, the Cyclic method can be
+// useful to validate the acyclic property.
+type FromList struct {
+ Paths []PathEnd // tree representation
+ Leaves Bits // leaves of tree
+ MaxLen int // length of longest path, max of all PathEnd.Len values
+}
+
+// PathEnd associates a half arc and a path length.
+//
+// A PathEnd list is an element type of FromList.
+type PathEnd struct {
+ From NI // a "from" half arc, the node the arc comes from
+ Len int // number of nodes in path from start
+}
+
+// NewFromList creates a FromList object of given order.
+//
+// The Paths member is allocated to length n but there is no other
+// initialization.
+func NewFromList(n int) FromList {
+ return FromList{Paths: make([]PathEnd, n)}
+}
+
+// BoundsOk validates the "from" values in the list.
+//
+// Negative values are allowed as they indicate root nodes.
+//
+// BoundsOk returns true when all from values are less than len(t).
+// Otherwise it returns false and a node with a from value >= len(t).
+func (f FromList) BoundsOk() (ok bool, n NI) {
+ for n, e := range f.Paths {
+ if int(e.From) >= len(f.Paths) {
+ return false, NI(n)
+ }
+ }
+ return true, -1
+}
+
+// CommonStart returns the common start node of minimal paths to a and b.
+//
+// It returns -1 if a and b cannot be traced back to a common node.
+//
+// The method relies on populated PathEnd.Len members. Use RecalcLen if
+// the Len members are not known to be present and correct.
+func (f FromList) CommonStart(a, b NI) NI {
+ p := f.Paths
+ if p[a].Len < p[b].Len {
+ a, b = b, a
+ }
+ for bl := p[b].Len; p[a].Len > bl; {
+ a = p[a].From
+ if a < 0 {
+ return -1
+ }
+ }
+ for a != b {
+ a = p[a].From
+ if a < 0 {
+ return -1
+ }
+ b = p[b].From
+ }
+ return a
+}
+
+// Cyclic determines if f contains a cycle, a non-empty path from a node
+// back to itself.
+//
+// Cyclic returns true if g contains at least one cycle. It also returns
+// an example of a node involved in a cycle.
+//
+// Cyclic returns (false, -1) in the normal case where f is acyclic.
+// Note that the bool is not an "ok" return. A cyclic FromList is usually
+// not okay.
+func (f FromList) Cyclic() (cyclic bool, n NI) {
+ var vis Bits
+ p := f.Paths
+ for i := range p {
+ var path Bits
+ for n := NI(i); vis.Bit(n) == 0; {
+ vis.SetBit(n, 1)
+ path.SetBit(n, 1)
+ if n = p[n].From; n < 0 {
+ break
+ }
+ if path.Bit(n) == 1 {
+ return true, n
+ }
+ }
+ }
+ return false, -1
+}
+
+// IsolatedNodeBits returns a bitmap of isolated nodes in receiver graph f.
+//
+// An isolated node is one with no arcs going to or from it.
+func (f FromList) IsolatedNodes() (iso Bits) {
+ p := f.Paths
+ iso.SetAll(len(p))
+ for n, e := range p {
+ if e.From >= 0 {
+ iso.SetBit(NI(n), 0)
+ iso.SetBit(e.From, 0)
+ }
+ }
+ return
+}
+
+// PathTo decodes a FromList, recovering a single path.
+//
+// The path is returned as a list of nodes where the first element will be
+// a root node and the last element will be the specified end node.
+//
+// Only the Paths member of the receiver is used. Other members of the
+// FromList do not need to be valid, however the MaxLen member can be useful
+// for allocating argument p.
+//
+// Argument p can provide the result slice. If p has capacity for the result
+// it will be used, otherwise a new slice is created for the result.
+//
+// See also function PathTo.
+func (f FromList) PathTo(end NI, p []NI) []NI {
+ return PathTo(f.Paths, end, p)
+}
+
+// PathTo decodes a single path from a PathEnd list.
+//
+// A PathEnd list is the main data representation in a FromList. See FromList.
+//
+// PathTo returns a list of nodes where the first element will be
+// a root node and the last element will be the specified end node.
+//
+// Argument p can provide the result slice. If p has capacity for the result
+// it will be used, otherwise a new slice is created for the result.
+//
+// See also method FromList.PathTo.
+func PathTo(paths []PathEnd, end NI, p []NI) []NI {
+ n := paths[end].Len
+ if n == 0 {
+ return nil
+ }
+ if cap(p) >= n {
+ p = p[:n]
+ } else {
+ p = make([]NI, n)
+ }
+ for {
+ n--
+ p[n] = end
+ if n == 0 {
+ return p
+ }
+ end = paths[end].From
+ }
+}
+
+// Preorder traverses f calling Visitor v in preorder.
+//
+// Nodes are visited in order such that for any node n with from node fr,
+// fr is visited before n. Where f represents a tree, the visit ordering
+// corresponds to a preordering, or depth first traversal of the tree.
+// Where f represents a forest, the preorderings of the trees can be
+// intermingled.
+//
+// Leaves must be set correctly first. Use RecalcLeaves if leaves are not
+// known to be set correctly. FromList f cannot be cyclic.
+//
+// Traversal continues while v returns true. It terminates if v returns false.
+// Preorder returns true if it completes without v returning false. Preorder
+// returns false if traversal is terminated by v returning false.
+func (f FromList) Preorder(v OkNodeVisitor) bool {
+ p := f.Paths
+ var done Bits
+ var df func(NI) bool
+ df = func(n NI) bool {
+ done.SetBit(n, 1)
+ if fr := p[n].From; fr >= 0 && done.Bit(fr) == 0 {
+ df(fr)
+ }
+ return v(n)
+ }
+ for n := range f.Paths {
+ p[n].Len = 0
+ }
+ return f.Leaves.Iterate(func(n NI) bool {
+ return df(n)
+ })
+}
+
+// RecalcLeaves recomputes the Leaves member of f.
+func (f *FromList) RecalcLeaves() {
+ p := f.Paths
+ lv := &f.Leaves
+ lv.SetAll(len(p))
+ for n := range f.Paths {
+ if fr := p[n].From; fr >= 0 {
+ lv.SetBit(fr, 0)
+ }
+ }
+}
+
+// RecalcLen recomputes Len for each path end, and recomputes MaxLen.
+//
+// RecalcLen relies on the Leaves member being valid. If it is not known
+// to be valid, call RecalcLeaves before calling RecalcLen.
+func (f *FromList) RecalcLen() {
+ p := f.Paths
+ var setLen func(NI) int
+ setLen = func(n NI) int {
+ switch {
+ case p[n].Len > 0:
+ return p[n].Len
+ case p[n].From < 0:
+ p[n].Len = 1
+ return 1
+ }
+ l := 1 + setLen(p[n].From)
+ p[n].Len = l
+ return l
+ }
+ for n := range f.Paths {
+ p[n].Len = 0
+ }
+ f.MaxLen = 0
+ f.Leaves.Iterate(func(n NI) bool {
+ if l := setLen(NI(n)); l > f.MaxLen {
+ f.MaxLen = l
+ }
+ return true
+ })
+}
+
+// ReRoot reorients the tree containing n to make n the root node.
+//
+// It keeps the tree connected by "reversing" the path from n to the old root.
+//
+// After ReRoot, the Leaves and Len members are invalid.
+// Call RecalcLeaves or RecalcLen as needed.
+func (f *FromList) ReRoot(n NI) {
+ p := f.Paths
+ fr := p[n].From
+ if fr < 0 {
+ return
+ }
+ p[n].From = -1
+ for {
+ ff := p[fr].From
+ p[fr].From = n
+ if ff < 0 {
+ return
+ }
+ n = fr
+ fr = ff
+ }
+}
+
+// Root finds the root of a node in a FromList.
+func (f FromList) Root(n NI) NI {
+ for p := f.Paths; ; {
+ fr := p[n].From
+ if fr < 0 {
+ return n
+ }
+ n = fr
+ }
+}
+
+// Transpose constructs the directed graph corresponding to FromList f
+// but with arcs in the opposite direction. That is, from roots toward leaves.
+//
+// The method relies only on the From member of f.Paths. Other members of
+// the FromList are not used.
+//
+// See FromList.TransposeRoots for a version that also accumulates and returns
+// information about the roots.
+func (f FromList) Transpose() Directed {
+ g := make(AdjacencyList, len(f.Paths))
+ for n, p := range f.Paths {
+ if p.From == -1 {
+ continue
+ }
+ g[p.From] = append(g[p.From], NI(n))
+ }
+ return Directed{g}
+}
+
+// TransposeLabeled constructs the directed labeled graph corresponding
+// to FromList f but with arcs in the opposite direction. That is, from
+// roots toward leaves.
+//
+// The argument labels can be nil. In this case labels are generated matching
+// the path indexes. This corresponds to the "to", or child node.
+//
+// If labels is non-nil, it must be the same length as f.Paths and is used
+// to look up label numbers by the path index.
+//
+// The method relies only on the From member of f.Paths. Other members of
+// the FromList are not used.
+//
+// See FromList.TransposeLabeledRoots for a version that also accumulates
+// and returns information about the roots.
+func (f FromList) TransposeLabeled(labels []LI) LabeledDirected {
+ g := make(LabeledAdjacencyList, len(f.Paths))
+ for n, p := range f.Paths {
+ if p.From == -1 {
+ continue
+ }
+ l := LI(n)
+ if labels != nil {
+ l = labels[n]
+ }
+ g[p.From] = append(g[p.From], Half{NI(n), l})
+ }
+ return LabeledDirected{g}
+}
+
+// TransposeLabeledRoots constructs the labeled directed graph corresponding
+// to FromList f but with arcs in the opposite direction. That is, from
+// roots toward leaves.
+//
+// TransposeLabeledRoots also returns a count of roots of the resulting forest
+// and a bitmap of the roots.
+//
+// The argument labels can be nil. In this case labels are generated matching
+// the path indexes. This corresponds to the "to", or child node.
+//
+// If labels is non-nil, it must be the same length as t.Paths and is used
+// to look up label numbers by the path index.
+//
+// The method relies only on the From member of f.Paths. Other members of
+// the FromList are not used.
+//
+// See FromList.TransposeLabeled for a simpler verstion that returns the
+// forest only.
+func (f FromList) TransposeLabeledRoots(labels []LI) (forest LabeledDirected, nRoots int, roots Bits) {
+ p := f.Paths
+ nRoots = len(p)
+ roots.SetAll(len(p))
+ g := make(LabeledAdjacencyList, len(p))
+ for i, p := range f.Paths {
+ if p.From == -1 {
+ continue
+ }
+ l := LI(i)
+ if labels != nil {
+ l = labels[i]
+ }
+ n := NI(i)
+ g[p.From] = append(g[p.From], Half{n, l})
+ if roots.Bit(n) == 1 {
+ roots.SetBit(n, 0)
+ nRoots--
+ }
+ }
+ return LabeledDirected{g}, nRoots, roots
+}
+
+// TransposeRoots constructs the directed graph corresponding to FromList f
+// but with arcs in the opposite direction. That is, from roots toward leaves.
+//
+// TransposeRoots also returns a count of roots of the resulting forest and
+// a bitmap of the roots.
+//
+// The method relies only on the From member of f.Paths. Other members of
+// the FromList are not used.
+//
+// See FromList.Transpose for a simpler verstion that returns the forest only.
+func (f FromList) TransposeRoots() (forest Directed, nRoots int, roots Bits) {
+ p := f.Paths
+ nRoots = len(p)
+ roots.SetAll(len(p))
+ g := make(AdjacencyList, len(p))
+ for i, e := range p {
+ if e.From == -1 {
+ continue
+ }
+ n := NI(i)
+ g[e.From] = append(g[e.From], n)
+ if roots.Bit(n) == 1 {
+ roots.SetBit(n, 0)
+ nRoots--
+ }
+ }
+ return Directed{g}, nRoots, roots
+}