source: branches/MetisMQI/src/main/java/weka/clusterers/MetisMQIClusterer.java @ 29

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

Taggata versione per la demo e aggiunto branch.

File size: 6.5 KB
Line 
1package weka.clusterers;
2
3import java.util.Enumeration;
4import java.util.HashMap;
5import java.util.Iterator;
6import java.util.Map;
7import java.util.Set;
8import java.util.Vector;
9
10import weka.clusterers.forMetisMQI.GraphAlgorithms;
11import weka.clusterers.forMetisMQI.graph.Node;
12import weka.clusterers.forMetisMQI.graph.UndirectedGraph;
13import weka.clusterers.forMetisMQI.util.Configuration;
14import weka.core.Attribute;
15import weka.core.Capabilities;
16import weka.core.Instance;
17import weka.core.Instances;
18import weka.core.Option;
19import weka.core.OptionHandler;
20import weka.core.Utils;
21import weka.core.Capabilities.Capability;
22
23public class MetisMQIClusterer extends AbstractClusterer implements
24                OptionHandler {
25
26        /**
27         * It maps each cluster with an integer id.
28         */
29        private Map<Set<Node>, Integer> clustersMap = null;
30
31        /**
32         * Holds the cluster membership for each node.
33         */
34        private Map<Node, Integer> nodeMap = null;
35       
36
37        /**
38         *
39         */
40        private static final long serialVersionUID = 1L;
41
42        @Override
43        public void buildClusterer(Instances data) throws Exception {
44                getCapabilities().testWithFail(data);
45                UndirectedGraph g = new UndirectedGraph();
46                g.loadFromInstance(data);
47                Set<Set<Node>> clusters = GraphAlgorithms.metisMqi(g);
48                setNumClusters(clusters.size());
49                int i = 0;
50                Iterator<Set<Node>> clusterIterator = clusters.iterator();
51                clustersMap = new HashMap<Set<Node>, Integer>();
52                nodeMap = new HashMap<Node, Integer>();
53                while (clusterIterator.hasNext()) {
54                        Set<Node> cluster = clusterIterator.next();
55                        clustersMap.put(cluster, i);
56                        Iterator<Node> nodeIterator = cluster.iterator();
57                        while (nodeIterator.hasNext()) {
58                                Node n = nodeIterator.next();
59                                if (nodeMap.get(n) == null) {
60                                        nodeMap.put(n, i);
61                                }
62                        }
63                        i++;
64                }
65        }
66
67        @Override
68        public int clusterInstance(Instance instance) throws Exception {
69                Attribute from = instance.dataset().attribute("from");
70                Attribute to = instance.dataset().attribute("to");
71                Instance edge = instance;
72                Node node1 = new Node(Integer.toString(((int) Math.round(edge
73                                .value(from)))));
74                Node node2 = new Node(Integer.toString(((int) Math
75                                .round(edge.value(to)))));
76                if (nodeMap.get(node1) == nodeMap.get(node2))
77                        return nodeMap.get(node1);
78                else
79                        throw new Exception();
80        }
81
82        /**
83         * Parses a given list of options.
84         * <p/>
85         *
86         * <!-- options-start --> Valid options are:
87         * <p/>
88         *
89         * <pre>
90         * -N &lt;num&gt;
91         *  number of clusters.
92         *  (default 2).
93         * </pre>
94         *
95         * <pre>
96         * -S
97         *  Maximum size of the finer graph during the coarsening phase.
98         * </pre>
99         *
100         * <!-- options-end -->
101         *
102         * @param options
103         *            the list of options as an array of strings
104         * @throws Exception
105         *             if an option is not supported
106         */
107        @Override
108        public void setOptions(String[] options) throws Exception {
109                String optionString = Utils.getOption('N', options);
110                if (optionString.length() != 0) {
111                        setNumClusters(Integer.parseInt(optionString));
112                }
113                optionString = Utils.getOption('S', options);
114                if (optionString.length() != 0) {
115                        setSizeFinerGraph(Integer.parseInt(optionString));
116                }
117                optionString = Utils.getOption('R', options);
118                setRandomBisection(Boolean.parseBoolean(optionString));
119                optionString = Utils.getOption('V', options);
120                if (optionString.length() != 0) {
121                        setVerboseLevel(Integer.parseInt(optionString));
122                }
123                optionString = Utils.getOption('o', options);
124                if (optionString.length() != 0) {
125                        setOutputFile(optionString);
126                }
127        }
128
129        private void setOutputFile(String outputFile) {
130                Configuration.instance().setOutputFile(outputFile);
131        }
132       
133        private String getOutputFile() {
134                return Configuration.instance().getOutputFile();
135        }
136
137        private void setVerboseLevel(int verboseLevel) {
138                Configuration.instance().setVerboseLevel(verboseLevel);
139        }
140
141        private void setRandomBisection(boolean b) {
142                Configuration.instance().setRandomBisection(b);
143        }
144
145        /**
146         * Gets the current settings of MetisMQIClusterer
147         *
148         * @return an array of strings suitable for passing to setOptions()
149         */
150        @SuppressWarnings("unchecked")
151        @Override
152        public String[] getOptions() {
153                Vector result;
154                result = new Vector();
155                result.add("-N");
156                result.add("" + getNumClusters());
157                result.add("-S");
158                result.add("" + getSizeFinerGraph());
159                result.add("-R");
160                result.add("" + getRandomBisection());
161                result.add("-V");
162                result.add("" + getVerboseLevel());
163                result.add("-o");
164                result.add("" + getOutputFile());
165                return (String[]) result.toArray(new String[result.size()]);
166        }
167
168        private boolean getRandomBisection() {
169                return Configuration.instance().isRandomBisection();
170        }
171
172        private int getVerboseLevel() {
173                return Configuration.instance().getVerboseLevel();
174        }
175
176        private int getSizeFinerGraph() {
177                return Configuration.instance().getSizeFinerGraph();
178        }
179
180        private int getNumClusters() {
181                return Configuration.instance().getNumberOfClusters();
182        }
183
184        /**
185         * Returns an enumeration describing the available options.
186         *
187         * @return an enumeration of all the available options.
188         */
189        @SuppressWarnings("unchecked")
190        @Override
191        public Enumeration listOptions() {
192                Vector result = new Vector();
193                result.addElement(new Option("\tnumber of clusters.\n"
194                                + "\t(default 2).", "N", 1, "-N <num>"));
195                result.addElement(new Option("\tsize of finer graph.\n"
196                                + "\t(default 10).", "S", 1, "-S <num>"));
197                result.addElement(new Option("\trandom bisection.\n"
198                                + "\t(default false).", "R", 1, "-V <boolean>"));
199                result.addElement(new Option("\tverbosity of graphical output.\n"
200                                + "\t(default 1).", "V", 1, "-V <num>"));
201                result.addElement(new Option("\tpath of the output file.\n"
202                                , "o", 1, "-o <path>"));
203                return result.elements();
204        }
205
206        private void setSizeFinerGraph(int size) {
207                Configuration.instance().setSizeFinerGraph(size);
208        }
209
210        private void setNumClusters(int n) {
211                Configuration.instance().setNumberOfClusters(n);
212        }
213
214        @Override
215        public double[] distributionForInstance(Instance instance) throws Exception {
216                double[] d = new double[numberOfClusters()];
217                d[clusterInstance(instance)] = 1.0;
218                return d;
219        }
220
221        @Override
222        public Capabilities getCapabilities() {
223                Capabilities result = super.getCapabilities();
224                result.enable(Capability.NUMERIC_ATTRIBUTES);
225                result.enable(Capability.NO_CLASS);
226                return result;
227        }
228
229        @Override
230        public int numberOfClusters() throws Exception {
231                return Configuration.instance().getNumberOfClusters();
232        }
233
234        /**
235         * Main method for executing this clusterer.
236         *
237         * @param args
238         *            the options, use "-h" to display options
239         */
240        public static void main(String[] args) {
241                AbstractClusterer.runClusterer(new MetisMQIClusterer(), args);
242        }
243
244}
Note: See TracBrowser for help on using the repository browser.