Javascript - Bron-Kerbosch,Girvan-Newman算法(图中最大集团/社区)

时间:2013-04-27 13:27:31

标签: javascript algorithm graph-algorithm

我正在搜索Bron-Kerbosch algorithmGirvan-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;
}

2 个答案:

答案 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)

Bron-Kerbosch-Algorithm 需要:

  • 所有顶点的集合
  • 对于给定的顶点,所有相邻顶点的集合

这是在图(边)函数中预先计算的。 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 )