File: distance.go

package info (click to toggle)
golang-gonum-v1-gonum 0.15.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 18,792 kB
  • sloc: asm: 6,252; fortran: 5,271; sh: 377; ruby: 211; makefile: 98
file content (132 lines) | stat: -rw-r--r-- 3,298 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// Copyright ©2015 The Gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package network

import (
	"math"

	"gonum.org/v1/gonum/graph"
	"gonum.org/v1/gonum/graph/path"
)

// Closeness returns the closeness centrality for nodes in the graph g used to
// construct the given shortest paths.
//
//	C(v) = 1 / \sum_u d(u,v)
//
// For directed graphs the incoming paths are used. Infinite distances are
// not considered.
func Closeness(g graph.Graph, p path.AllShortest) map[int64]float64 {
	nodes := graph.NodesOf(g.Nodes())
	c := make(map[int64]float64, len(nodes))
	for _, u := range nodes {
		uid := u.ID()
		var sum float64
		for _, v := range nodes {
			vid := v.ID()
			// The ordering here is not relevant for
			// undirected graphs, but we make sure we
			// are counting incoming paths.
			d := p.Weight(vid, uid)
			if math.IsInf(d, 0) {
				continue
			}
			sum += d
		}
		c[u.ID()] = 1 / sum
	}
	return c
}

// 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[int64]float64 {
	nodes := graph.NodesOf(g.Nodes())
	f := make(map[int64]float64, len(nodes))
	for _, u := range nodes {
		uid := u.ID()
		var sum float64
		for _, v := range nodes {
			vid := v.ID()
			// The ordering here is not relevant for
			// undirected graphs, but we make sure we
			// are counting incoming paths.
			d := p.Weight(vid, uid)
			if math.IsInf(d, 0) {
				continue
			}
			sum += d
		}
		f[u.ID()] = sum
	}
	return f
}

// 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[int64]float64 {
	nodes := graph.NodesOf(g.Nodes())
	h := make(map[int64]float64, len(nodes))
	for i, u := range nodes {
		uid := u.ID()
		var sum float64
		for j, v := range nodes {
			vid := v.ID()
			// The ordering here is not relevant for
			// undirected graphs, but we make sure we
			// are counting incoming paths.
			d := p.Weight(vid, uid)
			if math.IsInf(d, 0) {
				continue
			}
			if i != j {
				sum += 1 / d
			}
		}
		h[u.ID()] = sum
	}
	return h
}

// Residual returns the Dangalchev's residual closeness for nodes in the graph
// g used to construct the given shortest paths.
//
//	C(v)= \sum_{u ≠ v} 1 / 2^d(u,v)
//
// For directed graphs the incoming paths are used. Infinite distances are
// not considered.
func Residual(g graph.Graph, p path.AllShortest) map[int64]float64 {
	nodes := graph.NodesOf(g.Nodes())
	r := make(map[int64]float64, len(nodes))
	for i, u := range nodes {
		uid := u.ID()
		var sum float64
		for j, v := range nodes {
			vid := v.ID()
			// The ordering here is not relevant for
			// undirected graphs, but we make sure we
			// are counting incoming paths.
			d := p.Weight(vid, uid)
			if math.IsInf(d, 0) {
				continue
			}
			if i != j {
				sum += math.Exp2(-d)
			}
		}
		r[u.ID()] = sum
	}
	return r
}