    001    package ifs.example.tt;
    002
    003    import ifs.model.*;
    004    import ifs.solution.*;
    005    import ifs.solver.*;
    006    import ifs.util.*;
    007
    008    import java.io.*;
    009    import java.util.*;
    010
    011    /**
    012     * Test
    013     *
    014     * @author <a href="mailto:muller@ktiml.mff.cuni.cz">Tomáš Müller</a>
    015     * @version 1.0
    016     */
    017    public class Test {
    018        private static java.text.DecimalFormat sDoubleFormat = new java.text.DecimalFormat("0.000", new java.text.DecimalFormatSymbols(Locale.US));
    019        private static java.text.SimpleDateFormat sDateFormat = new java.text.SimpleDateFormat("dd-MMM-yy_HHmmss", java.util.Locale.US);
    020        private static org.apache.log4j.Logger sLogger = org.apache.log4j.Logger.getLogger(Test.class);
    021
    022        public static void test2(DataProperties properties) throws Exception {
    023            int nrTests = properties.getPropertyInt("Test.NrTests",1);
    024            PrintWriter logStat = new PrintWriter(new FileWriter(properties.getProperty("General.Output")+File.separator+"output.csv"));
    025            PrintWriter logAvgStat = new PrintWriter(new FileWriter(properties.getProperty("General.Output")+File.separator+"avg_stat.csv"));
    026            logStat.println("fillFact;nrResources;testNr;time[s];iters;speed[it/s];assigned;assigned[%];value;totalValue");
    027            logAvgStat.println("fillFact;nrResources;time[s];RMStime[s];iters;RMSiters;speed[it/s];assigned;RMSassigned;assigned[%];value;RMSvalue");
    028
    029            int nrResourcesMin = properties.getPropertyInt("Test.NrResourcesMin", -1);
    030            int nrResourcesMax = properties.getPropertyInt("Test.NrResourcesMax", -1);
    031            int nrResourcesStep = properties.getPropertyInt("Test.NrResourcesStep", 1);
    032            double fillFactorMin = properties.getPropertyDouble("Test.FillFactorMin", -1.0);
    033            double fillFactorMax = properties.getPropertyDouble("Test.FillFactorMax", -1.0);
    034            double fillFactorStep = properties.getPropertyDouble("Test.FillFactorStep", 0.01);
    035
    036            boolean saveInit = properties.getPropertyBoolean("General.SaveInitialXML", true);
    037            boolean saveSol = properties.getPropertyBoolean("General.SaveSolutionXML", true);
    038
    039            for (int nrResources=nrResourcesMin;nrResources<=nrResourcesMax;nrResources+=nrResourcesStep) {
    040                for (double fillFactor=fillFactorMin;fillFactor<=fillFactorMax;fillFactor+=fillFactorStep) {
    041                    double sumTime = 0;
    042                    double sumTime2 = 0;
    043                    int sumIters = 0;
    044                    int sumIters2 = 0;
    045                    int sumAssign = 0;
    046                    int sumAssign2 = 0;
    047                    int sumVal = 0;
    048                    int sumVal2 = 0;
    049                    int sumVar = 0;
    050                    int sumVar2 = 0;
    051                    for (int test=1;test<=nrTests;test++) {
    052                        if (nrResources>=0) {
    053                            properties.setProperty("Generator.NrRooms", String.valueOf(nrResources));
    054                            properties.setProperty("Generator.NrClasses", String.valueOf(nrResources));
    055                            properties.setProperty("Generator.NrInstructors", String.valueOf(nrResources));
    056                        }
    057                        if (fillFactor>=0.0) {
    058                            properties.setProperty("Generator.FillFactor", String.valueOf(fillFactor));
    059                        }
    060                        TimetableModel m = TimetableModel.generate(properties);
    061
    062                        Solver s = new Solver(properties);
    063                        if (saveInit) m.saveAsXML(properties, true, null,
    064                                new File(properties.getProperty("General.Output")+File.separator+"SimpleTT("+
    065                                (nrResources<0?properties.getPropertyInt("Generator.NrRooms",20):nrResources)+","+
    066                                ((int)(100.0*(fillFactor<0.0?properties.getPropertyDouble("Generator.FillFactor",0.8):fillFactor)+0.5))+","+
    067                                properties.getPropertyInt("Generator.NrDependencies",50)+")_"+test+".xml"));
    068                        s.setInitalSolution(m);
    069                        s.currentSolution().clearBest();
    070                        s.start();
    071                        try {
    072                            s.getSolverThread().join();
    073                        } catch (NullPointerException npe) {}
    074
    075
    076
    077                        if (s.lastSolution().getBestInfo()==null) sLogger.error("No solution found :-(");
    078                        sLogger.debug("Last solution:"+s.lastSolution().getInfo());
    079                        Solution best = s.lastSolution();
    080                        sLogger.debug("Best solution:"+s.lastSolution().getBestInfo());
    081                        best.restoreBest();
    082                        int val = 0;
    083                        for (Enumeration iv = best.getModel().assignedVariables().elements(); iv.hasMoreElements();)
    084                            val += ((Variable)iv.nextElement()).getAssignment().toInt();
    085                        if (saveSol) m.saveAsXML(properties, true, best,
    086                                new File(properties.getProperty("General.Output")+File.separator+"SimpleTT("+
    087                                (nrResources<0?properties.getPropertyInt("Generator.NrRooms",20):nrResources)+","+
    088                                ((int)(100.0*(fillFactor<0.0?properties.getPropertyDouble("Generator.FillFactor",0.8):fillFactor)+0.5))+","+
    089                                properties.getPropertyInt("Generator.NrDependencies",50)+")_"+test+"_sol.xml"));
    090                        sLogger.debug("Last solution:"+best.getInfo());
    091                        logStat.println(
    092                                sDoubleFormat.format(properties.getPropertyDouble("Generator.FillFactor",0.0))+";"+
    093                                sDoubleFormat.format(properties.getPropertyInt("Generator.NrRooms",0))+";"+
    094                                test+";"+sDoubleFormat.format(best.getTime())+";"+best.getIteration()+";"+sDoubleFormat.format(((double)best.getIteration())/best.getTime())+";"+best.getModel().assignedVariables().size()+";"+sDoubleFormat.format(100.0 * best.getModel().assignedVariables().size() / best.getModel().variables().size())+";"+val);
    095                        sLogger.debug("    time:         "+sDoubleFormat.format(best.getTime())+" s");
    096                        sLogger.debug("    iteration:    "+best.getIteration());
    097                        sLogger.debug("    speed:        "+sDoubleFormat.format(((double)best.getIteration())/best.getTime())+" it/s");
    098                        sLogger.debug("    assigned:     "+best.getModel().assignedVariables().size()+" ("+sDoubleFormat.format(100.0 * best.getModel().assignedVariables().size() / best.getModel().variables().size())+"%)");
    099                        sLogger.debug("    value:        "+val);
    100                        sumTime += best.getTime();
    101                        sumTime2 += best.getTime()*best.getTime();
    102                        sumIters += best.getIteration();
    103                        sumIters2 += best.getIteration()*best.getIteration();
    104                        sumAssign += best.getModel().assignedVariables().size();
    105                        sumAssign2 += best.getModel().assignedVariables().size()*best.getModel().assignedVariables().size();
    106                        sumVal += val;
    107                        sumVal2 += val * val;
    108                        sumVar += m.variables().size();
    109                        sumVar2 += m.variables().size()*m.variables().size();
    110                        logStat.flush();
    111                    }
    112                    logAvgStat.println(
    113                            sDoubleFormat.format(properties.getPropertyDouble("Generator.FillFactor",0.0))+";"+
    114                            sDoubleFormat.format(properties.getPropertyInt("Generator.NrRooms",0))+";"+
    115                            sDoubleFormat.format(sumTime/nrTests)+";"+
    116                            sDoubleFormat.format(ToolBox.rms(nrTests,sumTime,sumTime2))+";"+
    117                            sDoubleFormat.format(((double)sumIters)/nrTests)+";"+
    118                            sDoubleFormat.format(ToolBox.rms(nrTests,(double)sumIters,(double)sumIters2))+";"+
    119                            sDoubleFormat.format(((double)sumIters)/sumTime)+";"+
    120                            sDoubleFormat.format(((double)sumAssign)/nrTests)+";"+
    121                            sDoubleFormat.format(ToolBox.rms(nrTests,(double)sumAssign,(double)sumAssign2))+";"+
    122                            sDoubleFormat.format(100.0 * ((double) sumAssign) / sumVar)+";"+
    123                            sDoubleFormat.format(((double)sumVal)/nrTests)+";"+
    124                            sDoubleFormat.format(ToolBox.rms(nrTests,(double)sumVal,(double)sumVal2)));
    125                    logAvgStat.flush();
    126                }
    127            }
    128            logStat.close();
    129            logAvgStat.close();
    130        }
    131
    132        public static void test3(DataProperties properties, File xmlFile) throws Exception {
    133            int nrTests = properties.getPropertyInt("Test.NrTests",1);
    134            PrintWriter logStat = new PrintWriter(new FileWriter(properties.getProperty("General.Output")+File.separator+"output.csv"));
    135            logStat.println("fillFact;nrResources;testNr;time[s];iters;speed[it/s];assigned;assigned[%];value;totalValue");
    136
    137            boolean saveSol = properties.getPropertyBoolean("General.SaveSolutionXML", true);
    138            boolean assign = properties.getPropertyBoolean("General.InitialAssignment", true);
    139            int forcedPerturbances = properties.getPropertyInt("General.ForcedPerturbances", 0);
    140
    141            for (int test=1;test<=nrTests;test++) {
    142                TimetableModel m = TimetableModel.loadFromXML(xmlFile, assign);
    143
    144                if (forcedPerturbances>0) {
    145                    Vector initialVariables = new Vector();
    146                    for (Enumeration e=m.variables().elements();e.hasMoreElements();) {
    147                        Variable v = (Variable)e.nextElement();
    148                        if (v.getInitialAssignment()!=null)
    149                            initialVariables.addElement(v);
    150                    }
    151                    for (int i=0;i<forcedPerturbances;i++) {
    152                        if (initialVariables.isEmpty()) break;
    153                        Variable var = (Variable)ToolBox.random(initialVariables);
    154                        initialVariables.remove(var);
    155                        var.removeInitialValue();
    156                    }
    157                }
    158
    159                Solver s = new Solver(properties);
    160                s.setInitalSolution(m);
    161                s.currentSolution().clearBest();
    162                s.start();
    163                try {
    164                    s.getSolverThread().join();
    165                } catch (NullPointerException npe) {}
    166
    167                if (s.lastSolution().getBestInfo()==null) sLogger.error("No solution found :-(");
    168                sLogger.debug("Last solution:"+s.lastSolution().getInfo());
    169                Solution best = s.lastSolution();
    170                sLogger.debug("Best solution:"+s.lastSolution().getBestInfo());
    171                best.restoreBest();
    172                int val = 0;
    173                for (Enumeration iv = best.getModel().assignedVariables().elements(); iv.hasMoreElements();)
    174                    val += ((Variable)iv.nextElement()).getAssignment().toInt();
    175                if (saveSol) m.saveAsXML(properties, false, best, new File(properties.getProperty("General.Output")+File.separator+"solution_"+test+".xml"));
    176                sLogger.debug("Last solution:"+best.getInfo());
    177                logStat.println(
    178                        sDoubleFormat.format(properties.getPropertyDouble("Generator.FillFactor",0.0))+";"+
    179                        sDoubleFormat.format(properties.getPropertyInt("Generator.NrRooms",0))+";"+
    180                        test+";"+sDoubleFormat.format(best.getTime())+";"+best.getIteration()+";"+sDoubleFormat.format(((double)best.getIteration())/best.getTime())+";"+best.getModel().assignedVariables().size()+";"+sDoubleFormat.format(100.0 * best.getModel().assignedVariables().size() / best.getModel().variables().size())+";"+val);
    181                sLogger.debug("    time:         "+sDoubleFormat.format(best.getTime())+" s");
    182                sLogger.debug("    iteration:    "+best.getIteration());
    183                sLogger.debug("    speed:        "+sDoubleFormat.format(((double)best.getIteration())/best.getTime())+" it/s");
    184                sLogger.debug("    assigned:     "+best.getModel().assignedVariables().size()+" ("+sDoubleFormat.format(100.0 * best.getModel().assignedVariables().size() / best.getModel().variables().size())+"%)");
    185                sLogger.debug("    value:        "+val);
    186                logStat.flush();
    187            }
    188            logStat.close();
    189        }
    190
    191        public static void test(File inputCfg, String name, String include, String regexp, String outDir) throws Exception {
    192            if (regexp != null) {
    193                String incFile;
    194
    195                if (regexp.indexOf(';') > 0) {
    196                    incFile = regexp.substring(0, regexp.indexOf(';'));
    197                    regexp = regexp.substring(regexp.indexOf(';') + 1);
    198                } else {
    199                    incFile = regexp;
    200                    regexp = null;
    201                }
    202                if (incFile.startsWith("[") && incFile.endsWith("]")) {
    203                    test(inputCfg, name, include, regexp, outDir);
    204                    incFile = incFile.substring(1, incFile.length() - 1);
    205                }
    206                if (incFile.indexOf('{') >= 0 && incFile.indexOf('}') >= 0) {
    207                    String prefix = incFile.substring(0, incFile.indexOf('{'));
    208                    StringTokenizer middle = new StringTokenizer(incFile.substring(incFile.indexOf('{') + 1, incFile.indexOf('}')), "|");
    209                    String sufix = incFile.substring(incFile.indexOf('}') + 1);
    210
    211                    while (middle.hasMoreTokens()) {
    212                        String m = middle.nextToken();
    213
    214                        test(inputCfg, (name == null ? "" : name + "_") + m, (include == null ? "" : include + ";") + prefix + m + sufix, regexp, outDir);
    215                    }
    216                } else {
    217                    test(inputCfg, name, (include == null ? "" : include + ";") + incFile, regexp, outDir);
    218                }
    219            } else {
    220                DataProperties properties = ToolBox.loadProperties(inputCfg);
    221                StringTokenizer inc = new StringTokenizer(include, ";");
    222
    223                while (inc.hasMoreTokens()) {
    224                    String aFile = inc.nextToken();
    225
    226                    System.out.println("  Loading included file '" + aFile + "' ... ");
    227                    FileInputStream is = null;
    228
    229                    if ((new File(aFile)).exists()) {
    230                        is = new FileInputStream(aFile);
    231                    }
    232                    if ((new File(inputCfg.getParent() + File.separator + aFile)).exists()) {
    233                        is = new FileInputStream(inputCfg.getParent() + File.separator + aFile);
    234                    }
    235                    if (is == null) {
    236                        System.err.println("Unable to find include file '" + aFile + "'.");
    237                    }
    238                    properties.load(is);
    239                    is.close();
    240                }
    241                String outDirThisTest = (outDir==null?properties.getProperty("General.Output","."):outDir)+File.separator + name+File.separator+sDateFormat.format(new Date());
    242                properties.setProperty("General.Output", outDirThisTest.toString());
    243                System.out.println("Output folder: "+properties.getProperty("General.Output"));
    244                (new File(outDirThisTest)).mkdirs();
    245                ToolBox.configureLogging(outDirThisTest, null);
    246                FileOutputStream fos = new FileOutputStream(outDirThisTest + File.separator + "rcsp.conf");
    247
    248                properties.store(fos, "Random CSP problem configuration file");
    249                fos.flush(); fos.close();
    250                test2(properties);
    251            }
    252        }
    253
    254        public static void main(String[] args) {
    255            try {
    256                Progress.getInstance().addProgressListener(new ProgressWriter(System.out));
    257                File inputCfg = new File(args[0]);
    258                DataProperties properties = ToolBox.loadProperties(inputCfg);
    259                if (args.length==3) {
    260                    File xmlFile = new File(args[1]);
    261                    String outDir = args[2]+File.separator+(sDateFormat.format(new Date()));
    262                    properties.setProperty("General.Output", outDir.toString());
    263                    System.out.println("Input file: "+xmlFile);
    264                    System.out.println("Output folder: "+properties.getProperty("General.Output"));
    265                    (new File(outDir)).mkdirs();
    266                    ToolBox.configureLogging(outDir, null);
    267                    test3(properties, xmlFile);
    268                } else if (properties.getProperty("INCLUDE_REGEXP") != null) {
    269                    test(inputCfg, null, null, properties.getProperty("INCLUDE_REGEXP"), (args.length>1?args[1]:null));
    270                } else {
    271                    String outDir = properties.getProperty("General.Output", ".") + File.separator + inputCfg.getName().substring(0, inputCfg.getName().lastIndexOf('.')) + File.separator + sDateFormat.format(new Date());
    272                    if (args.length>1)
    273                        outDir = args[1]+File.separator+(sDateFormat.format(new Date()));
    274                    properties.setProperty("General.Output", outDir.toString());
    275                    System.out.println("Output folder: "+properties.getProperty("General.Output"));
    276                    (new File(outDir)).mkdirs();
    277                    ToolBox.configureLogging(outDir, null);
    278                    test2(properties);
    279                }
    280            } catch (Exception e) {
    281                e.printStackTrace();
    282            }
    283        }
    284    }