001 package ifs.example.tt;
002
003 import ifs.model.*;
004 import ifs.solution.*;
005 import ifs.solver.*;
006 import ifs.util.*;
007
008 import java.io.*;
009 import java.util.*;
010
011 /**
012 * Test
013 *
014 * @author <a href="mailto:muller@ktiml.mff.cuni.cz">Tomáš Müller</a>
015 * @version 1.0
016 */
017 public class Test {
018 private static java.text.DecimalFormat sDoubleFormat = new java.text.DecimalFormat("0.000", new java.text.DecimalFormatSymbols(Locale.US));
019 private static java.text.SimpleDateFormat sDateFormat = new java.text.SimpleDateFormat("dd-MMM-yy_HHmmss", java.util.Locale.US);
020 private static org.apache.log4j.Logger sLogger = org.apache.log4j.Logger.getLogger(Test.class);
021
022 public static void test2(DataProperties properties) throws Exception {
023 int nrTests = properties.getPropertyInt("Test.NrTests",1);
024 PrintWriter logStat = new PrintWriter(new FileWriter(properties.getProperty("General.Output")+File.separator+"output.csv"));
025 PrintWriter logAvgStat = new PrintWriter(new FileWriter(properties.getProperty("General.Output")+File.separator+"avg_stat.csv"));
026 logStat.println("fillFact;nrResources;testNr;time[s];iters;speed[it/s];assigned;assigned[%];value;totalValue");
027 logAvgStat.println("fillFact;nrResources;time[s];RMStime[s];iters;RMSiters;speed[it/s];assigned;RMSassigned;assigned[%];value;RMSvalue");
028
029 int nrResourcesMin = properties.getPropertyInt("Test.NrResourcesMin", -1);
030 int nrResourcesMax = properties.getPropertyInt("Test.NrResourcesMax", -1);
031 int nrResourcesStep = properties.getPropertyInt("Test.NrResourcesStep", 1);
032 double fillFactorMin = properties.getPropertyDouble("Test.FillFactorMin", -1.0);
033 double fillFactorMax = properties.getPropertyDouble("Test.FillFactorMax", -1.0);
034 double fillFactorStep = properties.getPropertyDouble("Test.FillFactorStep", 0.01);
035
036 boolean saveInit = properties.getPropertyBoolean("General.SaveInitialXML", true);
037 boolean saveSol = properties.getPropertyBoolean("General.SaveSolutionXML", true);
038
039 for (int nrResources=nrResourcesMin;nrResources<=nrResourcesMax;nrResources+=nrResourcesStep) {
040 for (double fillFactor=fillFactorMin;fillFactor<=fillFactorMax;fillFactor+=fillFactorStep) {
041 double sumTime = 0;
042 double sumTime2 = 0;
043 int sumIters = 0;
044 int sumIters2 = 0;
045 int sumAssign = 0;
046 int sumAssign2 = 0;
047 int sumVal = 0;
048 int sumVal2 = 0;
049 int sumVar = 0;
050 int sumVar2 = 0;
051 for (int test=1;test<=nrTests;test++) {
052 if (nrResources>=0) {
053 properties.setProperty("Generator.NrRooms", String.valueOf(nrResources));
054 properties.setProperty("Generator.NrClasses", String.valueOf(nrResources));
055 properties.setProperty("Generator.NrInstructors", String.valueOf(nrResources));
056 }
057 if (fillFactor>=0.0) {
058 properties.setProperty("Generator.FillFactor", String.valueOf(fillFactor));
059 }
060 TimetableModel m = TimetableModel.generate(properties);
061
062 Solver s = new Solver(properties);
063 if (saveInit) m.saveAsXML(properties, true, null,
064 new File(properties.getProperty("General.Output")+File.separator+"SimpleTT("+
065 (nrResources<0?properties.getPropertyInt("Generator.NrRooms",20):nrResources)+","+
066 ((int)(100.0*(fillFactor<0.0?properties.getPropertyDouble("Generator.FillFactor",0.8):fillFactor)+0.5))+","+
067 properties.getPropertyInt("Generator.NrDependencies",50)+")_"+test+".xml"));
068 s.setInitalSolution(m);
069 s.currentSolution().clearBest();
070 s.start();
071 try {
072 s.getSolverThread().join();
073 } catch (NullPointerException npe) {}
074
075
076
077 if (s.lastSolution().getBestInfo()==null) sLogger.error("No solution found :-(");
078 sLogger.debug("Last solution:"+s.lastSolution().getInfo());
079 Solution best = s.lastSolution();
080 sLogger.debug("Best solution:"+s.lastSolution().getBestInfo());
081 best.restoreBest();
082 int val = 0;
083 for (Enumeration iv = best.getModel().assignedVariables().elements(); iv.hasMoreElements();)
084 val += ((Variable)iv.nextElement()).getAssignment().toInt();
085 if (saveSol) m.saveAsXML(properties, true, best,
086 new File(properties.getProperty("General.Output")+File.separator+"SimpleTT("+
087 (nrResources<0?properties.getPropertyInt("Generator.NrRooms",20):nrResources)+","+
088 ((int)(100.0*(fillFactor<0.0?properties.getPropertyDouble("Generator.FillFactor",0.8):fillFactor)+0.5))+","+
089 properties.getPropertyInt("Generator.NrDependencies",50)+")_"+test+"_sol.xml"));
090 sLogger.debug("Last solution:"+best.getInfo());
091 logStat.println(
092 sDoubleFormat.format(properties.getPropertyDouble("Generator.FillFactor",0.0))+";"+
093 sDoubleFormat.format(properties.getPropertyInt("Generator.NrRooms",0))+";"+
094 test+";"+sDoubleFormat.format(best.getTime())+";"+best.getIteration()+";"+sDoubleFormat.format(((double)best.getIteration())/best.getTime())+";"+best.getModel().assignedVariables().size()+";"+sDoubleFormat.format(100.0 * best.getModel().assignedVariables().size() / best.getModel().variables().size())+";"+val);
095 sLogger.debug(" time: "+sDoubleFormat.format(best.getTime())+" s");
096 sLogger.debug(" iteration: "+best.getIteration());
097 sLogger.debug(" speed: "+sDoubleFormat.format(((double)best.getIteration())/best.getTime())+" it/s");
098 sLogger.debug(" assigned: "+best.getModel().assignedVariables().size()+" ("+sDoubleFormat.format(100.0 * best.getModel().assignedVariables().size() / best.getModel().variables().size())+"%)");
099 sLogger.debug(" value: "+val);
100 sumTime += best.getTime();
101 sumTime2 += best.getTime()*best.getTime();
102 sumIters += best.getIteration();
103 sumIters2 += best.getIteration()*best.getIteration();
104 sumAssign += best.getModel().assignedVariables().size();
105 sumAssign2 += best.getModel().assignedVariables().size()*best.getModel().assignedVariables().size();
106 sumVal += val;
107 sumVal2 += val * val;
108 sumVar += m.variables().size();
109 sumVar2 += m.variables().size()*m.variables().size();
110 logStat.flush();
111 }
112 logAvgStat.println(
113 sDoubleFormat.format(properties.getPropertyDouble("Generator.FillFactor",0.0))+";"+
114 sDoubleFormat.format(properties.getPropertyInt("Generator.NrRooms",0))+";"+
115 sDoubleFormat.format(sumTime/nrTests)+";"+
116 sDoubleFormat.format(ToolBox.rms(nrTests,sumTime,sumTime2))+";"+
117 sDoubleFormat.format(((double)sumIters)/nrTests)+";"+
118 sDoubleFormat.format(ToolBox.rms(nrTests,(double)sumIters,(double)sumIters2))+";"+
119 sDoubleFormat.format(((double)sumIters)/sumTime)+";"+
120 sDoubleFormat.format(((double)sumAssign)/nrTests)+";"+
121 sDoubleFormat.format(ToolBox.rms(nrTests,(double)sumAssign,(double)sumAssign2))+";"+
122 sDoubleFormat.format(100.0 * ((double) sumAssign) / sumVar)+";"+
123 sDoubleFormat.format(((double)sumVal)/nrTests)+";"+
124 sDoubleFormat.format(ToolBox.rms(nrTests,(double)sumVal,(double)sumVal2)));
125 logAvgStat.flush();
126 }
127 }
128 logStat.close();
129 logAvgStat.close();
130 }
131
132 public static void test3(DataProperties properties, File xmlFile) throws Exception {
133 int nrTests = properties.getPropertyInt("Test.NrTests",1);
134 PrintWriter logStat = new PrintWriter(new FileWriter(properties.getProperty("General.Output")+File.separator+"output.csv"));
135 logStat.println("fillFact;nrResources;testNr;time[s];iters;speed[it/s];assigned;assigned[%];value;totalValue");
136
137 boolean saveSol = properties.getPropertyBoolean("General.SaveSolutionXML", true);
138 boolean assign = properties.getPropertyBoolean("General.InitialAssignment", true);
139 int forcedPerturbances = properties.getPropertyInt("General.ForcedPerturbances", 0);
140
141 for (int test=1;test<=nrTests;test++) {
142 TimetableModel m = TimetableModel.loadFromXML(xmlFile, assign);
143
144 if (forcedPerturbances>0) {
145 Vector initialVariables = new Vector();
146 for (Enumeration e=m.variables().elements();e.hasMoreElements();) {
147 Variable v = (Variable)e.nextElement();
148 if (v.getInitialAssignment()!=null)
149 initialVariables.addElement(v);
150 }
151 for (int i=0;i<forcedPerturbances;i++) {
152 if (initialVariables.isEmpty()) break;
153 Variable var = (Variable)ToolBox.random(initialVariables);
154 initialVariables.remove(var);
155 var.removeInitialValue();
156 }
157 }
158
159 Solver s = new Solver(properties);
160 s.setInitalSolution(m);
161 s.currentSolution().clearBest();
162 s.start();
163 try {
164 s.getSolverThread().join();
165 } catch (NullPointerException npe) {}
166
167 if (s.lastSolution().getBestInfo()==null) sLogger.error("No solution found :-(");
168 sLogger.debug("Last solution:"+s.lastSolution().getInfo());
169 Solution best = s.lastSolution();
170 sLogger.debug("Best solution:"+s.lastSolution().getBestInfo());
171 best.restoreBest();
172 int val = 0;
173 for (Enumeration iv = best.getModel().assignedVariables().elements(); iv.hasMoreElements();)
174 val += ((Variable)iv.nextElement()).getAssignment().toInt();
175 if (saveSol) m.saveAsXML(properties, false, best, new File(properties.getProperty("General.Output")+File.separator+"solution_"+test+".xml"));
176 sLogger.debug("Last solution:"+best.getInfo());
177 logStat.println(
178 sDoubleFormat.format(properties.getPropertyDouble("Generator.FillFactor",0.0))+";"+
179 sDoubleFormat.format(properties.getPropertyInt("Generator.NrRooms",0))+";"+
180 test+";"+sDoubleFormat.format(best.getTime())+";"+best.getIteration()+";"+sDoubleFormat.format(((double)best.getIteration())/best.getTime())+";"+best.getModel().assignedVariables().size()+";"+sDoubleFormat.format(100.0 * best.getModel().assignedVariables().size() / best.getModel().variables().size())+";"+val);
181 sLogger.debug(" time: "+sDoubleFormat.format(best.getTime())+" s");
182 sLogger.debug(" iteration: "+best.getIteration());
183 sLogger.debug(" speed: "+sDoubleFormat.format(((double)best.getIteration())/best.getTime())+" it/s");
184 sLogger.debug(" assigned: "+best.getModel().assignedVariables().size()+" ("+sDoubleFormat.format(100.0 * best.getModel().assignedVariables().size() / best.getModel().variables().size())+"%)");
185 sLogger.debug(" value: "+val);
186 logStat.flush();
187 }
188 logStat.close();
189 }
190
191 public static void test(File inputCfg, String name, String include, String regexp, String outDir) throws Exception {
192 if (regexp != null) {
193 String incFile;
194
195 if (regexp.indexOf(';') > 0) {
196 incFile = regexp.substring(0, regexp.indexOf(';'));
197 regexp = regexp.substring(regexp.indexOf(';') + 1);
198 } else {
199 incFile = regexp;
200 regexp = null;
201 }
202 if (incFile.startsWith("[") && incFile.endsWith("]")) {
203 test(inputCfg, name, include, regexp, outDir);
204 incFile = incFile.substring(1, incFile.length() - 1);
205 }
206 if (incFile.indexOf('{') >= 0 && incFile.indexOf('}') >= 0) {
207 String prefix = incFile.substring(0, incFile.indexOf('{'));
208 StringTokenizer middle = new StringTokenizer(incFile.substring(incFile.indexOf('{') + 1, incFile.indexOf('}')), "|");
209 String sufix = incFile.substring(incFile.indexOf('}') + 1);
210
211 while (middle.hasMoreTokens()) {
212 String m = middle.nextToken();
213
214 test(inputCfg, (name == null ? "" : name + "_") + m, (include == null ? "" : include + ";") + prefix + m + sufix, regexp, outDir);
215 }
216 } else {
217 test(inputCfg, name, (include == null ? "" : include + ";") + incFile, regexp, outDir);
218 }
219 } else {
220 DataProperties properties = ToolBox.loadProperties(inputCfg);
221 StringTokenizer inc = new StringTokenizer(include, ";");
222
223 while (inc.hasMoreTokens()) {
224 String aFile = inc.nextToken();
225
226 System.out.println(" Loading included file '" + aFile + "' ... ");
227 FileInputStream is = null;
228
229 if ((new File(aFile)).exists()) {
230 is = new FileInputStream(aFile);
231 }
232 if ((new File(inputCfg.getParent() + File.separator + aFile)).exists()) {
233 is = new FileInputStream(inputCfg.getParent() + File.separator + aFile);
234 }
235 if (is == null) {
236 System.err.println("Unable to find include file '" + aFile + "'.");
237 }
238 properties.load(is);
239 is.close();
240 }
241 String outDirThisTest = (outDir==null?properties.getProperty("General.Output","."):outDir)+File.separator + name+File.separator+sDateFormat.format(new Date());
242 properties.setProperty("General.Output", outDirThisTest.toString());
243 System.out.println("Output folder: "+properties.getProperty("General.Output"));
244 (new File(outDirThisTest)).mkdirs();
245 ToolBox.configureLogging(outDirThisTest, null);
246 FileOutputStream fos = new FileOutputStream(outDirThisTest + File.separator + "rcsp.conf");
247
248 properties.store(fos, "Random CSP problem configuration file");
249 fos.flush(); fos.close();
250 test2(properties);
251 }
252 }
253
254 public static void main(String[] args) {
255 try {
256 Progress.getInstance().addProgressListener(new ProgressWriter(System.out));
257 File inputCfg = new File(args[0]);
258 DataProperties properties = ToolBox.loadProperties(inputCfg);
259 if (args.length==3) {
260 File xmlFile = new File(args[1]);
261 String outDir = args[2]+File.separator+(sDateFormat.format(new Date()));
262 properties.setProperty("General.Output", outDir.toString());
263 System.out.println("Input file: "+xmlFile);
264 System.out.println("Output folder: "+properties.getProperty("General.Output"));
265 (new File(outDir)).mkdirs();
266 ToolBox.configureLogging(outDir, null);
267 test3(properties, xmlFile);
268 } else if (properties.getProperty("INCLUDE_REGEXP") != null) {
269 test(inputCfg, null, null, properties.getProperty("INCLUDE_REGEXP"), (args.length>1?args[1]:null));
270 } else {
271 String outDir = properties.getProperty("General.Output", ".") + File.separator + inputCfg.getName().substring(0, inputCfg.getName().lastIndexOf('.')) + File.separator + sDateFormat.format(new Date());
272 if (args.length>1)
273 outDir = args[1]+File.separator+(sDateFormat.format(new Date()));
274 properties.setProperty("General.Output", outDir.toString());
275 System.out.println("Output folder: "+properties.getProperty("General.Output"));
276 (new File(outDir)).mkdirs();
277 ToolBox.configureLogging(outDir, null);
278 test2(properties);
279 }
280 } catch (Exception e) {
281 e.printStackTrace();
282 }
283 }
284 }