📄 modelconverter.java
字号:
// --- Methods for conversion JSIM --> JMVA -----------------------------------------------
/**
* Converts a JSIM model to JMVA. Visits are computed from thopology. To work well this
* method requires:
* <ul>
* <li> Reference station to be set for each class
* <li> Every station must have at least one incoming connection and one outgoing connection
* <li> Routing strategy have to be <code>ProbabilityRouting</code> or <code>RandomRouting</code>
* </ul>
* @param input JSIM model (read only)
* @param output empty JMVA model (write)
* @return a vector that enumerates all conversion warnings and how they have been fixed
*/
public static Vector convertJSIMtoJMVA(CommonModel input, ExactModel output) {
// Normalize probability routing
input.manageProbabilities();
// Used to store warnings
Vector res = new Vector();
int classNum, stationNum;
// Used to iterate on lists
Iterator it;
// Number of classes
classNum = input.getClassKeys().size();
Vector classKeys = input.getClassKeys();
// Find number of convertible stations
it = input.getStationKeys().iterator();
stationNum = 0;
Vector stationKeys = new Vector();
while (it.hasNext()) {
Object key = it.next();
String stationType = input.getStationType(key);
if (stationType.equals(CommonModel.STATION_TYPE_DELAY) ||
stationType.equals(CommonModel.STATION_TYPE_SERVER)) {
stationNum++;
stationKeys.add(key);
}
// Show here warning if a station type is discarded (fork and join)
}
// Resizes output data structure
output.resize(stationNum, classNum);
// Exports class data
int[] classTypes = new int[classNum];
String[] classNames = new String[classNum];
double[] classData = new double[classNum];
for (int i=0; i<classNum; i++) {
Object key = classKeys.get(i);
classNames[i] = input.getClassName(key);
if (input.getClassType(key) == CommonModel.CLASS_TYPE_CLOSED) {
// Closed class parameters
classTypes[i] = ExactModel.CLASS_CLOSED;
classData[i] = input.getClassPopulation(key).doubleValue();
}
else {
// Open class parameters
classTypes[i] = ExactModel.CLASS_OPEN;
Distribution d = (Distribution) input.getClassDistribution(key);
if (d.hasMean())
classData[i] = 1.0 / d.getMean();
else {
classData[i] = 1;
res.add(input.getClassName(key) + " arrival distribution does not have a valid mean value." +
" Arrival rate for that class was set to default value 1");
}
}
}
// Sets extracted values to output
output.setClassNames(classNames);
output.setClassTypes(classTypes);
output.setClassData(classData);
classNames = null;
classTypes = null;
classData = null;
// Exports station data
double[][][] serviceTimes = new double[stationNum][classNum][];
int[] stationTypes = new int[stationNum];
String[] stationNames = new String[stationNum];
for (int st=0; st<stationNum; st++) {
Object key = stationKeys.get(st);
stationNames[st] = input.getStationName(key);
if (input.getStationType(key).equals(CommonModel.STATION_TYPE_DELAY))
stationTypes[st] = ExactModel.STATION_DELAY;
else
stationTypes[st] = ExactModel.STATION_LI;
// Sets service time for each class
for (int cl=0; cl<classNum; cl++) {
Object serv = input.getServiceTimeDistribution(key, classKeys.get(cl));
if (serv instanceof Distribution) {
Distribution d = (Distribution) serv;
serviceTimes[st][cl] = new double[1]; // This is not load dependent
if (d.hasMean())
serviceTimes[st][cl][0] = d.getMean();
else {
serviceTimes[st][cl][0] = 1;
res.add(output.getStationNames()[st] + " service time distribution for "+
output.getClassNames()[cl] +
" does not have a valid mean value." +
" Service time is set to default value 1");
}
}
else if (serv instanceof ZeroStrategy) {
serviceTimes[st][cl] = new double[1];
serviceTimes[st][cl][0] = 0;
}
else if (serv instanceof LDStrategy) {
LDStrategy lds = (LDStrategy) serv;
if (output.isClosed() && !output.isMultiClass()) {
int pop = input.getClassPopulation(classKeys.get(cl)).intValue();
serviceTimes[st][cl] = new double[pop]; // This is load dependent
stationTypes[st] = ExactModel.STATION_LD;
for (int i=0; i<pop; i++)
serviceTimes[st][cl][i] = lds.getMeanValue(i);
}
else {
serviceTimes[st][cl] = new double[1]; // This is not load dependent
serviceTimes[st][cl][0] = lds.getMeanValue(1);
res.add("LD stations are supported only if model is closed and " +
"single class. " +stationNames[st]+ " was converted to a LI station.");
}
}
}
}
// Sets extracted values to output
output.setStationNames(stationNames);
stationNames = null;
output.setStationTypes(stationTypes);
stationTypes = null;
output.setServiceTimes(serviceTimes);
serviceTimes = null;
// Now calculates visits starting from routing.
Vector stations; // This is not equivalent to stationKeys as routers are considered
double[][] visits = new double[stationNum][classNum];
double[] vis = null; // array used to store results of mldivide
for (int cl=0; cl<classNum; cl++) {
if (output.getClassTypes()[cl] == ExactModel.CLASS_OPEN){
stations = input.getStationKeysNoSourceSink();
// Open class, must calculate routing from source
Object refStat = input.getClassRefStation(classKeys.get(cl));
double[] p0;
if (refStat == null) {
// Reference station for this class was not set
Vector sources = input.getStationKeysSource();
if (sources.size() > 0) {
refStat = sources.get(0);
res.add("Reference station for " + output.getClassNames()[cl] + " was " +
"not set. "+input.getStationName(refStat)+" was chosen.");
}
else
res.add("Reference station for " + output.getClassNames()[cl] + " was " +
"not set. "+output.getStationNames()[0]+" was chosen.");
}
if (refStat != null)
p0 = getRoutingProbability(refStat, classKeys.get(cl), input, stations, res);
else {
p0 = new double[stations.size()];
p0[0] = 1; // Assumes that all jobs enters in first station
}
try {
Matrix b = new Matrix(p0, 1);
Matrix P = new Matrix(buildProbabilityMatrix(stations, input, classKeys.get(cl), res));
// V = (P-eye(3))' \ (-b') where \ is "mldivide"
Matrix V = P.minus(Matrix.identity(stations.size(),stations.size())).solveTranspose(b.uminus());
vis = V.getColumnPackedCopy();
} catch (Exception e) {
// Matrix is singular
res.add("Cannot compute correctly visits for "+output.getClassNames()[cl] +" as" +
" network thopology was badly specified");
}
}
else {
// Closed class, system is indefinded, so sets visits to reference station to
// 1 and builds a smaller P matrix
stations = new Vector(input.getStationKeysNoSourceSink());
// Finds reference station
Object refStat = input.getClassRefStation(classKeys.get(cl));
if (refStat == null) {
refStat = stations.get(0);
res.add("Reference station for " + output.getClassNames()[cl] + " was " +
"not set. "+input.getStationName(refStat)+" was chosen.");
}
// Sets visits to reference station (if allowed) to 1
if (stationKeys.contains(refStat))
visits[stationKeys.lastIndexOf(refStat)][cl] =1;
// Removes reference station from stations vector and computes p0
stations.remove(refStat);
double[] p0 = getRoutingProbability(refStat, classKeys.get(cl), input, stations, res);
try {
Matrix b = new Matrix(p0, 1);
Matrix P = new Matrix(buildProbabilityMatrix(stations, input, classKeys.get(cl), res));
// V = (P-eye(3))' \ (-b') where \ is "mldivide"
Matrix V = P.minus(Matrix.identity(stations.size(),stations.size())).solveTranspose(b.uminus());
vis = V.getColumnPackedCopy();
} catch (Exception e) {
// Matrix is singular
res.add("Cannot compute correctly visits for "+output.getClassNames()[cl] +" as" +
" network thopology was badly specified");
}
}
// Puts computed values into visits matrix. Rounds at 1e-10 for machine precision issues
if (vis != null)
for (int i=0; i<vis.length; i++) {
// Skips not allowed components (Routers, Terminals, Fork, Join....)
if (stationKeys.contains(stations.get(i)))
visits[stationKeys.lastIndexOf(stations.get(i))][cl] = 1e-10 * Math.round(vis[i]*1e10);
}
}
output.setVisits(visits);
return res;
}
/**
* This method will return a reachability vector for given station and given class
* @param stationKey search's key for given station
* @param classKey search's key for given class
* @param model model data structure
* @param stations vector with ordered station keys (the same order is used in output array)
* @param warnings vector Vector to store warnings found during computation
* @return an array with probability to reach each other station starting from given station
*/
private static double[] getRoutingProbability(Object stationKey, Object classKey, CommonModel model,
Vector stations, Vector warnings) {
double[] p = new double[stations.size()];
RoutingStrategy strategy = (RoutingStrategy) model.getRoutingStrategy(stationKey, classKey);
if (strategy instanceof ProbabilityRouting &&
!model.getStationType(stationKey).equals(CommonModel.STATION_TYPE_FORK)) {
Map routingMap = strategy.getValues();
Iterator it = routingMap.keySet().iterator();
while (it.hasNext()) {
Object dest = it.next();
if (stations.lastIndexOf(dest) >= 0)
p[stations.lastIndexOf(dest)] = ((Double)routingMap.get(dest)).doubleValue();
}
}
else {
if (model.getStationType(stationKey).equals(CommonModel.STATION_TYPE_FORK)) {
warnings.add("Fork-Join are not supported in JMVA. They are considered as routers.");
}
else if (!(strategy instanceof RandomRouting))
warnings.add("\""+strategy.getName()+"\" routing strategy in "+model.getClassName(classKey) + " for " +model.getStationName(stationKey) +
" is not allowed. This was considered as RandomRouting");
Vector links = model.getForwardConnections(stationKey);
int linksNum = links.size();
// Now ignores sinks for closed classes
if (model.getClassType(classKey)==CommonModel.CLASS_TYPE_CLOSED)
for (int i=0; i<links.size();i++)
if (model.getStationType(links.get(i)).equals(CommonModel.STATION_TYPE_SINK))
linksNum--;
double weight = 1.0 / linksNum;
for (int i=0; i<links.size(); i++)
if (stations.contains(links.get(i)))
p[stations.lastIndexOf(links.get(i))] = weight;
}
return p;
}
/**
* Builds a routing probability matrix for a given set of stations
* @param stations stations to be considered
* @param model data structure
* @param classKey search's key for target class
* @param warnings Vector where computation warnings must be put
* @return computated routing probability matrix
*/
private static double[][] buildProbabilityMatrix(Vector stations, CommonModel model, Object classKey, Vector warnings) {
double[][] matrix = new double[stations.size()][stations.size()];
double[] tmp;
for (int i=0; i<stations.size(); i++) {
tmp = getRoutingProbability(stations.get(i), classKey, model, stations, warnings);
System.arraycopy(tmp, 0, matrix[i], 0, tmp.length);
}
return matrix;
}
// ----------------------------------------------------------------------------------------
// --- Methods for conversion JABA --> JMVA -----------------------------------------------
// ----------------------------------------------------------------------------------------
// --- Methods for conversion JMVA --> JABA -----------------------------------------------
// ----------------------------------------------------------------------------------------
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -