📄 solverdispatcher.java
字号:
throw rse;
} catch (SolverException se) {
throw se;
} catch (Exception e) {
fail("Error initializing SolverMuktiMixed", e);
}
}
}
solver.solve();
/* solution */
double[][] ql = ArrayUtils.resize2(solver.getQueueLen(), stations, classes, 0);
double[][] tp = ArrayUtils.resize2(solver.getThroughput(), stations, classes, 0);
double[][] rt = ArrayUtils.resize2(solver.getResTime(), stations, classes, 0);
double[][] util = ArrayUtils.resize2(solver.getUtilization(), stations, classes, 0);
model.setResults(ql, tp, rt, util, iteration);
}
/**
* Map station types from model constants to solver constants
*/
private int[] mapStationTypes(int[] stationTypes) {
int len = stationTypes.length;
int[] res = new int[len];
for (int i = 0; i < len; i++) {
switch (stationTypes[i]) {
case ExactModel.STATION_LD:
res[i] = Solver.LD;
break;
case ExactModel.STATION_LI:
res[i] = Solver.LI;
break;
case ExactModel.STATION_DELAY:
res[i] = Solver.DELAY;
break;
default:
res[i] = -1;
}
}
return res;
}
/**
* Map class types from model constants to solver constants
*/
private int[] mapClassTypes(int[] classTypes) {
int len = classTypes.length;
int[] res = new int[len];
for (int i = 0; i < len; i++) {
switch (classTypes[i]) {
case ExactModel.CLASS_OPEN:
res[i] = SolverMulti.OPEN_CLASS;
break;
case ExactModel.CLASS_CLOSED:
res[i] = SolverMulti.CLOSED_CLASS;
break;
default:
res[i] = -1;
}
}
return res;
}
/*
* To conserve memory, service times arrays for LI stations are "compressed" to a single value. This
* method expands them back to full length (single class version)
*/
private void expand(double[][] st, int pop) {
if (pop == 1) return;
int len1 = st.length;
for (int i = 0; i < len1; i++) {
if (st[i].length < pop) {
st[i] = ArrayUtils.resize(st[i], pop, st[i][0]);
}
}
}
/*
* To conserve memory, service times arrays for LI stations are "compressed" to a single value. This
* method expands them back to full length (multiclass version)
*/
private void expand(double[][][] st, int pop) {
if (pop == 1) return;
int len1 = st.length;
for (int i = 0; i < len1; i++) {
expand(st[i], pop);
}
}
/** HACK: adds an itial zero to all LD stations */
private void adjustLD(double[][] st, int[] types) {
for (int i = 0; i < st.length; i++) {
if (types[i] == Solver.LD) {
st[i] = ArrayUtils.prepend0(st[i]);
}
}
}
/** HACK: adds an initial zero to all LD stations */
private void adjustLD(double[][][] st, int[] types) {
for (int i = 0; i < st.length; i++) {
if (types[i] == Solver.LD) {
for (int j = 0; j < st[i].length; j++) {
st[i][j] = ArrayUtils.prepend0(st[i][j]);
}
}
}
}
// --- What-if Analysis methods --- Bertoli Marco -------------------------------------
/**
* Performs a what-if analysis by changing arrival rates
* @param model input model
*/
private void whatIfArrival(ExactModel model) throws SolverException, InputDataException{
// Sanity checks on input model.
if (model.getWhatIfClass() >= 0 && model.getClassTypes()[model.getWhatIfClass()] != ExactModel.CLASS_OPEN)
throw new InputDataException("Cannot change arrival rate of a closed class.");
if (model.isClosed())
throw new InputDataException("Cannot change arrival rates in a closed model.");
// Values for what-if
double[] values = model.getWhatIfValues();
// Backup class datas
double[] initials = (double[]) model.getClassData().clone();
// Iterates for what-if executions
for (int i=0; i<model.getWhatIfValues().length && !stopped; i++) {
double[] current = (double[])initials.clone();
// If this is one class only
if (model.getWhatIfClass() >= 0) {
current[model.getWhatIfClass()] = values[i];
}
// If this is all open classes
else {
for (int j=0; j<current.length; j++)
if (model.getClassTypes()[j] == ExactModel.CLASS_OPEN)
current[j] = initials[j] * values[i];
}
model.setClassData(current);
// Checks if stopped
if (stopped)
break;
// Now solves current model - we cannot interrupt this as it's not designed to be done.
finalDispatch(model, i);
}
// Resets initial model
model.setClassData(initials);
// Results are ok if the process was not stopped.
model.setResultsOK(!stopped);
}
/**
* Performs a what-if analysis by changing number of customers
* @param model input model
*/
private void whatIfCustomers(ExactModel model) throws SolverException, InputDataException{
// Sanity checks on input model.
if (model.getWhatIfClass() >= 0 && model.getClassTypes()[model.getWhatIfClass()] != ExactModel.CLASS_CLOSED)
throw new InputDataException("Cannot change number of customers of an open class.");
if (model.isOpen())
throw new InputDataException("Cannot change number of customers in an open model.");
// Values for what-if
double[] values = model.getWhatIfValues();
// Backup class datas
double[] initials = (double[]) model.getClassData().clone();
// Iterates for what-if executions
int i;
for (i=0; i<model.getWhatIfValues().length && !stopped; i++) {
double[] current = (double[])initials.clone();
// If this is one class only
if (model.getWhatIfClass() >= 0) {
current[model.getWhatIfClass()] = values[i];
// Check for not integer values
if (Math.abs(current[model.getWhatIfClass()] - Math.rint(current[model.getWhatIfClass()])) > 1e-8) {
throw new InputDataException("A fractional population value was assigned to class "+
model.getClassNames()[model.getWhatIfClass()]+ " during step " + i);
}
// Rounds number to avoid truncation problems
current[model.getWhatIfClass()] = Math.round(current[model.getWhatIfClass()]);
}
// If this is all closed classes
else {
for (int j=0; j<current.length; j++)
if (model.getClassTypes()[j] == ExactModel.CLASS_CLOSED) {
current[j] = initials[j] * values[i];
// Check for not integer values
if (Math.abs(current[j] - Math.rint(current[j])) > 1e-8) {
throw new InputDataException("A fractional population value was assigned to class "+
model.getClassNames()[j]+ " during step " + i);
}
// Rounds number to avoid truncation problems
current[j] = Math.round(current[j]);
}
}
model.setClassData(current);
// Checks if stopped
if (stopped)
break;
// Now solves current model - we cannot interrupt this as it's not designed to be done.
finalDispatch(model, i);
}
// Resets initial model
model.setClassData(initials);
// Results are ok if the process was not stopped.
model.setResultsOK(!stopped);
}
/**
* Performs a what-if analysis by changing service demands of a given station.
* @param model input model
*/
private void whatIfDemands(ExactModel model) throws SolverException, InputDataException{
// Sanity checks on input model.
if (model.getWhatIfStation() < 0 || model.getWhatIfStation() >= model.getStations())
throw new InputDataException("Station for what-if analysis not specified.");
if (model.getStationTypes()[model.getWhatIfStation()] == ExactModel.STATION_LD)
throw new InputDataException("Service Demands what-if analysis not supported on Load Dependent stations.");
// Values for what-if
double[] values = model.getWhatIfValues();
// Backup service times datas (note: we multiply only service times as it's the same of multiply service demands)
double[][][] initials = ArrayUtils.copy3(model.getServiceTimes());
// Saves what-if class and station indices
int cl = model.getWhatIfClass();
int st = model.getWhatIfStation();
// Iterates for what-if executions
int i;
for (i=0; i<model.getWhatIfValues().length && !stopped; i++) {
double[][][] current = ArrayUtils.copy3(initials);
// If this is one class only
if (cl >= 0) {
if (model.getVisits()[st][cl] > 0)
current[st][cl][0] = values[i] / model.getVisits()[st][cl];
else
current[st][cl][0] = 0.0;
}
// If this is all classes
else {
for (int j=0; j<model.getClasses(); j++)
current[st][j][0] = initials[st][j][0] * values[i];
}
model.setServiceTimes(current);
// Checks if stopped
if (stopped)
break;
// Now solves current model - we cannot interrupt this as it's not designed to be done.
finalDispatch(model, i);
}
// Resets initial model
model.setServiceTimes(initials);
// Results are ok if the process was not stopped.
model.setResultsOK(!stopped);
}
/**
* Performs a what-if analysis by changing population mix
* @param model input model
*/
private void whatIfMix(ExactModel model) throws SolverException, InputDataException{
// First and second closed class for population mix what-if
int class1, class2 = - 1;
class1 = model.getWhatIfClass();
if (class1 < 0)
throw new InputDataException("Class not specified for population mix what-if analysis.");
// Find second class
for (int i=0; i<model.getClasses(); i++)
if (model.getClassTypes()[i] == ExactModel.CLASS_CLOSED && i != class1) {
if (class2 < 0)
class2 = i;
else
throw new InputDataException("Only models with two closed classes are supported. More than two classes detected.");
}
if (class2 < 0)
throw new InputDataException("Only models with two closed classes are supported. Only one classes detected.");
// Values for what-if
double[] values = model.getWhatIfValues();
// Backup class datas
double[] initials = (double[]) model.getClassData().clone();
// Value for total number of customer
double N = initials[class1] + initials[class2];
// Iterates for what-if executions
int i;
for (i=0; i<model.getWhatIfValues().length && !stopped; i++) {
double[] current = (double[])initials.clone();
current[class1] = values[i] * N;
current[class2] = (1 - values[i]) * N;
// Check for not integer values
if (Math.abs(current[class1] - Math.rint(current[class1])) > 1e-8)
throw new InputDataException("A fractional population value was assigned to class "+
model.getClassNames()[class1]+ " during step " + i);
else if (Math.abs(current[class2] - Math.rint(current[class2])) > 1e-8)
throw new InputDataException("A fractional population value was assigned to class "+
model.getClassNames()[class2]+ " during step " + i);
// Rounds number to avoid truncation problems
current[class1] = Math.round(current[class1]);
current[class2] = Math.round(current[class2]);
model.setClassData(current);
// Checks if stopped
if (stopped)
break;
// Now solves current model - we cannot interrupt this as it's not designed to be done.
finalDispatch(model, i);
}
// Resets initial model
model.setClassData(initials);
// Results are ok if the process was not stopped.
model.setResultsOK(!stopped);
}
// ------------------------------------------------------------------------------------
// ---- Callbacks ---------------------------------------------------------------------
/**
* Adds a solver listener to be notified when computation of an iteration terminates.
* This is useful for notification of a progress window. Only one listener is allowed.
* @param listener listener to be added or null to remove previous one.
*/
public void addSolverListener(SolverListener listener) {
this.listener = listener;
}
/**
* Listener used to notify when computation of a model is terminated
*/
public interface SolverListener {
/**
* This method is called each time the computation of a model is terminated
* @param num number of computated model (used for iterated solutions)
*/
public void computationTerminated(int num);
}
// ------------------------------------------------------------------------------------
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -