@Override
  public List<Integer> mvMultRewMinMaxSingleChoices(
      int s, double vect[], STPGRewards rewards, boolean min1, boolean min2, double val) {
    int dsIter, dIter, k;
    double d, prob, minmax2;
    boolean first2;
    List<Integer> res;
    ArrayList<DistributionSet> step;

    // Create data structures to store strategy
    res = new ArrayList<Integer>();
    // One row of matrix-vector operation
    dsIter = -1;
    step = trans.get(s);
    for (DistributionSet distrs : step) {
      dsIter++;
      minmax2 = 0;
      first2 = true;
      dIter = -1;
      for (Distribution distr : distrs) {
        dIter++;
        // Compute sum for this distribution
        d = rewards.getNestedTransitionReward(s, dsIter, dIter);
        for (Map.Entry<Integer, Double> e : distr) {
          k = (Integer) e.getKey();
          prob = (Double) e.getValue();
          d += prob * vect[k];
        }
        // Check whether we have exceeded min/max so far
        if (first2 || (min2 && d < minmax2) || (!min2 && d > minmax2)) minmax2 = d;
        first2 = false;
      }
      minmax2 += rewards.getTransitionReward(s, dsIter);
      // Store strategy info if value matches
      // if (PrismUtils.doublesAreClose(val, d, termCritParam, termCrit == TermCrit.ABSOLUTE)) {
      if (PrismUtils.doublesAreClose(val, minmax2, 1e-12, false)) {
        res.add(dsIter);
        // res.add(distrs.getAction());
      }
    }

    return res;
  }
  @Override
  public double mvMultRewMinMaxSingle(
      int s, double vect[], STPGRewards rewards, boolean min1, boolean min2, int adv[]) {
    int dsIter, dIter, k;
    double d, prob, minmax1, minmax2;
    boolean first1, first2;
    ArrayList<DistributionSet> step;

    minmax1 = 0;
    first1 = true;
    dsIter = -1;
    step = trans.get(s);
    for (DistributionSet distrs : step) {
      dsIter++;
      minmax2 = 0;
      first2 = true;
      dIter = -1;
      for (Distribution distr : distrs) {
        dIter++;
        // Compute sum for this distribution
        d = rewards.getNestedTransitionReward(s, dsIter, dIter);
        for (Map.Entry<Integer, Double> e : distr) {
          k = (Integer) e.getKey();
          prob = (Double) e.getValue();
          d += prob * vect[k];
        }
        // Check whether we have exceeded min/max so far
        if (first2 || (min2 && d < minmax2) || (!min2 && d > minmax2)) minmax2 = d;
        first2 = false;
      }
      minmax2 += rewards.getTransitionReward(s, dsIter);
      // Check whether we have exceeded min/max so far
      if (first1 || (min1 && minmax2 < minmax1) || (!min1 && minmax2 > minmax1)) minmax1 = minmax2;
      first1 = false;
    }

    return minmax1;
  }