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