@Override public void prob1step( BitSet subset, BitSet u, BitSet v, boolean forall1, boolean forall2, BitSet result) { boolean b1, b2, b3; for (int i : new IterableStateSet(subset, numStates)) { b1 = forall1; // there exists or for all player 1 choices for (DistributionSet distrs : trans.get(i)) { b2 = forall2; // there exists or for all player 2 choices for (Distribution distr : distrs) { b3 = distr.containsOneOf(v) && distr.isSubsetOf(u); if (forall2) { if (!b3) b2 = false; } else { if (b3) b2 = true; } } if (forall1) { if (!b2) b1 = false; } else { if (b2) b1 = true; } } result.set(i, b1); } }
@Override public boolean someSuccessorsInSet(int s, BitSet set) { for (DistributionSet distrs : trans.get(s)) { for (Distribution distr : distrs) { if (distr.isSubsetOf(set)) return true; } } return false; }
@Override public boolean isSuccessor(int s1, int s2) { for (DistributionSet distrs : trans.get(s1)) { for (Distribution distr : distrs) { if (distr.contains(s2)) return true; } } return false; }
@Override public Iterator<Integer> getSuccessorsIterator(final int s, final int i) { // Need to build set to avoid duplicates // So not necessarily the fastest method to access successors HashSet<Integer> succs = new HashSet<Integer>(); for (Distribution distr : trans.get(s).get(i)) { succs.addAll(distr.getSupport()); } return succs.iterator(); }
/** * Fill the list recursively with collideNum numbers that sum to <i>sum</i>. Assuming items * already in the array p sum to <i>usedSum</i>. The numbers must be > min. It stops if it finds * <i>limit</i> patterns and the probability of those found patterns become very small comparing * to the other patterns found (probability <1/freq) * * @param patterns * @param collideNum * @param sum * @param usedSum sum of items in array <i>p</i> * @param min: is used to make p a sorted array * @param level what is the current level of recursion (number of items in array <i>p</i>) * @param p keeps track of already decided items in the pattern, it will be a sorted array * @param oldDistribution * @param limit the number of patterns to be found * @param freqI the frequency of the sum items in the sketch * @return */ private boolean getPatternRecursive( List<Map<Integer, Integer>> patterns, int collideNum, int sum, int usedSum, int min, int level, int[] p, Distribution oldDistribution, double limit, int freqI) { if (min > sum - usedSum) { // repetitive return false; } if (level == collideNum - 1) { // create the pattern with whatever remained out of sum p[level] = sum - usedSum; if (oldDistribution.getFreq(p[level]) == 0) { return false; } Map<Integer, Integer> pattern = getPattern(p); patterns.add(pattern); double prob = getProb(oldDistribution, pattern); if (sumProb == 0) { meanProb = prob * (level + 1); } else { meanProb = alpha * meanProb + (1 - alpha) * prob * (level + 1); } sumProb += prob; } else { for (int j = min; j <= sum - usedSum - (collideNum - level - 1); j++) { p[level] = j; if (oldDistribution.getFreq(p[level]) == 0) { continue; } // if I have found enough patterns and the probability of found items are very small if (patterns.size() > limit && meanProb / sumProb < 1.0 / freqI) { return true; } getPatternRecursive( patterns, collideNum, sum, usedSum + j, Math.max(min, j), level + 1, p, oldDistribution, limit, freqI); } } return false; }
@Override public int getNumNestedTransitions(int s, int i, int j) { DistributionSet ds = trans.get(s).get(i); Iterator<Distribution> iter = ds.iterator(); Distribution distr = null; int k = 0; while (iter.hasNext() && k <= j) { distr = iter.next(); k++; } if (k <= j) return 0; else return distr.size(); }
@Override public Iterator<Entry<Integer, Double>> getNestedTransitionsIterator(int s, int i, int j) { DistributionSet ds = trans.get(s).get(i); Iterator<Distribution> iter = ds.iterator(); Distribution distr = null; int k = 0; while (iter.hasNext() && k <= j) { distr = iter.next(); k++; } if (k <= j) return null; else return distr.iterator(); }
@Override public void findDeadlocks(boolean fix) throws PrismException { for (int i = 0; i < numStates; i++) { // Note that no distributions is a deadlock, not an empty distribution if (trans.get(i).isEmpty()) { addDeadlockState(i); if (fix) { DistributionSet distrs = newDistributionSet(null); Distribution distr = new Distribution(); distr.add(i, 1.0); distrs.add(distr); addDistributionSet(i, distrs); } } } }
@Override public void clearState(int i) { // Do nothing if state does not exist if (i >= numStates || i < 0) return; // Clear data structures and update stats List<DistributionSet> list = trans.get(i); numDistrSets -= list.size(); for (DistributionSet set : list) { numDistrs -= set.size(); for (Distribution distr : set) numTransitions -= distr.size(); } // TODO: recompute maxNumDistrSets // TODO: recompute maxNumDistrs // Remove all distribution sets trans.set(i, new ArrayList<DistributionSet>(0)); }
/** * Add distribution set 'newSet' to state s (which must exist). Distribution set is only actually * added if it does not already exists for state s. (Assuming 'allowDupes' flag is not enabled.) * Returns the index of the (existing or newly added) set. Returns -1 in case of error. */ public int addDistributionSet(int s, DistributionSet newSet) { ArrayList<DistributionSet> set; // Check state exists if (s >= numStates || s < 0) return -1; // Add distribution set (if new) set = trans.get(s); if (!allowDupes) { int i = set.indexOf(newSet); if (i != -1) return i; } set.add(newSet); // Update stats numDistrSets++; maxNumDistrSets = Math.max(maxNumDistrSets, set.size()); numDistrs += newSet.size(); maxNumDistrs = Math.max(maxNumDistrs, newSet.size()); for (Distribution distr : newSet) numTransitions += distr.size(); return set.size() - 1; }
/** * Generate random data and assign it to a variable in a belief network. The command line * arguments are: * * <pre> * java riso.remote_data.RandomEvidence [-h rmi-host] [-s server-name] * </pre> * * The <tt>rmi-host</tt> is the name of the host running <tt>rmiregistry</tt>. The * <tt>server-name</tt> is the name by which this data source will be known. */ public static void main(String[] args) { String bn_name = null, variable_name = null; int i, j; for (i = 0; i < args.length; i++) { switch (args[i].charAt(1)) { case 'b': bn_name = args[++i]; break; case 'x': variable_name = args[++i]; break; } } System.err.println("RandomEvidence: bn_name: " + bn_name + " variable_name: " + variable_name); try { String url = "rmi://" + bn_name; AbstractBeliefNetwork bn = (AbstractBeliefNetwork) Naming.lookup(url); AbstractVariable v = (AbstractVariable) bn.name_lookup(variable_name); Distribution p = bn.get_posterior(v); System.err.println("RandomEvidence: sample from: "); System.err.println(p.format_string("\t")); while (true) { double[] x = p.random(); bn.assign_evidence(v, x[0]); try { Thread.sleep(10000); } catch (InterruptedException e) { } } } catch (Exception e) { e.printStackTrace(); System.exit(1); } }
/** * Returns te probability of each of the key items in the pattern. It leverages Poisson * distribution. See the paper for its description * * @param distribution * @param pattern * @return */ private double getProb(Distribution distribution, Map<Integer, Integer> pattern) { return pattern .entrySet() .stream() .mapToDouble( e -> { double l = distribution.getFreq(e.getKey()) / capwidth; return l == 0 ? 0 : (new PoissonDistribution(l).probability(e.getValue()) / FastMath.exp(-l)); }) .reduce((a, b) -> (a * b)) .getAsDouble(); }
public static void main(String[] args) { boolean all_x = false, do_bind = false; String bn_name = "", context_name = ""; int i; for (i = 0; i < args.length; i++) { if (args[i].charAt(0) != '-') continue; switch (args[i].charAt(1)) { case 'b': bn_name = args[++i]; break; case 'c': context_name = args[++i]; break; case 'r': do_bind = true; break; } } AbstractBeliefNetworkContext bnc = null; AbstractBeliefNetwork bn = null; AbstractVariable x = null, e_var = null; try { if ("".equals(context_name)) { BeliefNetworkContext local_bnc = new BeliefNetworkContext(null); bnc = local_bnc; } else { String url = "rmi://" + context_name; System.err.println("Informativeness: url: " + url); long t0 = System.currentTimeMillis(); bnc = (AbstractBeliefNetworkContext) Naming.lookup(url); long tf = System.currentTimeMillis(); System.err.println( "Informativeness: Naming.lookup complete (for belief net context), elapsed time: " + ((tf - t0) / 1000.0) + " [s]"); } bn = (AbstractBeliefNetwork) bnc.load_network(bn_name); if (do_bind) { System.err.println("Informativeness: bind belief net."); bnc.bind(bn); } String e_name, x_name; double e_value; for (i = 0; i < args.length; i++) { if (args[i].charAt(0) != '-') continue; switch (args[i].charAt(1)) { case 'x': if ("-xall".equals(args[i])) { AbstractVariable[] u = bn.get_variables(); for (int j = 0; j < u.length; j++) { Distribution xposterior = bn.get_posterior(u[j]); System.out.println("Informativeness: posterior for " + u[j].get_name() + ":"); System.out.print(" " + xposterior.format_string(" ")); } } else { x_name = args[++i]; long t0 = System.currentTimeMillis(); x = (AbstractVariable) bn.name_lookup(x_name); long tf = System.currentTimeMillis(); System.err.println( "Informativeness: Naming.lookup complete (for variable ref), elapsed time: " + ((tf - t0) / 1000.0) + " [s]"); if (x == null) throw new Exception("name_lookup failed: x: " + x_name); Distribution xposterior = bn.get_posterior(x); System.out.println("Informativeness: posterior for " + x.get_name() + ":"); System.out.print(" " + xposterior.format_string(" ")); } break; case 'e': if (args[i].length() > 2 && args[i].charAt(2) == '-') { e_name = args[++i]; System.err.println("Informativeness.main: evidence: clear " + e_name); e_var = (AbstractVariable) bn.name_lookup(e_name); bn.clear_posterior(e_var); } else { e_name = args[++i]; e_value = Double.parseDouble(args[++i]); System.err.println( "Informativeness.main: evidence: set " + e_name + " to " + e_value); long t0 = System.currentTimeMillis(); e_var = (AbstractVariable) bn.name_lookup(e_name); long tf = System.currentTimeMillis(); System.err.println( "Informativeness: Naming.lookup complete (for variable ref), elapsed time: " + ((tf - t0) / 1000.0) + " [s]"); bn.assign_evidence(e_var, e_value); } break; default: continue; } } } catch (Exception e) { e.printStackTrace(); } System.exit(0); }
/** Simple test program */ public static void main(String args[]) { STPGModelChecker mc; STPGAbstrSimple stpg; DistributionSet set; Distribution distr; // ModelCheckerResult res; BitSet target; // Simple example: Create and solve the stochastic game from: // Mark Kattenbelt, Marta Kwiatkowska, Gethin Norman, David Parker // A Game-based Abstraction-Refinement Framework for Markov Decision Processes // Formal Methods in System Design 36(3): 246-280, 2010 try { // Build game stpg = new STPGAbstrSimple(); stpg.addStates(4); // State 0 (s_0) set = stpg.newDistributionSet(null); distr = new Distribution(); distr.set(1, 1.0); set.add(distr); stpg.addDistributionSet(0, set); // State 1 (s_1,s_2,s_3) set = stpg.newDistributionSet(null); distr = new Distribution(); distr.set(2, 1.0); set.add(distr); distr = new Distribution(); distr.set(1, 1.0); set.add(distr); stpg.addDistributionSet(1, set); set = stpg.newDistributionSet(null); distr = new Distribution(); distr.set(2, 0.5); distr.set(3, 0.5); set.add(distr); distr = new Distribution(); distr.set(3, 1.0); set.add(distr); stpg.addDistributionSet(1, set); // State 2 (s_4,s_5) set = stpg.newDistributionSet(null); distr = new Distribution(); distr.set(2, 1.0); set.add(distr); stpg.addDistributionSet(2, set); // State 3 (s_6) set = stpg.newDistributionSet(null); distr = new Distribution(); distr.set(3, 1.0); set.add(distr); stpg.addDistributionSet(3, set); // Print game System.out.println(stpg); // Model check mc = new STPGModelChecker(null); // mc.setVerbosity(2); target = new BitSet(); target.set(3); stpg.exportToDotFile("stpg.dot", target); System.out.println("min min: " + mc.computeReachProbs(stpg, target, true, true).soln[0]); System.out.println("max min: " + mc.computeReachProbs(stpg, target, false, true).soln[0]); System.out.println("min max: " + mc.computeReachProbs(stpg, target, true, false).soln[0]); System.out.println("max max: " + mc.computeReachProbs(stpg, target, false, false).soln[0]); } catch (PrismException e) { System.out.println(e); } }
/** {@inheritDoc} */ @Override public boolean equalDist(Distribution dist, double threshold) { if (dist.getClass().getName().equals("eu.amidst.core.distribution.GaussianMixture")) return this.equalDist((Normal) dist, threshold); return false; }
@Override public Map<Long, Long> findFS() { int[] usedCounts = Arrays.copyOfRange(counts, 0, capwidth); // initial frequency is the same as what we see from counters Map<Integer, Long> freq = Arrays.stream(usedCounts) .boxed() .collect(Collectors.groupingBy(Integer::intValue, Collectors.counting())); Long zeroNum = freq.get(0); if (zeroNum != null && zeroNum == capwidth) { return new HashMap<>(); } // estimate the number of items int num = (int) (capwidth * Math.log(1.0 * capwidth / zeroNum)); Distribution newDistribution = new Distribution(freq); Distribution oldDistribution = new Distribution(); // A pattern is a setting of itmes+frequencies that sum to sumI // All patterns in this list will map to a common number sumI List<Map<Integer, Integer>> patterns = new ArrayList<>(); List<Double> probabilities = new ArrayList<>(); int iterations = 0; // iteratively update the distribution // while (notConverged()) { while (iterations < MAXIMUM_ITERATIONS) { oldDistribution.fillFrom(newDistribution); newDistribution.clear(); for (Map.Entry<Integer, Long> entry : freq.entrySet()) { int sumI = entry.getKey(); int freqI = entry.getValue().intValue(); if (sumI == 0) { // skip key=0 continue; } // find new probable patterns, get their probabilities and update the distribution getPatterns(patterns, sumI, freqI, oldDistribution); computeProbabilities(patterns, oldDistribution, probabilities); Iterator<Double> probabilityIterator = probabilities.iterator(); for (Map<Integer, Integer> pattern : patterns) { // for each pattern double probability = probabilityIterator.next(); for (Map.Entry<Integer, Integer> patternEntry : pattern.entrySet()) { newDistribution.addFreq( patternEntry.getKey(), freqI * patternEntry.getValue() * probability); } } } // scale factor to make sum of distribution equal to 1 double scale = num / newDistribution.sumFreq(); pw.println( String.format( DISTRIBUTION_TRACE_FORMATTER, getStep() + 1, iterations + 1, newDistribution.toString(scale))); iterations++; } pw.flush(); System.out.println(getStep()); Map<Long, Long> output = new HashMap<>(); double freqSum = newDistribution.sumFreq(); for (Map.Entry<Integer, Double> entry : newDistribution.freq.entrySet()) { output.put(entry.getKey().longValue(), (long) (entry.getValue() / freqSum * num)); } return output; }
@Override public void buildFromPrismExplicit(String filename) throws PrismException { BufferedReader in; Distribution distr; DistributionSet distrs; String s, ss[]; int i, j, k1, k2, iLast, k1Last, k2Last, n, lineNum = 0; double prob; try { // Open file in = new BufferedReader(new FileReader(new File(filename))); // Parse first line to get num states s = in.readLine(); lineNum = 1; if (s == null) { in.close(); throw new PrismException("Missing first line of .tra file"); } ss = s.split(" "); n = Integer.parseInt(ss[0]); // Initialise initialise(n); // Go though list of transitions in file iLast = -1; k1Last = -1; k2Last = -1; distrs = null; distr = null; s = in.readLine(); lineNum++; while (s != null) { s = s.trim(); if (s.length() > 0) { ss = s.split(" "); i = Integer.parseInt(ss[0]); k1 = Integer.parseInt(ss[1]); k2 = Integer.parseInt(ss[2]); j = Integer.parseInt(ss[3]); prob = Double.parseDouble(ss[4]); // For a new state or distribution set or distribution if (i != iLast || k1 != k1Last || k2 != k2Last) { // Add any previous distribution to the last set, create new one if (distrs != null) { distrs.add(distr); } distr = new Distribution(); // Only for a new state or distribution set... if (i != iLast || k1 != k1Last) { // Add any previous distribution set to the last state, create new one if (distrs != null) { addDistributionSet(iLast, distrs); } distrs = newDistributionSet(null); } } // Add transition to the current distribution distr.add(j, prob); // Prepare for next iter iLast = i; k1Last = k1; k2Last = k2; } s = in.readLine(); lineNum++; } // Add previous distribution to the last set distrs.add(distr); // Add previous distribution set to the last state addDistributionSet(iLast, distrs); // Close file in.close(); } catch (IOException e) { System.out.println(e); System.exit(1); } catch (NumberFormatException e) { throw new PrismException("Problem in .tra file (line " + lineNum + ") for " + getModelType()); } // Set initial state (assume 0) initialStates.add(0); }
/** * Generates a synthetic network for provided vertices in the given graphh such that the provided * expected number of communities are generated with the specified expected number of edges. * * @param graph * @param vertices * @param expectedNumCommunities * @param expectedNumEdges * @return The actual number of edges generated. May be different from the expected number. */ public int generate( Graph graph, Iterable<Vertex> vertices, int expectedNumCommunities, int expectedNumEdges) { if (communitySize == null) throw new IllegalStateException("Need to initialize community size distribution"); if (edgeDegree == null) throw new IllegalStateException("Need to initialize degree distribution"); int numVertices = SizableIterable.sizeOf(vertices); Iterator<Vertex> iter = vertices.iterator(); ArrayList<ArrayList<Vertex>> communities = new ArrayList<ArrayList<Vertex>>(expectedNumCommunities); Distribution communityDist = communitySize.initialize(expectedNumCommunities, numVertices); while (iter.hasNext()) { int nextSize = communityDist.nextValue(random); ArrayList<Vertex> community = new ArrayList<Vertex>(nextSize); for (int i = 0; i < nextSize && iter.hasNext(); i++) { community.add(iter.next()); } if (!community.isEmpty()) communities.add(community); } double inCommunityPercentage = 1.0 - crossCommunityPercentage; Distribution degreeDist = edgeDegree.initialize(numVertices, expectedNumEdges); if (crossCommunityPercentage > 0 && communities.size() < 2) throw new IllegalArgumentException("Cannot have cross links with only one community"); int addedEdges = 0; // System.out.println("Generating links on communities: "+communities.size()); for (ArrayList<Vertex> community : communities) { for (Vertex v : community) { int degree = degreeDist.nextValue(random); degree = Math.min(degree, (int) Math.ceil((community.size() - 1) / inCommunityPercentage) - 1); Set<Vertex> inlinks = new HashSet<Vertex>(); for (int i = 0; i < degree; i++) { Vertex selected = null; if (random.nextDouble() < crossCommunityPercentage || (community.size() - 1 <= inlinks.size())) { // Cross community ArrayList<Vertex> othercomm = null; while (othercomm == null) { othercomm = communities.get(random.nextInt(communities.size())); if (othercomm.equals(community)) othercomm = null; } selected = othercomm.get(random.nextInt(othercomm.size())); } else { // In community while (selected == null) { selected = community.get(random.nextInt(community.size())); if (v.equals(selected) || inlinks.contains(selected)) selected = null; } inlinks.add(selected); } addEdge(graph, v, selected); addedEdges++; } } } return addedEdges; }