Class SolverMVA

Direct Known Subclasses:
MVA

public class SolverMVA extends NetworkSolver
SolverMVA implements Mean Value Analysis (MVA) for queueing networks. MVA is an exact analytical method for computing performance measures of closed queueing networks, particularly effective for networks with product-form solutions.
  • Field Details

    • CLOSED_POPULATION_METHODS

      public static final List<String> CLOSED_POPULATION_METHODS
      The AMVA algorithms whose recursion is over a CLOSED population vector. Each approximates the arrival-instant queue length E[Q(N-1_r)] from E[Q(N)] and is handed (L, N, Z) alone, with no arrival rate and no rate function, so an open chain gives it nothing to recur on. Canonical spellings only; an "amva." prefix is stripped before the list is consulted, exactly as Solver_amva strips it before it selects an algorithm. ONE list, read by methodFeatureSet (which drops OpenClass for these) and by Solver_amva (which refuses them by name), so the gate and the run cannot drift apart.
    • NON_BCMP_SCHED_FEATURES

      public static final String[] NON_BCMP_SCHED_FEATURES
      Scheduling feature names OUTSIDE the BCMP set {INF, PS, FCFS, SIRO, LCFS-PR} that the base MVA envelope declares. The chain algorithms that walk the stations one by one (the summation method, MVAC, QNA) accept the BCMP set and refuse the rest, so each drops these from its own envelope.
  • Constructor Details

    • SolverMVA

      public SolverMVA(Network model, String method)
      Creates a new SolverMVA instance with a specific method.
      Parameters:
      model - The network model to analyze
      method - The MVA method to use
    • SolverMVA

      public SolverMVA(Network model, SolverOptions options)
      Creates a new SolverMVA instance with specific options.
      Parameters:
      model - The network model to analyze
      options - The solver options to use
    • SolverMVA

      public SolverMVA(Network model, Object... varargin)
      Creates a new SolverMVA instance with variable arguments for options.
      Parameters:
      model - The network model to analyze
      varargin - Variable arguments for solver options
    • SolverMVA

      public SolverMVA(Network model)
      Creates a new SolverMVA instance with default options.
      Parameters:
      model - The network model to analyze
  • Method Details

    • supportsExactSensitivity

      public boolean supportsExactSensitivity()
      MVA differentiates its own recursion: getSensitivityTable uses the analytic branch (pfqn_sens) wherever the model is in scope.
      Overrides:
      supportsExactSensitivity in class NetworkSolver
      Returns:
      true
    • resetForkWarmStart

      public void resetForkWarmStart()
      Discards the retained MMT fixed point. Mirrors options.init_sol: the iterate survives reset() and is invalidated explicitly by the caller when the chain basis changes.
    • getForkWarmStart

      public Matrix getForkWarmStart()
      Returns the retained MMT fixed-point iterate, or null if none is held. Callers that drive this solver across an outer iteration without keeping the instance alive (e.g. the MATLAB lang='java' dispatch, which rebuilds the JLINE solver on every call) can carry it themselves via this accessor and setForkWarmStart.
    • setForkWarmStart

      public void setForkWarmStart(Matrix fjForkLambda)
      Seeds the MMT fixed point with a previously retained iterate. Conformance with the current fork topology is checked at the point of use in MVARunner, so a stale iterate is ignored rather than misapplied.
    • defaultOptions

      public static SolverOptions defaultOptions()
      Returns the default solver options for the MVA solver.
      Returns:
      Default solver options with SolverType.MVA
    • getFeatureSet

      public static FeatureSet getFeatureSet()
      Returns the feature set supported by the MVA solver
      Returns:
      - the feature set supported by the MVA solver
    • methodFeatureSet

      public static FeatureSet methodFeatureSet(String method)
      Per-method feature deltas applied to the base MVA envelope. QNA is a two-moment open-network method, so it drops closed-class support. The queueing-system and bounds methods are already structurally restricted by listValidMethods and inherit the base envelope. RQNA (open only) natively consumes the non-renewal MAP/MMPP/MMAP/RAP point processes through the index-of-dispersion equations, so it declares them on top of the base envelope; it dispatches from Solver_mva_analyzer to Solver_rqna, and the default method also selects it for bursty single-class open networks. Mirrors the MATLAB/Python SolverMVA.getMethodFeatureSet.
      Parameters:
      method - the concrete method name
      Returns:
      the per-method FeatureSet
    • getMethodFeatureSet

      public FeatureSet getMethodFeatureSet(String method)
      The per-method envelope plus the one MVA rule that is judged on the MODEL rather than on the name, which is why it cannot live in the static methodFeatureSet(java.lang.String) table.

      A single-station M/M/1/K with tail drop keeps a closed form under every name but "exact" (the moment-based Qsys_mg1k_loss_mgs branch of Solver_mva_qsys_analyzer, exact at scv = 1 only), so the grant is judged on SnIsMm1kLoss. MVARunner reaches that branch by SHAPE rather than by name and finiteCapacityReason(jline.lang.Network, jline.lang.NetworkStruct, java.lang.String) carries the matching exemption, so the report and the run agree on it.

      Overrides:
      getMethodFeatureSet in class Solver
      Parameters:
      method - the concrete method name
      Returns:
      the per-method FeatureSet for this model
    • methodFeatureSet

      public static FeatureSet methodFeatureSet(NetworkStruct sn, String method)
      The same envelope, asked of a struct rather than of a solver instance, so that the run gate in MVARunner and the report gate in getMethodFeatureSet(java.lang.String) apply ONE copy of the model-judged rule. The runner reads the static table alone until this exists, and would refuse the M/M/1/K shape under every name its own dispatch claims by shape.
      Parameters:
      sn - the network structure, or null to get the name-only envelope
      method - the concrete method name
      Returns:
      the per-method FeatureSet for this model
    • resolveMethod

      public String resolveMethod(SolverOptions options)
      Feature-driven resolution of options.method="default": a bursty single-class open network has a non-renewal (MAP/MMPP) arrival process whose autocorrelation a two-moment method cannot capture, so the default dispatch of Solver_mva_analyzer selects RQNA. Naming that here is what lets the feature gate admit the MAP family on the path that will actually run: without it "default" carried the base envelope, the MAP/MMPP arrival read as unsupported, and the model went to the random-environment approximation instead of the exact-in-IDC analyzer. Mirrors the MATLAB/Python SolverMVA.resolveMethod.
      Overrides:
      resolveMethod in class Solver
      Parameters:
      options - the solver options
      Returns:
      the concrete method the analyzer will dispatch
    • resolveMethodForStruct

      public static String resolveMethodForStruct(NetworkStruct sn, String method)
      The concrete method the MVA analyzer will dispatch, given a struct and a requested name. Static and struct-only so that MVARunner gates on exactly the name this solver resolves: two copies of this rule drift, and a gate that resolves differently from the analyzer either refuses a model the analyzer could solve or admits one it cannot.
      Parameters:
      sn - the network struct
      method - the requested method name
      Returns:
      the concrete method name
    • getStruct

      public NetworkStruct getStruct()
      Returns the network structure used by this solver. If the structure is not yet initialized, it will be created from the model.
      Returns:
      The network structure
    • setStruct

      public void setStruct(NetworkStruct sn)
      Sets the network structure for this solver.
      Parameters:
      sn - The network structure to use
    • runAnalyzer

      public void runAnalyzer() throws IllegalAccessException
      Runs the MVA analyzer to solve the queueing network. This method executes the Mean Value Analysis algorithm and stores the results in the solver's result object.
      Specified by:
      runAnalyzer in class Solver
      Throws:
      IllegalAccessException - if there are access issues during analysis
    • supports

      public boolean supports(Network model)
      Checks whether the given model is supported by the MVA solver
      Overrides:
      supports in class Solver
      Parameters:
      model - - the network model
      Returns:
      - true if the model is supported, false otherwise
    • supportsModelMethod

      public String supportsModelMethod(String method)
      Method-level gate. The base gate answers from the feature set; method "exact" additionally requires a product-form solution, which has no registry feature name and so cannot live in getMethodFeatureSet.
      Overrides:
      supportsModelMethod in class Solver
      Parameters:
      method - the concrete method name
      Returns:
      empty string if supported, else the offending reason
    • schmidtExtReasonForStruct

      public static String schmidtExtReasonForStruct(NetworkStruct sn, String method)
      schmidtExtReason(jline.util.matrix.Matrix, java.util.List<java.lang.Boolean>, java.lang.String) asked about a struct: it rebuilds the population vector and per-station discipline that Solver_amva's schmidt-ext arm hands the kernel, so the report and the run ask the same question of the same numbers.

      That arm recurs on the CHAIN populations under class switching and on the class ones otherwise, which is the vector the kernel is handed; this asks about the same one. All four codebases now agree on that basis.

      Parameters:
      sn - the network struct
      method - the requested method name
      Returns:
      empty string if the method may run, else the offending reason
    • schmidtExtReason

      public static String schmidtExtReason(Matrix N, List<Boolean> fcfs, String method)
      Refusal reason for the extended Schmidt method, empty when it may run. Schmidt's EXTENSION over plain Schmidt is an alpha correction applied at an FCFS station, and the correction is computed from the network with ONE class-r customer TAGGED, that is at population N - 1_r. A class holding no customer has none to tag: the sub-problem is formed at a negative population, whose state lattice prod(N+1) collapses to zero and the recursion indexes an empty array. Plain "schmidt" forms no such sub-problem, which is why the requirement is the -ext arm's alone.

      THE TEST IS STATED AT THE FCFS STATION AND NOT AT A CLASS-DEPENDENT ONE, because the four kernels differ on when they form the correction: MATLAB, the C++ port and native python form it only where the station's demands differ by class, while Pfqn_schmidt_amva forms it at EVERY FCFS station. Stating the union is what keeps one rule safe for all four; the case it costs -- an FCFS station whose demands are identical across classes, one of them empty -- is one where the extension reduces to plain "schmidt", which stays offered.

      Parameters:
      N - the population vector the kernel recurs on
      fcfs - whether each station row is served FCFS
      method - the requested method name
      Returns:
      empty string if the method may run, else the offending reason
    • baseMethod

      public static String baseMethod(String method)
      The method name with any leading "amva." alias stripped.
      Parameters:
      method - the requested method name
      Returns:
      the canonical spelling
    • isClosedPopulationMethod

      public static boolean isClosedPopulationMethod(String method)
      Whether the name, alias stripped, is one of the closed-population algorithms.
      Parameters:
      method - the requested method name
      Returns:
      true when it belongs to the family
    • closedPopulationReason

      public static String closedPopulationReason(NetworkStruct sn, String method)
      Refusal reason for the closed-population AMVA family, empty when it may run. Open chains are also expressed in the registry (methodFeatureSet drops OpenClass for these), which is what keeps them off the report; they are repeated here because the analyzer must refuse by name with a sentence rather than fall through and answer under a method nobody asked for. Strict product form has no registry name at all, so this is its only home.
      Parameters:
      sn - the network struct
      method - the requested method name
      Returns:
      empty string if the method may run, else the offending reason
    • singleClassOpenReason

      public static String singleClassOpenReason(NetworkStruct sn, String method)
      Refusal reason for RQNA and RQT, empty when the method may run. Both build one uncertainty set per flow out of the first two moments of a SINGLE stream, so a multiclass model has no counterpart in their equations. No registry feature names a class count, so the rule is structural.
      Parameters:
      sn - the network struct
      method - the requested method name
      Returns:
      empty string if the method may run, else the offending reason
    • mvacReason

      public static String mvacReason(NetworkStruct sn, String method)
      Refusal reason for MVAC, empty when the method may run. MVAC (Conway-de Souza e Silva-Lavenberg) is the exact chain recursion over single-server fixed-rate (SSFR) queues and infinite-server centres of a product-form network. Neither the server count nor product form has a registry feature name, so both are structural; the scheduling restriction IS nameable and lives in methodFeatureSet.
      Parameters:
      sn - the network struct
      method - the requested method name
      Returns:
      empty string if the method may run, else the offending reason
    • qnaSchedulingReason

      public static String qnaSchedulingReason(NetworkStruct sn)
      Refusal reason for QNA's station update, empty when every station has an arm. The update has an arm for INF, PS and FCFS and none for any other discipline, so a SIRO, LCFS, LCFS-PR, HOL or priority station used to leave its whole row of Q, U, R and T at zero and the table was returned as a solution. The registry expresses this as well (methodFeatureSet drops the disciplines from QNA's envelope); this is the analyzer's half of it.
      Parameters:
      sn - the network struct
      Returns:
      empty string if QNA may run, else the offending reason
    • exactnessReason

      public static String exactnessReason(Network model, String method)
      Product-form precondition of method "exact", the same rule MVARunner enforces at solve time. Order-independent and pass-and-swap stations are exempt: Solver_mva_oi_analyzer is exact for them regardless of the product-form test.
      Parameters:
      model - the network model
      method - the concrete method name
      Returns:
      empty string if the method may run, else the offending reason
    • finiteCapacityReason

      public static String finiteCapacityReason(Network model, NetworkStruct sn, String method)
      MVA-specific finite-capacity gate, asked of the METHOD as well as of the model. Mirrors MATLAB SolverMVA.supportsFiniteCapacity.

      A Blocking-After-Service model is exempt where the finite buffers ARE honoured, which is Solver_sqd alone: "sqd" names it and the default ladder of Solver_mva_analyzer selects it. Every other name (the exact recursion under "mva", every AMVA kernel, sum, mvac) solves the buffers away, and so does "default" on a load-, class- or joint-dependent model, whose ladder (Solver_mvald_analyzer) has no sqd arm. Everything else defers to the shared product-form gate.

      THE SECOND EXEMPTION is a single-station M/M/1/K with tail drop, which the moment-based (MacGregor Smith) Qsys_mg1k_loss_mgs branch of Solver_mva_qsys_analyzer answers, MVARunner reaching it by SHAPE under every name. That branch is exact at scv=1 only, so "exact" is NOT exempted and must refuse; every other name is.

      Parameters:
      model - - the network model
      sn - - the network structure
      method - - the concrete method name, "default" when unknown
      Returns:
      null if the model has no binding capacity, otherwise the reason
    • finiteCapacityReason

      public static String finiteCapacityReason(Network model, NetworkStruct sn)
      The solver-level form of finiteCapacityReason(Network, NetworkStruct, String), answered as the default method, as MATLAB answers it when supportsFiniteCapacity is called with no method.
      Parameters:
      model - - the network model
      sn - - the network structure
      Returns:
      null if the model has no binding capacity, otherwise the reason
    • getProbNormConstAggr

      public Ret.ProbabilityResult getProbNormConstAggr()
      Returns the logarithm of the normalizing constant for the aggregate state probabilities
      Overrides:
      getProbNormConstAggr in class NetworkSolver
      Returns:
      the log of the normalizing constant
    • getProbAggr

      public Ret.ProbabilityResult getProbAggr(int ist)
      Get marginal state probabilities for a specific station
      Overrides:
      getProbAggr in class NetworkSolver
      Parameters:
      ist - station index (0-based)
      Returns:
      ProbabilityResult with probability and log probability
    • getProbSysAggr

      public Ret.ProbabilityResult getProbSysAggr()
      Get joint system state probabilities
      Overrides:
      getProbSysAggr in class NetworkSolver
      Returns:
      ProbabilityResult with probability and log probability
    • getProbMarg

      public Ret.ProbabilityResult getProbMarg(int ist, int jobclass)
      Get marginalized state probabilities for a specific station and job class
      Overrides:
      getProbMarg in class NetworkSolver
      Parameters:
      ist - station index (0-based)
      jobclass - job class index (0-based)
      Returns:
      ProbabilityResult with marginalized state probabilities
    • getProbMarg

      public Ret.ProbabilityResult getProbMarg(int ist, int jobclass, Matrix state_m)
      Get marginalized state probabilities for a specific station and job class with state filter
      Overrides:
      getProbMarg in class NetworkSolver
      Parameters:
      ist - station index (0-based)
      jobclass - job class index (0-based)
      state_m - marginalized state vector to query (optional, null for all states)
      Returns:
      ProbabilityResult with marginalized state probabilities
    • listValidMethods

      public String[] listValidMethods()
      List all valid solution methods supported by this solver
      Returns:
      array of valid method names