source: src/main/java/weka/clusterers/forMetisMQI/GraphAlgorithms.java @ 22

Last change on this file since 22 was 22, checked in by gnappo, 14 years ago

Implementata ricorsione corretta di MQI. Aggiunto parametro a linea di comando per la bisezione casuale.

File size: 4.4 KB
Line 
1package weka.clusterers.forMetisMQI;
2
3import java.util.HashSet;
4import java.util.Iterator;
5import java.util.Set;
6import java.util.Stack;
7
8import weka.clusterers.forMetisMQI.graph.Bisection;
9import weka.clusterers.forMetisMQI.graph.Node;
10import weka.clusterers.forMetisMQI.graph.Subgraph;
11import weka.clusterers.forMetisMQI.graph.UndirectedGraph;
12import weka.clusterers.forMetisMQI.util.CoarserGraphElement;
13import weka.clusterers.forMetisMQI.util.Util;
14
15public class GraphAlgorithms {
16
17       
18        static public Bisection KLRefinement(Bisection b) {
19                int remainingNumberOfSwap = 50;
20                Bisection partition = b;
21                Bisection result = partition;
22                int bestEdgeCut = partition.edgeCut();
23                Node u = partition.getCandidate();
24                while (u != null && remainingNumberOfSwap > 0) {
25                        partition.swap(u);
26                        if (partition.edgeCut() <= bestEdgeCut) {
27                                bestEdgeCut = partition.edgeCut();
28                                result = partition.clone();
29                                remainingNumberOfSwap = 50;
30                        } else
31                                remainingNumberOfSwap--;
32                        u = partition.getCandidate();
33                }
34                return result;
35        }
36       
37       
38        /**
39         * Given an undirected graph, performs the Kernighan-Li algorithm to find a bisection and
40         * then returns it.
41         * @param g
42         * @return
43         */
44        static public Bisection KL(UndirectedGraph g) {
45                int remainingNumberOfSwap = 50;
46                Bisection partition = new Bisection(g);
47                Bisection result = partition;
48                int bestEdgeCut = partition.edgeCut();
49                Node u = partition.getCandidate();
50                while (u != null && remainingNumberOfSwap > 0) {
51                        partition.swap(u);
52                        if (partition.edgeCut() <= bestEdgeCut) {
53                                bestEdgeCut = partition.edgeCut();
54                                result = partition.clone();
55                                remainingNumberOfSwap = 50;
56                        } else
57                                remainingNumberOfSwap--;
58                        u = partition.getCandidate();
59                }
60                return result;
61        }
62       
63        static public Bisection metis(UndirectedGraph g, int sizeFinerGraph) {
64                Coarse.setFinerSize(sizeFinerGraph);
65                Stack<CoarserGraphElement> stack = Coarse.coarse(g);
66                Bisection partition = null;
67                if (stack.size() > 0) {
68                        partition = KL(stack.peek().getContracted());
69                        partition = Uncoarse.uncoarse(stack, partition);
70                }
71                return partition;
72        }
73
74        /**
75         * Given an UndirectedGraph, runs metis+mqi for <code>numberOfCluster</code> times and
76         * returns a set of clusters. With the third parameter you can control the maximum size of the finer
77         * graph during the coarsening phase. 
78         * @param g
79         * @param numberOfCluster
80         * @param sizeFinerGraph
81         */
82        static public Set<Set<Node>> metisMqi(UndirectedGraph g, int numberOfCluster, int sizeFinerGraph, boolean randomBisection) {
83                System.out.println("Vertex count: " + g.getVertexCount());
84                System.out.println("Edges count: " + g.getEdgeCount());
85                Iterator<Node> iNodes = g.getVertices().iterator();
86                int degreeCounter = 0;
87                while(iNodes.hasNext()) {
88                        Node node = iNodes.next();
89                        if(g.degree(node) == 1) {
90                                degreeCounter++;
91                        }
92                }
93                Set<Set<Node>> clusters = new HashSet<Set<Node>>();
94                UndirectedGraph gclone = g.clone();
95//              Util.viewGraph(g);
96                for (int i = 0; i < numberOfCluster; i++) {
97                        Bisection bisection = null;
98                        if(!randomBisection)
99                                bisection = metis(g,sizeFinerGraph);
100                        else
101                                bisection = new Bisection(g);
102                        System.out.print("Partizione iniziale: ");
103                        System.out.print("V1: " + bisection.getSubgraph().getVertexCount());
104                        System.out.print(" V2: " + bisection.getComplement().getVertexCount());
105                        System.out.println(" EC: " + bisection.edgeCut() * 0.5);
106                        System.out.println("Conductance: " + 
107                                        ((double)bisection.edgeCut() / 2) / Math.min(bisection.getSubgraph().totalDegree(),bisection.getComplement().totalDegree()));
108                        Set<Node> cluster = MQI.mqi(bisection,true);
109                       
110                        UndirectedGraph clusterGraph = new Subgraph(gclone,cluster).createInducedSubgraph();
111                       
112//                      System.out.println(cluster);
113                        Bisection mqiBisection = new Bisection(new Subgraph(g,cluster));
114                        System.out.println("Partizione raffinata (MQI)");
115                        double newConductance = ((double)mqiBisection.edgeCut() / 2) / Math.min(mqiBisection.getSubgraph().totalDegree(),mqiBisection.getComplement().totalDegree());
116                        System.out.println("Conductance: " + newConductance);
117                       
118                        System.out.println("CLUSTER "+ i + ":  V=" + clusterGraph.getVertexCount() + ", E=" + clusterGraph.getEdgeCount()+".");
119                        clusters.add(cluster);
120                       
121                        System.out.println();
122                        Iterator<Node> clustersNode = cluster.iterator();
123                        while(clustersNode.hasNext()){
124                                g.removeVertex(clustersNode.next());
125                        }
126                }
127                Util.viewClusters(gclone, clusters);
128                return clusters;
129        }
130
131}
Note: See TracBrowser for help on using the repository browser.