本文整理汇总了Golang中github.com/gonum/graph.Graph.Nodes方法的典型用法代码示例。如果您正苦于以下问题:Golang Graph.Nodes方法的具体用法?Golang Graph.Nodes怎么用?Golang Graph.Nodes使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类github.com/gonum/graph.Graph
的用法示例。
在下文中一共展示了Graph.Nodes方法的13个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Golang代码示例。
示例1: 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, 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 Weighting
if wg, ok := g.(graph.Weighter); ok {
weight = wg.Weight
} else {
weight = UniformCost(g)
}
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()]
w, ok := weight(u, v)
if !ok {
panic("bellman-ford: unexpected invalid weight")
}
joint := path.dist[j] + w
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()]
w, ok := weight(u, v)
if !ok {
panic("bellman-ford: unexpected invalid weight")
}
if path.dist[j]+w < path.dist[k] {
return path, false
}
}
}
return path, true
}
示例2: Dominators
// PostDominatores returns all dominators for all nodes in g. It does not
// prune for strict post-dominators, immediate dominators etc.
//
// A dominates B if and only if the only path through B travels through A.
func Dominators(start graph.Node, g graph.Graph) map[int]set.Nodes {
allNodes := make(set.Nodes)
nlist := g.Nodes()
dominators := make(map[int]set.Nodes, len(nlist))
for _, node := range nlist {
allNodes.Add(node)
}
var to func(graph.Node) []graph.Node
switch g := g.(type) {
case graph.Directed:
to = g.To
default:
to = g.From
}
for _, node := range nlist {
dominators[node.ID()] = make(set.Nodes)
if node.ID() == start.ID() {
dominators[node.ID()].Add(start)
} else {
dominators[node.ID()].Copy(allNodes)
}
}
for somethingChanged := true; somethingChanged; {
somethingChanged = false
for _, node := range nlist {
if node.ID() == start.ID() {
continue
}
preds := to(node)
if len(preds) == 0 {
continue
}
tmp := make(set.Nodes).Copy(dominators[preds[0].ID()])
for _, pred := range preds[1:] {
tmp.Intersect(tmp, dominators[pred.ID()])
}
dom := make(set.Nodes)
dom.Add(node)
dom.Union(dom, tmp)
if !set.Equal(dom, dominators[node.ID()]) {
dominators[node.ID()] = dom
somethingChanged = true
}
}
}
return dominators
}
示例3: brandes
// brandes is the common code for Betweenness and EdgeBetweenness. It corresponds
// to algorithm 1 in http://algo.uni-konstanz.de/publications/b-vspbc-08.pdf with
// the accumulation loop provided by the accumulate closure.
func brandes(g graph.Graph, accumulate func(s graph.Node, stack internal.NodeStack, p map[int][]graph.Node, delta, sigma map[int]float64)) {
var (
nodes = g.Nodes()
stack internal.NodeStack
p = make(map[int][]graph.Node, len(nodes))
sigma = make(map[int]float64, len(nodes))
d = make(map[int]int, len(nodes))
delta = make(map[int]float64, len(nodes))
queue internal.NodeQueue
)
for _, s := range nodes {
stack = stack[:0]
for _, w := range nodes {
p[w.ID()] = p[w.ID()][:0]
}
for _, t := range nodes {
sigma[t.ID()] = 0
d[t.ID()] = -1
}
sigma[s.ID()] = 1
d[s.ID()] = 0
queue.Enqueue(s)
for queue.Len() != 0 {
v := queue.Dequeue()
stack.Push(v)
for _, w := range g.From(v) {
// w found for the first time?
if d[w.ID()] < 0 {
queue.Enqueue(w)
d[w.ID()] = d[v.ID()] + 1
}
// shortest path to w via v?
if d[w.ID()] == d[v.ID()]+1 {
sigma[w.ID()] += sigma[v.ID()]
p[w.ID()] = append(p[w.ID()], v)
}
}
}
for _, v := range nodes {
delta[v.ID()] = 0
}
// S returns vertices in order of non-increasing distance from s
accumulate(s, stack, p, delta, sigma)
}
}
示例4: 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, UniformCost is used.
//
// The time complexity of FloydWarshall is O(|V|^3).
func FloydWarshall(g graph.Graph) (paths AllShortest, ok bool) {
var weight Weighting
if wg, ok := g.(graph.Weighter); ok {
weight = wg.Weight
} else {
weight = UniformCost(g)
}
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()]
w, ok := weight(u, v)
if !ok {
panic("floyd-warshall: unexpected invalid weight")
}
paths.set(i, j, w, 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
}
示例5: PostDominators
// PostDominatores returns all post-dominators for all nodes in g. It does not
// prune for strict post-dominators, immediate post-dominators etc.
//
// A post-dominates B if and only if all paths from B travel through A.
func PostDominators(end graph.Node, g graph.Graph) map[int]set.Nodes {
allNodes := make(set.Nodes)
nlist := g.Nodes()
dominators := make(map[int]set.Nodes, len(nlist))
for _, node := range nlist {
allNodes.Add(node)
}
for _, node := range nlist {
dominators[node.ID()] = make(set.Nodes)
if node.ID() == end.ID() {
dominators[node.ID()].Add(end)
} else {
dominators[node.ID()].Copy(allNodes)
}
}
for somethingChanged := true; somethingChanged; {
somethingChanged = false
for _, node := range nlist {
if node.ID() == end.ID() {
continue
}
succs := g.From(node)
if len(succs) == 0 {
continue
}
tmp := make(set.Nodes).Copy(dominators[succs[0].ID()])
for _, succ := range succs[1:] {
tmp.Intersect(tmp, dominators[succ.ID()])
}
dom := make(set.Nodes)
dom.Add(node)
dom.Union(dom, tmp)
if !set.Equal(dom, dominators[node.ID()]) {
dominators[node.ID()] = dom
somethingChanged = true
}
}
}
return dominators
}
示例6: 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, 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 Weighting
if wg, ok := g.(graph.Weighter); ok {
weight = wg.Weight
} else {
weight = UniformCost(g)
}
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, ok := weight(mid.node, v)
if !ok {
panic("dijkstra: unexpected invalid weight")
}
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
}
示例7: Farness
// Farness returns the farness for nodes in the graph g used to construct
// the given shortest paths.
//
// F(v) = \sum_u d(u,v)
//
// For directed graphs the incoming paths are used. Infinite distances are
// not considered.
func Farness(g graph.Graph, p path.AllShortest) map[int]float64 {
nodes := g.Nodes()
f := make(map[int]float64, len(nodes))
for _, u := range nodes {
var sum float64
for _, v := range nodes {
// The ordering here is not relevant for
// undirected graphs, but we make sure we
// are counting incoming paths.
d := p.Weight(v, u)
if math.IsInf(d, 0) {
continue
}
sum += d
}
f[u.ID()] = sum
}
return f
}
示例8: 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
}
示例9: Harmonic
// Harmonic returns the harmonic centrality for nodes in the graph g used to
// construct the given shortest paths.
//
// H(v)= \sum_{u ≠ v} 1 / d(u,v)
//
// For directed graphs the incoming paths are used. Infinite distances are
// not considered.
func Harmonic(g graph.Graph, p path.AllShortest) map[int]float64 {
nodes := g.Nodes()
h := make(map[int]float64, len(nodes))
for i, u := range nodes {
var sum float64
for j, v := range nodes {
// The ordering here is not relevant for
// undirected graphs, but we make sure we
// are counting incoming paths.
d := p.Weight(v, u)
if math.IsInf(d, 0) {
continue
}
if i != j {
sum += 1 / d
}
}
h[u.ID()] = sum
}
return h
}
示例10: 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.")
//.........这里部分代码省略.........
示例11: NewDStarLite
// NewDStarLite returns a new DStarLite planner for the path from s to t in g using the
// heuristic h. The world model, m, is used to store shortest path information during path
// planning. The world model must be an empty graph when NewDStarLite is called.
//
// If h is nil, the DStarLite will use the g.HeuristicCost method if g implements
// path.HeuristicCoster, falling back to path.NullHeuristic otherwise. If the graph does not
// implement graph.Weighter, path.UniformCost is used. NewDStarLite will panic if g has
// a negative edge weight.
func NewDStarLite(s, t graph.Node, g graph.Graph, h path.Heuristic, m WorldModel) *DStarLite {
/*
procedure Initialize()
{02”} U = ∅;
{03”} k_m = 0;
{04”} for all s ∈ S rhs(s) = g(s) = ∞;
{05”} rhs(s_goal) = 0;
{06”} U.Insert(s_goal, [h(s_start, s_goal); 0]);
*/
d := &DStarLite{
s: newDStarLiteNode(s),
t: newDStarLiteNode(t), // badKey is overwritten below.
model: m,
heuristic: h,
}
d.t.rhs = 0
/*
procedure Main()
{29”} s_last = s_start;
{30”} Initialize();
*/
d.last = d.s
if wg, ok := g.(graph.Weighter); ok {
d.weight = wg.Weight
} else {
d.weight = path.UniformCost(g)
}
if d.heuristic == nil {
if g, ok := g.(path.HeuristicCoster); ok {
d.heuristic = g.HeuristicCost
} else {
d.heuristic = path.NullHeuristic
}
}
d.queue.insert(d.t, key{d.heuristic(s, t), 0})
for _, n := range g.Nodes() {
switch n.ID() {
case d.s.ID():
d.model.AddNode(d.s)
case d.t.ID():
d.model.AddNode(d.t)
default:
d.model.AddNode(newDStarLiteNode(n))
}
}
for _, u := range d.model.Nodes() {
for _, v := range g.From(u) {
w := edgeWeight(d.weight, u, v)
if w < 0 {
panic("D* Lite: negative edge weight")
}
d.model.SetEdge(concrete.Edge{F: u, T: d.model.Node(v.ID()), W: w})
}
}
/*
procedure Main()
{31”} ComputeShortestPath();
*/
d.findShortestPath()
return d
}
示例12: DijkstraAllPaths
// DijkstraAllPaths returns a shortest-path tree for shortest paths in the graph g.
// If the graph does not implement graph.Weighter, UniformCost is used.
// DijkstraAllPaths will panic if g has a negative edge weight.
//
// The time complexity of DijkstrAllPaths is O(|V|.|E|+|V|^2.log|V|).
func DijkstraAllPaths(g graph.Graph) (paths AllShortest) {
paths = newAllShortest(g.Nodes(), false)
dijkstraAllPaths(g, paths)
return paths
}
示例13: Betweenness
// Betweenness returns the non-zero betweenness centrality for nodes in the unweighted graph g.
//
// C_B(v) = \sum_{s ≠ v ≠ t ∈ V} (\sigma_{st}(v) / \sigma_{st})
//
// where \sigma_{st} and \sigma_{st}(v) are the number of shortest paths from s to t,
// and the subset of those paths containing v respectively.
func Betweenness(g graph.Graph) map[int]float64 {
// Brandes' algorithm for finding betweenness centrality for nodes in
// and unweighted graph:
//
// http://www.inf.uni-konstanz.de/algo/publications/b-fabc-01.pdf
// TODO(kortschak): Consider using the parallel algorithm when
// GOMAXPROCS != 1.
//
// http://htor.inf.ethz.ch/publications/img/edmonds-hoefler-lumsdaine-bc.pdf
// Also note special case for sparse networks:
// http://wwwold.iit.cnr.it/staff/marco.pellegrini/papiri/asonam-final.pdf
var (
cb = make(map[int]float64)
nodes = g.Nodes()
stack internal.NodeStack
p = make(map[int][]graph.Node, len(nodes))
sigma = make(map[int]float64, len(nodes))
d = make(map[int]int, len(nodes))
delta = make(map[int]float64, len(nodes))
queue internal.NodeQueue
)
for _, s := range nodes {
stack = stack[:0]
for _, w := range nodes {
p[w.ID()] = p[w.ID()][:0]
}
for _, t := range nodes {
sigma[t.ID()] = 0
d[t.ID()] = -1
}
sigma[s.ID()] = 1
d[s.ID()] = 0
queue.Enqueue(s)
for queue.Len() != 0 {
v := queue.Dequeue()
stack.Push(v)
for _, w := range g.From(v) {
// w found for the first time?
if d[w.ID()] < 0 {
queue.Enqueue(w)
d[w.ID()] = d[v.ID()] + 1
}
// shortest path to w via v?
if d[w.ID()] == d[v.ID()]+1 {
sigma[w.ID()] += sigma[v.ID()]
p[w.ID()] = append(p[w.ID()], v)
}
}
}
for _, v := range nodes {
delta[v.ID()] = 0
}
// S returns vertices in order of non-increasing distance from s
for stack.Len() != 0 {
w := stack.Pop()
for _, v := range p[w.ID()] {
delta[v.ID()] += sigma[v.ID()] / sigma[w.ID()] * (1 + delta[w.ID()])
}
if w.ID() != s.ID() {
if d := delta[w.ID()]; d != 0 {
cb[w.ID()] += d
}
}
}
}
return cb
}