All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jasima.core.experiment.AbstractMultiConfExperiment Maven / Gradle / Ivy

Go to download

JAva SImulatior for MAnufacturing and logistics - A framework for discrete event simulation and computer experiments with a main focus on modelling and analyzing logistic/manufacturing systems.

There is a newer version: 1.3.0
Show newest version
/*******************************************************************************
 * Copyright (c) 2010-2013 Torsten Hildebrandt and jasima contributors
 *
 * This file is part of jasima, v1.0.
 *
 * jasima 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 3 of the License, or
 * (at your option) any later version.
 *
 * jasima 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 jasima.  If not, see .
 *
 * $Id: AbstractMultiConfExperiment.java 125 2013-10-07 14:29:11Z [email protected] $
 *******************************************************************************/
package jasima.core.experiment;

import jasima.core.util.Util;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

/**
 * Base class for experiments that execute variations of a
 * {@code baseExperiment} by changing its properties.
 * 

* * The order in which properties are applied is determined by the length of the * property name to guarantee that sub-properties are set after the object * containing them. This also applies when {@link ComplexFactorSetter} is used. * Properties with equally long names are executed in an undefined order. * Exceptions are null, which is regarded as having a length of -1, and * {@link #KEY_EXPERIMENT}, which is regarded has having a length of -2. * {@link #KEY_EXPERIMENT} can be present in any number of configurations. If it * is present in all configurations, baseExperiment need not be set. * * @author Robin Kreis * @author Torsten Hildebrandt * @version * "$Id: AbstractMultiConfExperiment.java 125 2013-10-07 14:29:11Z [email protected] $" */ public abstract class AbstractMultiConfExperiment extends AbstractMultiExperiment { private static final long serialVersionUID = 8651960788951812186L; public static final String KEY_EXPERIMENT = "@"; /** * Allows finer control of the way a base experiment is configured than the * usual mechanism using JavaBean properties. If an object implementing * ComplexFactorSetter is passed as a value when calling * {@link FullFactorialExperiment#addFactor(String, Object) * addFactor(String, Object)} then instead of setting a bean property the * method {@link #configureExperiment(Experiment)} is called. * * @see FullFactorialExperiment#addFactor(String, Object) */ public interface ComplexFactorSetter extends Serializable { /** * Configures an experiment. * * @param e * The experiment to configure. */ void configureExperiment(final Experiment e); } /** * An (optional) way to veto certain configurations, because some * combinations of factors and their values might not make sense. * * @see FullFactorialExperiment#setConfigurationValidator(ConfigurationValidator) */ public interface ConfigurationValidator extends Serializable { boolean isValid(Map configuration); } // parameters private Experiment baseExperiment = null; private ConfigurationValidator configurationValidator = null; // fields used during run protected int numConfs = 0; @Override public void init() { numConfs = 0; super.init(); } protected abstract void createExperiments(); protected void handleConfig(Map conf) { if (isValidConfiguration(conf)) { numConfs++; try { experiments.add(createExperimentForConf(conf)); } catch (final Exception e) { print(ExpMsgCategory.ERROR, e.getMessage()); experiments.add(new Experiment() { private static final long serialVersionUID = 4259612422796656502L; @Override protected void produceResults() { aborted++; super.produceResults(); resultMap.put(Experiment.EXCEPTION_MESSAGE, e.getMessage()); resultMap.put(Experiment.EXCEPTION, Util.exceptionToString(e)); } @Override protected void performRun() { // do nothing } }); } } } protected Experiment createExperimentForConf(Map conf) { Experiment e = conf.containsKey(KEY_EXPERIMENT) ? ((Experiment) conf .get(KEY_EXPERIMENT)).silentClone() : getBaseExperiment() .silentClone(); configureRunExperiment(e); List> entries = new ArrayList>( conf.entrySet()); // sort by length Collections.sort(entries, new Comparator>() { @Override public int compare(Entry o1, Entry o2) { String a = o1.getKey(); String b = o2.getKey(); if (a == b) return 0; if (a == null) return -1; if (b == null) return 1; return a.length() - b.length(); } }); for (Map.Entry p : entries) { if (p.getKey().equals(KEY_EXPERIMENT)) continue; if (p.getValue() != null && p.getValue() instanceof ComplexFactorSetter) { ((ComplexFactorSetter) p.getValue()).configureExperiment(e); } else { Util.setProperty(e, p.getKey(), Util.cloneIfPossible(p.getValue())); } } return e; } protected boolean isValidConfiguration(Map conf) { if (getConfigurationValidator() == null) return true; return getConfigurationValidator().isValid(conf); } @Override protected final String prefix() { return "conf"; } /** * Returns the number of experiment configurations to be executed. */ @Override public int getNumExperiments() { return numConfs; } public Experiment getBaseExperiment() { return baseExperiment; } /** * Sets the base experiment that is executed multiple times. */ public void setBaseExperiment(Experiment baseExperiment) { this.baseExperiment = baseExperiment; } public ConfigurationValidator getConfigurationValidator() { return configurationValidator; } public void setConfigurationValidator( ConfigurationValidator configurationValidator) { this.configurationValidator = configurationValidator; } @Override public AbstractMultiConfExperiment clone() throws CloneNotSupportedException { AbstractMultiConfExperiment e = (AbstractMultiConfExperiment) super .clone(); if (baseExperiment != null) e.baseExperiment = baseExperiment.clone(); return e; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy