    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}