    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}