gonum.org/v1/gonum@v0.14.0/graph/network/distance.go (about) 1 // Copyright ©2015 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 5 package network 6 7 import ( 8 "math" 9 10 "gonum.org/v1/gonum/graph" 11 "gonum.org/v1/gonum/graph/path" 12 ) 13 14 // Closeness returns the closeness centrality for nodes in the graph g used to 15 // construct the given shortest paths. 16 // 17 // C(v) = 1 / \sum_u d(u,v) 18 // 19 // For directed graphs the incoming paths are used. Infinite distances are 20 // not considered. 21 func Closeness(g graph.Graph, p path.AllShortest) map[int64]float64 { 22 nodes := graph.NodesOf(g.Nodes()) 23 c := make(map[int64]float64, len(nodes)) 24 for _, u := range nodes { 25 uid := u.ID() 26 var sum float64 27 for _, v := range nodes { 28 vid := v.ID() 29 // The ordering here is not relevant for 30 // undirected graphs, but we make sure we 31 // are counting incoming paths. 32 d := p.Weight(vid, uid) 33 if math.IsInf(d, 0) { 34 continue 35 } 36 sum += d 37 } 38 c[u.ID()] = 1 / sum 39 } 40 return c 41 } 42 43 // Farness returns the farness for nodes in the graph g used to construct 44 // the given shortest paths. 45 // 46 // F(v) = \sum_u d(u,v) 47 // 48 // For directed graphs the incoming paths are used. Infinite distances are 49 // not considered. 50 func Farness(g graph.Graph, p path.AllShortest) map[int64]float64 { 51 nodes := graph.NodesOf(g.Nodes()) 52 f := make(map[int64]float64, len(nodes)) 53 for _, u := range nodes { 54 uid := u.ID() 55 var sum float64 56 for _, v := range nodes { 57 vid := v.ID() 58 // The ordering here is not relevant for 59 // undirected graphs, but we make sure we 60 // are counting incoming paths. 61 d := p.Weight(vid, uid) 62 if math.IsInf(d, 0) { 63 continue 64 } 65 sum += d 66 } 67 f[u.ID()] = sum 68 } 69 return f 70 } 71 72 // Harmonic returns the harmonic centrality for nodes in the graph g used to 73 // construct the given shortest paths. 74 // 75 // H(v)= \sum_{u ≠ v} 1 / d(u,v) 76 // 77 // For directed graphs the incoming paths are used. Infinite distances are 78 // not considered. 79 func Harmonic(g graph.Graph, p path.AllShortest) map[int64]float64 { 80 nodes := graph.NodesOf(g.Nodes()) 81 h := make(map[int64]float64, len(nodes)) 82 for i, u := range nodes { 83 uid := u.ID() 84 var sum float64 85 for j, v := range nodes { 86 vid := v.ID() 87 // The ordering here is not relevant for 88 // undirected graphs, but we make sure we 89 // are counting incoming paths. 90 d := p.Weight(vid, uid) 91 if math.IsInf(d, 0) { 92 continue 93 } 94 if i != j { 95 sum += 1 / d 96 } 97 } 98 h[u.ID()] = sum 99 } 100 return h 101 } 102 103 // Residual returns the Dangalchev's residual closeness for nodes in the graph 104 // g used to construct the given shortest paths. 105 // 106 // C(v)= \sum_{u ≠ v} 1 / 2^d(u,v) 107 // 108 // For directed graphs the incoming paths are used. Infinite distances are 109 // not considered. 110 func Residual(g graph.Graph, p path.AllShortest) map[int64]float64 { 111 nodes := graph.NodesOf(g.Nodes()) 112 r := make(map[int64]float64, len(nodes)) 113 for i, u := range nodes { 114 uid := u.ID() 115 var sum float64 116 for j, v := range nodes { 117 vid := v.ID() 118 // The ordering here is not relevant for 119 // undirected graphs, but we make sure we 120 // are counting incoming paths. 121 d := p.Weight(vid, uid) 122 if math.IsInf(d, 0) { 123 continue 124 } 125 if i != j { 126 sum += math.Exp2(-d) 127 } 128 } 129 r[u.ID()] = sum 130 } 131 return r 132 }