Esempio n. 1
0
 /*  43:    */
 /*  44:    */ private Integer getPivotRow(SimplexTableau tableau, int col) /*  45:    */ {
   /*  46: 90 */ List<Integer> minRatioPositions = new ArrayList();
   /*  47: 91 */ double minRatio = 1.7976931348623157E+308D;
   /*  48: 92 */ for (int i = tableau.getNumObjectiveFunctions(); i < tableau.getHeight(); i++)
   /*  49:    */ {
     /*  50: 93 */ double rhs = tableau.getEntry(i, tableau.getWidth() - 1);
     /*  51: 94 */ double entry = tableau.getEntry(i, col);
     /*  52: 96 */ if (Precision.compareTo(entry, 0.0D, this.maxUlps) > 0)
     /*  53:    */ {
       /*  54: 97 */ double ratio = rhs / entry;
       /*  55: 98 */ int cmp = Precision.compareTo(ratio, minRatio, this.maxUlps);
       /*  56: 99 */ if (cmp == 0)
       /*  57:    */ {
         /*  58:100 */ minRatioPositions.add(Integer.valueOf(i));
         /*  59:    */ }
       /*  60:101 */ else if (cmp < 0)
       /*  61:    */ {
         /*  62:102 */ minRatio = ratio;
         /*  63:103 */ minRatioPositions = new ArrayList();
         /*  64:104 */ minRatioPositions.add(Integer.valueOf(i));
         /*  65:    */ }
       /*  66:    */ }
     /*  67:    */ }
   /*  68:109 */ if (minRatioPositions.size() == 0) {
     /*  69:110 */ return null;
     /*  70:    */ }
   /*  71:111 */ if (minRatioPositions.size() > 1) {
     /*  72:114 */ for (Integer row : minRatioPositions) {
       /*  73:115 */ for (int i = 0; i < tableau.getNumArtificialVariables(); i++)
       /*  74:    */ {
         /*  75:116 */ int column = i + tableau.getArtificialVariableOffset();
         /*  76:117 */ double entry = tableau.getEntry(row.intValue(), column);
         /*  77:118 */ if ((Precision.equals(entry, 1.0D, this.maxUlps))
             && (row.equals(tableau.getBasicRow(column)))) {
           /*  78:120 */ return row;
           /*  79:    */ }
         /*  80:    */ }
       /*  81:    */ }
     /*  82:    */ }
   /*  83:125 */ return (Integer) minRatioPositions.get(0);
   /*  84:    */ }
Esempio n. 2
0
 /*  27:    */
 /*  28:    */ private Integer getPivotColumn(SimplexTableau tableau) /*  29:    */ {
   /*  30: 70 */ double minValue = 0.0D;
   /*  31: 71 */ Integer minPos = null;
   /*  32: 72 */ for (int i = tableau.getNumObjectiveFunctions(); i < tableau.getWidth() - 1; i++)
   /*  33:    */ {
     /*  34: 73 */ double entry = tableau.getEntry(0, i);
     /*  35: 74 */ if (Precision.compareTo(entry, minValue, this.maxUlps) < 0)
     /*  36:    */ {
       /*  37: 75 */ minValue = entry;
       /*  38: 76 */ minPos = Integer.valueOf(i);
       /*  39:    */ }
     /*  40:    */ }
   /*  41: 79 */ return minPos;
   /*  42:    */ }
Esempio n. 3
0
  /**
   * Returns the row with the minimum ratio as given by the minimum ratio test (MRT).
   *
   * @param tableau Simple tableau for the problem.
   * @param col Column to test the ratio of (see {@link #getPivotColumn(SimplexTableau)}).
   * @return the row with the minimum ratio.
   */
  private Integer getPivotRow(SimplexTableau tableau, final int col) {
    // create a list of all the rows that tie for the lowest score in the minimum ratio test
    List<Integer> minRatioPositions = new ArrayList<Integer>();
    double minRatio = Double.MAX_VALUE;
    for (int i = tableau.getNumObjectiveFunctions(); i < tableau.getHeight(); i++) {
      final double rhs = tableau.getEntry(i, tableau.getWidth() - 1);
      final double entry = tableau.getEntry(i, col);

      if (Precision.compareTo(entry, 0d, maxUlps) > 0) {
        final double ratio = rhs / entry;
        // check if the entry is strictly equal to the current min ratio
        // do not use a ulp/epsilon check
        final int cmp = Double.compare(ratio, minRatio);
        if (cmp == 0) {
          minRatioPositions.add(i);
        } else if (cmp < 0) {
          minRatio = ratio;
          minRatioPositions = new ArrayList<Integer>();
          minRatioPositions.add(i);
        }
      }
    }

    if (minRatioPositions.size() == 0) {
      return null;
    } else if (minRatioPositions.size() > 1) {
      // there's a degeneracy as indicated by a tie in the minimum ratio test

      // 1. check if there's an artificial variable that can be forced out of the basis
      if (tableau.getNumArtificialVariables() > 0) {
        for (Integer row : minRatioPositions) {
          for (int i = 0; i < tableau.getNumArtificialVariables(); i++) {
            int column = i + tableau.getArtificialVariableOffset();
            final double entry = tableau.getEntry(row, column);
            if (Precision.equals(entry, 1d, maxUlps) && row.equals(tableau.getBasicRow(column))) {
              return row;
            }
          }
        }
      }

      // 2. apply Bland's rule to prevent cycling:
      //    take the row for which the corresponding basic variable has the smallest index
      //
      // see http://www.stanford.edu/class/msande310/blandrule.pdf
      // see http://en.wikipedia.org/wiki/Bland%27s_rule (not equivalent to the above paper)
      //
      // Additional heuristic: if we did not get a solution after half of maxIterations
      //                       revert to the simple case of just returning the top-most row
      // This heuristic is based on empirical data gathered while investigating MATH-828.
      if (getEvaluations() < getMaxEvaluations() / 2) {
        Integer minRow = null;
        int minIndex = tableau.getWidth();
        final int varStart = tableau.getNumObjectiveFunctions();
        final int varEnd = tableau.getWidth() - 1;
        for (Integer row : minRatioPositions) {
          for (int i = varStart; i < varEnd && !row.equals(minRow); i++) {
            final Integer basicRow = tableau.getBasicRow(i);
            if (basicRow != null && basicRow.equals(row) && i < minIndex) {
              minIndex = i;
              minRow = row;
            }
          }
        }
        return minRow;
      }
    }
    return minRatioPositions.get(0);
  }