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'><caption>Related Solver Parameters</caption> 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 * @author Tomáš Müller 285 * @version IFS 1.3 (Iterative Forward Search)<br> 286 * Copyright (C) 2006 - 2014 Tomáš Müller<br> 287 * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br> 288 * <a href="http://muller.unitime.org">http://muller.unitime.org</a><br> 289 * <br> 290 * This library is free software; you can redistribute it and/or modify 291 * it under the terms of the GNU Lesser General Public License as 292 * published by the Free Software Foundation; either version 3 of the 293 * License, or (at your option) any later version. <br> 294 * <br> 295 * This library is distributed in the hope that it will be useful, but 296 * WITHOUT ANY WARRANTY; without even the implied warranty of 297 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 298 * Lesser General Public License for more details. <br> 299 * <br> 300 * You should have received a copy of the GNU Lesser General Public 301 * License along with this library; if not see 302 * <a href='http://www.gnu.org/licenses/'>http://www.gnu.org/licenses/</a>. 303 */ 304public class Test { 305 private static java.text.DecimalFormat sDoubleFormat = new java.text.DecimalFormat("0.000", 306 new java.text.DecimalFormatSymbols(Locale.US)); 307 private static java.text.SimpleDateFormat sDateFormat = new java.text.SimpleDateFormat("dd-MMM-yy_HHmmss", 308 java.util.Locale.US); 309 private static org.apache.logging.log4j.Logger sLogger = org.apache.logging.log4j.LogManager.getLogger(Test.class); 310 311 private static void test(DataProperties properties) throws Exception { 312 boolean sameProblemStep = properties.getPropertyBoolean("CSP.SameProblemEachStep", false); 313 boolean sameProblemTest = properties.getPropertyBoolean("CSP.SameProblemEachTest", false); 314 int nrVars = properties.getPropertyInt("CSP.NrVariables", 20); 315 int nrKernels = properties.getPropertyInt("CSP.NrKernels", 2); 316 int nrKernelVariables = properties.getPropertyInt("CSP.KernelSize", 8); 317 int nrVariablesMin = properties.getPropertyInt("CSP.NrVariablesMin", nrVars); 318 int nrVariablesMax = properties.getPropertyInt("CSP.NrVariablesMax", nrVars); 319 int nrVariablesStep = properties.getPropertyInt("CSP.NrVariablesStep", 1); 320 int nrValues = properties.getPropertyInt("CSP.DomainSize", 10); 321 double nrValuesRatio = properties.getPropertyDouble("CSP.DomainSizeRatio", -1); 322 float kernelTightness = properties.getPropertyFloat("CSP.KernelTightness", 0.097f); 323 float kernelDensity = properties.getPropertyFloat("CSP.KernelDensity", 0.097f); 324 float tightnessInit = properties.getPropertyFloat("CSP.Tightness", 0.4f); 325 float tightnessMin = properties.getPropertyFloat("CSP.TightnessMin", tightnessInit); 326 float tightnessMax = properties.getPropertyFloat("CSP.TightnessMax", tightnessInit) + 1e-6f; 327 float tightnessStep = properties.getPropertyFloat("CSP.TightnessStep", 0.1f); 328 float densityInit = properties.getPropertyFloat("CSP.Density", 0.4f); 329 float densityMin = properties.getPropertyFloat("CSP.DensityMin", densityInit); 330 float densityMax = properties.getPropertyFloat("CSP.DensityMax", densityInit) + 1e-6f; 331 float densityStep = properties.getPropertyFloat("CSP.DensityStep", 0.1f); 332 long seed = properties.getPropertyLong("CSP.Seed", System.currentTimeMillis()); 333 int nrTests = properties.getPropertyInt("CPS.NrTests", 10); 334 boolean mpp = properties.getPropertyBoolean("General.MPP", false); 335 PrintWriter logStat = new PrintWriter(new FileWriter(properties.getProperty("General.Output") + File.separator 336 + "rcsp_" + nrVariablesMin + "_" + nrValues + ".csv")); 337 PrintWriter logAvgStat = new PrintWriter(new FileWriter(properties.getProperty("General.Output") 338 + File.separator + "avg_stat.csv")); 339 PrintWriter log = new PrintWriter(new FileWriter(properties.getProperty("General.Output") + File.separator 340 + "info.txt")); 341 logStat 342 .println("testNr;nrVars;nrVals;density[%];tightness[%];time[s];iters;speed[it/s];unassConstr;assigned;assigned[%]" 343 + (mpp ? ";perts;perts[%]" : "") + ";value;totalValue"); 344 logAvgStat 345 .println("nrVars;nrVals;density[%];tightness[%];time[s];RMStime[s];iters;RMSiters;speed[it/s];unassConst;assigned;RMSassigned;assigned[%]" 346 + (mpp ? ";perts;RMSperts;perts[%]" : "") + ";value;RMSvalue;totalValue;RMStotalValue"); 347 System.out.println("Number of variables: " + nrVariablesMin + " .. " + nrVariablesMax + " (step=" 348 + nrVariablesStep + ")"); 349 System.out.println("Density: " + densityMin + " .. " + densityMax + " (step=" + densityStep + ")"); 350 System.out.println("Tightness: " + tightnessMin + " .. " + tightnessMax + " (step=" + tightnessStep 351 + ")"); 352 for (int nrVariables = nrVariablesMin; nrVariables <= nrVariablesMax; nrVariables += nrVariablesStep) { 353 if (nrValuesRatio > 0.0) 354 nrValues = (int) Math.round(nrValuesRatio * nrVariables); 355 for (float density = densityMin; density <= densityMax; density += densityStep) { 356 for (float tightness = tightnessMin; tightness <= tightnessMax; tightness += tightnessStep) { 357 log.println("CSP{#Var=" + nrVariables + ", #Val=" + nrValues + ", P(density)=" 358 + sDoubleFormat.format(100.0 * density) + "%, P(tighness)=" 359 + sDoubleFormat.format(100.0 * tightness) + ", " + nrKernels + "x Kernel{#Var=" 360 + nrKernelVariables + ", P(density)=" + sDoubleFormat.format(100.0 * kernelDensity) 361 + "%, P(tighness)=" + sDoubleFormat.format(100.0 * kernelTightness) + "%}}"); 362 double sumTime = 0; 363 double sumTime2 = 0; 364 int sumIters = 0; 365 int sumIters2 = 0; 366 int sumConfl = 0; 367 int sumAssign = 0; 368 int sumAssign2 = 0; 369 int sumPert = 0; 370 int sumPert2 = 0; 371 int sumVal = 0; 372 int sumVal2 = 0; 373 int sumTotalVal = 0; 374 int sumTotalVal2 = 0; 375 for (int test = 1; test <= nrTests; test++) { 376 log.println(" " + test + ". test"); 377 log.flush(); 378 properties.setProperty("CSP.NrVariables", String.valueOf(nrVariables)); 379 properties.setProperty("CSP.Tightness", String.valueOf(tightness)); 380 properties.setProperty("CSP.Density", String.valueOf(density)); 381 382 long currentSeed = (seed * 1000000L) 383 + (1000 * (long) ((sameProblemStep ? densityMin : density) * 1000.0)) 384 + ((long) ((sameProblemStep ? tightnessMin : tightness) * 1000.0)); 385 currentSeed = (currentSeed * nrTests) + (sameProblemTest ? 0 : test - 1); 386 387 sLogger.debug("Seed: " + currentSeed); 388 StructuredCSPModel csp = new StructuredCSPModel(properties, currentSeed); 389 390 Solver<CSPVariable, CSPValue> s = new Solver<CSPVariable, CSPValue>(properties); 391 s.setInitalSolution(csp); 392 s.currentSolution().clearBest(); 393 s.start(); 394 395 try { 396 s.getSolverThread().join(); 397 } catch (NullPointerException npe) { 398 } 399 400 if (s.lastSolution().getBestInfo() == null) 401 sLogger.error("No solution found :-("); 402 sLogger.debug("Last solution:" + s.lastSolution().getInfo()); 403 Solution<CSPVariable, CSPValue> best = s.lastSolution(); 404 sLogger.debug("Best solution:" + s.lastSolution().getBestInfo()); 405 best.restoreBest(); 406 int val = 0; 407 for (CSPValue v: best.getAssignment().assignedValues()) 408 val += (int) v.toDouble(); 409 int totalVal = val + (best.getModel().unassignedVariables(best.getAssignment()).size() * nrValues); 410 sLogger.debug("Last solution:" + best.getInfo()); 411 logStat.println(test 412 + ";" 413 + nrVariables 414 + ";" 415 + nrValues 416 + ";" 417 + sDoubleFormat.format(density) 418 + ";" 419 + sDoubleFormat.format(tightness) 420 + ";" 421 + sDoubleFormat.format(best.getTime()) 422 + ";" 423 + best.getIteration() 424 + ";" 425 + sDoubleFormat.format((best.getIteration()) / best.getTime()) 426 + ";" 427 + best.getModel().unassignedHardConstraints(best.getAssignment()).size() 428 + ";" 429 + best.getModel().assignedVariables(best.getAssignment()).size() 430 + ";" 431 + sDoubleFormat.format(100.0 * best.getModel().assignedVariables(best.getAssignment()).size() 432 / best.getModel().variables().size()) 433 + (mpp ? ";" 434 + (best.getModel().perturbVariables(best.getAssignment()).size() + best.getModel() 435 .unassignedVariables(best.getAssignment()).size()) 436 + ";" 437 + sDoubleFormat.format(100.0 438 * (best.getModel().perturbVariables(best.getAssignment()).size() + best.getModel() 439 .unassignedVariables(best.getAssignment()).size()) 440 / best.getModel().variables().size()) : "") + ";" + val + ";" 441 + totalVal); 442 log.println(" seed: " + currentSeed); 443 log.println(" constraints: " + best.getModel().constraints().size()); 444 for (Iterator<Constraint<CSPVariable, CSPValue>> i = best.getModel().constraints().iterator(); i 445 .hasNext();) { 446 CSPBinaryConstraint c = (CSPBinaryConstraint) i.next(); 447 log.println(" " + c.getName() + " (" + c.first().getName() + "," 448 + c.second().getName() + ")"); 449 for (CSPValue v0 : c.first().values(best.getAssignment())) { 450 log.print(" "); 451 for (CSPValue v1 : c.second().values(best.getAssignment())) 452 log.print(c.isConsistent(v0, v1) ? "1 " : "0 "); 453 } 454 log.println(); 455 } 456 log.println(" time: " + sDoubleFormat.format(best.getTime()) + " s"); 457 log.println(" iteration: " + best.getIteration()); 458 log.println(" speed: " + sDoubleFormat.format((best.getIteration()) / best.getTime()) 459 + " it/s"); 460 log.println(" assigned: " 461 + best.getModel().assignedVariables(best.getAssignment()).size() 462 + " (" 463 + sDoubleFormat.format(100.0 * best.getModel().assignedVariables(best.getAssignment()).size() 464 / best.getModel().variables().size()) + "%)"); 465 log.println(" total value: " + val); 466 if (mpp) 467 log.println(" perturbations:" 468 + (best.getModel().perturbVariables(best.getAssignment()).size() + best.getModel() 469 .unassignedVariables(best.getAssignment()).size()) 470 + " (" 471 + sDoubleFormat 472 .format(100.0 473 * (best.getModel().perturbVariables(best.getAssignment()).size() + best.getModel() 474 .unassignedVariables(best.getAssignment()).size()) 475 / best.getModel().variables().size()) + "%)"); 476 log.print(" solution: "); 477 for (CSPVariable v : best.getModel().variables()) { 478 if (v.getBestAssignment() == null) 479 continue; 480 log.print(v.getName() + "=" + v.getBestAssignment().getName()); 481 log.print(", "); 482 } 483 log.println(); 484 sumTime += best.getTime(); 485 sumTime2 += best.getTime() * best.getTime(); 486 sumIters += best.getIteration(); 487 sumIters2 += best.getIteration() * best.getIteration(); 488 sumConfl += best.getModel().unassignedHardConstraints(best.getAssignment()).size(); 489 sumAssign += best.getModel().assignedVariables(best.getAssignment()).size(); 490 sumAssign2 += best.getModel().assignedVariables(best.getAssignment()).size() 491 * best.getModel().assignedVariables(best.getAssignment()).size(); 492 sumVal += val; 493 sumVal2 += val * val; 494 sumTotalVal += totalVal; 495 sumTotalVal2 += totalVal * totalVal; 496 if (mpp) { 497 sumPert += (best.getModel().perturbVariables(best.getAssignment()).size() + best.getModel() 498 .unassignedVariables(best.getAssignment()).size()); 499 sumPert2 += (best.getModel().perturbVariables(best.getAssignment()).size() + best.getModel() 500 .unassignedVariables(best.getAssignment()).size()) 501 * (best.getModel().perturbVariables(best.getAssignment()).size() + best.getModel() 502 .unassignedVariables(best.getAssignment()).size()); 503 } 504 log.flush(); 505 logStat.flush(); 506 } 507 logAvgStat.println(nrVariables 508 + ";" 509 + nrValues 510 + ";" 511 + sDoubleFormat.format(density) 512 + ";" 513 + sDoubleFormat.format(tightness) 514 + ";" 515 + sDoubleFormat.format(sumTime / nrTests) 516 + ";" 517 + sDoubleFormat.format(ToolBox.rms(nrTests, sumTime, sumTime2)) 518 + ";" 519 + sDoubleFormat.format(((double) sumIters) / nrTests) 520 + ";" 521 + sDoubleFormat.format(ToolBox.rms(nrTests, sumIters, sumIters2)) 522 + ";" 523 + sDoubleFormat.format((sumIters) / sumTime) 524 + ";" 525 + sDoubleFormat.format(((double) sumConfl) / nrTests) 526 + ";" 527 + sDoubleFormat.format(((double) sumAssign) / nrTests) 528 + ";" 529 + sDoubleFormat.format(ToolBox.rms(nrTests, sumAssign, sumAssign2)) 530 + ";" 531 + sDoubleFormat.format(100.0 * (sumAssign) / (nrVariables * nrTests)) 532 + (mpp ? ";" + sDoubleFormat.format(((double) sumPert) / nrTests) + ";" 533 + sDoubleFormat.format(ToolBox.rms(nrTests, sumPert, sumPert2)) + ";" 534 + sDoubleFormat.format(100.0 * (sumPert) / (nrVariables * nrTests)) : "") 535 + ";" 536 + sDoubleFormat.format(((double) sumVal) / (nrTests * nrVariables)) 537 + ";" 538 + sDoubleFormat.format(ToolBox.rms(nrTests, (double) sumVal / nrVariables, (double) sumVal2 539 / (nrVariables * nrVariables))) + ";" 540 + sDoubleFormat.format(((double) sumTotalVal) / nrTests) + ";" 541 + sDoubleFormat.format(ToolBox.rms(nrTests, sumTotalVal, sumTotalVal2))); 542 logAvgStat.flush(); 543 } 544 } 545 } 546 log.flush(); 547 log.close(); 548 logStat.flush(); 549 logStat.close(); 550 logAvgStat.flush(); 551 logAvgStat.close(); 552 } 553 554 private static void test(File inputCfg, String name, String include, String regexp, String outDir) throws Exception { 555 if (regexp != null) { 556 String incFile; 557 558 if (regexp.indexOf(';') > 0) { 559 incFile = regexp.substring(0, regexp.indexOf(';')); 560 regexp = regexp.substring(regexp.indexOf(';') + 1); 561 } else { 562 incFile = regexp; 563 regexp = null; 564 } 565 if (incFile.startsWith("[") && incFile.endsWith("]")) { 566 test(inputCfg, name, include, regexp, outDir); 567 incFile = incFile.substring(1, incFile.length() - 1); 568 } 569 if (incFile.indexOf('{') >= 0 && incFile.indexOf('}') >= 0) { 570 String prefix = incFile.substring(0, incFile.indexOf('{')); 571 StringTokenizer middle = new StringTokenizer(incFile.substring(incFile.indexOf('{') + 1, incFile 572 .indexOf('}')), "|"); 573 String sufix = incFile.substring(incFile.indexOf('}') + 1); 574 575 while (middle.hasMoreTokens()) { 576 String m = middle.nextToken(); 577 578 test(inputCfg, (name == null ? "" : name + "_") + m, (include == null ? "" : include + ";") 579 + prefix + m + sufix, regexp, outDir); 580 } 581 } else { 582 test(inputCfg, name, (include == null ? "" : include + ";") + incFile, regexp, outDir); 583 } 584 } else { 585 DataProperties properties = ToolBox.loadProperties(inputCfg); 586 StringTokenizer inc = new StringTokenizer(include, ";"); 587 588 while (inc.hasMoreTokens()) { 589 String aFile = inc.nextToken(); 590 591 System.out.println(" Loading included file '" + aFile + "' ... "); 592 FileInputStream is = null; 593 594 if ((new File(aFile)).exists()) { 595 is = new FileInputStream(aFile); 596 } 597 if ((new File(inputCfg.getParent() + File.separator + aFile)).exists()) { 598 is = new FileInputStream(inputCfg.getParent() + File.separator + aFile); 599 } 600 if (is == null) { 601 System.err.println("Unable to find include file '" + aFile + "'."); 602 } 603 properties.load(is); 604 is.close(); 605 } 606 String outDirThisTest = (outDir == null ? properties.getProperty("General.Output", ".") : outDir) 607 + File.separator + name + File.separator + sDateFormat.format(new Date()); 608 properties.setProperty("General.Output", outDirThisTest.toString()); 609 System.out.println("Output folder: " + properties.getProperty("General.Output")); 610 (new File(outDirThisTest)).mkdirs(); 611 ToolBox.configureLogging(outDirThisTest, null); 612 FileOutputStream fos = new FileOutputStream(outDirThisTest + File.separator + "rcsp.conf"); 613 614 properties.store(fos, "Random CSP problem configuration file"); 615 fos.flush(); 616 fos.close(); 617 test(properties); 618 } 619 } 620 621 public static void main(String[] args) { 622 try { 623 Progress.getInstance().addProgressListener(new ProgressWriter(System.out)); 624 File inputCfg = new File(args[0]); 625 DataProperties properties = ToolBox.loadProperties(inputCfg); 626 if (properties.getProperty("INCLUDE_REGEXP") != null) { 627 test(inputCfg, null, null, properties.getProperty("INCLUDE_REGEXP"), (args.length > 1 ? args[1] : null)); 628 } else { 629 String outDir = properties.getProperty("General.Output", ".") + File.separator 630 + inputCfg.getName().substring(0, inputCfg.getName().lastIndexOf('.')) + File.separator 631 + sDateFormat.format(new Date()); 632 if (args.length > 1) 633 outDir = args[1] + File.separator + (sDateFormat.format(new Date())); 634 properties.setProperty("General.Output", outDir.toString()); 635 System.out.println("Output folder: " + properties.getProperty("General.Output")); 636 (new File(outDir)).mkdirs(); 637 ToolBox.configureLogging(outDir, null); 638 test(properties); 639 } 640 } catch (Exception e) { 641 e.printStackTrace(); 642 } 643 } 644}