/** * Compute bounded reachability/until probabilities. i.e. compute the min/max probability of * reaching a state in {@code target}, within time t, and while remaining in states in @{code * remain}. * * @param ctmdp The CTMDP * @param remain Remain in these states (optional: null means "all") * @param target Target states * @param t: Time bound * @param min Min or max probabilities (true=min, false=max) * @param init: Initial solution vector - pass null for default * @param results: Optional array of size b+1 to store (init state) results for each step (null if * unused) */ public ModelCheckerResult computeBoundedReachProbsOld( CTMDP ctmdp, BitSet remain, BitSet target, double t, boolean min, double init[], double results[]) throws PrismException { // TODO: implement until ModelCheckerResult res = null; int i, n, iters; double soln[], soln2[], tmpsoln[], sum[]; long timer; // Fox-Glynn stuff FoxGlynn fg; int left, right; double q, qt, weights[], totalWeight; // Start bounded probabilistic reachability timer = System.currentTimeMillis(); mainLog.println("Starting time-bounded probabilistic reachability..."); // Store num states n = ctmdp.getNumStates(); // Get uniformisation rate; do Fox-Glynn q = 99; // ctmdp.unif; qt = q * t; mainLog.println("\nUniformisation: q.t = " + q + " x " + t + " = " + qt); fg = new FoxGlynn(qt, 1e-300, 1e+300, termCritParam / 8.0); left = fg.getLeftTruncationPoint(); right = fg.getRightTruncationPoint(); if (right < 0) { throw new PrismException("Overflow in Fox-Glynn computation (time bound too big?)"); } weights = fg.getWeights(); totalWeight = fg.getTotalWeight(); for (i = left; i <= right; i++) { weights[i - left] /= totalWeight; } mainLog.println("Fox-Glynn: left = " + left + ", right = " + right); // Create solution vector(s) soln = new double[n]; soln2 = (init == null) ? new double[n] : init; sum = new double[n]; // Initialise solution vectors. Use passed in initial vector, if present if (init != null) { for (i = 0; i < n; i++) soln[i] = soln2[i] = target.get(i) ? 1.0 : init[i]; } else { for (i = 0; i < n; i++) soln[i] = soln2[i] = target.get(i) ? 1.0 : 0.0; } for (i = 0; i < n; i++) sum[i] = 0.0; // If necessary, do 0th element of summation (doesn't require any matrix powers) if (left == 0) for (i = 0; i < n; i++) sum[i] += weights[0] * soln[i]; // Start iterations iters = 1; while (iters <= right) { // Matrix-vector multiply and min/max ops ctmdp.mvMultMinMax(soln, min, soln2, target, true, null); // Since is globally uniform, can do this? and more? for (i = 0; i < n; i++) soln2[i] /= q; // Store intermediate results if required // TODO? // Swap vectors for next iter tmpsoln = soln; soln = soln2; soln2 = tmpsoln; // Add to sum if (iters >= left) { for (i = 0; i < n; i++) sum[i] += weights[iters - left] * soln[i]; } iters++; } // Print vector (for debugging) mainLog.println(sum); // Finished bounded probabilistic reachability timer = System.currentTimeMillis() - timer; mainLog.print("Time-bounded probabilistic reachability (" + (min ? "min" : "max") + ")"); mainLog.println(" took " + iters + " iters and " + timer / 1000.0 + " seconds."); // Return results res = new ModelCheckerResult(); res.soln = sum; res.lastSoln = soln2; res.numIters = iters; res.timeTaken = timer / 1000.0; return res; }
/** * Compute bounded reachability/until probabilities. i.e. compute the min/max probability of * reaching a state in {@code target}, within k steps, and while remaining in states in @{code * remain}. * * @param stpg The STPG * @param remain Remain in these states (optional: null means "all") * @param target Target states * @param k Bound * @param min1 Min or max probabilities for player 1 (true=lower bound, false=upper bound) * @param min2 Min or max probabilities for player 2 (true=min, false=max) * @param init Initial solution vector - pass null for default * @param results Optional array of size k+1 to store (init state) results for each step (null if * unused) */ public ModelCheckerResult computeBoundedReachProbs( STPG stpg, BitSet remain, BitSet target, int k, boolean min1, boolean min2, double init[], double results[]) throws PrismException { // TODO: implement until ModelCheckerResult res = null; int i, n, iters; double soln[], soln2[], tmpsoln[]; long timer; // Start bounded probabilistic reachability timer = System.currentTimeMillis(); if (verbosity >= 1) mainLog.println("\nStarting bounded probabilistic reachability..."); // Store num states n = stpg.getNumStates(); // Create solution vector(s) soln = new double[n]; soln2 = (init == null) ? new double[n] : init; // Initialise solution vectors. Use passed in initial vector, if present if (init != null) { for (i = 0; i < n; i++) soln[i] = soln2[i] = target.get(i) ? 1.0 : init[i]; } else { for (i = 0; i < n; i++) soln[i] = soln2[i] = target.get(i) ? 1.0 : 0.0; } // Store intermediate results if required // (compute min/max value over initial states for first step) if (results != null) { results[0] = Utils.minMaxOverArraySubset(soln2, stpg.getInitialStates(), min2); } // Start iterations iters = 0; while (iters < k) { iters++; // Matrix-vector multiply and min/max ops stpg.mvMultMinMax(soln, min1, min2, soln2, target, true, null); // Store intermediate results if required // (compute min/max value over initial states for this step) if (results != null) { results[iters] = Utils.minMaxOverArraySubset(soln2, stpg.getInitialStates(), min2); } // Swap vectors for next iter tmpsoln = soln; soln = soln2; soln2 = tmpsoln; } // Print vector (for debugging) // mainLog.println(soln); // Finished bounded probabilistic reachability timer = System.currentTimeMillis() - timer; if (verbosity >= 1) { mainLog.print( "Bounded probabilistic reachability (" + (min1 ? "min" : "max") + (min2 ? "min" : "max") + ")"); mainLog.println(" took " + iters + " iterations and " + timer / 1000.0 + " seconds."); } // Return results res = new ModelCheckerResult(); res.soln = soln; res.lastSoln = soln2; res.numIters = iters; res.timeTaken = timer / 1000.0; res.timePre = 0.0; return res; }