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  }