本文整理汇总了Golang中github.com/gonum/graph.Graph.Edge方法的典型用法代码示例。如果您正苦于以下问题:Golang Graph.Edge方法的具体用法?Golang Graph.Edge怎么用?Golang Graph.Edge使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类github.com/gonum/graph.Graph
的用法示例。
在下文中一共展示了Graph.Edge方法的9个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Golang代码示例。
示例1: visit
func (d *DepthFirst) visit(g graph.Graph, t graph.Node, until func(graph.Node) bool) graph.Node {
if until != nil && until(t) {
return t
}
d.stack.Push(t)
children := osgraph.ByID(g.From(t))
sort.Sort(children)
for _, n := range children {
if d.EdgeFilter != nil && !d.EdgeFilter(g.Edge(t, n)) {
continue
}
if d.visited(n.ID()) {
continue
}
if d.Visit != nil {
d.Visit(t, n)
}
result := d.visit(g, n, until)
if result != nil {
return result
}
}
d.stack.Pop()
return nil
}
示例2: Walk
// Walk performs a depth-first traversal of the graph g starting from the given node,
// depending on the the EdgeFilter field and the until parameter if they are non-nil. The
// traversal follows edges for which EdgeFilter(edge) is true and returns the first node
// for which until(node) is true. During the traversal, if the Visit field is non-nil, it
// is called with the nodes joined by each followed edge.
func (d *DepthFirst) Walk(g graph.Graph, from graph.Node, until func(graph.Node) bool) graph.Node {
if d.visited == nil {
d.visited = &intsets.Sparse{}
}
d.stack.Push(from)
d.visited.Insert(from.ID())
for d.stack.Len() > 0 {
t := d.stack.Pop()
if until != nil && until(t) {
return t
}
for _, n := range g.From(t) {
if d.EdgeFilter != nil && !d.EdgeFilter(g.Edge(t, n)) {
continue
}
if d.visited.Has(n.ID()) {
continue
}
if d.Visit != nil {
d.Visit(t, n)
}
d.visited.Insert(n.ID())
d.stack.Push(n)
}
}
return nil
}
示例3: UniformCost
// UniformCost returns a Weighting that returns an edge cost of 1 for existing
// edges, zero for node identity and Inf for otherwise absent edges.
func UniformCost(g graph.Graph) Weighting {
return func(x, y graph.Node) (w float64, ok bool) {
xid := x.ID()
yid := y.ID()
if xid == yid {
return 0, true
}
if e := g.Edge(x, y); e != nil {
return 1, true
}
return math.Inf(1), false
}
}
示例4: BellmanFordFrom
// BellmanFordFrom returns a shortest-path tree for a shortest path from u to all nodes in
// the graph g, or false indicating that a negative cycle exists in the graph. If the graph
// does not implement graph.Weighter, graph.UniformCost is used.
//
// The time complexity of BellmanFordFrom is O(|V|.|E|).
func BellmanFordFrom(u graph.Node, g graph.Graph) (path Shortest, ok bool) {
if !g.Has(u) {
return Shortest{from: u}, true
}
var weight graph.WeightFunc
if g, ok := g.(graph.Weighter); ok {
weight = g.Weight
} else {
weight = graph.UniformCost
}
nodes := g.Nodes()
path = newShortestFrom(u, nodes)
path.dist[path.indexOf[u.ID()]] = 0
// TODO(kortschak): Consider adding further optimisations
// from http://arxiv.org/abs/1111.5414.
for i := 1; i < len(nodes); i++ {
changed := false
for j, u := range nodes {
for _, v := range g.From(u) {
k := path.indexOf[v.ID()]
joint := path.dist[j] + weight(g.Edge(u, v))
if joint < path.dist[k] {
path.set(k, joint, j)
changed = true
}
}
}
if !changed {
break
}
}
for j, u := range nodes {
for _, v := range g.From(u) {
k := path.indexOf[v.ID()]
if path.dist[j]+weight(g.Edge(u, v)) < path.dist[k] {
return path, false
}
}
}
return path, true
}
示例5: FloydWarshall
// FloydWarshall returns a shortest-path tree for the graph g or false indicating
// that a negative cycle exists in the graph. If the graph does not implement
// graph.Weighter, graph.UniformCost is used.
//
// The time complexity of FloydWarshall is O(|V|^3).
func FloydWarshall(g graph.Graph) (paths AllShortest, ok bool) {
var weight graph.WeightFunc
if g, ok := g.(graph.Weighter); ok {
weight = g.Weight
} else {
weight = graph.UniformCost
}
nodes := g.Nodes()
paths = newAllShortest(nodes, true)
for i, u := range nodes {
paths.dist.Set(i, i, 0)
for _, v := range g.From(u) {
j := paths.indexOf[v.ID()]
paths.set(i, j, weight(g.Edge(u, v)), j)
}
}
for k := range nodes {
for i := range nodes {
for j := range nodes {
ij := paths.dist.At(i, j)
joint := paths.dist.At(i, k) + paths.dist.At(k, j)
if ij > joint {
paths.set(i, j, joint, paths.at(i, k)...)
} else if ij-joint == 0 {
paths.add(i, j, paths.at(i, k)...)
}
}
}
}
ok = true
for i := range nodes {
if paths.dist.At(i, i) < 0 {
ok = false
break
}
}
return paths, ok
}
示例6: dijkstraAllPaths
// dijkstraAllPaths is the all-paths implementation of Dijkstra. It is shared
// between DijkstraAllPaths and JohnsonAllPaths to avoid repeated allocation
// of the nodes slice and the indexOf map. It returns nothing, but stores the
// result of the work in the paths parameter which is a reference type.
func dijkstraAllPaths(g graph.Graph, paths AllShortest) {
var weight graph.WeightFunc
if g, ok := g.(graph.Weighter); ok {
weight = g.Weight
} else {
weight = graph.UniformCost
}
var Q priorityQueue
for i, u := range paths.nodes {
// Dijkstra's algorithm here is implemented essentially as
// described in Function B.2 in figure 6 of UTCS Technical
// Report TR-07-54 with the addition of handling multiple
// co-equal paths.
//
// http://www.cs.utexas.edu/ftp/techreports/tr07-54.pdf
// Q must be empty at this point.
heap.Push(&Q, distanceNode{node: u, dist: 0})
for Q.Len() != 0 {
mid := heap.Pop(&Q).(distanceNode)
k := paths.indexOf[mid.node.ID()]
if mid.dist < paths.dist.At(i, k) {
paths.dist.Set(i, k, mid.dist)
}
for _, v := range g.From(mid.node) {
j := paths.indexOf[v.ID()]
w := weight(g.Edge(mid.node, v))
if w < 0 {
panic("dijkstra: negative edge weight")
}
joint := paths.dist.At(i, k) + w
if joint < paths.dist.At(i, j) {
heap.Push(&Q, distanceNode{node: v, dist: joint})
paths.set(i, j, joint, k)
} else if joint == paths.dist.At(i, j) {
paths.add(i, j, k)
}
}
}
}
}
示例7: DijkstraFrom
// DijkstraFrom returns a shortest-path tree for a shortest path from u to all nodes in
// the graph g. If the graph does not implement graph.Weighter, graph.UniformCost is used.
// DijkstraFrom will panic if g has a u-reachable negative edge weight.
//
// The time complexity of DijkstrFrom is O(|E|+|V|.log|V|).
func DijkstraFrom(u graph.Node, g graph.Graph) Shortest {
if !g.Has(u) {
return Shortest{from: u}
}
var weight graph.WeightFunc
if g, ok := g.(graph.Weighter); ok {
weight = g.Weight
} else {
weight = graph.UniformCost
}
nodes := g.Nodes()
path := newShortestFrom(u, nodes)
// Dijkstra's algorithm here is implemented essentially as
// described in Function B.2 in figure 6 of UTCS Technical
// Report TR-07-54.
//
// http://www.cs.utexas.edu/ftp/techreports/tr07-54.pdf
Q := priorityQueue{{node: u, dist: 0}}
for Q.Len() != 0 {
mid := heap.Pop(&Q).(distanceNode)
k := path.indexOf[mid.node.ID()]
if mid.dist < path.dist[k] {
path.dist[k] = mid.dist
}
for _, v := range g.From(mid.node) {
j := path.indexOf[v.ID()]
w := weight(g.Edge(mid.node, v))
if w < 0 {
panic("dijkstra: negative edge weight")
}
joint := path.dist[k] + w
if joint < path.dist[j] {
heap.Push(&Q, distanceNode{node: v, dist: joint})
path.set(j, joint, k)
}
}
}
return path
}
示例8: print
func (p *printer) print(g graph.Graph, name string, needsIndent, isSubgraph bool) error {
nodes := g.Nodes()
sort.Sort(ordered.ByID(nodes))
p.buf.WriteString(p.prefix)
if needsIndent {
for i := 0; i < p.depth; i++ {
p.buf.WriteString(p.indent)
}
}
_, isDirected := g.(graph.Directed)
if isSubgraph {
p.buf.WriteString("sub")
} else if isDirected {
p.buf.WriteString("di")
}
p.buf.WriteString("graph")
if name == "" {
if g, ok := g.(Graph); ok {
name = g.DOTID()
}
}
if name != "" {
p.buf.WriteByte(' ')
p.buf.WriteString(name)
}
p.openBlock(" {")
if a, ok := g.(Attributers); ok {
p.writeAttributeComplex(a)
}
if s, ok := g.(Structurer); ok {
for _, g := range s.Structure() {
_, subIsDirected := g.(graph.Directed)
if subIsDirected != isDirected {
return errors.New("dot: mismatched graph type")
}
p.buf.WriteByte('\n')
p.print(g, g.DOTID(), true, true)
}
}
havePrintedNodeHeader := false
for _, n := range nodes {
if s, ok := n.(Subgrapher); ok {
// If the node is not linked to any other node
// the graph needs to be written now.
if len(g.From(n)) == 0 {
g := s.Subgraph()
_, subIsDirected := g.(graph.Directed)
if subIsDirected != isDirected {
return errors.New("dot: mismatched graph type")
}
if !havePrintedNodeHeader {
p.newline()
p.buf.WriteString("// Node definitions.")
havePrintedNodeHeader = true
}
p.newline()
p.print(g, graphID(g, n), false, true)
}
continue
}
if !havePrintedNodeHeader {
p.newline()
p.buf.WriteString("// Node definitions.")
havePrintedNodeHeader = true
}
p.newline()
p.writeNode(n)
if a, ok := n.(Attributer); ok {
p.writeAttributeList(a)
}
p.buf.WriteByte(';')
}
havePrintedEdgeHeader := false
for _, n := range nodes {
to := g.From(n)
sort.Sort(ordered.ByID(to))
for _, t := range to {
if isDirected {
if p.visited[edge{inGraph: name, from: n.ID(), to: t.ID()}] {
continue
}
p.visited[edge{inGraph: name, from: n.ID(), to: t.ID()}] = true
} else {
if p.visited[edge{inGraph: name, from: n.ID(), to: t.ID()}] {
continue
}
p.visited[edge{inGraph: name, from: n.ID(), to: t.ID()}] = true
p.visited[edge{inGraph: name, from: t.ID(), to: n.ID()}] = true
}
if !havePrintedEdgeHeader {
p.buf.WriteByte('\n')
p.buf.WriteString(strings.TrimRight(p.prefix, " \t\xa0")) // Trim whitespace suffix.
p.newline()
p.buf.WriteString("// Edge definitions.")
//.........这里部分代码省略.........
示例9: BFSTree
// Builds a BFS tree (as a directed graph) from the given graph and start node.
func BFSTree(g graph.Graph, start graph.Node) *simple.DirectedGraph {
if !g.Has(start) {
panic(fmt.Sprintf("BFSTree: Start node %r not in graph %r", start, g))
}
ret := simple.NewDirectedGraph(0.0, math.Inf(1))
seen := make(map[int]bool)
q := queue.New()
q.Add(start)
ret.AddNode(simple.Node(start.ID()))
for q.Length() > 0 {
node := q.Peek().(graph.Node)
q.Remove()
for _, neighbor := range g.From(node) {
if !seen[neighbor.ID()] {
seen[neighbor.ID()] = true
ret.AddNode(simple.Node(neighbor.ID()))
ret.SetEdge(simple.Edge{F: simple.Node(node.ID()), T: simple.Node(neighbor.ID()), W: g.Edge(node, neighbor).Weight()})
q.Add(neighbor)
}
}
}
return ret
}