Advertisement
xerpi

Untitled

Jun 2nd, 2015
449
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 8.16 KB | None | 0 0
  1. package wikipedia.domain;
  2. import g13.*;
  3. import java.util.*;
  4.  
  5. /**
  6.  * Newman-Girvan algorithm implementation
  7.  * @author G13.2
  8.  */
  9. public class NewmanGirvan implements Algorithm {
  10.  
  11.     /**
  12.      * Put the nodes of connected component to community
  13.      * @param G The Graph where the nodes are
  14.      * @param nodes The Nodes of the Graph
  15.      * @param vist Indicate if the node are visited or not
  16.      * @param i The index of the first node of the connected component
  17.      * @return A community with nodes of the connected component
  18.      */
  19.     private Community putToCollectionIt(Graph G, Node[] nodes, boolean[] vist, int i) {
  20.         Stack<Integer> s = new Stack<Integer>();
  21.         Community c = new Community();
  22.         vist[i] = true;
  23.  
  24.         s.push(i);
  25.         while (!s.isEmpty()) {
  26.             int j = s.peek();
  27.             c.addNode(nodes[j]);
  28.             s.pop();
  29.             Collection<Edge> adjEdgesSet = G.getAdjacencyList(nodes[j]);
  30.             for (Edge e : adjEdgesSet) {
  31.                 Node adjNode = e.getNeighbor(nodes[j]);
  32.                 int k = java.util.Arrays.asList(nodes).indexOf(adjNode);
  33.                 if (!vist[k] && e.isValid()) {
  34.                     vist[k] = true;
  35.                     s.push(k);
  36.                 }
  37.             }
  38.         }
  39.         return c;
  40.     }
  41.  
  42.     /**
  43.      * Put the nodes of Graph to community collection
  44.      * @param G The Graph where the nodes are
  45.      * @param nodes The Nodes of the Graph
  46.      * @return The community collection of the Graph
  47.      */
  48.     private CommunityCollection putToCollection(Graph G, Node[] nodes) {
  49.         int nodeCount = G.getOrder();
  50.         CommunityCollection cc = new CommunityCollection();
  51.  
  52.         boolean[] vist = new boolean[nodeCount];
  53.         Arrays.fill(vist, false);
  54.  
  55.         for (int i = 0; i < nodeCount; ++i) {
  56.             if (!vist[i]) {
  57.                 cc.addCommunity(putToCollectionIt(G, nodes, vist, i));
  58.             }
  59.         }
  60.         return cc;
  61.     }
  62.  
  63.     /**
  64.      * Travel the nodes of connected component
  65.      * @param G The Graph where the nodes are
  66.      * @param nodes The Nodes of the Graph
  67.      * @param vist Indicate if the node are visited or not
  68.      * @param i The index of the first node of the connected component
  69.      */
  70.     private void getConnectedComponentCountIt(Graph G, Node[] nodes, boolean[] vist, int i) {
  71.         Stack<Integer> s = new Stack<Integer>();
  72.         vist[i] = true;
  73.  
  74.         s.push(i);
  75.         while (!s.isEmpty()) {
  76.             int j = s.peek();
  77.             s.pop();
  78.             Collection<Edge> adjEdgesSet = G.getAdjacencyList(nodes[j]);
  79.             for (Edge e : adjEdgesSet) {
  80.                 Node adjNode = e.getNeighbor(nodes[j]);
  81.                 int k = java.util.Arrays.asList(nodes).indexOf(adjNode);
  82.                 if (!vist[k] && e.isValid()) {
  83.                     vist[k] = true;
  84.                     s.push(k);
  85.                 }
  86.             }
  87.         }
  88.     }
  89.  
  90.     /**
  91.      * Get the number of connected components
  92.      * @param G The Graph where the nodes are
  93.      * @param nodes The Nodes of the Graph
  94.      * @return The number of connected components
  95.      */
  96.     private int getConnectedComponentCount(Graph G, Node[] nodes) {
  97.         int nodeCount = G.getOrder();
  98.  
  99.         boolean[] vist = new boolean[nodeCount];
  100.         Arrays.fill(vist, false);
  101.  
  102.         int count = 0;
  103.         for (int i = 0; i < nodeCount; ++i) {
  104.             //if (!vist[i]) {
  105.             // Arregla incoherencia con el boton de la vista?
  106.             if (!vist[i] && ((ONode)nodes[i]).getElement().getElementType() != Element.ElementType.ELEMENT_PAGE) {
  107.                 getConnectedComponentCountIt(G, nodes, vist, i);
  108.                 ++count;
  109.             }
  110.         }
  111.         return count;
  112.     }
  113.  
  114.     /**
  115.      * The first step of Newman-Girvan algorithm
  116.      * @param G The Graph
  117.      * @param nodes The Nodes of the Graph
  118.      * @param d The distances from source to s
  119.      * @param w The number shortest path from source to s
  120.      * @param s The node that applies BFS
  121.      * @param pila The integer stack that be used for the algorithm
  122.      */
  123.     private void stage1_BFS(Graph G, Node[] nodes, double[] d, double[] w, int s, Stack<Integer> pila) {
  124.  
  125.         int nodeCount = G.getOrder();
  126.         boolean[] vist = new boolean[nodeCount];
  127.         Arrays.fill(vist, false);
  128.         Arrays.fill(d, Integer.MAX_VALUE);
  129.         Arrays.fill(w, 0);
  130.  
  131.         d[s] = 0;
  132.         w[s] = 1;
  133.  
  134.         Queue<Integer> q = new LinkedList<Integer>();
  135.         q.add(s);
  136.         pila.push(s); // Guardar orden inverso
  137.  
  138.         while (!q.isEmpty()) {
  139.             int u = q.poll();
  140.             if (!vist[u]) {
  141.                 vist[u] = true;
  142.                 Collection<Edge> adjEdgesSet = G.getAdjacencyList(nodes[u]);
  143.  
  144.                 for (Edge e : adjEdgesSet) {
  145.                     if (e.isValid()) {
  146.                         Node adjNode = e.getNeighbor(nodes[u]);
  147.                         int v = java.util.Arrays.asList(nodes).indexOf(adjNode);
  148.                         if (d[v] > d[u] + 1) {
  149.                             d[v] = d[u] + 1;
  150.                             w[v] = w[u];
  151.                             q.add(v);
  152.                             pila.push(v); // Guardar orden inverso
  153.                         } else if (d[v] == d[u] + 1) {
  154.                             w[v] += w[u];
  155.                         }
  156.                     }
  157.                 }
  158.             }
  159.         }
  160.     }
  161.  
  162.     /**
  163.      * The second step of Newman-Girvan algorithm
  164.      * @param G The Graph
  165.      * @param nodes The Nodes of the Graph
  166.      * @param edgeMap The Map representation of Edge's Set
  167.      * @param pila The integer stack that be used for the algorithm
  168.      * @param d The distances from source to s
  169.      * @param b Number shortest path between source to any vertex in graph pass through vertex i
  170.      * @param w The number shortest path from source to s
  171.      * @param arco The weight of the nodes
  172.      */
  173.     private void stage2_betweenness(Graph G, Node[] nodes, Map<Edge, Integer> edgeMap, Stack<Integer> pila, double[] d,
  174.                             double[] b, double[] w, double[] arco) {
  175.  
  176.         while (!pila.isEmpty()) {
  177.             int u = pila.pop();
  178.             b[u] += 1;
  179.  
  180.             Collection<Edge> adjEdgesSet = G.getAdjacencyList(nodes[u]);
  181.  
  182.             for (Edge e : adjEdgesSet) {
  183.                 Node adjNode = e.getNeighbor(nodes[u]);
  184.                 int v = java.util.Arrays.asList(nodes).indexOf(adjNode);
  185.                 int uvArco = edgeMap.get(e);
  186.                 if (d[v] < d[u]) {
  187.                     double calc = w[v]/w[u]*b[u];
  188.                     arco[uvArco] += calc; // fraccion de shortest paths
  189.                                           // que pasan por la arista
  190.                     b[v] += calc;         // fraccion de shortest paths
  191.                                           // que pasan por el vertice
  192.                 }
  193.             }
  194.         }
  195.     }
  196.  
  197.     /**
  198.      * Applies a iteration of the Newman-Girvan algorithm
  199.      * @param G the Graph to apply the Newman-Girvan algorithm
  200.      * @param nodes The nodes of the Graph
  201.      * @param edges The edges of the Graph
  202.      */
  203.     private void runNGAlgorithmIt(Graph G, Node[] nodes, Edge[] edges) {
  204.         int nodeCount = G.getOrder();
  205.         // Build the edgeId -> Edge hashtable (*TODO*)
  206.         double[] arco = new double[G.getEdgeCount()];
  207.         // Reset vector<> arco
  208.         Arrays.fill(arco, 0);
  209.         // Create edgeMap
  210.         Collection<Edge> edgeSet = G.getEdges();
  211.         Map<Edge, Integer> edgeMap = new LinkedHashMap<Edge, Integer>();
  212.  
  213.         Integer id = 0;
  214.         for (Edge e: edgeSet) {
  215.             edgeMap.put(e, id++);
  216.         }
  217.  
  218.         for (int i = 0; i < nodeCount; ++i) {
  219.             double[] d; //Distancia
  220.             double[] w; //Number shortest path from source to i
  221.  
  222.             d = new double[nodeCount];
  223.             w = new double[nodeCount];
  224.  
  225.             Stack<Integer> pila = new Stack<Integer>();
  226.             stage1_BFS(G, nodes, d, w, i, pila);
  227.  
  228.             double[] b = new double[G.getOrder()]; //Number shortest path between source to any
  229.                                             //vertex in graph pass through vertex i
  230.  
  231.             stage2_betweenness(G, nodes, edgeMap, pila, d, b, w, arco);
  232.  
  233.         }
  234.  
  235.         /*for (int i = 0; i < arco.length; i++) {
  236.             print(arco[i]);
  237.         }*/
  238.  
  239.         int imax = -1;
  240.         double max = -1;
  241.         for (int i = 0; i < arco.length; i++) {
  242.             if (!edges[i].isValid()) continue;
  243.             if (max < arco[i]/edges[i].getWeight()) {
  244.                 max = arco[i]/edges[i].getWeight();
  245.                 imax = i;
  246.             }
  247.         }
  248.  
  249.         edges[imax].setValidity(false);
  250.     }
  251.  
  252.     /**
  253.      * Applies the Newman-Girvan repeatedly to a graph until
  254.      * there are nCom's left or the algorithm can't be applied
  255.      * anymore, and returns the CommunityCollection of them
  256.      * @param G the Graph to apply the Newman-Girvan algorithm
  257.      * @param nCom the number of communities one wants to split the graph into
  258.      * @return the CommunityCollection result
  259.      */
  260.     public CommunityCollection runAlgorithm(Graph G, int nCom) {
  261.  
  262.         // Create node array
  263.         Node[] nodes = G.getNodes().toArray(new Node[G.getOrder()]);
  264.         // Create edges array
  265.         Edge[] edges = G.getEdges().toArray(new Edge[G.getEdgeCount()]);
  266.  
  267.         for (Edge e : G.getEdges()) e.setValidity(true);
  268.         int ncc = getConnectedComponentCount(G, nodes);
  269.  
  270.         // Si no hay mas aristas en el grafo paramos
  271.         while (nCom > ncc && G.getValidEdgeCount() > 0) {
  272.             runNGAlgorithmIt(G, nodes, edges);
  273.             ncc = getConnectedComponentCount(G, nodes);
  274.         }
  275.         //GraphIO.saveDOTformat((OGraph)G, "graph_out.dot");
  276.         return putToCollection(G, nodes);
  277.     }
  278. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement