001package org.cpsolver.coursett;
002
003import java.io.BufferedReader;
004import java.io.File;
005import java.io.FileReader;
006import java.io.FileWriter;
007import java.io.IOException;
008import java.io.PrintWriter;
009import java.util.HashMap;
010import java.util.Iterator;
011import java.util.Map;
012import 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.3 (University Course Timetabling)<br>
020 *          Copyright (C) 2007 - 2014 Tomáš Müller<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 */
038public 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}