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

📄 modelconverter.java

📁 一个用于排队系统仿真的开源软件,有非常形象的图象仿真过程!
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
// --- 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 + -