Working on it more. :(

This commit is contained in:
Brian Buller 2017-08-17 13:12:16 -05:00
parent 5c8e8cba21
commit dc34a45b94
4 changed files with 110 additions and 93 deletions

Binary file not shown.

View File

@ -1,13 +1,26 @@
package main package main
import pov ".." import (
"fmt"
pov ".."
)
func main() { func main() {
g := pov.New() g := pov.New()
g.AddNode("sibling")
g.AddNode("x")
g.AddNode("parent") g.AddNode("parent")
g.AddArc("parent", "sibling")
g.AddArc("parent", "x") g.AddArc("parent", "x")
g.AddArc("x", "sib-2")
g.AddArc("x", "sib-3")
g.AddArc("x", "sib-4")
g.AddArc("parent", "sibling")
g.AddArc("sibling", "child-1")
g.AddArc("sibling", "child-2")
g.AddArc("sibling", "child-3")
g.AddArc("child-3", "grandchild-1")
g.AddArc("grandchild-1", "greatgrandchild-1")
pov.PrintGraph(g) pov.PrintGraph(g)
fmt.Println("== Change Root to child-3 ==")
n := g.ChangeRoot("parent", "child-3")
pov.PrintGraph(n)
} }

View File

@ -7,128 +7,128 @@ type Graph struct {
} }
func New() *Graph { func New() *Graph {
g := new(Graph) return new(Graph)
return g
} }
// GetNode returns the node from the graph with label lbl
func (g *Graph) GetNode(lbl string) *Node {
for i := range g.leaves {
if n := g.leaves[i].GetNode(lbl); n != nil {
return n
}
}
return nil
}
// AddNode adds a top level leaf with label lbl
func (g *Graph) AddNode(lbl string) { func (g *Graph) AddNode(lbl string) {
// Make sure that g doesn't already have node lbl
if g.getNode(lbl) != nil {
return
}
g.leaves = append(g.leaves, Node{label: lbl}) g.leaves = append(g.leaves, Node{label: lbl})
} }
// addRealNode adds the node n to the top level func (g *Graph) AddArc(fr, to string) {
func (g *Graph) addRealNode(n *Node) { if frN := g.getNode(fr); frN != nil {
g.leaves = append(g.leaves, *n) frN.AddNode(to)
}
// AddArc creates a new node after to named from
func (g *Graph) AddArc(from, to string) {
if n := g.GetNode(to); n != nil {
n.AddNode(from)
} }
} }
// ArcList returns a list of all arcs
func (g *Graph) ArcList() []string { func (g *Graph) ArcList() []string {
var ret []string var arcList []string
for i := range g.leaves { for i := range g.leaves {
ret = append(ret, g.leaves[i].ArcList()...) arcList = append(arcList, g.leaves[i].ArcList()...)
} }
return ret return arcList
} }
// ChangeRoot changes the graph from starting at oldRoot going to newRoot func (g *Graph) GetPath(fr, to string) []string {
func (g *Graph) ChangeRoot(oldRoot, newRoot string) *Graph { if frN := g.getNode(fr); frN != nil {
// First of all, find the newRoot node return frN.GetPath(to)
ret := New()
// The new graph will start with newRoot and have newRoot's leaves
var rt *Node
if rt = g.GetNode(newRoot); rt == nil {
return ret
} }
// It'll have one more leaf, it's parent node return []string{}
//rt.addRealNode(g.GetNode(oldRoot))
ret.addRealNode(rt)
return ret
} }
func (g *Graph) getPath(from, to string) []string { func (g *Graph) getNode(lbl string) *Node {
var ret []string for i := range g.leaves {
// Get the 'from' node if r := g.leaves[i].getNode(lbl); r != nil {
frNode := g.GetNode(from)
if frNode == nil {
// Couldn't find the starting node
return ret
}
// Just in case we got the same value for both
if from == to {
return []string{from}
}
// Found it
return frNode.getPath(to)
}
type Node struct {
label string
leaves []Node
}
func (n *Node) AddNode(lbl string) {
n.leaves = append(n.leaves, Node{label: lbl})
}
func (n *Node) addRealNode(nd *Node) {
n.leaves = append(n.leaves, *nd)
}
func (n *Node) GetNode(lbl string) *Node {
if n.label == lbl {
return n
}
for i := range n.leaves {
if r := n.leaves[i].GetNode(lbl); r != nil {
return r return r
} }
} }
return nil return nil
} }
// Return a graph from 'newRoot's POV
func (g *Graph) ChangeRoot(oldRoot, newRoot string) *Graph {
root := g.getNode(newRoot)
if root == nil {
return nil
}
ret := New()
//pth := g.GetPath(oldRoot, newRoot)
if root.parent != nil {
root.parent.removeLeaf(root.label)
root.parent.parent = root
root.addWholeNode(root.parent)
root.parent = nil
}
ret.addWholeNode(root)
return ret
}
func (g *Graph) addWholeNode(n *Node) {
g.leaves = append(g.leaves, *n)
}
type Node struct {
label string
leaves []Node
parent *Node
}
func (n *Node) AddNode(lbl string) {
nn := Node{label: lbl, parent: n}
n.leaves = append(n.leaves, nn)
}
func (n *Node) addWholeNode(nd *Node) {
n.leaves = append(n.leaves, *nd)
}
func (n *Node) removeLeaf(lbl string) {
for i := range n.leaves {
if n.leaves[i].label == lbl {
n.leaves = append(n.leaves[:i], n.leaves[i+1:]...)
}
}
}
func (n *Node) ArcList() []string { func (n *Node) ArcList() []string {
var ret []string var ret []string
for i := range n.leaves { for i := range n.leaves {
ret = append(ret, n.leaves[i].label+" -> "+n.label) // Append this arc
ret = append(ret, n.label+" -> "+n.leaves[i].label)
// Append all sub-arcs
ret = append(ret, n.leaves[i].ArcList()...) ret = append(ret, n.leaves[i].ArcList()...)
} }
return ret return ret
} }
func (n *Node) getPath(to string) []string { // GetPath returns a string slice of all leaves leading to 'to'
func (n *Node) GetPath(to string) []string {
ret := []string{n.label} ret := []string{n.label}
if n.label == to { if n.label == to {
return ret return ret
} }
var i int for i := range n.leaves {
var found bool if toN := n.leaves[i].getNode(to); toN != nil {
for i = range n.leaves { // This is the leaf to follow
if n.leaves[i].GetNode(to) != nil { return append(ret, n.leaves[i].GetPath(to)...)
found = true
break
} }
} }
if !found { // Couldn't get there
// We didn't find a path... :( return []string{}
return ret }
}
// n.leaves[i] should be the right leaf now // Returns the node with label lbl or nil
return append(ret, n.leaves[i].getPath(to)...) func (n *Node) getNode(lbl string) *Node {
if n.label == lbl {
return n
}
for i := range n.leaves {
if r := n.leaves[i].getNode(lbl); r != nil {
return r
}
}
return nil
} }

View File

@ -12,8 +12,12 @@ func PrintGraph(g *Graph) {
} }
func PrintNode(n *Node, lvl int) { func PrintNode(n *Node, lvl int) {
strings.Repeat(" ", lvl) fmt.Print(strings.Repeat(" ", lvl))
fmt.Println(n.label) if n.parent == nil {
fmt.Println("{label:", n.label, "}")
} else {
fmt.Println("{label:", n.label, ", parent:", n.parent.label, "}")
}
for i := range n.leaves { for i := range n.leaves {
PrintNode(&n.leaves[i], lvl+1) PrintNode(&n.leaves[i], lvl+1)
} }