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