001 package net.sf.cpsolver.ifs.example.csp; 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 of Structured CSP problems. It takes one argument -- property file with all the parameters. 014 * It allows to execute given number of tests. It also allows to define several configurations which will be executed. For instance CSP(20,15,5%..95%,5..95%), 10 runs of each configuration. All such configuration are processed in one run of Test class. 015 * <br><br> 016 * In Structured CSP, variables are divided into several kernels (some variables may remain ouside kernels). 017 * Different constraints (in density and tightnes) are generated according to whether variables are from the same kernel or not. 018 * <br><br> 019 * Test's parameters: 020 * <br> 021 * <table border='1'><tr><th>Parameter</th><th>Type</th><th>Comment</th></tr> 022 * <tr><td>General.MPP</td><td>{@link String}</td><td>Minimal perturbation problem (if true), this mj. means that initial assignment will be generated</td></tr> 023 * <tr><td>CSP.Seed</td><td>{@link Long}</td><td>Random number generator seed, {@link System#currentTimeMillis()} is taken if not present</td></tr> 024 * <tr><td>CSP.ForceSolutionExistance</td><td>{@link Boolean}</td><td>If true, generated problem will always have at least one feasible solution</td></tr> 025 * <tr><td>CPS.NrTests</td><td>{@link Integer}</td><td>Number of tests (for each input configuration)</td></tr> 026 * <tr><td>CSP.NrVariables</td><td>{@link Integer}</td><td>Number of variables</td></tr> 027 * <tr><td>CSP.NrVariablesMin<br>CSP.NrVariablesMax<br>CSP.NrVariablesStep</td><td>{@link Integer}</td><td>Range of the number variables (a set of different configurations will be generated)<br>Use either CSP.NrVariables or these CSP.NrVariablesMin, CSP.NrVariablesMax, CSP.NrVariablesStep</td></tr> 028 * <tr><td>CSP.DomainSize</td><td>{@link Integer}</td><td>Number of values of every variable</td></tr> 029 * <tr><td>CSP.DomainSizeRatio</td><td>{@link Double}</td><td>Number of values as a ration of the number of variables. This way we can model for instance CSP(N,2N,p1,p2) problems with one configuration.<br>Use either CSP.DomainSize or CSP.DomainSizeRatio</td></tr> 030 * <tr><td>CSP.Tightness</td><td>{@link Double}</td><td>Tightness of constraints outside kernels</td></tr> 031 * <tr><td>CSP.TightnessMin<br>CSP.TightnessMax<br>CSP.TightnessStep</td><td>{@link Double}</td><td>Tightness of constraints outside kernels given as a range -> respective configurations will be generated and tested</td></tr> 032 * <tr><td>CSP.Density</td><td>{@link Double}</td><td>Density of constraints outside kernels</td></tr> 033 * <tr><td>CSP.DensityMin<br>CSP.DensityMax<br>CSP.DensityStep</td><td>{@link Double}</td><td>Density of constraints outside kernels given as a range -> respective configurations will be generated and tested</td></tr> 034 * <tr><td>CSP.NrKernels</td><td>{@link Integer}</td><td>Number of kernels (Structured CSP, use 0 for "normal" CSP)</td></tr> 035 * <tr><td>CSP.KernelSize</td><td>{@link Integer}</td><td>Number of variables in each kernel</td></tr> 036 * <tr><td>CSP.KernelTightness</td><td>{@link Double}</td><td>Tightness of constraints inside a kernel</td></tr> 037 * <tr><td>CSP.KernelDensity</td><td>{@link Double}</td><td>Density of constraints inside a kernel</td></tr> 038 * <tr><td>CSP.SameProblemEachStep</td><td>{@link Boolean}</td><td>If true, each configuration will start with the same seed</td></tr> 039 * <tr><td>CSP.SameProblemEachTest</td><td>{@link Boolean}</td><td>If true, each test of the same configuration will start with the same seed</td></tr> 040 * <tr><td>General.Output</td><td>{@link String}</td><td>Output folder where a log file and tables with results. In order not to overwrite the results if executed more than once, a subfolder with the name taken from current date and time will be created in this folder and all results will go to this subfolder.</td></tr> 041 * </table> 042 * <br><br> 043 * Also, the configuration file can consist only from one parameter (named INCLUDE_REGEXP) which is processed as a regular expression of semicolon separated list of property files, for instance<ul> 044 * <code>INCLUDE_REGEXP=general.ini;{CSP(50,12,250,p2)|CSP(25,15,198,p2)}.ini;{std|opt}.ini;{10x1min}.ini;{cbs|rw1|tabu20}.ini</code><br> 045 * </ul>where {a|b|c|...} means a selection of a, b, c, .. All possible combinations are taken and for each of them an input configuration is combined from the relevant files. So, for instance, the above example will result into the following configurations:<ul> 046 * <li>general.ini;CSP(50,12,250,p2).ini;std.ini;10x1min.ini;cbs.ini 047 * <li>general.ini;CSP(50,12,250,p2).ini;std.ini;10x1min.ini;rw1.ini 048 * <li>general.ini;CSP(50,12,250,p2).ini;std.ini;10x1min.ini;tabu20.ini 049 * <li>general.ini;CSP(50,12,250,p2).ini;opt.ini;10x1min.ini;cbs.ini 050 * <li>general.ini;CSP(50,12,250,p2).ini;opt.ini;10x1min.ini;rw1.ini 051 * <li>general.ini;CSP(50,12,250,p2).ini;opt.ini;10x1min.ini;tabu20.ini 052 * <li>general.ini;CSP(25,15,198,p2).ini;std.ini;10x1min.ini;cbs.ini 053 * <li>general.ini;CSP(25,15,198,p2).ini;std.ini;10x1min.ini;rw1.ini 054 * <li>general.ini;CSP(25,15,198,p2).ini;std.ini;10x1min.ini;tabu20.ini 055 * <li>general.ini;CSP(25,15,198,p2).ini;opt.ini;10x1min.ini;cbs.ini 056 * <li>general.ini;CSP(25,15,198,p2).ini;opt.ini;10x1min.ini;rw1.ini 057 * <li>general.ini;CSP(25,15,198,p2).ini;opt.ini;10x1min.ini;tabu20.ini 058 * </ul>To be able to distinguish such configuration a subfolder in General.Output folder is created, its name is combined from the names which are in parenthesis. 059 * So, for instance the first bunch of tests will output into the folder:<ul> 060 * ${General.Output}\CSP(50,12,250,p2)_std_10x1min_csb\25-Feb-05_191136 061 * </ul>If one parameter is defined in more than one configuration files (e.g. in general.ini as well as cbs.ini) the one from the file more on the right is taken. 062 * <br><br> 063 * An example of the configurations:<br> 064 * File<b> general.ini</b><ul><code> 065 * #Default settings common for all configurations<br> 066 * General.MPP=false<br> 067 * General.InitialAssignment=false<br> 068 * General.Output=output\\RandomCSP\\IFS<br> 069 * <br> 070 * #Value selection heuristics<br> 071 * Value.Class=net.sf.cpsolver.ifs.heuristics.GeneralValueSelection<br> 072 * Value.WeightWeightedConflicts=0.0<br> 073 * Value.RandomWalkProb=0.0<br> 074 * Value.WeightConflicts=1.0<br> 075 * Value.WeightNrAssignments=0.0<br> 076 * Value.WeightValue=0.0<br> 077 * Value.Tabu=0<br> 078 * <br> 079 * #Variable selection heuristics<br> 080 * Variable.Class=net.sf.cpsolver.ifs.heuristics.GeneralVariableSelection<br> 081 * Variable.RandomSelection=true<br> 082 * <br> 083 * #Termination condition<br> 084 * Termination.Class=net.sf.cpsolver.ifs.termination.GeneralTerminationCondition<br> 085 * Termination.MaxIters=-1<br> 086 * Termination.TimeOut=-1<br> 087 * Termination.StopWhenComplete=true<br> 088 * <br> 089 * #Solution comparator<br> 090 * Comparator.Class=net.sf.cpsolver.ifs.solution.GeneralSolutionComparator<br> 091 * </code></ul><br> 092 * File<b> CSP(50,12,250,p2).ini</b><ul><code> 093 * #Sparse problem CSP(50,12,250/1225,p2)<br> 094 * CSP.NrVariables=50<br> 095 * CSP.DomainSize=12<br> 096 * CSP.Density=0.2<br> 097 * CSP.TightnessMin=0.10<br> 098 * CSP.TightnessMax=0.95<br> 099 * CSP.TightnessStep=0.02<br> 100 * <br> 101 * CSP.Seed=780921<br> 102 * <br> 103 * CSP.ForceSolutionExistance=false<br> 104 * CSP.SameProblemEachStep=false<br> 105 * CSP.SameProblemEachTest=false<br> 106 * <br> 107 * CSP.NrKernels=0<br> 108 * </code></ul><br> 109 * File<b> std.ini</b><ul><code> 110 * #Standard problem<br> 111 * CSP.ForceSolutionExistance=false<br> 112 * </code></ul><br> 113 * File<b> opt.ini</b><ul><code> 114 * #Optimization problem (minCSP)<br> 115 * #Value selection: use weigh of a conflict, but when there are more than one value<br> 116 * # with the same number of conflicts, use the one with lower value<br> 117 * Value.WeightValue=0.0001<br> 118 * Value.WeightConflicts=1.0<br> 119 * #Do not stop when a complete solution is found<br> 120 * Termination.StopWhenComplete=false<br> 121 * </code></ul><br> 122 * File<b> 10x1min.ini</b><ul><code> 123 * #For each configuration, execute 10 tests, each with 1 minute timeout<br> 124 * CPS.NrTests=10<br> 125 * Termination.TimeOut=60<br> 126 * </code></ul><br> 127 * File<b> cbs.ini</b><ul><code> 128 * #Use conflict-based statistics<br> 129 * Extensions.Classes=net.sf.cpsolver.ifs.extension.ConflictStatistics<br> 130 * Value.WeightWeightedConflicts=1.0<br> 131 * </code></ul><br> 132 * File<b> tabu20.ini</b><ul><code> 133 * #Use tabu-list of the length 20<br> 134 * Value.Tabu=20<br> 135 * </code></ul><br> 136 * File<b> rw1.ini</b><ul><code> 137 * #Use 1% random walk selection<br> 138 * Value.RandomWalkProb=0.01<br> 139 * </code></ul><br> 140 * 141 * @see StructuredCSPModel 142 * @see net.sf.cpsolver.ifs.extension.ConflictStatistics 143 * @see net.sf.cpsolver.ifs.heuristics.GeneralValueSelection 144 * @see net.sf.cpsolver.ifs.heuristics.GeneralVariableSelection 145 * @see net.sf.cpsolver.ifs.termination.GeneralTerminationCondition 146 * @see net.sf.cpsolver.ifs.solution.GeneralSolutionComparator 147 * 148 * @version 149 * IFS 1.1 (Iterative Forward Search)<br> 150 * Copyright (C) 2006 Tomáš Müller<br> 151 * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br> 152 * Lazenska 391, 76314 Zlin, Czech Republic<br> 153 * <br> 154 * This library is free software; you can redistribute it and/or 155 * modify it under the terms of the GNU Lesser General Public 156 * License as published by the Free Software Foundation; either 157 * version 2.1 of the License, or (at your option) any later version. 158 * <br><br> 159 * This library is distributed in the hope that it will be useful, 160 * but WITHOUT ANY WARRANTY; without even the implied warranty of 161 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 162 * Lesser General Public License for more details. 163 * <br><br> 164 * You should have received a copy of the GNU Lesser General Public 165 * License along with this library; if not, write to the Free Software 166 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 167 */ 168 public class Test { 169 private static java.text.DecimalFormat sDoubleFormat = new java.text.DecimalFormat("0.000", new java.text.DecimalFormatSymbols(Locale.US)); 170 private static java.text.SimpleDateFormat sDateFormat = new java.text.SimpleDateFormat("dd-MMM-yy_HHmmss", java.util.Locale.US); 171 private static org.apache.log4j.Logger sLogger = org.apache.log4j.Logger.getLogger(Test.class); 172 173 private static void test(DataProperties properties) throws Exception { 174 boolean sameProblemStep = properties.getPropertyBoolean("CSP.SameProblemEachStep", false); 175 boolean sameProblemTest = properties.getPropertyBoolean("CSP.SameProblemEachTest", false); 176 int nrVars = properties.getPropertyInt("CSP.NrVariables",20); 177 int nrKernels = properties.getPropertyInt("CSP.NrKernels", 2); 178 int nrKernelVariables = properties.getPropertyInt("CSP.KernelSize", 8); 179 int nrVariablesMin = properties.getPropertyInt("CSP.NrVariablesMin",nrVars); 180 int nrVariablesMax = properties.getPropertyInt("CSP.NrVariablesMax",nrVars); 181 int nrVariablesStep = properties.getPropertyInt("CSP.NrVariablesStep",1); 182 int nrValues = properties.getPropertyInt("CSP.DomainSize",10); 183 double nrValuesRatio = properties.getPropertyDouble("CSP.DomainSizeRatio",-1); 184 float kernelTightness = properties.getPropertyFloat("CSP.KernelTightness", 0.097f); 185 float kernelDensity = properties.getPropertyFloat("CSP.KernelDensity", 0.097f); 186 float tightnessInit = properties.getPropertyFloat( "CSP.Tightness", 0.4f); 187 float tightnessMin = properties.getPropertyFloat( "CSP.TightnessMin", tightnessInit); 188 float tightnessMax = properties.getPropertyFloat( "CSP.TightnessMax", tightnessInit)+1e-6f; 189 float tightnessStep = properties.getPropertyFloat( "CSP.TightnessStep", 0.1f); 190 float densityInit = properties.getPropertyFloat( "CSP.Density", 0.4f); 191 float densityMin = properties.getPropertyFloat( "CSP.DensityMin", densityInit); 192 float densityMax = properties.getPropertyFloat( "CSP.DensityMax", densityInit)+1e-6f; 193 float densityStep = properties.getPropertyFloat( "CSP.DensityStep", 0.1f); 194 long seed = properties.getPropertyLong( "CSP.Seed", System.currentTimeMillis()); 195 int nrTests = properties.getPropertyInt("CPS.NrTests",10); 196 boolean mpp = properties.getPropertyBoolean("General.MPP", false); 197 PrintWriter logStat = new PrintWriter(new FileWriter(properties.getProperty("General.Output")+File.separator+"rcsp_"+nrVariablesMin+"_"+nrValues+".csv")); 198 PrintWriter logAvgStat = new PrintWriter(new FileWriter(properties.getProperty("General.Output")+File.separator+"avg_stat.csv")); 199 PrintWriter log = new PrintWriter(new FileWriter(properties.getProperty("General.Output")+File.separator+"info.txt")); 200 logStat.println("testNr;nrVars;nrVals;density[%];tightness[%];time[s];iters;speed[it/s];unassConstr;assigned;assigned[%]"+(mpp?";perts;perts[%]":"")+";value;totalValue"); 201 logAvgStat.println("nrVars;nrVals;density[%];tightness[%];time[s];RMStime[s];iters;RMSiters;speed[it/s];unassConst;assigned;RMSassigned;assigned[%]"+(mpp?";perts;RMSperts;perts[%]":"")+";value;RMSvalue;totalValue;RMStotalValue"); 202 System.out.println("Number of variables: "+nrVariablesMin+" .. "+nrVariablesMax+" (step="+nrVariablesStep+")"); 203 System.out.println("Density: "+densityMin+" .. "+densityMax+" (step="+densityStep+")"); 204 System.out.println("Tightness: "+tightnessMin+" .. "+tightnessMax+" (step="+tightnessStep+")"); 205 for (int nrVariables=nrVariablesMin;nrVariables<=nrVariablesMax;nrVariables+=nrVariablesStep) { 206 if (nrValuesRatio>0.0) nrValues = (int)Math.round(nrValuesRatio*nrVariables); 207 for (float density=densityMin;density<=densityMax;density+=densityStep) { 208 for (float tightness=tightnessMin;tightness<=tightnessMax;tightness+=tightnessStep) { 209 log.println("CSP{#Var="+nrVariables+", #Val="+nrValues+", P(density)="+sDoubleFormat.format(100.0*density)+"%, P(tighness)="+sDoubleFormat.format(100.0*tightness)+", "+nrKernels+"x Kernel{#Var="+nrKernelVariables+", P(density)="+sDoubleFormat.format(100.0*kernelDensity)+"%, P(tighness)="+sDoubleFormat.format(100.0*kernelTightness)+"%}}"); 210 double sumTime = 0; 211 double sumTime2 = 0; 212 int sumIters = 0; 213 int sumIters2 = 0; 214 int sumConfl = 0; 215 int sumAssign = 0; 216 int sumAssign2 = 0; 217 int sumPert = 0; 218 int sumPert2 = 0; 219 int sumVal = 0; 220 int sumVal2 = 0; 221 int sumTotalVal = 0; 222 int sumTotalVal2 = 0; 223 double sumAssignPer = 0; 224 double sumPertPer = 0; 225 for (int test=1;test<=nrTests;test++) { 226 log.println(" "+test+". test"); 227 log.flush(); 228 properties.setProperty("CSP.NrVariables", String.valueOf(nrVariables)); 229 properties.setProperty("CSP.Tightness", String.valueOf(tightness)); 230 properties.setProperty("CSP.Density", String.valueOf(density)); 231 232 long currentSeed = (seed*1000000L) + (1000 * (long)((sameProblemStep?densityMin:density)*1000.0)) + ((long)((sameProblemStep?tightnessMin:tightness)*1000.0)); 233 currentSeed = (currentSeed*nrTests) + (sameProblemTest?0:test-1); 234 235 sLogger.debug("Seed: "+currentSeed); 236 StructuredCSPModel csp = new StructuredCSPModel(properties, currentSeed); 237 238 Solver s = new Solver(properties); 239 s.setInitalSolution(csp); 240 s.currentSolution().clearBest(); 241 s.start(); 242 243 try { 244 s.getSolverThread().join(); 245 } catch (NullPointerException npe) {} 246 247 if (s.lastSolution().getBestInfo()==null) sLogger.error("No solution found :-("); 248 sLogger.debug("Last solution:"+s.lastSolution().getInfo()); 249 Solution best = s.lastSolution(); 250 sLogger.debug("Best solution:"+s.lastSolution().getBestInfo()); 251 best.restoreBest(); 252 int val = 0; 253 for (Enumeration iv = best.getModel().assignedVariables().elements(); iv.hasMoreElements();) 254 val += (int)((Variable)iv.nextElement()).getAssignment().toDouble(); 255 int totalVal = val + (best.getModel().unassignedVariables().size()*nrValues); 256 sLogger.debug("Last solution:"+best.getInfo()); 257 logStat.println(test+";"+nrVariables+";"+nrValues+";"+sDoubleFormat.format(density)+";"+sDoubleFormat.format(tightness)+";"+ sDoubleFormat.format(best.getTime())+";"+best.getIteration()+";"+sDoubleFormat.format(((double)best.getIteration())/best.getTime())+";"+best.getModel().unassignedHardConstraints().size()+";"+best.getModel().assignedVariables().size()+";"+sDoubleFormat.format(100.0 * best.getModel().assignedVariables().size() / best.getModel().variables().size())+ (mpp?";"+(best.getModel().perturbVariables().size()+best.getModel().unassignedVariables().size())+";"+sDoubleFormat.format(100.0 * (best.getModel().perturbVariables().size()+best.getModel().unassignedVariables().size()) / best.getModel().variables().size()):"")+";"+val+";"+totalVal); 258 log.println(" seed: "+currentSeed); 259 log.println(" constraints: "+best.getModel().constraints().size()); 260 for (Enumeration i=best.getModel().constraints().elements();i.hasMoreElements();) { 261 CSPBinaryConstraint c = (CSPBinaryConstraint)i.nextElement(); 262 log.println(" "+c.getName()+" ("+c.first().getName()+","+c.second().getName()+")"); 263 for (Enumeration a=c.first().values().elements();a.hasMoreElements();) { 264 Value v0 = (Value)a.nextElement(); 265 log.print(" "); 266 for (Enumeration b=c.second().values().elements();b.hasMoreElements();) { 267 Value v1 = (Value)b.nextElement(); 268 log.print(c.isConsistent(v0,v1)?"1 ":"0 "); 269 } 270 log.println(); 271 } 272 } 273 log.println(" time: "+sDoubleFormat.format(best.getTime())+" s"); 274 log.println(" iteration: "+best.getIteration()); 275 log.println(" speed: "+sDoubleFormat.format(((double)best.getIteration())/best.getTime())+" it/s"); 276 log.println(" assigned: "+best.getModel().assignedVariables().size()+" ("+sDoubleFormat.format(100.0 * best.getModel().assignedVariables().size() / best.getModel().variables().size())+"%)"); 277 log.println(" total value: "+val); 278 if (mpp) log.println(" perturbations:"+(best.getModel().perturbVariables().size()+best.getModel().unassignedVariables().size())+" ("+sDoubleFormat.format(100.0 * (best.getModel().perturbVariables().size()+best.getModel().unassignedVariables().size()) / best.getModel().variables().size())+"%)"); 279 log.print(" solution: "); 280 for (Enumeration i=best.getModel().variables().elements();i.hasMoreElements();) { 281 CSPVariable v = (CSPVariable)i.nextElement(); 282 if (v.getBestAssignment()==null) continue; 283 log.print(v.getName()+"="+v.getBestAssignment().getName()); 284 if (i.hasMoreElements()) log.print(", "); 285 } 286 log.println(); 287 sumTime += best.getTime(); 288 sumTime2 += best.getTime()*best.getTime(); 289 sumIters += best.getIteration(); 290 sumIters2 += best.getIteration()*best.getIteration(); 291 sumConfl += best.getModel().unassignedHardConstraints().size(); 292 sumAssign += best.getModel().assignedVariables().size(); 293 sumAssign2 += best.getModel().assignedVariables().size()*best.getModel().assignedVariables().size(); 294 sumAssignPer += 100.0*((double)best.getModel().assignedVariables().size()/((double)best.getModel().variables().size())); 295 sumVal += val; 296 sumVal2 += val * val; 297 sumTotalVal += totalVal; 298 sumTotalVal2 += totalVal * totalVal; 299 if (mpp) { 300 sumPert += (best.getModel().perturbVariables().size()+best.getModel().unassignedVariables().size()); 301 sumPert2 += (best.getModel().perturbVariables().size()+best.getModel().unassignedVariables().size())*(best.getModel().perturbVariables().size()+best.getModel().unassignedVariables().size()); 302 sumPertPer += 100.0 * (best.getModel().perturbVariables().size()+best.getModel().unassignedVariables().size()) / best.getModel().variables().size(); 303 } 304 log.flush(); 305 logStat.flush(); 306 } 307 logAvgStat.println(nrVariables+";"+nrValues+";"+sDoubleFormat.format(density)+";"+sDoubleFormat.format(tightness)+";"+ 308 sDoubleFormat.format(sumTime/nrTests)+";"+ 309 sDoubleFormat.format(ToolBox.rms(nrTests,sumTime,sumTime2))+";"+ 310 sDoubleFormat.format(((double)sumIters)/nrTests)+";"+ 311 sDoubleFormat.format(ToolBox.rms(nrTests,(double)sumIters,(double)sumIters2))+";"+ 312 sDoubleFormat.format(((double)sumIters)/sumTime)+";"+ 313 sDoubleFormat.format(((double)sumConfl)/nrTests)+";"+ 314 sDoubleFormat.format(((double)sumAssign)/nrTests)+";"+ 315 sDoubleFormat.format(ToolBox.rms(nrTests,(double)sumAssign,(double)sumAssign2))+";"+ 316 sDoubleFormat.format(100.0*((double)sumAssign)/(nrVariables*nrTests))+ 317 (mpp?";"+ 318 sDoubleFormat.format(((double)sumPert)/nrTests)+";"+ 319 sDoubleFormat.format(ToolBox.rms(nrTests,(double)sumPert,(double)sumPert2))+";"+ 320 sDoubleFormat.format(100.0*((double)sumPert)/(nrVariables*nrTests)) 321 :"")+";"+ 322 sDoubleFormat.format(((double)sumVal)/(nrTests*nrVariables))+";"+ 323 sDoubleFormat.format(ToolBox.rms(nrTests,(double)sumVal/nrVariables,(double)sumVal2/(nrVariables*nrVariables)))+";"+ 324 sDoubleFormat.format(((double)sumTotalVal)/nrTests)+";"+ 325 sDoubleFormat.format(ToolBox.rms(nrTests,(double)sumTotalVal,(double)sumTotalVal2))); 326 logAvgStat.flush(); 327 } 328 } 329 } 330 log.flush(); 331 log.close(); 332 logStat.flush(); 333 logStat.close(); 334 logAvgStat.flush(); 335 logAvgStat.close(); 336 } 337 338 private static void test(File inputCfg, String name, String include, String regexp, String outDir) throws Exception { 339 if (regexp != null) { 340 String incFile; 341 342 if (regexp.indexOf(';') > 0) { 343 incFile = regexp.substring(0, regexp.indexOf(';')); 344 regexp = regexp.substring(regexp.indexOf(';') + 1); 345 } else { 346 incFile = regexp; 347 regexp = null; 348 } 349 if (incFile.startsWith("[") && incFile.endsWith("]")) { 350 test(inputCfg, name, include, regexp, outDir); 351 incFile = incFile.substring(1, incFile.length() - 1); 352 } 353 if (incFile.indexOf('{') >= 0 && incFile.indexOf('}') >= 0) { 354 String prefix = incFile.substring(0, incFile.indexOf('{')); 355 StringTokenizer middle = new StringTokenizer(incFile.substring(incFile.indexOf('{')+1,incFile.indexOf('}')),"|"); 356 String sufix = incFile.substring(incFile.indexOf('}') + 1); 357 358 while (middle.hasMoreTokens()) { 359 String m = middle.nextToken(); 360 361 test(inputCfg, (name==null?"":name+"_")+m, (include==null?"":include+";")+prefix+m+sufix, regexp, outDir); 362 } 363 } else { 364 test(inputCfg, name, (include == null ? "" : include + ";") + incFile, regexp, outDir); 365 } 366 } else { 367 DataProperties properties = ToolBox.loadProperties(inputCfg); 368 StringTokenizer inc = new StringTokenizer(include, ";"); 369 370 while (inc.hasMoreTokens()) { 371 String aFile = inc.nextToken(); 372 373 System.out.println(" Loading included file '" + aFile+ "' ... "); 374 FileInputStream is = null; 375 376 if ((new File(aFile)).exists()) { 377 is = new FileInputStream(aFile); 378 } 379 if ((new File(inputCfg.getParent() + File.separator + aFile)).exists()) { 380 is = new FileInputStream(inputCfg.getParent() + File.separator + aFile); 381 } 382 if (is == null) { 383 System.err.println("Unable to find include file '" + aFile + "'."); 384 } 385 properties.load(is); 386 is.close(); 387 } 388 String outDirThisTest = (outDir==null?properties.getProperty("General.Output","."):outDir)+File.separator + name+File.separator+sDateFormat.format(new Date()); 389 properties.setProperty("General.Output", outDirThisTest.toString()); 390 System.out.println("Output folder: "+properties.getProperty("General.Output")); 391 (new File(outDirThisTest)).mkdirs(); 392 ToolBox.configureLogging(outDirThisTest, null); 393 FileOutputStream fos = new FileOutputStream(outDirThisTest + File.separator + "rcsp.conf"); 394 395 properties.store(fos, "Random CSP problem configuration file"); 396 fos.flush(); fos.close(); 397 test(properties); 398 } 399 } 400 401 public static void main(String[] args) { 402 try { 403 Progress.getInstance().addProgressListener(new ProgressWriter(System.out)); 404 File inputCfg = new File(args[0]); 405 DataProperties properties = ToolBox.loadProperties(inputCfg); 406 if (properties.getProperty("INCLUDE_REGEXP") != null) { 407 test(inputCfg, null, null, properties.getProperty("INCLUDE_REGEXP"), (args.length>1?args[1]:null)); 408 } else { 409 String outDir = properties.getProperty("General.Output", ".") + File.separator + inputCfg.getName().substring(0, inputCfg.getName().lastIndexOf('.')) + File.separator + sDateFormat.format(new Date()); 410 if (args.length>1) 411 outDir = args[1]+File.separator+(sDateFormat.format(new Date())); 412 properties.setProperty("General.Output", outDir.toString()); 413 System.out.println("Output folder: "+properties.getProperty("General.Output")); 414 (new File(outDir)).mkdirs(); 415 ToolBox.configureLogging(outDir, null); 416 test(properties); 417 } 418 } catch (Exception e) { 419 e.printStackTrace(); 420 } 421 } 422 }