source: branches/MetisMQI/src/main/java/weka/clusterers/forMetisMQI/GraphAlgorithms.java

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

Taggata versione per la demo e aggiunto branch.

File size: 6.8 KB
Line 
1package weka.clusterers.forMetisMQI;
2
3import java.io.File;
4import java.io.FileOutputStream;
5import java.io.IOException;
6import java.util.HashSet;
7import java.util.Iterator;
8import java.util.Set;
9import java.util.Stack;
10
11import org.jdom.Document;
12import org.jdom.Element;
13import org.jdom.output.Format;
14import org.jdom.output.XMLOutputter;
15
16import weka.clusterers.forMetisMQI.graph.Bisection;
17import weka.clusterers.forMetisMQI.graph.Node;
18import weka.clusterers.forMetisMQI.graph.Subgraph;
19import weka.clusterers.forMetisMQI.graph.UndirectedGraph;
20import weka.clusterers.forMetisMQI.util.CoarserGraphElement;
21import weka.clusterers.forMetisMQI.util.Configuration;
22import weka.clusterers.forMetisMQI.util.GraphsFrame;
23import weka.clusterers.forMetisMQI.util.Random;
24import weka.clusterers.forMetisMQI.util.Util;
25
26public class GraphAlgorithms {
27
28       
29        static public Bisection KLRefinement(Bisection b) {
30                int remainingNumberOfSwap = 50;
31                Bisection partition = b;
32                Bisection result = partition;
33                int bestEdgeCut = partition.edgeCut();
34                Node u = partition.getCandidate();
35                while (u != null && remainingNumberOfSwap > 0) {
36                        partition.swap(u);
37                        if (partition.edgeCut() <= bestEdgeCut) {
38                                bestEdgeCut = partition.edgeCut();
39                                result = partition.clone();
40                                remainingNumberOfSwap = 50;
41                        } else
42                                remainingNumberOfSwap--;
43                        u = partition.getCandidate();
44                }
45                return result;
46        }
47       
48       
49        /**
50         * Given an undirected graph, performs the Kernighan-Li algorithm to find a bisection and
51         * then returns it.
52         * @param g
53         * @return
54         */
55        static public Bisection KL(UndirectedGraph g) {
56                int remainingNumberOfSwap = 50;
57                Bisection partition = new Bisection(g);
58                Bisection result = partition;
59                int bestEdgeCut = partition.edgeCut();
60                Node u = partition.getCandidate();
61                while (u != null && remainingNumberOfSwap > 0) {
62                        partition.swap(u);
63                        if (partition.edgeCut() <= bestEdgeCut) {
64                                bestEdgeCut = partition.edgeCut();
65                                result = partition.clone();
66                                remainingNumberOfSwap = 50;
67                        } else
68                                remainingNumberOfSwap--;
69                        u = partition.getCandidate();
70                }
71                return result;
72        }
73       
74        static public Bisection metis(UndirectedGraph g, int sizeFinerGraph) {
75                Coarse.setFinerSize(sizeFinerGraph);
76                Stack<CoarserGraphElement> stack = Coarse.coarse(g);
77                Bisection partition = null;
78                if (stack.size() > 0) {
79                        partition = KL(stack.peek().getContracted());
80                        if(Configuration.instance().getVerboseLevel() > 1) {
81                                GraphsFrame.instance().addPanel(Util.panelContractedGraph(stack.peek()));
82                                GraphsFrame.instance().addPanel(Util.panelContractedGraph(stack.peek(),partition.getSmallerSubgraph().createInducedSubgraph().getVertices()));
83                        }
84                        partition = Uncoarse.uncoarse(stack, partition);
85                }
86                return partition;
87        }
88
89        /**
90         * Given an UndirectedGraph, runs metis+mqi for <code>numberOfCluster</code> times and
91         * returns a set of clusters. With the third parameter you can control the maximum size of the finer
92         * graph during the coarsening phase. 
93         * @param g
94         * @param numberOfCluster
95         * @param sizeFinerGraph
96         */
97        static public Set<Set<Node>> metisMqi(UndirectedGraph g) {
98                int numberOfCluster = Configuration.instance().getNumberOfClusters();
99                boolean randomBisection = Configuration.instance().isRandomBisection();
100                int sizeFinerGraph = Configuration.instance().getSizeFinerGraph();
101                int verboseLevel = Configuration.instance().getVerboseLevel();
102                GraphsFrame gf = GraphsFrame.instance();
103               
104                Element rootXML = new Element("run");
105                Document logXML = new Document(rootXML);
106                rootXML.setAttribute("seed", Long.toString(Random.instance().getSeed()));
107                Element graphXML = new Element("graph");
108                graphXML.addContent(new Element("vertex").setText(Integer.toString(g.getVertexCount())));
109                graphXML.addContent(new Element("edge").setText(Integer.toString(g.getEdgeCount())));
110                rootXML.addContent(graphXML);
111                Element clustersXML = new Element("clusters");
112                rootXML.addContent(clustersXML);
113               
114                System.out.println("Seed: " + Random.instance().getSeed());
115                System.out.println("Vertex count: " + g.getVertexCount());
116                System.out.println("Edges count: " + g.getEdgeCount());
117                Set<Set<Node>> clusters = new HashSet<Set<Node>>();
118                UndirectedGraph gclone = g.clone();
119               
120                for (int i = 0; i < numberOfCluster; i++) {
121                        Bisection bisection = null;
122                        if(verboseLevel > 1)
123                                gf.addPanel(Util.panelGraph(g.clone()));
124                        if(!randomBisection)
125                                bisection = metis(g,sizeFinerGraph);
126                        else
127                                bisection = new Bisection(g);
128                       
129                        if(verboseLevel > 1)
130                                gf.addPanel(Util.panelCluster(g.clone(),bisection.getSmallerSubgraph().createInducedSubgraph().getVertices()));
131                       
132                        System.out.print("Initial partition: ");
133                        System.out.print("V1: " + bisection.getSubgraph().getVertexCount());
134                        System.out.print(" V2: " + bisection.getComplement().getVertexCount());
135                        System.out.println(" EC: " + bisection.edgeCut() * 0.5);
136                        System.out.println("Conductance: " + 
137                                        ((double)bisection.edgeCut() / 2) / Math.min(bisection.getSubgraph().totalDegree(),bisection.getComplement().totalDegree()));
138                        Set<Node> cluster = MQI.mqi(bisection,true);
139                       
140                        UndirectedGraph clusterGraph = new Subgraph(gclone,cluster).createInducedSubgraph();
141                       
142//                      System.out.println(cluster);
143                        Bisection mqiBisection = new Bisection(new Subgraph(g,cluster));
144                        System.out.println("Refined partition (MQI)");
145                        double newConductance = ((double)mqiBisection.edgeCut() / 2) / Math.min(mqiBisection.getSubgraph().totalDegree(),mqiBisection.getComplement().totalDegree());
146                        System.out.print("Cluster "+ i + ":  V=" + clusterGraph.getVertexCount() + ", E=" + clusterGraph.getEdgeCount()+", ");
147                        System.out.println("Cond: " + newConductance);
148                       
149                       
150                        mqiBisection = new Bisection(new Subgraph(gclone,cluster));
151                        newConductance = ((double)mqiBisection.edgeCut() / 2) / Math.min(mqiBisection.getSubgraph().totalDegree(),mqiBisection.getComplement().totalDegree());
152                        System.out.println("Cluster conductance: " + newConductance);
153                       
154                       
155                        Element clusterXML = new Element("cluster");
156                        clusterXML.setAttribute("id", Integer.toString(i));
157                        clusterXML.addContent(new Element("vertex").setText(Integer.toString(clusterGraph.getVertexCount())));
158                        clusterXML.addContent(new Element("edge").setText(Integer.toString(clusterGraph.getEdgeCount())));
159                        clusterXML.addContent(new Element("conductance").setText(Double.toString(newConductance)));
160                        clustersXML.addContent(clusterXML);
161                       
162                        clusters.add(cluster);
163                       
164                        System.out.println();
165                        Iterator<Node> clustersNode = cluster.iterator();
166                        while(clustersNode.hasNext()){
167                                g.removeVertex(clustersNode.next());
168                        }
169                }
170               
171               
172                XMLOutputter xmlOutputter = new XMLOutputter();
173                xmlOutputter.setFormat(Format.getPrettyFormat());
174                try {
175                        xmlOutputter.output(logXML, new FileOutputStream(new File(Configuration.instance().getOutputFile())));
176                } catch (IOException e) {
177                        e.printStackTrace();
178                }
179               
180                if(verboseLevel > 0) {
181                        gf.addPanel(Util.panelClusters(gclone, clusters));
182                        gf.setVisible(true);
183                }
184                return clusters;
185        }
186
187}
Note: See TracBrowser for help on using the repository browser.