001package org.cpsolver.ifs.example.csp; 002 003import java.io.File; 004import java.io.FileInputStream; 005import java.io.FileOutputStream; 006import java.io.FileWriter; 007import java.io.PrintWriter; 008import java.util.Date; 009import java.util.Iterator; 010import java.util.Locale; 011import java.util.StringTokenizer; 012 013import org.cpsolver.ifs.model.Constraint; 014import org.cpsolver.ifs.solution.Solution; 015import org.cpsolver.ifs.solver.Solver; 016import org.cpsolver.ifs.util.DataProperties; 017import org.cpsolver.ifs.util.Progress; 018import org.cpsolver.ifs.util.ProgressWriter; 019import org.cpsolver.ifs.util.ToolBox; 020 021 022/** 023 * Test of Structured CSP problems. It takes one argument -- property file with 024 * all the parameters. It allows to execute given number of tests. It also 025 * allows to define several configurations which will be executed. For instance 026 * CSP(20,15,5%..95%,5..95%), 10 runs of each configuration. All such 027 * configuration are processed in one run of Test class. <br> 028 * <br> 029 * In Structured CSP, variables are divided into several kernels (some variables 030 * may remain ouside kernels). Different constraints (in density and tightnes) 031 * are generated according to whether variables are from the same kernel or not. <br> 032 * <br> 033 * Test's parameters: <br> 034 * <table border='1' summary='Related Solver Parameters'> 035 * <tr> 036 * <th>Parameter</th> 037 * <th>Type</th> 038 * <th>Comment</th> 039 * </tr> 040 * <tr> 041 * <td>General.MPP</td> 042 * <td>{@link String}</td> 043 * <td>Minimal perturbation problem (if true), this mj. means that initial 044 * assignment will be generated</td> 045 * </tr> 046 * <tr> 047 * <td>CSP.Seed</td> 048 * <td>{@link Long}</td> 049 * <td>Random number generator seed, {@link System#currentTimeMillis()} is taken 050 * if not present</td> 051 * </tr> 052 * <tr> 053 * <td>CSP.ForceSolutionExistance</td> 054 * <td>{@link Boolean}</td> 055 * <td>If true, generated problem will always have at least one feasible 056 * solution</td> 057 * </tr> 058 * <tr> 059 * <td>CPS.NrTests</td> 060 * <td>{@link Integer}</td> 061 * <td>Number of tests (for each input configuration)</td> 062 * </tr> 063 * <tr> 064 * <td>CSP.NrVariables</td> 065 * <td>{@link Integer}</td> 066 * <td>Number of variables</td> 067 * </tr> 068 * <tr> 069 * <td>CSP.NrVariablesMin<br> 070 * CSP.NrVariablesMax<br> 071 * CSP.NrVariablesStep</td> 072 * <td>{@link Integer}</td> 073 * <td>Range of the number variables (a set of different configurations will be 074 * generated)<br> 075 * Use either CSP.NrVariables or these CSP.NrVariablesMin, CSP.NrVariablesMax, 076 * CSP.NrVariablesStep</td> 077 * </tr> 078 * <tr> 079 * <td>CSP.DomainSize</td> 080 * <td>{@link Integer}</td> 081 * <td>Number of values of every variable</td> 082 * </tr> 083 * <tr> 084 * <td>CSP.DomainSizeRatio</td> 085 * <td>{@link Double}</td> 086 * <td>Number of values as a ration of the number of variables. This way we can 087 * model for instance CSP(N,2N,p1,p2) problems with one configuration.<br> 088 * Use either CSP.DomainSize or CSP.DomainSizeRatio</td> 089 * </tr> 090 * <tr> 091 * <td>CSP.Tightness</td> 092 * <td>{@link Double}</td> 093 * <td>Tightness of constraints outside kernels</td> 094 * </tr> 095 * <tr> 096 * <td>CSP.TightnessMin<br> 097 * CSP.TightnessMax<br> 098 * CSP.TightnessStep</td> 099 * <td>{@link Double}</td> 100 * <td>Tightness of constraints outside kernels given as a range → respective 101 * configurations will be generated and tested</td> 102 * </tr> 103 * <tr> 104 * <td>CSP.Density</td> 105 * <td>{@link Double}</td> 106 * <td>Density of constraints outside kernels</td> 107 * </tr> 108 * <tr> 109 * <td>CSP.DensityMin<br> 110 * CSP.DensityMax<br> 111 * CSP.DensityStep</td> 112 * <td>{@link Double}</td> 113 * <td>Density of constraints outside kernels given as a range → respective 114 * configurations will be generated and tested</td> 115 * </tr> 116 * <tr> 117 * <td>CSP.NrKernels</td> 118 * <td>{@link Integer}</td> 119 * <td>Number of kernels (Structured CSP, use 0 for "normal" CSP)</td> 120 * </tr> 121 * <tr> 122 * <td>CSP.KernelSize</td> 123 * <td>{@link Integer}</td> 124 * <td>Number of variables in each kernel</td> 125 * </tr> 126 * <tr> 127 * <td>CSP.KernelTightness</td> 128 * <td>{@link Double}</td> 129 * <td>Tightness of constraints inside a kernel</td> 130 * </tr> 131 * <tr> 132 * <td>CSP.KernelDensity</td> 133 * <td>{@link Double}</td> 134 * <td>Density of constraints inside a kernel</td> 135 * </tr> 136 * <tr> 137 * <td>CSP.SameProblemEachStep</td> 138 * <td>{@link Boolean}</td> 139 * <td>If true, each configuration will start with the same seed</td> 140 * </tr> 141 * <tr> 142 * <td>CSP.SameProblemEachTest</td> 143 * <td>{@link Boolean}</td> 144 * <td>If true, each test of the same configuration will start with the same 145 * seed</td> 146 * </tr> 147 * <tr> 148 * <td>General.Output</td> 149 * <td>{@link String}</td> 150 * <td>Output folder where a log file and tables with results. In order not to 151 * overwrite the results if executed more than once, a subfolder with the name 152 * taken from current date and time will be created in this folder and all 153 * results will go to this subfolder.</td> 154 * </tr> 155 * </table> 156 * <br> 157 * <br> 158 * Also, the configuration file can consist only from one parameter (named 159 * INCLUDE_REGEXP) which is processed as a regular expression of semicolon 160 * separated list of property files, for instance 161 * <pre><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></pre> 162 * where {a|b|c|...} means a selection of a, b, c, .. All possible combinations 163 * are taken and for each of them an input configuration is combined from the 164 * relevant files. So, for instance, the above example will result into the 165 * following configurations: 166 * <ul> 167 * <li>general.ini;CSP(50,12,250,p2).ini;std.ini;10x1min.ini;cbs.ini 168 * <li>general.ini;CSP(50,12,250,p2).ini;std.ini;10x1min.ini;rw1.ini 169 * <li>general.ini;CSP(50,12,250,p2).ini;std.ini;10x1min.ini;tabu20.ini 170 * <li>general.ini;CSP(50,12,250,p2).ini;opt.ini;10x1min.ini;cbs.ini 171 * <li>general.ini;CSP(50,12,250,p2).ini;opt.ini;10x1min.ini;rw1.ini 172 * <li>general.ini;CSP(50,12,250,p2).ini;opt.ini;10x1min.ini;tabu20.ini 173 * <li>general.ini;CSP(25,15,198,p2).ini;std.ini;10x1min.ini;cbs.ini 174 * <li>general.ini;CSP(25,15,198,p2).ini;std.ini;10x1min.ini;rw1.ini 175 * <li>general.ini;CSP(25,15,198,p2).ini;std.ini;10x1min.ini;tabu20.ini 176 * <li>general.ini;CSP(25,15,198,p2).ini;opt.ini;10x1min.ini;cbs.ini 177 * <li>general.ini;CSP(25,15,198,p2).ini;opt.ini;10x1min.ini;rw1.ini 178 * <li>general.ini;CSP(25,15,198,p2).ini;opt.ini;10x1min.ini;tabu20.ini 179 * </ul> 180 * To be able to distinguish such configuration a subfolder in General.Output 181 * folder is created, its name is combined from the names which are in 182 * parenthesis. So, for instance the first bunch of tests will output into the 183 * folder: 184 * <pre><code> 185 * ${General.Output}\CSP(50,12,250,p2)_std_10x1min_csb\25-Feb-05_191136 186 * </code></pre> 187 * If one parameter is defined in more than one configuration files (e.g. in 188 * general.ini as well as cbs.ini) the one from the file more on the right is 189 * taken. <br> 190 * <br> 191 * An example of the configurations:<br> 192 * File<b> general.ini</b> 193 * <pre><code> 194 * #Default settings common for all configurations 195 * General.MPP=false 196 * General.InitialAssignment=false 197 * General.Output=output\\RandomCSP\\IFS 198 * 199 * #Value selection heuristics 200 * Value.Class=org.cpsolver.ifs.heuristics.GeneralValueSelection 201 * Value.WeightWeightedConflicts=0.0 202 * Value.RandomWalkProb=0.0 203 * Value.WeightConflicts=1.0 204 * Value.WeightNrAssignments=0.0 205 * Value.WeightValue=0.0 206 * Value.Tabu=0 207 * 208 * #Variable selection heuristics 209 * Variable.Class=org.cpsolver.ifs.heuristics.GeneralVariableSelection 210 * Variable.RandomSelection=true 211 * 212 * #Termination condition 213 * Termination.Class=org.cpsolver.ifs.termination.GeneralTerminationCondition 214 * Termination.MaxIters=-1 215 * Termination.TimeOut=-1 216 * Termination.StopWhenComplete=true 217 * 218 * #Solution comparator 219 * Comparator.Class=org.cpsolver.ifs.solution.GeneralSolutionComparator 220 * </code></pre> 221 * File<b> CSP(50,12,250,p2).ini</b> 222 * <pre><code> 223 * #Sparse problem CSP(50,12,250/1225,p2) 224 * CSP.NrVariables=50 225 * CSP.DomainSize=12 226 * CSP.Density=0.2 227 * CSP.TightnessMin=0.10 228 * CSP.TightnessMax=0.95 229 * CSP.TightnessStep=0.02 230 * 231 * CSP.Seed=780921 232 * 233 * CSP.ForceSolutionExistance=false 234 * CSP.SameProblemEachStep=false 235 * CSP.SameProblemEachTest=false 236 * 237 * CSP.NrKernels=0 238 * </code></pre> 239 * File<b> std.ini</b> 240 * <pre><code> 241 * #Standard problem 242 * CSP.ForceSolutionExistance=false 243 * </code></pre> 244 * File<b> opt.ini</b> 245 * <pre><code> 246 * #Optimization problem (minCSP) 247 * #Value selection: use weigh of a conflict, but when there are more than one value 248 * # with the same number of conflicts, use the one with lower value 249 * Value.WeightValue=0.0001 250 * Value.WeightConflicts=1.0 251 * #Do not stop when a complete solution is found 252 * Termination.StopWhenComplete=false 253 * </code></pre> 254 * File<b> 10x1min.ini</b> 255 * <pre><code> 256 * #For each configuration, execute 10 tests, each with 1 minute timeout 257 * CPS.NrTests=10 258 * Termination.TimeOut=60 259 * </code></pre> 260 * File<b> cbs.ini</b> 261 * <pre><code> 262 * #Use conflict-based statistics 263 * Extensions.Classes=org.cpsolver.ifs.extension.ConflictStatistics 264 * Value.WeightWeightedConflicts=1.0 265 * </code></pre> 266 * File<b> tabu20.ini</b> 267 * <pre><code> 268 * #Use tabu-list of the length 20 269 * Value.Tabu=20 270 * </code></pre> 271 * File<b> rw1.ini</b> 272 * <pre><code> 273 * #Use 1% random walk selection 274 * Value.RandomWalkProb=0.01 275 * </code></pre> 276 * 277 * @see StructuredCSPModel 278 * @see org.cpsolver.ifs.extension.ConflictStatistics 279 * @see org.cpsolver.ifs.heuristics.GeneralValueSelection 280 * @see org.cpsolver.ifs.heuristics.GeneralVariableSelection 281 * @see org.cpsolver.ifs.termination.GeneralTerminationCondition 282 * @see org.cpsolver.ifs.solution.GeneralSolutionComparator 283 * 284 * @version IFS 1.3 (Iterative Forward Search)<br> 285 * Copyright (C) 2006 - 2014 Tomáš Müller<br> 286 * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br> 287 * <a href="http://muller.unitime.org">http://muller.unitime.org</a><br> 288 * <br> 289 * This library is free software; you can redistribute it and/or modify 290 * it under the terms of the GNU Lesser General Public License as 291 * published by the Free Software Foundation; either version 3 of the 292 * License, or (at your option) any later version. <br> 293 * <br> 294 * This library is distributed in the hope that it will be useful, but 295 * WITHOUT ANY WARRANTY; without even the implied warranty of 296 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 297 * Lesser General Public License for more details. <br> 298 * <br> 299 * You should have received a copy of the GNU Lesser General Public 300 * License along with this library; if not see 301 * <a href='http://www.gnu.org/licenses/'>http://www.gnu.org/licenses/</a>. 302 */ 303public class Test { 304 private static java.text.DecimalFormat sDoubleFormat = new java.text.DecimalFormat("0.000", 305 new java.text.DecimalFormatSymbols(Locale.US)); 306 private static java.text.SimpleDateFormat sDateFormat = new java.text.SimpleDateFormat("dd-MMM-yy_HHmmss", 307 java.util.Locale.US); 308 private static org.apache.log4j.Logger sLogger = org.apache.log4j.Logger.getLogger(Test.class); 309 310 private static void test(DataProperties properties) throws Exception { 311 boolean sameProblemStep = properties.getPropertyBoolean("CSP.SameProblemEachStep", false); 312 boolean sameProblemTest = properties.getPropertyBoolean("CSP.SameProblemEachTest", false); 313 int nrVars = properties.getPropertyInt("CSP.NrVariables", 20); 314 int nrKernels = properties.getPropertyInt("CSP.NrKernels", 2); 315 int nrKernelVariables = properties.getPropertyInt("CSP.KernelSize", 8); 316 int nrVariablesMin = properties.getPropertyInt("CSP.NrVariablesMin", nrVars); 317 int nrVariablesMax = properties.getPropertyInt("CSP.NrVariablesMax", nrVars); 318 int nrVariablesStep = properties.getPropertyInt("CSP.NrVariablesStep", 1); 319 int nrValues = properties.getPropertyInt("CSP.DomainSize", 10); 320 double nrValuesRatio = properties.getPropertyDouble("CSP.DomainSizeRatio", -1); 321 float kernelTightness = properties.getPropertyFloat("CSP.KernelTightness", 0.097f); 322 float kernelDensity = properties.getPropertyFloat("CSP.KernelDensity", 0.097f); 323 float tightnessInit = properties.getPropertyFloat("CSP.Tightness", 0.4f); 324 float tightnessMin = properties.getPropertyFloat("CSP.TightnessMin", tightnessInit); 325 float tightnessMax = properties.getPropertyFloat("CSP.TightnessMax", tightnessInit) + 1e-6f; 326 float tightnessStep = properties.getPropertyFloat("CSP.TightnessStep", 0.1f); 327 float densityInit = properties.getPropertyFloat("CSP.Density", 0.4f); 328 float densityMin = properties.getPropertyFloat("CSP.DensityMin", densityInit); 329 float densityMax = properties.getPropertyFloat("CSP.DensityMax", densityInit) + 1e-6f; 330 float densityStep = properties.getPropertyFloat("CSP.DensityStep", 0.1f); 331 long seed = properties.getPropertyLong("CSP.Seed", System.currentTimeMillis()); 332 int nrTests = properties.getPropertyInt("CPS.NrTests", 10); 333 boolean mpp = properties.getPropertyBoolean("General.MPP", false); 334 PrintWriter logStat = new PrintWriter(new FileWriter(properties.getProperty("General.Output") + File.separator 335 + "rcsp_" + nrVariablesMin + "_" + nrValues + ".csv")); 336 PrintWriter logAvgStat = new PrintWriter(new FileWriter(properties.getProperty("General.Output") 337 + File.separator + "avg_stat.csv")); 338 PrintWriter log = new PrintWriter(new FileWriter(properties.getProperty("General.Output") + File.separator 339 + "info.txt")); 340 logStat 341 .println("testNr;nrVars;nrVals;density[%];tightness[%];time[s];iters;speed[it/s];unassConstr;assigned;assigned[%]" 342 + (mpp ? ";perts;perts[%]" : "") + ";value;totalValue"); 343 logAvgStat 344 .println("nrVars;nrVals;density[%];tightness[%];time[s];RMStime[s];iters;RMSiters;speed[it/s];unassConst;assigned;RMSassigned;assigned[%]" 345 + (mpp ? ";perts;RMSperts;perts[%]" : "") + ";value;RMSvalue;totalValue;RMStotalValue"); 346 System.out.println("Number of variables: " + nrVariablesMin + " .. " + nrVariablesMax + " (step=" 347 + nrVariablesStep + ")"); 348 System.out.println("Density: " + densityMin + " .. " + densityMax + " (step=" + densityStep + ")"); 349 System.out.println("Tightness: " + tightnessMin + " .. " + tightnessMax + " (step=" + tightnessStep 350 + ")"); 351 for (int nrVariables = nrVariablesMin; nrVariables <= nrVariablesMax; nrVariables += nrVariablesStep) { 352 if (nrValuesRatio > 0.0) 353 nrValues = (int) Math.round(nrValuesRatio * nrVariables); 354 for (float density = densityMin; density <= densityMax; density += densityStep) { 355 for (float tightness = tightnessMin; tightness <= tightnessMax; tightness += tightnessStep) { 356 log.println("CSP{#Var=" + nrVariables + ", #Val=" + nrValues + ", P(density)=" 357 + sDoubleFormat.format(100.0 * density) + "%, P(tighness)=" 358 + sDoubleFormat.format(100.0 * tightness) + ", " + nrKernels + "x Kernel{#Var=" 359 + nrKernelVariables + ", P(density)=" + sDoubleFormat.format(100.0 * kernelDensity) 360 + "%, P(tighness)=" + sDoubleFormat.format(100.0 * kernelTightness) + "%}}"); 361 double sumTime = 0; 362 double sumTime2 = 0; 363 int sumIters = 0; 364 int sumIters2 = 0; 365 int sumConfl = 0; 366 int sumAssign = 0; 367 int sumAssign2 = 0; 368 int sumPert = 0; 369 int sumPert2 = 0; 370 int sumVal = 0; 371 int sumVal2 = 0; 372 int sumTotalVal = 0; 373 int sumTotalVal2 = 0; 374 for (int test = 1; test <= nrTests; test++) { 375 log.println(" " + test + ". test"); 376 log.flush(); 377 properties.setProperty("CSP.NrVariables", String.valueOf(nrVariables)); 378 properties.setProperty("CSP.Tightness", String.valueOf(tightness)); 379 properties.setProperty("CSP.Density", String.valueOf(density)); 380 381 long currentSeed = (seed * 1000000L) 382 + (1000 * (long) ((sameProblemStep ? densityMin : density) * 1000.0)) 383 + ((long) ((sameProblemStep ? tightnessMin : tightness) * 1000.0)); 384 currentSeed = (currentSeed * nrTests) + (sameProblemTest ? 0 : test - 1); 385 386 sLogger.debug("Seed: " + currentSeed); 387 StructuredCSPModel csp = new StructuredCSPModel(properties, currentSeed); 388 389 Solver<CSPVariable, CSPValue> s = new Solver<CSPVariable, CSPValue>(properties); 390 s.setInitalSolution(csp); 391 s.currentSolution().clearBest(); 392 s.start(); 393 394 try { 395 s.getSolverThread().join(); 396 } catch (NullPointerException npe) { 397 } 398 399 if (s.lastSolution().getBestInfo() == null) 400 sLogger.error("No solution found :-("); 401 sLogger.debug("Last solution:" + s.lastSolution().getInfo()); 402 Solution<CSPVariable, CSPValue> best = s.lastSolution(); 403 sLogger.debug("Best solution:" + s.lastSolution().getBestInfo()); 404 best.restoreBest(); 405 int val = 0; 406 for (CSPValue v: best.getAssignment().assignedValues()) 407 val += (int) v.toDouble(); 408 int totalVal = val + (best.getModel().unassignedVariables(best.getAssignment()).size() * nrValues); 409 sLogger.debug("Last solution:" + best.getInfo()); 410 logStat.println(test 411 + ";" 412 + nrVariables 413 + ";" 414 + nrValues 415 + ";" 416 + sDoubleFormat.format(density) 417 + ";" 418 + sDoubleFormat.format(tightness) 419 + ";" 420 + sDoubleFormat.format(best.getTime()) 421 + ";" 422 + best.getIteration() 423 + ";" 424 + sDoubleFormat.format((best.getIteration()) / best.getTime()) 425 + ";" 426 + best.getModel().unassignedHardConstraints(best.getAssignment()).size() 427 + ";" 428 + best.getModel().assignedVariables(best.getAssignment()).size() 429 + ";" 430 + sDoubleFormat.format(100.0 * best.getModel().assignedVariables(best.getAssignment()).size() 431 / best.getModel().variables().size()) 432 + (mpp ? ";" 433 + (best.getModel().perturbVariables(best.getAssignment()).size() + best.getModel() 434 .unassignedVariables(best.getAssignment()).size()) 435 + ";" 436 + sDoubleFormat.format(100.0 437 * (best.getModel().perturbVariables(best.getAssignment()).size() + best.getModel() 438 .unassignedVariables(best.getAssignment()).size()) 439 / best.getModel().variables().size()) : "") + ";" + val + ";" 440 + totalVal); 441 log.println(" seed: " + currentSeed); 442 log.println(" constraints: " + best.getModel().constraints().size()); 443 for (Iterator<Constraint<CSPVariable, CSPValue>> i = best.getModel().constraints().iterator(); i 444 .hasNext();) { 445 CSPBinaryConstraint c = (CSPBinaryConstraint) i.next(); 446 log.println(" " + c.getName() + " (" + c.first().getName() + "," 447 + c.second().getName() + ")"); 448 for (CSPValue v0 : c.first().values(best.getAssignment())) { 449 log.print(" "); 450 for (CSPValue v1 : c.second().values(best.getAssignment())) 451 log.print(c.isConsistent(v0, v1) ? "1 " : "0 "); 452 } 453 log.println(); 454 } 455 log.println(" time: " + sDoubleFormat.format(best.getTime()) + " s"); 456 log.println(" iteration: " + best.getIteration()); 457 log.println(" speed: " + sDoubleFormat.format((best.getIteration()) / best.getTime()) 458 + " it/s"); 459 log.println(" assigned: " 460 + best.getModel().assignedVariables(best.getAssignment()).size() 461 + " (" 462 + sDoubleFormat.format(100.0 * best.getModel().assignedVariables(best.getAssignment()).size() 463 / best.getModel().variables().size()) + "%)"); 464 log.println(" total value: " + val); 465 if (mpp) 466 log.println(" perturbations:" 467 + (best.getModel().perturbVariables(best.getAssignment()).size() + best.getModel() 468 .unassignedVariables(best.getAssignment()).size()) 469 + " (" 470 + sDoubleFormat 471 .format(100.0 472 * (best.getModel().perturbVariables(best.getAssignment()).size() + best.getModel() 473 .unassignedVariables(best.getAssignment()).size()) 474 / best.getModel().variables().size()) + "%)"); 475 log.print(" solution: "); 476 for (CSPVariable v : ((CSPModel) best.getModel()).variables()) { 477 if (v.getBestAssignment() == null) 478 continue; 479 log.print(v.getName() + "=" + v.getBestAssignment().getName()); 480 log.print(", "); 481 } 482 log.println(); 483 sumTime += best.getTime(); 484 sumTime2 += best.getTime() * best.getTime(); 485 sumIters += best.getIteration(); 486 sumIters2 += best.getIteration() * best.getIteration(); 487 sumConfl += best.getModel().unassignedHardConstraints(best.getAssignment()).size(); 488 sumAssign += best.getModel().assignedVariables(best.getAssignment()).size(); 489 sumAssign2 += best.getModel().assignedVariables(best.getAssignment()).size() 490 * best.getModel().assignedVariables(best.getAssignment()).size(); 491 sumVal += val; 492 sumVal2 += val * val; 493 sumTotalVal += totalVal; 494 sumTotalVal2 += totalVal * totalVal; 495 if (mpp) { 496 sumPert += (best.getModel().perturbVariables(best.getAssignment()).size() + best.getModel() 497 .unassignedVariables(best.getAssignment()).size()); 498 sumPert2 += (best.getModel().perturbVariables(best.getAssignment()).size() + best.getModel() 499 .unassignedVariables(best.getAssignment()).size()) 500 * (best.getModel().perturbVariables(best.getAssignment()).size() + best.getModel() 501 .unassignedVariables(best.getAssignment()).size()); 502 } 503 log.flush(); 504 logStat.flush(); 505 } 506 logAvgStat.println(nrVariables 507 + ";" 508 + nrValues 509 + ";" 510 + sDoubleFormat.format(density) 511 + ";" 512 + sDoubleFormat.format(tightness) 513 + ";" 514 + sDoubleFormat.format(sumTime / nrTests) 515 + ";" 516 + sDoubleFormat.format(ToolBox.rms(nrTests, sumTime, sumTime2)) 517 + ";" 518 + sDoubleFormat.format(((double) sumIters) / nrTests) 519 + ";" 520 + sDoubleFormat.format(ToolBox.rms(nrTests, sumIters, sumIters2)) 521 + ";" 522 + sDoubleFormat.format((sumIters) / sumTime) 523 + ";" 524 + sDoubleFormat.format(((double) sumConfl) / nrTests) 525 + ";" 526 + sDoubleFormat.format(((double) sumAssign) / nrTests) 527 + ";" 528 + sDoubleFormat.format(ToolBox.rms(nrTests, sumAssign, sumAssign2)) 529 + ";" 530 + sDoubleFormat.format(100.0 * (sumAssign) / (nrVariables * nrTests)) 531 + (mpp ? ";" + sDoubleFormat.format(((double) sumPert) / nrTests) + ";" 532 + sDoubleFormat.format(ToolBox.rms(nrTests, sumPert, sumPert2)) + ";" 533 + sDoubleFormat.format(100.0 * (sumPert) / (nrVariables * nrTests)) : "") 534 + ";" 535 + sDoubleFormat.format(((double) sumVal) / (nrTests * nrVariables)) 536 + ";" 537 + sDoubleFormat.format(ToolBox.rms(nrTests, (double) sumVal / nrVariables, (double) sumVal2 538 / (nrVariables * nrVariables))) + ";" 539 + sDoubleFormat.format(((double) sumTotalVal) / nrTests) + ";" 540 + sDoubleFormat.format(ToolBox.rms(nrTests, sumTotalVal, sumTotalVal2))); 541 logAvgStat.flush(); 542 } 543 } 544 } 545 log.flush(); 546 log.close(); 547 logStat.flush(); 548 logStat.close(); 549 logAvgStat.flush(); 550 logAvgStat.close(); 551 } 552 553 private static void test(File inputCfg, String name, String include, String regexp, String outDir) throws Exception { 554 if (regexp != null) { 555 String incFile; 556 557 if (regexp.indexOf(';') > 0) { 558 incFile = regexp.substring(0, regexp.indexOf(';')); 559 regexp = regexp.substring(regexp.indexOf(';') + 1); 560 } else { 561 incFile = regexp; 562 regexp = null; 563 } 564 if (incFile.startsWith("[") && incFile.endsWith("]")) { 565 test(inputCfg, name, include, regexp, outDir); 566 incFile = incFile.substring(1, incFile.length() - 1); 567 } 568 if (incFile.indexOf('{') >= 0 && incFile.indexOf('}') >= 0) { 569 String prefix = incFile.substring(0, incFile.indexOf('{')); 570 StringTokenizer middle = new StringTokenizer(incFile.substring(incFile.indexOf('{') + 1, incFile 571 .indexOf('}')), "|"); 572 String sufix = incFile.substring(incFile.indexOf('}') + 1); 573 574 while (middle.hasMoreTokens()) { 575 String m = middle.nextToken(); 576 577 test(inputCfg, (name == null ? "" : name + "_") + m, (include == null ? "" : include + ";") 578 + prefix + m + sufix, regexp, outDir); 579 } 580 } else { 581 test(inputCfg, name, (include == null ? "" : include + ";") + incFile, regexp, outDir); 582 } 583 } else { 584 DataProperties properties = ToolBox.loadProperties(inputCfg); 585 StringTokenizer inc = new StringTokenizer(include, ";"); 586 587 while (inc.hasMoreTokens()) { 588 String aFile = inc.nextToken(); 589 590 System.out.println(" Loading included file '" + aFile + "' ... "); 591 FileInputStream is = null; 592 593 if ((new File(aFile)).exists()) { 594 is = new FileInputStream(aFile); 595 } 596 if ((new File(inputCfg.getParent() + File.separator + aFile)).exists()) { 597 is = new FileInputStream(inputCfg.getParent() + File.separator + aFile); 598 } 599 if (is == null) { 600 System.err.println("Unable to find include file '" + aFile + "'."); 601 } 602 properties.load(is); 603 is.close(); 604 } 605 String outDirThisTest = (outDir == null ? properties.getProperty("General.Output", ".") : outDir) 606 + File.separator + name + File.separator + sDateFormat.format(new Date()); 607 properties.setProperty("General.Output", outDirThisTest.toString()); 608 System.out.println("Output folder: " + properties.getProperty("General.Output")); 609 (new File(outDirThisTest)).mkdirs(); 610 ToolBox.configureLogging(outDirThisTest, null); 611 FileOutputStream fos = new FileOutputStream(outDirThisTest + File.separator + "rcsp.conf"); 612 613 properties.store(fos, "Random CSP problem configuration file"); 614 fos.flush(); 615 fos.close(); 616 test(properties); 617 } 618 } 619 620 public static void main(String[] args) { 621 try { 622 Progress.getInstance().addProgressListener(new ProgressWriter(System.out)); 623 File inputCfg = new File(args[0]); 624 DataProperties properties = ToolBox.loadProperties(inputCfg); 625 if (properties.getProperty("INCLUDE_REGEXP") != null) { 626 test(inputCfg, null, null, properties.getProperty("INCLUDE_REGEXP"), (args.length > 1 ? args[1] : null)); 627 } else { 628 String outDir = properties.getProperty("General.Output", ".") + File.separator 629 + inputCfg.getName().substring(0, inputCfg.getName().lastIndexOf('.')) + File.separator 630 + sDateFormat.format(new Date()); 631 if (args.length > 1) 632 outDir = args[1] + File.separator + (sDateFormat.format(new Date())); 633 properties.setProperty("General.Output", outDir.toString()); 634 System.out.println("Output folder: " + properties.getProperty("General.Output")); 635 (new File(outDir)).mkdirs(); 636 ToolBox.configureLogging(outDir, null); 637 test(properties); 638 } 639 } catch (Exception e) { 640 e.printStackTrace(); 641 } 642 } 643}