001    package net.sf.cpsolver.coursett;
002    
003    import java.io.BufferedReader;
004    import java.io.File;
005    import java.io.FileReader;
006    import java.io.FileWriter;
007    import java.io.IOException;
008    import java.io.PrintWriter;
009    import java.util.HashMap;
010    import java.util.Iterator;
011    import java.util.Map;
012    import java.util.TreeSet;
013    
014    /**
015     * Process all solutions (files output.csv) in all subfolders of the given
016     * folder and create a CSV (comma separated values text file) combining all
017     * minimal perturbation information of the found solutions.
018     * 
019     * @version CourseTT 1.2 (University Course Timetabling)<br>
020     *          Copyright (C) 2007 - 2010 Tomas Muller<br>
021     *          <a href="mailto:muller@unitime.org">muller@unitime.org</a><br>
022     *          <a href="http://muller.unitime.org">http://muller.unitime.org</a><br>
023     * <br>
024     *          This library is free software; you can redistribute it and/or modify
025     *          it under the terms of the GNU Lesser General Public License as
026     *          published by the Free Software Foundation; either version 3 of the
027     *          License, or (at your option) any later version. <br>
028     * <br>
029     *          This library is distributed in the hope that it will be useful, but
030     *          WITHOUT ANY WARRANTY; without even the implied warranty of
031     *          MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
032     *          Lesser General Public License for more details. <br>
033     * <br>
034     *          You should have received a copy of the GNU Lesser General Public
035     *          License along with this library; if not see
036     *          <a href='http://www.gnu.org/licenses/'>http://www.gnu.org/licenses/</a>.
037     */
038    public class GetMppInfo {
039        public static HashMap<String, String> getInfo(File outputFile) {
040            try {
041                BufferedReader reader = new BufferedReader(new FileReader(outputFile));
042                String line = null;
043                HashMap<String, String> info = new HashMap<String, String>();
044                while ((line = reader.readLine()) != null) {
045                    int idx = line.indexOf(',');
046                    if (idx >= 0) {
047                        String key = line.substring(0, idx).trim();
048                        String value = line.substring(idx + 1).trim();
049                        if (value.indexOf('(') >= 0 && value.indexOf(')') >= 0) {
050                            value = value.substring(value.indexOf('(') + 1, value.indexOf(')'));
051                            if (value.indexOf('/') >= 0) {
052                                String bound = value.substring(value.indexOf('/') + 1);
053                                if (bound.indexOf("..") >= 0) {
054                                    String min = bound.substring(0, bound.indexOf(".."));
055                                    String max = bound.substring(bound.indexOf("..") + 2);
056                                    info.put(key + " Min", min);
057                                    info.put(key + " Max", max);
058                                } else {
059                                    info.put(key + " Bound", bound);
060                                }
061                                value = value.substring(0, value.indexOf('/'));
062                            }
063                        }
064                        if (value.length() > 0)
065                            info.put(key, value);
066                    }
067                }
068                reader.close();
069                return info;
070            } catch (Exception e) {
071                System.err.println("Error reading info, message: " + e.getMessage());
072                e.printStackTrace();
073                return null;
074            }
075        }
076    
077        public static void getInfos(File file, HashMap<String, HashMap<String, HashMap<Integer, double[]>>> infos,
078                String instance) {
079            HashMap<String, String> info = getInfo(file);
080            if (info == null || info.isEmpty() || !info.containsKey("000.053 Given perturbations"))
081                return;
082            Integer pert = Integer.valueOf(info.get("000.053 Given perturbations"));
083            for (Map.Entry<String, String> entry : info.entrySet()) {
084                String key = entry.getKey();
085                String value = entry.getValue();
086                if (!key.startsWith("000.") || key.equals("000.053 Given perturbations"))
087                    continue;
088                HashMap<String, HashMap<Integer, double[]>> keyTable = infos.get(key);
089                if (keyTable == null) {
090                    keyTable = new HashMap<String, HashMap<Integer, double[]>>();
091                    infos.put(key, keyTable);
092                }
093                HashMap<Integer, double[]> instanceTable = keyTable.get(instance);
094                if (instanceTable == null) {
095                    instanceTable = new HashMap<Integer, double[]>();
096                    keyTable.put(instance, instanceTable);
097                }
098                double[] pertTable = instanceTable.get(pert);
099                if (pertTable == null) {
100                    pertTable = new double[] { 0, 0 };
101                    instanceTable.put(pert, pertTable);
102                }
103                pertTable[0] += Double.parseDouble(value);
104                pertTable[1] += 1;
105            }
106        }
107    
108        public static void writeInfos(HashMap<String, HashMap<String, HashMap<Integer, double[]>>> infos, File file)
109                throws IOException {
110            PrintWriter out = new PrintWriter(new FileWriter(file));
111            for (String key: new TreeSet<String>(infos.keySet())) {
112                out.println(key);
113                HashMap<String, HashMap<Integer, double[]>> keyTable = infos.get(key);
114                TreeSet<Integer> perts = new TreeSet<Integer>();
115                for (String instance: new TreeSet<String>(keyTable.keySet())) {
116                    HashMap<Integer, double[]> instanceTable = keyTable.get(instance);
117                    perts.addAll(instanceTable.keySet());
118                }
119                out.print(",,");
120                for (Iterator<Integer> i = perts.iterator(); i.hasNext();) {
121                    Integer pert = i.next();
122                    out.print(pert);
123                    if (i.hasNext())
124                        out.print(",");
125                }
126                out.println();
127                for (String instance: new TreeSet<String>(keyTable.keySet())) {
128                    HashMap<Integer, double[]> instanceTable = keyTable.get(instance);
129                    perts.addAll(instanceTable.keySet());
130                    out.print("," + instance + ",");
131                    for (Iterator<Integer> i = perts.iterator(); i.hasNext();) {
132                        Integer pert = i.next();
133                        double[] pertTable = instanceTable.get(pert);
134                        if (pertTable != null)
135                            out.print(pertTable[0] / pertTable[1]);
136                        if (i.hasNext())
137                            out.print(",");
138                    }
139                    out.println();
140                }
141            }
142            out.flush();
143            out.close();
144        }
145    
146        public static void main(String args[]) {
147            try {
148                File folder = new File(".");
149                if (args.length >= 1)
150                    folder = new File(args[0]);
151                String config = "mpp";
152                if (args.length >= 2)
153                    config = args[1];
154                File[] instanceFolders = folder.listFiles();
155                HashMap<String, HashMap<String, HashMap<Integer, double[]>>> infos = new HashMap<String, HashMap<String, HashMap<Integer, double[]>>>();
156                for (int i = 0; i < instanceFolders.length; i++) {
157                    File instanceFolder = instanceFolders[i];
158                    if (!instanceFolder.exists() || !instanceFolder.isDirectory()
159                            || !instanceFolder.getName().startsWith(config + "-"))
160                        continue;
161                    System.out.println("Checking " + instanceFolder.getName() + " ...");
162                    File[] files = instanceFolder.listFiles();
163                    for (int j = 0; j < files.length; j++)
164                        if (files[j].isDirectory()) {
165                            File outputFile = new File(files[j], "output.csv");
166                            if (outputFile.exists()) {
167                                System.out.println("  Checking " + files[j].getName() + " ...");
168                                getInfos(outputFile, infos, instanceFolder.getName().substring(config.length() + 1));
169                            }
170                        }
171                }
172                if (!infos.isEmpty())
173                    writeInfos(infos, new File(folder, "info.csv"));
174            } catch (Exception e) {
175                e.printStackTrace();
176            }
177        }
178    }