我正在搜索Bron-Kerbosch algorithm或Girvan-Newman algorithm的Javascript实现。
基本上我想在无向图中为最大派系/社区着色。
可悲的是,我发现只有神秘的Python和臃肿的Java& C ++库代码。我需要它在普通的Javascript代码中(最好没有膨胀的JS库或JQuery等依赖)。
// I am using the following data structure
fg_p = []; // Points (Users)
fg_e = []; // Edges
function fgAddUser(uid, name) {
var t_obj = {};
t_obj.id = id;
t_obj.name = name;
fg_g[fg_g.length] = t_obj;
}
function fgAddEdge(a, b) {
var t_obj = {};
t_obj.a = a; // user A
t_obj.b = b; // user B
fg_e[fg_e.length] = t_obj;
}
答案 0 :(得分:0)
我制作了一个模块,用于执行第一版 Bron-Kerbosch 算法
'use strict';
function graphUtils(){
var methods = {};
methods.allCliques = function(g){
var cliques=[];
var p=[];
g.forEachNode(function(node){
p.push(node.id);
});
var r =[];
var x=[];
bronKerbosch(g, r, p, x, cliques);
return cliques;
};
function bronKerbosch(g, r, p, x, cliques) {
if (p.length===0 && x.length===0){
cliques.push(r);
}
p.forEach(function(v){
var tempR= r.splice(0);
tempR.push(v);
bronKerbosch(g, tempR, p.filter(function(temp){
return methods.neighbors(g, v).indexOf(temp)!=-1;
}), x.filter(function(temp){
return methods.neighbors(g, v).indexOf(temp)!=-1;
}), cliques);
p.splice(p.indexOf(v),1);
x.push(v);
});
}
methods.neighbors = function(g, v){
var neighbors=[];
g.forEachLinkedNode(v, function(linkedNode){
neighbors.push(linkedNode.id);
});
return neighbors;
};
return methods;
}
module.exports = graphUtils();
我没有尝试过,因为事实证明我不需要它,告诉我它是否有效或者我是否需要修理
答案 1 :(得分:0)
这是在图(边)函数中预先计算的。 allCliques( g ) 函数计算所有最大团的集合。它调用了递归的 bronKerbosch 函数。
在最后两行中,我添加了一个如何使用它的示例。
function graph( edges ){
const vertices = edges.reduce( ( verticesMap, edge ) => ( verticesMap[ edge.vertex1 ] = 1, verticesMap[ edge.vertex2 ] = 1, verticesMap ) , {} );
const neighbours = edges.reduce( ( verticesMap, edge ) => (
verticesMap[ edge.vertex1 ] = ( verticesMap[ edge.vertex1 ] || [] ).concat( edge.vertex2 ),
verticesMap[ edge.vertex2 ] = ( verticesMap[ edge.vertex2 ] || [] ).concat( edge.vertex1 ),
verticesMap
) , {} );
return {
neighboursOf : vertex => neighbours[ vertex ],
vertices : () => Object.keys( vertices ),
};
}
function allCliques( g ){
const cliques = [];
const r = [];
const p = g.vertices();
const x = [];
if( p.length == 0 ){
// prevent empty cliques in empty graphs
return cliques;
}
bronKerbosch(
g,
r,
p,
x,
cliques
);
return cliques;
};
function bronKerbosch( g, r, p, x, cliques ){
if( p.length === 0 && x.length === 0 ){
cliques.push( r );
}
const isNeighbourOf = v => vertex => g.neighboursOf( v ).includes( vertex );
p.forEach( ( v, index ) => bronKerbosch(
g,
r.concat( [ v ] ),
p.slice( index ) .filter( isNeighbourOf( v ) ),
x.concat( p.slice( 0, index ) ).filter( isNeighbourOf( v ) ),
cliques
));
}
g = graph( [ { vertex1 : 'a', vertex2 : 'b' }, { vertex1 : 'a', vertex2 : 'c' }, { vertex1 : 'a', vertex2 : 'd' }, { vertex1 : 'c', vertex2 : 'd' }, { vertex1 : 'b', vertex2 : 'd' } ] )
allCliques( g )