package vroom.optimization.online.jmsa.components; import java.util.Collection; import java.util.List; import vroom.optimization.online.jmsa.IActualRequest; import vroom.optimization.online.jmsa.IDistinguishedSolution; import vroom.optimization.online.jmsa.IInstance; import vroom.optimization.online.jmsa.IMSARequest; import vroom.optimization.online.jmsa.ISampledRequest; import vroom.optimization.online.jmsa.IScenario; import vroom.optimization.online.jmsa.MSABase; import vroom.optimization.online.jmsa.MSABase.MSAProxy; import vroom.optimization.online.jmsa.MSAGlobalParameters; /** * <code>MSAComponentManager</code> is the class responsible for the management of the components of an MSA procedure. Calls to the components methods * should be performed by using the delegate methods from this class, as it enables multithreading management. * * @author Victor Pillac, <a href="http://uniandes.edu.co">Universidad de Los Andes</a> - <a href="http://copa.uniandes.edu.co">Copa</a>, <a * href="http://www.emn.fr">Ecole des Mines de Nantes</a>-<a href="http://www.irccyn.ec-nantes.fr/irccyn/d/en/equipes/Slp">SLP</a> * @version 1.0 #updated 16-Feb-2010 10:06:49 a.m. * @param <S> * the implementation of {@link IScenario} used in the MSA procedure * @param <I> * the implementation of {@link IInstance} used in the MSA procedure */ public abstract class ComponentManager<S extends IScenario, I extends IInstance> { /** * Factory method for the creation of a <code>ComponentManager</code> for a singled thread MSA procedure * * @param <S> * the type of scenario * @param <D> * the type of mSolution * @param <I> * the type of instance * @param msa * the parent MSA procedure * @return a <code>ComponentManager</code> associated with the given <code>msa</code> that can be used in a single thread context */ public static <S extends IScenario, I extends IInstance> ComponentManager<S, I> newSingleThreadComponentManager( MSABase<S, I> msa, MSAProxy<S, I> msaProxy) { return new DefaultComponentManager<S, I>(msa, msaProxy); } /** * The parent MSA instance */ private final MSABase<S, I> mMSA; /** * A proxy to access some of the MSA properties */ protected final MSAProxy<S, I> mMSAProxy; /** The <code>PoolCleanerBase</code> to be used **/ protected final PoolCleanerBase mPoolCleaner; /** The <code>RequestValidatorBase</code> to be used **/ protected final RequestValidatorBase mRequestValidator; /** The <code>ScenarioUpdaterBase</code> to be used **/ protected final ScenarioUpdaterBase mScenarioUpdater; /** The <code>RequestSamplerBase</code> to be used **/ protected final RequestSamplerBase mRequestSampler; /** The <code>ScenarioGeneratorBase</code> to be used **/ protected final ScenarioGeneratorBase<S> mScenarioGenerator; /** The <code>ScenarioOptimizerBase</code> to be used **/ protected final ScenarioOptimizerBase<S> mScenarioOptimizer; /** The <code>SolutionBuilderBase</code> to be used **/ protected final SolutionBuilderBase mSolutionBuilder; protected long mLastOptTime; /** * Creates a new <code>ComponentManager</code> associated with the given {@linkplain MSABase MSA procedure} * * @param msa */ public ComponentManager(MSABase<S, I> msa, MSAProxy<S, I> msaProxy) { this.mMSA = msa; this.mMSAProxy = msaProxy; this.mPoolCleaner = msa.getParameters().<PoolCleanerBase> newInstance( MSAGlobalParameters.POOL_CLEANER_CLASS, this); this.mRequestValidator = msa.getParameters().<RequestValidatorBase> newInstance( MSAGlobalParameters.REQUEST_VALIDATOR_CLASS, this); this.mScenarioUpdater = msa.getParameters().<ScenarioUpdaterBase> newInstance( MSAGlobalParameters.SCENARIO_UPDATER_CLASS, this); this.mRequestSampler = msa.getParameters().<RequestSamplerBase> newInstance( MSAGlobalParameters.REQUEST_SAMPLER_CLASS, this); this.mScenarioGenerator = msa.getParameters().<ScenarioGeneratorBase<S>> newInstance( MSAGlobalParameters.SCENARIO_GENERATOR_CLASS, this); this.mScenarioOptimizer = msa.getParameters().<ScenarioOptimizerBase<S>> newInstance( MSAGlobalParameters.SCENARIO_OPTIMIZER_CLASS, this); this.mSolutionBuilder = msa.getParameters().<SolutionBuilderBase> newInstance( MSAGlobalParameters.SOLUTION_BUILDER_CLASS, this); } /** * Building of a distinguished mSolution from the given <code>pool</code> and based on the given <code>instance</code> * * @param params * an optional parameter for the building of the distinguished plan * @see SolutionBuilderBase#buildDistinguishedPlan(ISolutionBuilderParam) */ public abstract IDistinguishedSolution buildDistinguishedPlan(ISolutionBuilderParam params); /** * Validation of a request * * @param request * the request that has to be validated * @return <code>true</code> if the request can be serviced, <code>false</code> otherwise * @see RequestValidatorBase#canBeServiced(IActualRequest) */ public abstract boolean canBeServiced(IActualRequest request); /** * Remove the scenarios from the pool that are incompatible with the given <code>instance</code> * * @return a collection containing the scenarios that were removed * @see PoolCleanerBase#cleanPool() */ public abstract Collection<IScenario> cleanPool(); /** * Update the scenario pool after the servicing of a request by a resource and remove scenarios that are incoherent with the current state. * * @param resourceId * the id (index) of the considered resource * @param servedRequest * the request that has been served by the specified resource * @return a collection containing the removed scenarios * @see ScenarioUpdaterBase#endOfServiceUpdate(IScenario, int, IActualRequest) */ public abstract Collection<S> endOfServiceUpdate(int resourceId, IActualRequest servedRequest); /** * Remove the scenarios from the pool that are incompatible with the current distinguished mSolution * * @param committedRequest * the request that will be served next by the specified resource * @param resourceId * the id of the resource that will be committed to <code>committedRequest</code> * @return a collection containing the scenarios that were removed * @see ScenarioUpdaterBase#enforceDecision(IScenario, IActualRequest, int) * @see MSABase#getDistinguishedSolution() */ public abstract Collection<S> enforceDecision(int resourceId, IActualRequest committedRequest); /** * Generation of sampled requests * * @return an array of length <code>numRequests</code> containing the generated sampled requests * @param params * an optional parameter for the generation of sampled requests * @see RequestSamplerBase#generateSampledRequest(RequestSamplerParam) */ public abstract List<ISampledRequest> generateSampledRequest(RequestSamplerParam params); /** * Generation of a new scenario. <br/> * The implementation of this method should consider the possible parallelization of scenario generation * * @param params * optional parameters for the scenario generation s * @see ScenarioGeneratorBase#generateScenario(ScenarioGeneratorParam) */ public abstract void generateScenarios(ScenarioGeneratorParam params); /** * Getter for the parent MSA * * @return the parent MSA instance */ public MSABase<S, I> getParentMSA() { return this.mMSA; } /** * Getter for the proxy to the parent MSA * * @return a proxy for the parent MSA */ public MSAProxy<S, I> getParentMSAProxy() { return this.mMSAProxy; } /** * @return a instance of {@link PoolCleanerBase} to be used in the MSA procedure */ public PoolCleanerBase getPoolCleaner() { return this.mPoolCleaner; } /** * @return an instance of {@link RequestSamplerBase} to be used in the MSA procedure */ public RequestSamplerBase getRequestSampler() { return this.mRequestSampler; } /** * @return an instance of {@link RequestValidatorBase} to be used in the MSA procedure */ public RequestValidatorBase getRequestValidator() { return this.mRequestValidator; } /** * @return an instance of {@link ScenarioGeneratorBase} to be used in the MSA procedure */ public ScenarioGeneratorBase<S> getScenarioGenerator() { return this.mScenarioGenerator; } /** * @return an instance of {@link ScenarioOptimizerBase} to be used in the MSA procedure */ public ScenarioOptimizerBase<S> getScenarioOptimizer() { return this.mScenarioOptimizer; } /** * @return an instance of {@link ScenarioUpdaterBase} to be used in the MSA procedure */ public ScenarioUpdaterBase getScenarioUpdater() { return this.mScenarioUpdater; } /** * @return an instance of {@link SolutionBuilderBase} to be used in the MSA procedure */ public SolutionBuilderBase getSolutionBuilder() { return this.mSolutionBuilder; } /** * Perform the update of the <code>pool</code> by inserting all the requests from <code>requests</code> and removing incompatible scenarios * * @param requests * the requests that will be inserted in the scenarios from the <code>pool</code> * @see ScenarioUpdaterBase#insertRequests(IScenario, IMSARequest...) * @return a collection containing the removed scenarios */ public abstract Collection<S> insertRequest(IMSARequest... requests); /** * Optimize a single scenario. * * @param params * an optional parameter for the optimization of scenarios * @param scenario * the scenario to be optimized * @return <code>true</code> if the optimization procedure finished correctly, <code>false</code> otherwise * @see ScenarioOptimizerBase#optimize(IScenario, ScenarioOptimizerParam) */ public abstract boolean optimize(S scenario, ScenarioOptimizerParam params); /** * Optimize the whole pool of scenarios of the associated MSA procedure * * @param params * an optional parameter for the optimization of scenarios * @see ScenarioOptimizerBase#optimize(IScenario, ScenarioOptimizerParam) */ public abstract void optimizePool(ScenarioOptimizerParam params); /** * Update the scenario pool when a resource starts the service of a request. * * @param resourceId * the id (index) of the considered resource * @param request * the request which is beeing served by the specified resource * @return a collection containing the removed scenarios */ public abstract Collection<S> startOfServiceUpdate(int resourceId, IActualRequest request); /** * Update the scenario pool the start of servicing by a resource and remove scenarios that are incoherent with the current state * * @param resourceId * the id (index) of the considered resource * @return a collection containing the removed scenarios * @see ScenarioUpdaterBase#startServicingUpdate(IScenario, int) */ public abstract Collection<S> startServicingUpdate(int resourceId); /** * Update the scenario pool after the end of servicing by a resource * * @param resourceId * the id (index) of the considered resource and remove scenarios that are incoherent with the current state * @return a collection containing the removed scenarios * @see ScenarioUpdaterBase#stopServicingUpdate(IScenario, int) */ public abstract Collection<S> stopServicingUpdate(int resourceId); @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append(this.getClass().getSimpleName()); sb.append("\n"); sb.append("Scenario Generator:\n "); sb.append(getScenarioGenerator()); sb.append("\n"); sb.append("Scenario Optimizer:\n "); sb.append(getScenarioOptimizer()); sb.append("\n"); sb.append("Scenario Updater:\n "); sb.append(getScenarioUpdater()); sb.append("\n"); sb.append("Solution Builder:\n "); sb.append(getSolutionBuilder()); sb.append("\n"); sb.append("Pool Cleaner:\n "); sb.append(getPoolCleaner()); sb.append("\n"); sb.append("Request Sampler:\n "); sb.append(getRequestSampler()); sb.append("\n"); sb.append("Request Validator:\n "); sb.append(getRequestValidator()); return sb.toString(); } }// end ComponentManager