📄 solverdispatcher.java
字号:
/**
* 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 + -