Advertisement
Guest User

Untitled

a guest
May 30th, 2015
227
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 7.70 KB | None | 0 0
  1. package domini;
  2.  
  3. import java.util.ArrayList;
  4. import java.util.HashMap;
  5. import java.util.Random;
  6. import java.util.TimeZone;
  7. import java.util.Vector;
  8.  
  9. public class Louvain extends Algorithm {
  10.     private int[] n2cFinal;
  11.     private Node[] initialNodes;
  12.     private int level;
  13.     private class LouvainCom{
  14.         private Graph<Node> gc;
  15.         private int size;
  16.         private int[] n2c;//node to community
  17.         private float[] in;
  18.         private float[] tot;
  19.         private Node[] node;
  20.        
  21.         LouvainCom(Graph <Node> graph){
  22.             this.gc=graph;
  23.             node = new Node[gc.getAllNodes().size()];
  24.             gc.getAllNodes().toArray(node);
  25.             size=node.length;
  26.             n2c=new int[size];
  27.             in= new float[size];
  28.             tot= new float[size];
  29.             for(int i=0;i<size;++i){
  30.                 n2c[i]=i;
  31.                 in[i]= OpsLouvain.nb_selfloops(gc, node[i]);
  32.                 tot[i]= OpsLouvain.weighted_degree(gc,node[i]);
  33.             }
  34.         }
  35.        
  36.         public void remove(int node,int comm,double linksToComm){
  37.             tot[comm] -=  OpsLouvain.weighted_degree(gc,this.node[node]);
  38.             in[comm] -= 2*linksToComm +  OpsLouvain.nb_selfloops(gc,this.node[node]);
  39.             n2c[node]=-1;
  40.         }
  41.        
  42.         public void insert(int node,int comm,double linksToComm){
  43.             tot[comm] +=  OpsLouvain.weighted_degree(gc,this.node[node]);
  44.             in[comm] += 2*linksToComm + OpsLouvain.nb_selfloops(gc,this.node[node]);
  45.             n2c[node]=comm;
  46.            
  47.         }
  48.        
  49.         public double modularityGain(int node,int comm, double linksToComm,double wDegree){
  50.             double totcom=tot[comm];
  51.             double degcom=wDegree;
  52.             double m= OpsLouvain.getTotalWeight(gc);
  53.             double linkscom=linksToComm;
  54.             double r=(linkscom-totcom*degcom/m);
  55.             return r;
  56.         }
  57.        
  58.         public int neighComm(int node,int[] veins,double[] weights){
  59.            
  60.             for (int i=0;i<size;++i) weights[i]=-1.0;
  61.             Vector<Pair<Integer,Float>> p=OpsLouvain.neighbors(gc,node);
  62.             int degreeN=gc.getAdjacentNodesTo(this.node[node]).size();
  63.             veins[0]=n2c[node];
  64.             weights[veins[0]]=0;
  65.             int nvecinos=1;
  66.             for(int i=0;i<degreeN;++i){
  67.                 int neigh=p.get(i).getFirst();
  68.                 int neighCom=n2c[neigh];
  69.                 double neighW=p.get(i).getSecond();
  70.                 if(neigh!=node){
  71.                     if(weights[neighCom]==-1){
  72.                         weights[neighCom]=0.0;
  73.                         veins[nvecinos]=neighCom;
  74.                         ++nvecinos;
  75.                     }
  76.                     weights[neighCom]+=neighW;
  77.                 }
  78.             }
  79.             return nvecinos;
  80.         }
  81.        
  82.         double modularity(){
  83.             double q=0;
  84.             double m=OpsLouvain.getTotalWeight(gc);
  85.             for(int i=0;i<size;++i){
  86.                 if(tot[i]>0) q+= (in[i]/m) -(tot[i]/m)*(tot[i]/m);
  87.             }
  88.             return q;
  89.         }
  90.        
  91.         public Graph<Node> partition2graph(){
  92.             if (level==0)n2cFinal=n2c;
  93.             Graph<Node> gf2=new Graph<Node>();
  94.             ArrayList <Integer> communities= new ArrayList<Integer>();
  95.             //per a cada node, faig add de la seva comunitat al arraylist communities(per l'implementacio de l'add, no tindre repetides)
  96.             for(int i=0;i<size;++i){
  97.                 communities.add(n2c[i]);
  98.             }
  99.            
  100.             double [][] comToCom= new double[size][size];
  101.             //Per a cada comunitat creo un node al nou graf
  102.             for (int i=0;i<size;++i){
  103.                 //inicialitzacions per millorar rendiment
  104.                 for(int j=0;j<size;++j) comToCom[i][j]=0;
  105.             }
  106.             //per cada node, agafo la suma de edges que van a ell i acumulo la suma a la comunitat pertinent si els dos nodes son de la mateixa comunitat
  107.             //si no, acumulo la suma en el array comToCom que, per la comunitat i acumula la suma cap a la comunitat j
  108.             for(int i=0;i<size;++i){
  109.                 int comi=n2c[i];
  110.                 for(int j=i;j<size;++j){
  111.                     if(gc.getEdge(node[i], node[j])!=null){
  112.                     if(comi==n2c[j]){
  113.                         comToCom[comi][comi]+= gc.getEdge(node[i] , node[j] ).getWeight();
  114.                     }
  115.                     else comToCom[comi][n2c[j]] += gc.getEdge(node[i] , (Node)node[j]).getWeight();
  116.                 }
  117.                 }
  118.                
  119.             }
  120.             int nodeDesti=0;
  121.             HashMap<Integer,Integer> c2n=new HashMap<Integer,Integer>();
  122.             for(int i=0;i<size;++i){
  123.                 if(c2n.get(n2c[i])==null){
  124.                     c2n.put(n2c[i],nodeDesti);
  125.                     ++nodeDesti;
  126.                     gf2.addNode( new NodeLouvain("com: "+nodeDesti));
  127.                 }
  128.                
  129.             }
  130.  
  131.             //track dels nodes inicials
  132.             int numeroComunitats=c2n.size();
  133.             Node[] nodesNew= new Node[numeroComunitats];
  134.             gf2.getAllNodes().toArray(nodesNew);
  135.            
  136.                 for(int i=0;i<n2cFinal.length;++i){
  137.                     if(c2n.get(n2cFinal[i])!=null)n2cFinal[i]=c2n.get(n2cFinal[i]);
  138.                 }
  139.            
  140.            
  141.            
  142.             //Per a cada node del nou graf, li poso el edge corresponent segons elsvectors abans calculats
  143.            
  144.             Edge e= new Edge();
  145.             for(int i=0;i<numeroComunitats;++i){
  146.                 //para[i][j] comToCom
  147.                 for(int j=i;j<numeroComunitats;++j){
  148.                     if(comToCom[i][j]!=0){
  149.                         int idnode1= c2n.get(i);
  150.                         int idnode2=c2n.get(j);
  151.                         e=new Edge();
  152.                         e.setWeight((float)comToCom[i][j] );
  153.                         gf2.addEdge(nodesNew[idnode1], nodesNew[idnode2], e);
  154.                     }
  155.                 }
  156.             }
  157.             return gf2;
  158.         }
  159.        
  160.         public boolean oneLevel(){
  161.             boolean improvement=false;
  162.             int moves=0;
  163.             int passes=0;
  164.             double newMod=modularity();
  165.             double mod=newMod;
  166.             // reordenem el vector d'ids de nodes de forma aleatoria per tal de tenir millor resultats en els calculs
  167.             int [] random= new int[size];
  168.             Random r=new Random();
  169.             //ponemos a cada posicion i, la propia i para lujego hacer un shuffle entre ella en posiciones random del vector
  170.             for(int i=0;i<size;++i)random[i]=i;
  171.             for(int i=0;i<size;++i){
  172.                 int rpos= r.nextInt(size);
  173.                 int aux= random[i];
  174.                 random[i]=random[rpos];
  175.                 random[rpos]=aux;
  176.             }
  177.             mod=-newMod-1;
  178.             moves=1;
  179.             //itera mientras haya ganancia de modularidad (newMod-mod>0)
  180.  
  181.             while(moves>0 && newMod-mod>0){
  182.                 mod=newMod;
  183.                 moves=0;
  184.                 ++passes;
  185.                 for(int i=0;i<size;++i){
  186.                     int nodeid=random[i];
  187.                     int comunitat=n2c[nodeid];
  188.                     double weightDegree=OpsLouvain.weighted_degree(gc,node[nodeid]);
  189.                     //buscamos los links hacia otras comunidades, cogiendo su peso
  190.                     int[] veins=new int[size];
  191.                     double[] weights= new double[size];
  192.                     int nvecinos= neighComm(nodeid,veins,weights);
  193.                     //quitamos el nodo de su comunidad actual
  194.                     remove(nodeid,comunitat,weights[comunitat]);
  195.                     //Buscamos la mejor comunidad entre sus vecinos
  196.                     int bestCommunity=comunitat;
  197.                     double linksMillor=0.0;
  198.                     double bestIncrease=0.0;
  199.                     for(int j=0;j<nvecinos;++j){
  200.                         int vei=veins[j];
  201.  
  202.                        
  203.                         double millora=modularityGain(nodeid, vei, weights[vei],weightDegree);
  204.                         if(millora>bestIncrease){
  205.                             bestCommunity=vei;
  206.                             linksMillor=weights[vei];
  207.                             bestIncrease=millora;
  208.                         }
  209.                     }
  210.                     //insertem el node a la millor comunitat trobada
  211.                     insert(nodeid,bestCommunity,linksMillor);
  212.                     if(bestCommunity!=comunitat){
  213.                         ++moves;
  214.                         improvement=true;
  215.                     }
  216.                    
  217.                 }
  218.                 if (moves>0)newMod=modularity();
  219.                
  220.             }
  221.             return improvement;
  222.         }
  223.        
  224.        
  225.     }
  226.     public Louvain() {
  227.        
  228.     }
  229.  
  230.     @Override
  231.     public Solution getSolution(Graph<Node> g) {
  232.         long startTime = System.nanoTime();
  233.         initialNodes= new Node[g.getAllNodes().size()];
  234.         n2cFinal= new int[g.getAllNodes().size()];
  235.         g.getAllNodes().toArray(initialNodes);
  236.         LouvainCom c=new LouvainCom(g);
  237.         boolean improvement=true;
  238.         double mod=c.modularity();
  239.         double newMod;
  240.         level=0;
  241.         while(improvement){
  242.             improvement=c.oneLevel();
  243.             newMod=c.modularity();
  244.             g=c.partition2graph();
  245.             c=new LouvainCom(g);
  246.             mod=newMod;
  247.             ++level;
  248.         }
  249.  
  250.         long genTime = System.nanoTime() - startTime;
  251.         Solution s=new Solution();
  252.         s.setAlg('L');
  253.         System.out.println("Time: "+genTime);
  254.         s.setTime(genTime);
  255.         NodeLouvain[] comunitatsFinals=new NodeLouvain[g.getAllNodes().size()];
  256.         g.getAllNodes().toArray(comunitatsFinals);
  257.         Community[] p= new Community[comunitatsFinals.length];
  258.         for(int i=0;i<p.length;++i) p[i]=new Community();
  259.         for(int i=0;i<n2cFinal.length;++i){
  260.             p[n2cFinal[i]].addNode(initialNodes[i]);
  261.         }
  262.         for(int i=0;i<p.length;++i)s.addCommunity(p[i]);
  263.        
  264.         return s;
  265.     }
  266.  
  267. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement