📄 randommvamodelgenerator.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.engine.testSystem;
import jmt.common.xml.resources.XSDSchemaLoader;
import jmt.gui.exact.utils.ArrayUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.File;
import java.util.Random;
/**
* This class creates models with random parameters.
* Models can be saved into xml file, according to JMTmodel.xsd schema
*
* @author Stefano Omini
*/
public class RandomMVAModelGenerator {
private static int counter = 0;
public static final int CLOSED_MODEL = 0;
public static final int OPEN_MODEL = 1;
public static final int MIXED_MODEL = 2;
public static final int STATION_DELAY = 0;
public static final int STATION_LI = 1; //load independent
public static final int STATION_LD = 2; //load dependent
public static final String[] STATION_TYPENAMES_CLOSED = {"delay", "LI", "LD"};
public static final String[] STATION_TYPENAMES = {"delay", "LI"};
public static final int CLASS_CLOSED = 0;
public static final int CLASS_OPEN = 1;
public static final String[] CLASS_TYPENAMES = {"closed", "open"};
//see constants above: CLOSED_MODEL, OPEN_MODEL, MIXED_MODEL
private int modelType;
//true if the model is closed
private boolean closed;
//true if the model is open
private boolean open;
//true if the model is mixed
private boolean mixed;
//true if the model contains load dependent stations
private boolean ld;
//description of the model
private String description;
private Document modelDOM = null;
//generator of random numbers
private Random randomGenerator = null;
//seed of random generator
private long seed;
//if only FCFS service strategy is available, to have a BCMP model
//jSIM must have, for each station, the same exp distribution
//private static final boolean onlyFCFS = true;
private static final boolean onlyFCFS = true;
/***********************STATIONS AND CLASSES******************************/
//number of service centers
private int stations;
//number of classes
private int classes;
//total population (computed as the sum of all closed class populations)
private int maxpop;
//class data is class population for closed classes, class arrival rate for open classes
//dim: classData[classes]
private double[] classData;
//station names
//dim: stationNames[stations]
private String[] stationNames;
//station types
//dim: stationTypes[stations]
private int[] stationTypes;
//class names
//dim: classNames[classes]
private String[] classNames;
//class types
//dim: classTypes[classes]
private int[] classTypes;
/***********************SOME CONSTRAINTS****************************/
//max number of class
public static final int maxNumber_Classes = 5;
//max number of stations
public static final int maxNumber_Station = 15;
//FOR OPEN MODELS, we want to set the Umax, that is the bottleneck resource utilization,
//so that it's contained in a fixed interval [min, max]
private double U_min_bottleneck = 0.3;
private double U_max_bottleneck = 0.85;
/***********************SERVICE PARAMETERS**************************/
/**
* visits to the service centers
* dim: visits[stations][classes]
*/
private double[][] visits;
/**
* service times of the service centers
* dim: serviceTimes[stations][classes][p]
* p=maxpop if stationTypes[s]==STATION_LD
* p=1 otherwise
*/
private double[][][] serviceTimes;
/*******************************************************************/
/**
* Creates a random model.
* @param classNumber number of classes (max is <tt>maxNumber_classes</tt>)
* @param stationNumber number of stations (max is <tt>maxNumber_stations</tt>)
* @param type model type (see constants)
* @param seed the seed of random generator (if -1, a random seed will be used)
*/
public RandomMVAModelGenerator(int classNumber, int stationNumber, int type, long seed) {
counter++;
if (seed == -1) {
//automatic seed
//uses current time as seed
seed = System.currentTimeMillis();
randomGenerator = new Random(seed);
} else {
randomGenerator = new Random(seed);
}
this.seed = seed;
description = "created with RandomMVAModelGenerator: model n. " + counter + " (seed = " +
Long.toString(seed) + ")";
classes = classNumber;
if (classes > maxNumber_Classes) {
classes = maxNumber_Classes;
}
stations = stationNumber;
if (stations > maxNumber_Station) {
stations = maxNumber_Station;
}
modelType = type;
createNames();
randomVisits();
randomServiceTimes();
randomStationTypes();
randomClassTypes();
createClassData();
calcModelType();
createDocument();
saveToFile();
}
/**
* Generates random numbers to fill the matrix of service times
* (LD case not supported)
*
*/
private void randomServiceTimes() {
serviceTimes = new double[stations][classes][1];
if (onlyFCFS) {
//for each station, all classes must have the same service time
//loop over classes
for (int s = 0; s < stations; s++) {
double temp = Math.abs(randomGenerator.nextDouble());
//loop over classes and set the same service time
for (int c = 0; c < classes; c++) {
serviceTimes[s][c][0] = temp;
}
}
//do not normalize service times
} else {
//loop over classes
for (int c = 0; c < classes; c++) {
double max = 0.0;
double temp;
//loop over stations and saves the maximum service time
for (int i = 0; i < stations; i++) {
temp = Math.abs(randomGenerator.nextDouble());
serviceTimes[i][c][0] = temp;
//determines whether it's the maximum value for this class
if (temp > max) {
max = temp;
}
}
//Normalize values so that the max service time for this class becomes 1
for (int i = 0; i < stations; i++) {
serviceTimes[i][c][0] /= max;
}
}
}
}
/**
* Generates random numbers to fill the matrix of visits
*/
private void randomVisits() {
visits = new double[stations][classes];
double temp;
//loop over classes
for (int c = 0; c < classes; c++) {
//loop over stations
for (int i = 0; i < stations; i++) {
do {
temp = Math.abs(randomGenerator.nextDouble());
if (temp <= 0.5) {
visits[i][c] = temp * 2;
}
} while (temp > 0.5 || temp == 0.0);
}
}
}
/**
* Generates random station types to fill the vector of station types (LI, Delay).
* LD service centers not supported yet.
*
* According to some articles in QN literature, the proportion is LI 95% and Delay 5%
* (see "Lineariser")
*
*/
private void randomStationTypes() {
stationTypes = new int[stations];
double temp;
//at least one LI station
stationTypes[0] = STATION_LI;
//loop over stations
for (int i = 1; i < stations; i++) {
temp = Math.abs(randomGenerator.nextDouble());
if (temp < 0.95) {
stationTypes[i] = STATION_LI;
} else {
stationTypes[i] = STATION_DELAY;
}
}
}
/**
* Creates class and station names (Class0, Class1, ..., Station0, Station1, ...)
*/
private void createNames() {
classNames = new String[classes];
for (int c = 0; c < classes; c++) {
classNames[c] = "Class" + c;
}
stationNames = new String[stations];
for (int s = 0; s < stations; s++) {
stationNames[s] = "Station" + s;
}
return;
}
private void randomClassTypes() {
classTypes = new int[classes];
switch (modelType) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -