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