001 package net.sf.cpsolver.ifs.example.rpp; 002 003 import java.io.*; 004 import java.util.*; 005 006 import net.sf.cpsolver.ifs.model.*; 007 import net.sf.cpsolver.ifs.solution.*; 008 import net.sf.cpsolver.ifs.solver.*; 009 import net.sf.cpsolver.ifs.util.*; 010 011 /** 012 * RPP test. It takes one argument -- property file with all the parameters. 013 * It allows to execute given number of tests. The problem is loaded from prolog-based text files. 014 * For description of RPP problem see {@link RPPModel}. 015 * <br><br> 016 * Description of the input problem files can be found at <a href='http://www.fi.muni.cz/~hanka/rpp/instances.html'>http://www.fi.muni.cz/~hanka/rpp/instances.html</a>. Each input problem (e.g., gen22.pl) has the following structure:<ul><code> 017 * objects([<br> 018 * object(<br> 019 * name( rect1 ),<br> 020 * size( [ 2, 1 ] ),<br> 021 * valid_positions( [ 0-38, 0-13 ] )<br> 022 * ),<br> 023 * object(<br> 024 * name( rect2 ),<br> 025 * size( [ 2, 1 ] ),<br> 026 * valid_positions( [ 0-38, 0-13 ] )<br> 027 * ), <br> 028 * ... <br> 029 * object(<br> 030 * name( rect200 ),<br> 031 * size( [ 2, 1 ] ),<br> 032 * valid_positions( [ 0-38, 7-13 ] )<br> 033 * )<br> 034 * ] ). <br> 035 * </code></ul> 036 * Stating that the first rectangle (named rect1) has size 2x1 and its valid position are with x between 0 and 38, y between 0 and 13, and so on. 037 * <br> 038 * MPP instances contain an extra file with the solution (e.g., gen22.solution), with the following structure<ul><code> 039 * assigned([[rect1X,[17]], [rect1Y,[5]], [rect2X,[24]], [rect2Y,[4]], ... [rect200X,[37]], [rect200Y,[10]]]). 040 * </code></ul> 041 * Which means that the first rectangle (named rect1) is to be placed at [17,5], second at [24,4] and so on. 042 * <br> 043 * There is also a file (e.g., gen22.mpp) describing which input placements are to be prohibited (not that if the input placement is prohibited, it means that also all values with the same X or Y coordinate are prohibited). It has the following structure:<ul><code> 044 * perturbation( 1, 0, [] ).<br> 045 * perturbation( 2, 0, [] ).<br> 046 * ...<br> 047 * perturbation( 1, 2, [44,127] ).<br> 048 * perturbation( 2, 2, [80,153] ).<br> 049 * ...<br> 050 * perturbation( 1, 4, [44,80,127,153] ).<br> 051 * perturbation( 2, 4, [48,67,138,170] ). <br> 052 * ...<br> 053 * </code></ul> 054 * Stating that for instance in the first test with 4 perturbations the rectangles rect44, rect80, rect127 and rect153 will have their initial value prohibited. 055 * <br><br> 056 * Test's parameters: 057 * <br> 058 * <table border='1'><tr><th>Parameter</th><th>Type</th><th>Comment</th></tr> 059 * <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> 060 * <tr><td>RPP.NrTests</td><td>{@link Integer}</td><td>Number of tests to be executed for each input instance</td></tr> 061 * <tr><td>Rpp.Min<br>Rpp.Max<br>Rpp.Step</td><td>{@link Integer}</td><td>In case of MPP: minimal, maximal number and increment of input perturbations. An instance is loaded and tested for each given number of input perturbations.</td></tr> 062 * <tr><td>Rpp.Min<br>Rpp.Max</td><td>{@link Integer}</td><td>In case of initial problem: minimal and maximal number of the input problem. An instance is loaded and tested for each given number from RPP.Min to RPP.Max.</td></tr> 063 * <tr><td>Rpp.ProblemWidth<br>Rpp.ProblemHeight</td><td>{@link Integer}</td><td>Width and height of the placement area.</td></tr> 064 * <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> 065 * </table> 066 * <br><br> 067 * 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> 068 * <code>INCLUDE_REGEXP=general.ini;{rpp85|rpp90|rpp95|mpp22}.ini;{5min}.ini;{cbs|rw1|tabu20}.ini</code><br> 069 * </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> 070 * <li>general.ini;rpp85.ini;5min.ini;cbs.ini 071 * <li>general.ini;rpp85.ini;5min.ini;rw1.ini 072 * <li>general.ini;rpp85.ini;5min.ini;tabu20.ini 073 * <li>general.ini;rpp90.ini;5min.ini;cbs.ini 074 * <li>general.ini;rpp90.ini;5min.ini;rw1.ini 075 * <li>general.ini;rpp90.ini;5min.ini;tabu20.ini 076 * <li>general.ini;rpp95.ini;5min.ini;cbs.ini 077 * <li>general.ini;rpp95.ini;5min.ini;rw1.ini 078 * <li>general.ini;rpp95.ini;5min.ini;tabu20.ini 079 * <li>general.ini;mpp22.ini;5min.ini;cbs.ini 080 * <li>general.ini;mpp22.ini;5min.ini;rw1.ini 081 * <li>general.ini;mpp22.ini;5min.ini;tabu20.ini 082 * </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. 083 * So, for instance the first bunch of tests will output into the folder:<ul> 084 * ${General.Output}\rpp85_5min_csb\25-Feb-05_191136 085 * </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. 086 * <br><br> 087 * An example of the configurations:<br> 088 * File<b> general.ini</b><ul><code> 089 * #Default settings common for all configurations<br> 090 * General.MPP=false<br> 091 * General.InitialAssignment=false<br> 092 * General.Output=output\\RPP\\IFS<br> 093 * <br> 094 * #Value selection heuristics<br> 095 * Value.Class=net.sf.cpsolver.ifs.heuristics.GeneralValueSelection<br> 096 * Value.WeightWeightedConflicts=0.0<br> 097 * Value.RandomWalkProb=0.0<br> 098 * Value.WeightConflicts=1.0<br> 099 * Value.WeightNrAssignments=0.0<br> 100 * Value.WeightValue=0.0<br> 101 * Value.Tabu=0<br> 102 * <br> 103 * #Variable selection heuristics<br> 104 * Variable.Class=net.sf.cpsolver.ifs.heuristics.GeneralVariableSelection<br> 105 * Variable.RandomSelection=true<br> 106 * <br> 107 * #Termination condition<br> 108 * Termination.Class=net.sf.cpsolver.ifs.termination.GeneralTerminationCondition<br> 109 * Termination.MaxIters=-1<br> 110 * Termination.TimeOut=-1<br> 111 * Termination.StopWhenComplete=true<br> 112 * <br> 113 * #Solution comparator<br> 114 * Comparator.Class=net.sf.cpsolver.ifs.solution.GeneralSolutionComparator<br> 115 * </code></ul><br> 116 * File<b> rpp80.ini</b><ul><code> 117 * #RPP instances with 200 objects and the placement area filled to 80% in average<br> 118 * General.Input=input\\rpp\\80<br> 119 * Rpp.ProblemWidth=40<br> 120 * Rpp.ProblemHeight=14<br> 121 * #Use 10 problem instances (this means problem files gen1.pl, gen2.pl,... gen10.pl will be taken), each run 10 times<br> 122 * Rpp.Min=1<br> 123 * Rpp.Max=10<br> 124 * Rpp.NrTests=10<br> 125 * </code></ul><br> 126 * File<b> mpp22.ini</b><ul><code> 127 * #RPP MPP instance 22 (with 200 objects and the placement area filled to 80% in average)<br> 128 * # files gen22.pl (input problem), gen22.solution (initial solution) and gen22.mpp (input perturbations) are to be taken<br> 129 * General.Input=input\\rpp-mpp\\gen22<br> 130 * Rpp.ProblemWidth=40<br> 131 * Rpp.ProblemHeight=14<br> 132 * # 0, 4, 8, .. 200 input perturbations to be used<br> 133 * Rpp.Min=0<br> 134 * Rpp.Max=200<br> 135 * Rpp.Step=4<br> 136 * </code></ul><br> 137 * File<b> 5min.ini</b><ul><code> 138 * #5 minute time limit for each run<br> 139 * Termination.TimeOut=300<br> 140 * </code></ul><br> 141 * File<b> cbs.ini</b><ul><code> 142 * #Use conflict-based statistics<br> 143 * Extensions.Classes=net.sf.cpsolver.ifs.extension.ConflictStatistics<br> 144 * Value.WeightWeightedConflicts=1.0<br> 145 * </code></ul><br> 146 * File<b> tabu20.ini</b><ul><code> 147 * #Use tabu-list of the length 20<br> 148 * Value.Tabu=20<br> 149 * </code></ul><br> 150 * File<b> rw1.ini</b><ul><code> 151 * #Use 1% random walk selection<br> 152 * Value.RandomWalkProb=0.01<br> 153 * </code></ul><br> 154 * 155 * @see RPPModel 156 * @see net.sf.cpsolver.ifs.extension.ConflictStatistics 157 * @see net.sf.cpsolver.ifs.heuristics.GeneralValueSelection 158 * @see net.sf.cpsolver.ifs.heuristics.GeneralVariableSelection 159 * @see net.sf.cpsolver.ifs.termination.GeneralTerminationCondition 160 * @see net.sf.cpsolver.ifs.solution.GeneralSolutionComparator 161 * 162 * @version 163 * IFS 1.1 (Iterative Forward Search)<br> 164 * Copyright (C) 2006 Tomáš Müller<br> 165 * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br> 166 * Lazenska 391, 76314 Zlin, Czech Republic<br> 167 * <br> 168 * This library is free software; you can redistribute it and/or 169 * modify it under the terms of the GNU Lesser General Public 170 * License as published by the Free Software Foundation; either 171 * version 2.1 of the License, or (at your option) any later version. 172 * <br><br> 173 * This library is distributed in the hope that it will be useful, 174 * but WITHOUT ANY WARRANTY; without even the implied warranty of 175 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 176 * Lesser General Public License for more details. 177 * <br><br> 178 * You should have received a copy of the GNU Lesser General Public 179 * License along with this library; if not, write to the Free Software 180 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 181 */ 182 public class Test { 183 private static java.text.DecimalFormat sDoubleFormat = new java.text.DecimalFormat("0.00", new java.text.DecimalFormatSymbols(Locale.US)); 184 private static java.text.SimpleDateFormat sDateFormat = new java.text.SimpleDateFormat("dd-MMM-yy_HHmmss", java.util.Locale.US); 185 private static org.apache.log4j.Logger sLogger = org.apache.log4j.Logger.getLogger(Test.class); 186 187 private static Model loadModel(int mWidth, int mHeight, Vector objects, Vector assigned, Vector perturbations, int perb, int test) { 188 try { 189 sLogger.debug("Loading model " + perb + "." + test + " ..."); 190 double startTime = JProf.currentTimeSec(); 191 RPPModel m = new RPPModel(); 192 ResourceConstraint c = new ResourceConstraint(mWidth, mHeight); 193 m.addConstraint(c); 194 for (Enumeration e = ((PrologFile.Term) ((PrologFile.Term)objects.elementAt(0)).getContent().elementAt(0)).getContent().elements(); e.hasMoreElements();) { 195 PrologFile.Term object = (PrologFile.Term)e.nextElement(); 196 String name = object.elementAt(0).elementAt(0).getText(); 197 int width = object.elementAt(1).elementAt(0).elementAt(0).toInt(); 198 int height = object.elementAt(1).elementAt(0).elementAt(1).toInt(); 199 String xpos = object.elementAt(2).elementAt(0).elementAt(0).getText(); 200 String ypos = object.elementAt(2).elementAt(0).elementAt(1).getText(); 201 int xmin = Integer.parseInt(xpos.substring(0, xpos.indexOf('-'))); 202 int xmax = Integer.parseInt(xpos.substring(xpos.indexOf('-') + 1)); 203 int ymin = Integer.parseInt(ypos.substring(0, ypos.indexOf('-'))); 204 int ymax = Integer.parseInt(ypos.substring(ypos.indexOf('-') + 1)); 205 Rectangle r = new Rectangle(name, width, height, xmin, xmax, ymin, ymax, null); 206 m.addVariable(r); 207 c.addVariable(r); 208 } 209 for (Enumeration e = ((PrologFile.Term) ((PrologFile.Term)assigned.elementAt(0)).elementAt(0)).getContent().elements(); e.hasMoreElements();) { 210 PrologFile.Term assignment = (PrologFile.Term)e.nextElement(); 211 String name = assignment.elementAt(0).getText(); 212 name = name.substring(0, name.length() - 1); 213 int x = assignment.elementAt(1).elementAt(0).toInt(); 214 assignment = (PrologFile.Term)e.nextElement(); 215 int y = assignment.elementAt(1).elementAt(0).toInt(); 216 m.getRectangle(name).setInitialAssignment(new Location(m.getRectangle(name), x, y)); 217 } 218 for (Enumeration e = perturbations.elements(); e.hasMoreElements();) { 219 PrologFile.Term pert = (PrologFile.Term)e.nextElement(); 220 if (test == pert.elementAt(0).toInt() && perb == pert.elementAt(1).toInt() && perb > 0) { 221 for (Enumeration x = pert.elementAt(2).getContent().elements(); x.hasMoreElements();) { 222 int rec = ((PrologFile.Term)x.nextElement()).toInt(); 223 m.getRectangle("rect" + rec).setProhibited(); 224 } 225 } 226 } 227 sLogger.debug("Loaded in " + sDoubleFormat.format(JProf.currentTimeSec() - startTime) + " sec."); 228 return m; 229 } 230 catch (Exception e) { 231 e.printStackTrace(); 232 return null; 233 } 234 } 235 236 private static Model loadModel(int mWidth, int mHeight, Vector objects) { 237 try { 238 sLogger.debug("Loading model ..."); 239 double startTime = JProf.currentTimeSec(); 240 RPPModel m = new RPPModel(); 241 ResourceConstraint c = new ResourceConstraint(mWidth, mHeight); 242 m.addConstraint(c); 243 for (Enumeration e = ((PrologFile.Term) ((PrologFile.Term)objects.elementAt(0)).getContent().elementAt(0)).getContent().elements(); e.hasMoreElements();) { 244 PrologFile.Term object = (PrologFile.Term)e.nextElement(); 245 String name = object.elementAt(0).elementAt(0).getText(); 246 int width =object.elementAt(1).elementAt(0).elementAt(0).toInt(); 247 int height = object.elementAt(1).elementAt(0).elementAt(1).toInt(); 248 String xpos = object.elementAt(2).elementAt(0).elementAt(0).getText(); 249 String ypos = object.elementAt(2).elementAt(0).elementAt(1).getText(); 250 int xmin = Integer.parseInt(xpos.substring(0, xpos.indexOf('-'))); 251 int xmax = Integer.parseInt(xpos.substring(xpos.indexOf('-') + 1)); 252 int ymin = Integer.parseInt(ypos.substring(0, ypos.indexOf('-'))); 253 int ymax = Integer.parseInt(ypos.substring(ypos.indexOf('-') + 1)); 254 Rectangle r = new Rectangle(name, width, height, xmin, xmax, ymin, ymax, null); 255 m.addVariable(r); 256 c.addVariable(r); 257 } 258 sLogger.debug("Loaded in " + sDoubleFormat.format(JProf.currentTimeSec() - startTime) + " sec."); 259 return m; 260 } 261 catch (Exception e) { 262 e.printStackTrace(); 263 return null; 264 } 265 } 266 267 private static void testMPP(DataProperties properties) { 268 try { 269 FileInputStream fis = new FileInputStream(properties.getProperty("General.Input") + ".pl"); 270 Vector v1 = PrologFile.readTermsFromStream(fis, "objects"); 271 fis.close(); 272 fis = new FileInputStream(properties.getProperty("General.Input") + ".solution"); 273 Vector v2 = PrologFile.readTermsFromStream(fis, "assigned"); 274 fis.close(); 275 fis = new FileInputStream(properties.getProperty("General.Input") + ".mpp"); 276 Vector v3 = PrologFile.readTermsFromStream(fis, "perturbation"); 277 fis.close(); 278 279 PrintWriter res = new PrintWriter(new FileWriter(properties.getProperty("General.Output") + File.separator + "result.pl")); 280 PrintWriter stat = new PrintWriter(new FileWriter(properties.getProperty("General.Output") + File.separator + "stat.pl")); 281 PrintWriter txt = new PrintWriter(new FileWriter(properties.getProperty("General.Output") + File.separator + "stat.csv")); 282 txt.println("pert;time[s];timeRMS;assigned;assignedRMS;perturbations;perturbationsRMS;iters;itersRMS"); 283 java.text.DecimalFormat nf = new java.text.DecimalFormat("0.000", new java.text.DecimalFormatSymbols(Locale.US)); 284 int size = -1; //gen80_22_initial().getRectangles().size(); 285 int tests = properties.getPropertyInt("Rpp.NrTests", 10); 286 int step = properties.getPropertyInt("Rpp.Step", 4); 287 int min = properties.getPropertyInt("Rpp.Min", 0); 288 int max = properties.getPropertyInt("Rpp.Max", -1); 289 for (int i = min; size == -1 || i <= (max > 0 ? Math.min(max, size) : size); i += step) { 290 double time = 0; 291 long assigned = 0; 292 long perturbation = 0; 293 long iters = 0; 294 double time2 = 0; 295 long assigned2 = 0; 296 long perturbation2 = 0; 297 long iters2 = 0; 298 for (int t = 1; t <= tests; t++) { 299 Model m = loadModel(properties.getPropertyInt("Rpp.ProblemWidth", 40), properties.getPropertyInt("Rpp.ProblemHeight", 14), v1, v2, v3, i, t); 300 if (size < 0) size = m.variables().size(); 301 Solver s = new Solver(properties); 302 s.setInitalSolution(m); 303 s.start(); 304 s.getSolverThread().join(); 305 Solution best = s.currentSolution(); 306 best.restoreBest(); 307 res.println("result(" + t + "," + i + "," + nf.format(best.getBestTime()) + "," + (best.getModel().variables().size() - best.getModel().getBestUnassignedVariables()) + "," + best.getBestIteration() + ","); 308 EnumerableCollection notPlaced = best.getModel().bestUnassignedVariables(); 309 if (notPlaced == null) 310 notPlaced = new FastVector(); 311 res.print(" unassigned(" + (2 * notPlaced.size()) + "/["); 312 for (Enumeration it = notPlaced.elements(); it.hasMoreElements();) { 313 Rectangle rect = (Rectangle)it.nextElement(); 314 res.print(rect.getName() + "X," + rect.getName() + "Y" + (it.hasMoreElements() ? "," : "")); 315 } 316 res.println("]),"); 317 StringBuffer sb = new StringBuffer(); 318 int perts = 0; 319 for (Enumeration it = best.getModel().variables().elements(); it.hasMoreElements();) { 320 Rectangle rect = (Rectangle)it.nextElement(); 321 if (rect.getBestAssignment() != null && (rect.getInitialAssignment() == null || !rect.getBestAssignment().equals( 322 rect.getInitialAssignment()))) { 323 sb.append(sb.length() == 0 ? "" : ","); 324 sb.append(rect.getName() + "X-" + ((Location)rect.getBestAssignment()).getX()); 325 sb.append(sb.length() == 0 ? "" : ","); 326 sb.append(rect.getName() + "Y-" + ((Location)rect.getBestAssignment()).getY()); 327 perts++; 328 } 329 if (rect.getBestAssignment() == null) { 330 perts++; 331 } 332 } 333 res.println(" perturbations(" + (2 * perts) + "/[" + sb + "])"); 334 res.println(")."); 335 res.flush(); 336 iters += best.getBestIteration(); 337 iters2 += (best.getBestIteration() * best.getBestIteration()); 338 time += best.getBestTime(); 339 time2 += (best.getBestTime() * best.getBestTime()); 340 assigned += (best.getModel().variables().size() - best.getModel().getBestUnassignedVariables()); 341 assigned2 += (best.getModel().variables().size() - best.getModel().getBestUnassignedVariables()) * (best.getModel().variables().size() - best.getModel().getBestUnassignedVariables()); 342 perturbation += perts; 343 perturbation2 += perts * perts; 344 } 345 txt.println(i + ";" + nf.format(time / tests) + ";" + nf.format(ToolBox.rms(tests, time, time2)) + ";" + nf.format(((double)assigned) / tests) + ";" + 346 nf.format(ToolBox.rms(tests, (double)assigned, (double)assigned2)) + ";" + 347 nf.format(((double)perturbation) / tests) + ";" + 348 nf.format(ToolBox.rms(tests, (double)perturbation, (double)perturbation2)) + ";" + 349 nf.format(((double)iters) / tests) + ";" + 350 nf.format(ToolBox.rms(tests, (double)iters, (double)iters2))); 351 txt.flush(); 352 stat.println("averages( initperturbations( " + i + " ), time( " + nf.format(time / tests)+ " ), assigned( " + 353 nf.format(((double)assigned) / tests) + " ), perturbations( " + nf.format(((double)perturbation) / tests) + " ) )."); 354 stat.println("deviations( initperturbations( " + i + " ), time( " + 355 nf.format(ToolBox.rms(tests, (double)time, (double)time2)) + " ), assigned( " + 356 nf.format(ToolBox.rms(tests, (double)assigned, (double)assigned2)) + " ), perturbations( " + 357 nf.format(ToolBox.rms(tests, (double)perturbation, (double)perturbation2)) + " ) )."); 358 stat.flush(); 359 } 360 res.close(); 361 txt.close(); 362 stat.close(); 363 } 364 catch (Exception e) { 365 e.printStackTrace(); 366 } 367 } 368 369 private static void test(DataProperties properties) { 370 try { 371 int tests = properties.getPropertyInt("Rpp.NrTests", 10); 372 int min = properties.getPropertyInt("Rpp.Min", 0); 373 int max = properties.getPropertyInt("Rpp.Max", -1); 374 PrintWriter res = new PrintWriter(new FileWriter(properties.getProperty("General.Output") + File.separator + "result.pl")); 375 PrintWriter stat = new PrintWriter(new FileWriter(properties.getProperty("General.Output") + File.separator + "stat.pl")); 376 PrintWriter txt = new PrintWriter(new FileWriter(properties.getProperty("General.Output") + File.separator + "stat.csv")); 377 txt.println("gen;time[s];timeRMS;assigned;assignedRMS;iters;itersRMS"); 378 java.text.DecimalFormat nf = new java.text.DecimalFormat("0.000", new java.text.DecimalFormatSymbols(Locale.US)); 379 for (int genNr = min; genNr <= max; genNr++) { 380 FileInputStream fis = new FileInputStream(properties.getProperty("General.Input") + File.separator + "gen" + genNr + ".pl"); 381 Vector v1 = PrologFile.readTermsFromStream(fis, "objects"); 382 fis.close(); 383 double time = 0; 384 long assigned = 0; 385 long iters = 0; 386 double time2 = 0; 387 long assigned2 = 0; 388 long iters2 = 0; 389 for (int t = 1; t <= tests; t++) { 390 Model m = loadModel(properties.getPropertyInt("Rpp.ProblemWidth", 40), properties.getPropertyInt("Rpp.ProblemHeight", 14), v1); 391 Solver s = new Solver(properties); 392 s.setInitalSolution(m); 393 s.start(); 394 s.getSolverThread().join(); 395 Solution best = s.currentSolution(); 396 best.restoreBest(); 397 iters += best.getBestIteration(); 398 iters2 += (best.getBestIteration() * best.getBestIteration()); 399 time += best.getBestTime(); 400 time2 += (best.getBestTime() * best.getBestTime()); 401 assigned += (best.getModel().variables().size() - best.getModel().getBestUnassignedVariables()); 402 assigned2 += (best.getModel().variables().size() - best.getModel().getBestUnassignedVariables()) * (best.getModel().variables().size() - best.getModel().getBestUnassignedVariables()); 403 res.println("result(" + genNr + ","+t+"," + nf.format(best.getBestTime()) + "," + (best.getModel().variables().size() - best.getModel().getBestUnassignedVariables()) + "," + best.getBestIteration() + ","); 404 EnumerableCollection notPlaced = best.getModel().bestUnassignedVariables(); 405 if (notPlaced == null) 406 notPlaced = new FastVector(); 407 res.print(" unassigned(" + (2 * notPlaced.size()) + "/["); 408 for (Enumeration it = notPlaced.elements(); it.hasMoreElements();) { 409 Rectangle rect = (Rectangle)it.nextElement(); 410 res.print(rect.getName() + "X," + rect.getName() + "Y" + (it.hasMoreElements() ? "," : "")); 411 } 412 res.println("]),"); 413 int perts = 0; 414 StringBuffer sb = new StringBuffer(); 415 for (Enumeration it = best.getModel().variables().elements(); it.hasMoreElements();) { 416 Rectangle rect = (Rectangle)it.nextElement(); 417 if (rect.getBestAssignment() != null) { 418 sb.append(sb.length() == 0 ? "" : ","); 419 sb.append(rect.getName() + "X-" + ((Location)rect.getBestAssignment()).getX()); 420 sb.append(sb.length() == 0 ? "" : ","); 421 sb.append(rect.getName() + "Y-" + ((Location)rect.getBestAssignment()).getY()); 422 perts++; 423 } 424 } 425 res.println(" assigned(" + (2 * perts) + "/[" + sb + "])"); 426 res.println(")."); 427 res.flush(); 428 } 429 txt.println(genNr + ";" + nf.format(time / tests) + ";" + nf.format(ToolBox.rms(tests, time, time2)) + ";" + nf.format(((double)assigned) / tests) + ";" + 430 nf.format(ToolBox.rms(tests, (double)assigned, (double)assigned2)) + ";" + 431 nf.format(((double)iters) / tests) + ";" + 432 nf.format(ToolBox.rms(tests, (double)iters, (double)iters2))); 433 txt.flush(); 434 stat.println("averages( problem( " + genNr + " ), time( " + nf.format(time / tests)+ " ), assigned( " + 435 nf.format(((double)assigned) / tests) + " ) )."); 436 stat.println("deviations( problem( " + genNr + " ), time( " + 437 nf.format(ToolBox.rms(tests, (double)time, (double)time2)) + " ), assigned( " + 438 nf.format(ToolBox.rms(tests, (double)assigned, (double)assigned2)) + " ) )."); 439 stat.flush(); 440 } 441 res.close(); 442 txt.close(); 443 stat.close(); 444 } 445 catch (Exception e) { 446 e.printStackTrace(); 447 } 448 } 449 450 private static void test(File inputCfg, String name, String include, String regexp, String outDir) throws Exception { 451 if (regexp != null) { 452 String incFile; 453 if (regexp.indexOf(';') > 0) { 454 incFile = regexp.substring(0, regexp.indexOf(';')); 455 regexp = regexp.substring(regexp.indexOf(';') + 1); 456 } 457 else { 458 incFile = regexp; 459 regexp = null; 460 } 461 if (incFile.startsWith("[") && incFile.endsWith("]")) { 462 test(inputCfg, name, include, regexp, outDir); 463 incFile = incFile.substring(1, incFile.length() - 1); 464 } 465 if (incFile.indexOf('{') >= 0 && incFile.indexOf('}') >= 0) { 466 String prefix = incFile.substring(0, incFile.indexOf('{')); 467 StringTokenizer middle = 468 new StringTokenizer(incFile.substring( incFile.indexOf('{') + 1, incFile.indexOf('}')), "|"); 469 String sufix = incFile.substring(incFile.indexOf('}') + 1); 470 while (middle.hasMoreTokens()) { 471 String m = middle.nextToken(); 472 test(inputCfg, (name == null ? "" : name + "_") + m, (include == null ? "" : include + ";") + prefix + m + sufix, regexp, outDir); 473 } 474 } 475 else { 476 test(inputCfg, name, (include == null ? "" : include + ";") + incFile, regexp, outDir); 477 } 478 } 479 else { 480 DataProperties properties = ToolBox.loadProperties(inputCfg); 481 StringTokenizer inc = new StringTokenizer(include, ";"); 482 while (inc.hasMoreTokens()) { 483 String aFile = inc.nextToken(); 484 System.out.println(" Loading included file '" + aFile + "' ... "); 485 FileInputStream is = null; 486 if ((new File(aFile)).exists()) 487 is = new FileInputStream(aFile); 488 if ((new File(inputCfg.getParent() + File.separator + aFile)).exists()) 489 is = new FileInputStream(inputCfg.getParent() + File.separator + aFile); 490 if (is == null) 491 System.err.println("Unable to find include file '" + aFile + "'."); 492 properties.load(is); 493 is.close(); 494 } 495 String outDirTisTest = (outDir==null?properties.getProperty("General.Output", "."):outDir) + File.separator + name + File.separator + sDateFormat.format(new Date()); 496 properties.setProperty("General.Output", outDirTisTest.toString()); 497 System.out.println("Output folder: "+properties.getProperty("General.Output")); 498 (new File(outDirTisTest)).mkdirs(); 499 ToolBox.configureLogging(outDirTisTest, null); 500 FileOutputStream fos = new FileOutputStream(outDirTisTest + File.separator + "rcsp.conf"); 501 properties.store(fos, "Random CSP problem configuration file"); 502 fos.flush(); 503 fos.close(); 504 boolean mpp = properties.getPropertyBoolean("General.MPP", true); 505 if (mpp) 506 testMPP(properties); 507 else 508 test(properties); 509 } 510 } 511 512 /** 513 * RPP test. 514 * @param args the command line arguments 515 */ 516 public static void main(String[] args) { 517 try { 518 Progress.getInstance().addProgressListener( 519 new ProgressWriter(System.out)); 520 521 File inputCfg = new File(args[0]); 522 DataProperties properties = ToolBox.loadProperties(inputCfg); 523 if (properties.getProperty("INCLUDE_REGEXP") != null) { 524 if (args.length>1) 525 properties.setProperty("General.Output", args[1]); 526 test(inputCfg, null, null, properties.getProperty("INCLUDE_REGEXP"), (args.length>1?args[1]:null)); 527 } else { 528 String outDir = properties.getProperty("General.Output", ".") + File.separator + inputCfg.getName().substring(0, inputCfg.getName().lastIndexOf('.')) + File.separator + sDateFormat.format(new Date()); 529 if (args.length>1) 530 outDir = args[1]+File.separator+(sDateFormat.format(new Date())); 531 (new File(outDir)).mkdirs(); 532 properties.setProperty("General.Output", outDir.toString()); 533 System.out.println("Output folder: "+properties.getProperty("General.Output")); 534 ToolBox.configureLogging(outDir, null); 535 boolean mpp = properties.getPropertyBoolean("General.MPP", false); 536 if (mpp) 537 testMPP(properties); 538 else 539 test(properties); 540 } 541 542 } 543 catch (Exception e) { 544 e.printStackTrace(); 545 } 546 } 547 }