|
import Heap from '../../heap'; |
|
import * as util from '../../util'; |
|
|
|
const defaults = util.defaults({ |
|
weight: null, |
|
directed: false |
|
}); |
|
|
|
let elesfn = ({ |
|
|
|
|
|
betweennessCentrality: function( options ){ |
|
let { directed, weight } = defaults(options); |
|
let weighted = weight != null; |
|
let cy = this.cy(); |
|
|
|
|
|
let V = this.nodes(); |
|
let A = {}; |
|
let _C = {}; |
|
let max = 0; |
|
let C = { |
|
set: function( key, val ){ |
|
_C[ key ] = val; |
|
|
|
if( val > max ){ max = val; } |
|
}, |
|
|
|
get: function( key ){ return _C[ key ]; } |
|
}; |
|
|
|
|
|
for( let i = 0; i < V.length; i++ ){ |
|
let v = V[ i ]; |
|
let vid = v.id(); |
|
|
|
if( directed ){ |
|
A[ vid ] = v.outgoers().nodes(); |
|
} else { |
|
A[ vid ] = v.openNeighborhood().nodes(); |
|
} |
|
|
|
C.set( vid, 0 ); |
|
} |
|
|
|
for( let s = 0; s < V.length; s++ ){ |
|
let sid = V[s].id(); |
|
let S = []; |
|
let P = {}; |
|
let g = {}; |
|
let d = {}; |
|
let Q = new Heap(function( a, b ){ |
|
return d[a] - d[b]; |
|
}); |
|
|
|
|
|
for( let i = 0; i < V.length; i++ ){ |
|
let vid = V[ i ].id(); |
|
|
|
P[ vid ] = []; |
|
g[ vid ] = 0; |
|
d[ vid ] = Infinity; |
|
} |
|
|
|
g[ sid ] = 1; |
|
d[ sid ] = 0; |
|
|
|
Q.push( sid ); |
|
|
|
while( !Q.empty() ){ |
|
let v = Q.pop(); |
|
|
|
S.push( v ); |
|
|
|
if( weighted ){ |
|
for( let j = 0; j < A[v].length; j++ ){ |
|
let w = A[v][j]; |
|
let vEle = cy.getElementById( v ); |
|
|
|
let edge; |
|
if( vEle.edgesTo( w ).length > 0 ){ |
|
edge = vEle.edgesTo( w )[0]; |
|
} else { |
|
edge = w.edgesTo( vEle )[0]; |
|
} |
|
|
|
let edgeWeight = weight( edge ); |
|
|
|
w = w.id(); |
|
|
|
if( d[w] > d[v] + edgeWeight ){ |
|
d[w] = d[v] + edgeWeight; |
|
|
|
if( Q.nodes.indexOf( w ) < 0 ){ |
|
Q.push( w ); |
|
} else { |
|
Q.updateItem( w ); |
|
} |
|
|
|
g[w] = 0; |
|
P[w] = []; |
|
} |
|
|
|
if( d[w] == d[v] + edgeWeight ){ |
|
g[w] = g[w] + g[v]; |
|
P[w].push( v ); |
|
} |
|
} |
|
} else { |
|
for( let j = 0; j < A[v].length; j++ ){ |
|
let w = A[v][j].id(); |
|
|
|
if( d[w] == Infinity ){ |
|
Q.push( w ); |
|
|
|
d[w] = d[v] + 1; |
|
} |
|
|
|
if( d[w] == d[v] + 1 ){ |
|
g[w] = g[w] + g[v]; |
|
P[w].push( v ); |
|
} |
|
} |
|
} |
|
} |
|
|
|
let e = {}; |
|
for( let i = 0; i < V.length; i++ ){ |
|
e[ V[ i ].id() ] = 0; |
|
} |
|
|
|
while( S.length > 0 ){ |
|
let w = S.pop(); |
|
|
|
for( let j = 0; j < P[w].length; j++ ){ |
|
let v = P[w][j]; |
|
|
|
e[v] = e[v] + (g[v] / g[w]) * (1 + e[w]); |
|
} |
|
|
|
if( w != V[s].id() ){ |
|
C.set( w, C.get( w ) + e[w] ); |
|
} |
|
} |
|
} |
|
|
|
let ret = { |
|
betweenness: function( node ){ |
|
let id = cy.collection(node).id(); |
|
|
|
return C.get( id ); |
|
}, |
|
|
|
betweennessNormalized: function( node ){ |
|
if ( max == 0 ){ return 0; } |
|
|
|
let id = cy.collection(node).id(); |
|
|
|
return C.get( id ) / max; |
|
} |
|
}; |
|
|
|
|
|
ret.betweennessNormalised = ret.betweennessNormalized; |
|
|
|
return ret; |
|
} |
|
|
|
}); |
|
|
|
|
|
elesfn.bc = elesfn.betweennessCentrality; |
|
|
|
export default elesfn; |
|
|