📄 experiment.java
字号:
/* * YALE - Yet Another Learning Environment * Copyright (C) 2002, 2003 * Simon Fischer, Ralf Klinkenberg, Ingo Mierswa, * Katharina Morik, Oliver Ritthoff * Artificial Intelligence Unit * Computer Science Department * University of Dortmund * 44221 Dortmund, Germany * email: yale@ls8.cs.uni-dortmund.de * web: http://yale.cs.uni-dortmund.de/ * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA. */package edu.udo.cs.yale;import edu.udo.cs.yale.tools.Tools;import edu.udo.cs.yale.tools.xml.XML2ObjectParser;import edu.udo.cs.yale.tools.xml.XMLException;import edu.udo.cs.yale.tools.xml.TextTagObject;import edu.udo.cs.yale.tools.TempFileService;import edu.udo.cs.yale.tools.RandomGenerator;import edu.udo.cs.yale.tools.ResultService;import edu.udo.cs.yale.tools.param.*;import edu.udo.cs.yale.tools.LogService;import edu.udo.cs.yale.operator.Operator;import edu.udo.cs.yale.operator.IOObject;import edu.udo.cs.yale.operator.IOContainer;import edu.udo.cs.yale.operator.OperatorChain;import edu.udo.cs.yale.operator.SimpleOperatorChain;import edu.udo.cs.yale.operator.ExperimentOperator;import edu.udo.cs.yale.operator.OperatorException;import edu.udo.cs.yale.operator.IllegalInputException;import edu.udo.cs.yale.operator.IllegalNumberOfInnerOperatorsException;import java.util.Collection;import java.util.Map;import java.util.HashMap;import java.util.List;import java.util.LinkedList;import java.util.Iterator;import java.net.URL;import java.io.IOException;import java.io.File;import java.io.FileReader;import java.io.Reader;import java.io.PrintWriter;import java.io.FileWriter;import java.io.InputStreamReader;/** This class was introduced to avoid confusing handling of operator maps and other * stuff when a new experiment is created. */public class Experiment { private static final Class[] TAG_CLASS = { SingleParameter.class, OperatorParams.class, ParameterList.class }; private static final String[] TAG_NAME = { "parameter", "operator", "list" }; private ExperimentOperator rootOperator; private Operator currentOperator; private Map operatorNameMap = new HashMap(); private File experimentFile; private List breakpointListeners = new LinkedList(); private boolean stopExperiment = false; /** Maps names of ExperimentLogOperators to Objects, that these Operators use for statistics. */ private Map statisticsMap = new HashMap(); /** Constructs an experiment consisting only of a SimpleOperatorChain. */ public Experiment() { this.rootOperator = new ExperimentOperator(this); rootOperator.register(this, "Root"); } public Experiment(URL url) throws IOException, XMLException { this(new InputStreamReader(url.openStream())); } public Experiment(File file) throws IOException, XMLException { this(new FileReader(file)); this.experimentFile = file; } /** Reads an experiment configuration from the given file. */ public Experiment(Reader in) throws IOException, XMLException { readExperiment(in); in.close(); } /** Reads the experiment configuration from the given reader. */ public void readExperiment(Reader reader) throws XMLException, IOException { Map oldNameMap = operatorNameMap; operatorNameMap = new HashMap(); XML2ObjectParser parser = new XML2ObjectParser(TAG_NAME, TAG_CLASS); List newblocks = null; try { newblocks = parser.parseAll(reader); } catch (XMLException e) { operatorNameMap = oldNameMap; throw e; } if (newblocks == null) { operatorNameMap = oldNameMap; throw new XMLException("Malformed experiment!"); } OperatorParams rootOperatorParams = null; Iterator i = newblocks.iterator(); while (i.hasNext()) { Object o = i.next(); if (o instanceof OperatorParams) { rootOperatorParams = (OperatorParams)o; break; } } if (rootOperatorParams == null) { operatorNameMap = oldNameMap; throw new XMLException("Outer tag in experiment must be <operator>!"); } while (i.hasNext()) { if (!(i.next() instanceof TextTagObject)) { operatorNameMap = oldNameMap; throw new XMLException("Experiment must contain at most 1 outer <operator> tag!"); } break; } try { Operator op = rootOperatorParams.instantiateOperator(this); if (!(op instanceof ExperimentOperator)) { throw new XMLException("Root operator is not an 'Experiment' operator."); } else { this.rootOperator = (ExperimentOperator)op; } } catch (InstantiationException e) { operatorNameMap = oldNameMap; throw new XMLException("Cannot instantiate: "+e.getMessage()); } catch (IllegalAccessException e) { operatorNameMap = oldNameMap; throw new XMLException("Illegal access: "+e.getMessage()); } catch (RuntimeException e) { operatorNameMap = oldNameMap; throw e; } } /** Returns true if a statistics object with the given name exists. */ public boolean statisticsExist(String name) { return statisticsMap.get(name) != null; } /** Returns the statistics associated with the given name. If the name was not * used yet, an empty Statistics object is created. */ public Statistics getStatistics(String name) { Statistics stats = (Statistics)statisticsMap.get(name); if (stats == null) { stats = new Statistics(name); statisticsMap.put(name, stats); } return stats; } public Collection getStatistics() { return statisticsMap.values(); } public ExperimentOperator getRootOperator() { return rootOperator; } public File getExperimentFile() { return experimentFile; } /** Returns a "name (i)" if name is already in use. */ public String getFirstFreeName(String name) { if (operatorNameMap.get(name) != null) { int i = 2; while (operatorNameMap.get(name+" ("+i+")") != null) { i++; } name += " ("+i+")"; } return name; } /** Registers the operator as part of the experiment. */ public void registerOperator(String name, Operator operator) { operatorNameMap.put(name, operator); } /** Unregisters the operator as part of the experiment. */ public void unRegisterOperator(String name) { operatorNameMap.remove(name); } /** Returns the operator with the given name. */ public Operator getOperator(String name) { return (Operator)operatorNameMap.get(name); } /** Returns the operator that is currently being executed. */ public Operator getCurrentOperator() { return currentOperator; } /** Returns a Collection view of all operators. */ public Collection getAllOperators() { return operatorNameMap.values(); } /** Returns a Set view of all operator names (i.e. Strings). */ public Collection getAllOperatorNames() { return operatorNameMap.keySet(); } /** Returns the operator that is currently being executed. */ public void setCurrentOperator(Operator operator) { this.currentOperator = operator; } public void addBreakpointListener(BreakpointListener listener) { breakpointListeners.add(listener); } public void removeBreakpointListener(BreakpointListener listener) { breakpointListeners.remove(listener); } public void fireBreakpointEvent(Operator operator, IOContainer ioContainer) { Iterator i = breakpointListeners.iterator(); while (i.hasNext()) { ((BreakpointListener)i.next()).breakpointReached(operator, ioContainer); } } private int checkIO() { Class[] nullClass = new Class[0]; LogService.logMessage("Checking i/o classes...", LogService.INIT); try { Class[] output = rootOperator.checkIO(nullClass); if (output.length == 0) { LogService.logMessage("i/o classes are ok", LogService.INIT); } else { String left = ""; for (int i = 0; i < output.length; i++) { left += output[i].getName(); if (i < output.length-1) left+=", "; } LogService.logMessage("i/o classes are ok, but there is surplus output ("+left+")", LogService.INIT); } return 0; } catch (IllegalInputException e) { if (e.getOperator() != null) e.getOperator().addError(e.getMessage()); return 1; } } private int checkNumberOfInnerOperators() { LogService.logMessage("Checking experimental setup...", LogService.INIT); int errorCount = ((OperatorChain)rootOperator).checkNumberOfInnerOperators(); if (errorCount == 0) LogService.logMessage("Inner operators are ok", LogService.INIT); else LogService.logMessage("Experimental setup not ok", LogService.ERROR); return errorCount; } private int checkProperties() { LogService.logMessage("Checking properties...", LogService.INIT); int errorCount = rootOperator.checkProperties(); if (errorCount == 0) LogService.logMessage("Properties are ok", LogService.INIT); else LogService.logMessage("Properties are not ok", LogService.ERROR); return errorCount; } /** Checks for correct number of inner operators, properties, and io. */ public boolean checkExperiment() { rootOperator.clearErrorList(); int errorCount = checkProperties(); errorCount += checkNumberOfInnerOperators(); if (errorCount == 0) errorCount += checkIO(); if (errorCount == 0) { LogService.logMessage("Experiment ok.", LogService.INIT); return true; } else { LogService.logMessage("There were " + errorCount + " errors.", LogService.ERROR); return false; } } public void prepareRun() throws OperatorException { stopExperiment = false; LogService.logMessage("Initialising experiment", LogService.INIT); RandomGenerator.init(this); ResultService.init(this); //LogService.setRootOperator(getRootOperator()); TempFileService.init(this); checkExperiment(); rootOperator.experimentStarts(); LogService.logMessage("Experiment initialised", LogService.INIT); } /** Starts the experiment with no input. */ public IOContainer run() throws OperatorException { IOObject[] nullIO = {}; IOContainer nullInput = new IOContainer(nullIO); return run(nullInput); } /** Starts the experiment with the given input. */ public IOContainer run(IOContainer input) throws OperatorException { long start = System.currentTimeMillis(); LogService.logMessage("Experiment starts", LogService.MAXIMUM); LogService.logMessage("Experiment:\n"+getRootOperator().createExperimentTree(3), LogService.INIT); IOContainer result = rootOperator.apply(input); rootOperator.experimentFinished(); long end = System.currentTimeMillis(); LogService.logMessage("Experiment finished after " + ((end-start)/1000) + " seconds", LogService.INIT); LogService.logMessage("Experiment:\n"+getRootOperator().createExperimentTree(3), LogService.INIT); LogService.logMessage("Experiment finished successfully", LogService.MAXIMUM); return result; } public void tearDown() { //LogService.setRootOperator(null); } /** Stops the experiment and fires an experimentEnded()-Event */ public void fatal() { rootOperator.experimentFinished(); } /** Saves the experiment to the experiment file. */ public void save() throws IOException { PrintWriter writer = new PrintWriter(new FileWriter(experimentFile)); rootOperator.writeXML(writer, ""); writer.close(); LogService.logMessage("Wrote experiment file '"+experimentFile+"'.", LogService.STATUS); } public void setExperimentFile(File file) { this.experimentFile = file; } /** Stops the experiment as soon as possible. */ public void stop() { this.stopExperiment = true; } /** Returns true iff the experiment should be stopped. */ public boolean shouldStop() { return stopExperiment; } /** Resolves the given filename against the directory containing the experiment file. */ public File resolveFileName(String name) { File workingDir = new File(System.getProperty("user.dir")); return Tools.getFile(experimentFile != null ? experimentFile.getParentFile() : workingDir, name); } public File createFile(String name) { File file = resolveFileName(name); Tools.mkdir(file.getParentFile()); return file; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -