⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 solverdispatcher.java

📁 一个用于排队系统仿真的开源软件,有非常形象的图象仿真过程!
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/**    
  * Copyright (C) 2006, Laboratorio di Valutazione delle Prestazioni - Politecnico di Milano

  * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
  
package jmt.gui.exact.link;

import jmt.analytical.*;
import jmt.common.exception.InputDataException;
import jmt.common.exception.SolverException;
import jmt.gui.exact.ExactModel;
import jmt.gui.exact.utils.ArrayUtils;
import jmt.gui.exact.xml.XMLUtils;
import org.xml.sax.SAXException;

import java.io.File;


/**
 * Server side of the solver interface.<br>
 * This object takes a model, instantiates the correct solver, and solves it.<br>
 * Should probably be rewritten using a different data structure to hold model information
 *
 * @author unknown, Bertoli Marco (what-if analysis)
 */
public class SolverDispatcher {

	private static final boolean DEBUG = true;
	private static final boolean PRINTMODEL = false;

    private boolean stopped = false;

    private XMLUtils xmlUtils;
    /** Used to notify when a computation ends */
    private SolverListener listener;

    public SolverDispatcher() {
		xmlUtils = new XMLUtils();
	}

	/**
	 * Solves the model in file.
	 * @throws jmt.common.exception.SolverException if there were errors operation was not successful
	 */
	public void solve(File file) throws SolverException, InputDataException {
		ExactModel model = new ExactModel();
		try {
			if (!model.loadDocument(xmlUtils.loadXML(file))) {
				fail("Error loading model from tempfile", null);
			}
		} catch (SAXException e) {
			fail("XML parse error in tempfile", e);
		} catch (Exception e) {
			fail("Error loading model from tempfile", e);
		}

		if (PRINTMODEL) System.out.println(model);

		solve(model);

		if (PRINTMODEL) System.out.println(model);

		try {
			if (!xmlUtils.saveXML(model.createDocument(), file)) {
				fail("Error saving solved model to tempfile", null);
			}
		} catch (SAXException e) {
			fail("XML parse error in tempfile", e);
		} catch (Exception e) {
			fail("Error saving solved model to tempfile", e);
		}

	}

    /**
     * Stops What-if analysis and invalidates results
     */
    public void stop() {
        stopped = true;
    }

    /**
     * Solves input model. This method will look for what-if analysis data and
     * perform a what-if analysis if requested.
     * <br>
     * Author: Bertoli Marco
     * @param model model to be solved
     * @throws SolverException if something goes wrong during solution
     * @throws InputDataException if some input data are malformed
     */
    public void solve(ExactModel model) throws SolverException, InputDataException {
        stopped = false;
        model.resetResults();
        // Solves normal models
        if (!model.isWhatIf()) {
            finalDispatch(model, 0);
        }
        // Now solves what-if models
        else {
            // Arrival rates what-if analysis
            if (model.getWhatIfType().equalsIgnoreCase(ExactModel.WHAT_IF_ARRIVAL)) {
                whatIfArrival(model);
            }
            // Customers number what-if analysis
            else if(model.getWhatIfType().equalsIgnoreCase(ExactModel.WHAT_IF_CUSTOMERS)) {
                whatIfCustomers(model);
            }
            // Service demands what-if analysis
            else if (model.getWhatIfType().equalsIgnoreCase(ExactModel.WHAT_IF_DEMANDS)) {
                whatIfDemands(model);
            }
            // Population mix what-if analysis
            else if (model.getWhatIfType().equalsIgnoreCase(ExactModel.WHAT_IF_MIX)) {
                whatIfMix(model);
            }
        }
    }


    public void finalDispatch(ExactModel model, int iteration) throws SolverException, InputDataException {

		/* disable all change-checking */
		model.discardChanges();
		model.setChanged();

		try {
			if (model.isMultiClass()) {
				solveMulti(model,iteration);
			} else {
				solveSingle(model, iteration);
			}
            // Notify termination of current model solution
            if (listener != null)
                listener.computationTerminated(iteration);
        } catch (InputDataException rse) {
            throw rse;
        } catch (SolverException se) {
			throw se;
		} catch (Exception e) {
			fail("Unhandled exception", e);
        }
	}

	private void fail(String message, Throwable t) throws SolverException {
		if (DEBUG && t != null) t.printStackTrace();
		StringBuffer s = new StringBuffer(message);
		if (t != null) {
			s.append("\n");
			s.append(t.toString());
		}

		throw new SolverException(s.toString(), t);
	}

	private void solveSingle(ExactModel model, int iteration) throws Exception, InputDataException {

		int stations = model.getStations();
		Solver solver = null;

		//init

		String[] names = model.getStationNames();
		int[] types = mapStationTypes(model.getStationTypes());
		double[][] servicetimes = (ArrayUtils.extract13(model.getServiceTimes(), 0));

        //no supplemental copy here since extract13 already copies the first level of the array
		adjustLD(servicetimes, types);
		double[] visits = ArrayUtils.extract1(model.getVisits(), 0);


		if (model.isClosed()) {

			//single closed

            int pop = model.getMaxpop();

            //NEW
            //@author Stefano Omini

            //First of all controls that the closed class has population greater than 0.
            //Otherwise throws a InputDataException
            if (pop <= 0) {
                //error: population is not greater than 0.0
                throw new InputDataException("Population must be greater than zero");
            }

            //end NEW

			try {
                solver = new SolverSingleClosedMVA(pop, stations);
				if (!solver.input(names, types, servicetimes, visits)) {
                    fail("Error initializing MVASolver", null);
                }
			} catch (SolverException se) {
				throw se;
			} catch (Exception e) {
				fail("Error initializing MVASolver", e);
			}
		} else {

			/* single open */
            double lambda = (model.getClassData())[0];

            //First of all controls that the open class has rate greater than 0.
            //Otherwise throws a InputDataException
            if (lambda <= 0) {
                //error: rate is not greater than 0.0
                throw new InputDataException("Arrival rate must be greater than zero");

            }


			try {
				solver = new SolverSingleOpen(model.getClassData()[0], stations);
				if (!solver.input(names, types, servicetimes, visits)) fail("Error initializing OpenSolver", null);

                //NEW
                //@author Stefano Omini
                //controls processing capacity
                if (!solver.hasSufficientProcessingCapacity()) {
                    throw new InputDataException("One or more resources are in saturation. Decrease arrival rates or service demands.");
                }
                //end NEW
            } catch (InputDataException rse) {
				throw rse;
			} catch (SolverException se) {
				throw se;
			} catch (Exception e) {
				fail("Error initializing OpenSolver", e);
			}
		}

		/* solve */

		solver.solve();

		/* solution */
		double[][] ql = ArrayUtils.makeFilled(stations, 1, -1);
		ArrayUtils.insert1(ql, solver.getQueueLen(), 0);

		double[][] tp = ArrayUtils.makeFilled(stations, 1, -1);
		ArrayUtils.insert1(tp, solver.getThroughput(), 0);

		double[][] rt = ArrayUtils.makeFilled(stations, 1, -1);
		ArrayUtils.insert1(rt, solver.getResTime(), 0);

		double[][] util = ArrayUtils.makeFilled(stations, 1, -1);
		ArrayUtils.insert1(util, solver.getUtilization(), 0);

		model.setResults(ql, tp, rt, util, iteration);

	}

	private void solveMulti(ExactModel model, int iteration) throws SolverException, InputDataException {

        if (model.isLd()) {
            throw new SolverException("Multiclass solver does not support LD stations");
        }

		int classes = model.getClasses();
		int stations = model.getStations();
		int pop = model.getMaxpop();

		String[] stationNames = model.getStationNames();
		int[] stationTypes = mapStationTypes(model.getStationTypes());
		double[] classData = model.getClassData();
		double[][][] serviceTimes = model.getServiceTimes();
		double[][] visits = model.getVisits();
		int[] classPop = ArrayUtils.toInt(classData);

		SolverMulti solver = null;


        //NEW
        //@author Stefano Omini
        //First of all controls that all classes have population or rate greater than 0.
        //Otherwise throws a InputDataException

        for (int c = 0; c < classData.length; c++) {
            if (classData[c] <= 0) {
                //error: population or rate not greater than 0.0
                //prepare message according to model type (mixed, open or closed)

                if (model.isMixed()) {
                    //mixed model -> populations or rates
                    throw new InputDataException("Populations and arrival rates must be greater than zero");
                } else if (model.isOpen()) {
                    //open model -> rates
                    throw new InputDataException("Arrival rates must be greater than zero");
                } else {
                    //closed model -> populations
                    throw new InputDataException("Populations must be greater than zero");
                }

            }
        }

        //end NEW


		/* init */

		if (model.isOpen()) {

			try {
				solver = new SolverMultiOpen(classes, stations, model.getClassData());
				if (!solver.input(stationNames, stationTypes, serviceTimes, visits))
                    fail("Error initializing SolverMultiOpen", null);

                //NEW
                //@author Stefano Omini
                //controls processing capacity
                if (!solver.hasSufficientProcessingCapacity()) {
                    throw new InputDataException("One or more resources are in saturation. Decrease arrival rates or service demands.");
                }
                //end NEW
            } catch (InputDataException rse) {
				throw rse;
			} catch (SolverException se) {
				throw se;
			} catch (Exception e) {
				fail("Error initializing SolverMultiOpen", e);
			}
		} else {


			if (model.isClosed()) {

				try {
					SolverMultiClosedMVA closedsolver = new SolverMultiClosedMVA(classes, stations);
					//ClosedSolverMulti closedsolver = new ClosedSolverMulti(classes,stations,classPop);
					if (!closedsolver.input(stationNames, stationTypes, serviceTimes, visits,classPop)) fail("Error initializing MVAMultiSolver", null);
					solver = closedsolver;
				} catch (SolverException se) {
					throw se;
				} catch (Exception e) {
					fail("Error initializing MVAMultiSolver", e);
				}
			} else {
                //model is multiclass mixed
				int[] classTypes = mapClassTypes(model.getClassTypes());

				try {
					SolverMultiMixed mixedsolver = new SolverMultiMixed(classes, stations);
					if (!mixedsolver.input(stationNames, stationTypes, serviceTimes, visits, classData, classTypes)) fail("Error initializing SolverMultiMixed", null);

                    solver = mixedsolver;
                    //NEW
                    //@author Stefano Omini
                    //controls processing capacity
                    if (!solver.hasSufficientProcessingCapacity()) {
                        throw new InputDataException("One or more resources are in saturation. Decrease arrival rates or service demands.");
                    }
                    //end NEW
                } catch (InputDataException rse) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -