// SAA overrides this method
  // here we remove scnenarios as we use them to make sure each policy is generated using its own
  // scenarios.
  // so we call getIdealBids which uses m_numScenarios most recent scenarios and then remove them so
  // the next call to getIdealBids gets different scenarios
  public ArrayList<Bid> getBids() {
    Misc.myassert(!(numPolicies == 1 && numEvaluations != 0));

    ArrayList<Bid>[] policies = new ArrayList[numPolicies];
    for (int i = 0; i < numPolicies; i++) {
      policies[i] = getIdealBids();
      repository.removeXMostRecent(numScenarios);
    }

    if (numPolicies == 1) return policies[0];

    Misc.println("Algorithm.getBids : evaluating more than 1 policies...");

    // evaluation scenarios
    Priceline[] evaluationScenarios = repository.removeXMostRecent(numEvaluations);

    // evaluate policies
    int bestPolicy = -1;
    float bestEvaluation = 0;
    for (int i = 0; i < numPolicies; i++) {

      float evaluation = evaluate(policies[i], evaluationScenarios);
      if (bestPolicy == -1 || evaluation > bestEvaluation) {
        bestPolicy = i;
        bestEvaluation = evaluation;
      }
    }

    // this is to make sure we do not generate extra scenarios.
    // also see the comment at the top of the method: we need to generate enough scenarios otherwise
    // we won't have enough for all policies - vn
    Misc.myassert(repository.getAvailableScenarios().length == 0);

    Misc.println("Algorithm.getBids : best policy = " + bestPolicy);

    return policies[bestPolicy];
  }
  // evaluates a policy (an ArrayList of Bids)
  public float evaluate(ArrayList<Bid> bids, Priceline[] evaluationScenarios) {
    float ret = 0;
    for (int i = 0; i < numEvaluations; i++) {
      Misc.println("Algorithm.evaluate : scenario " + i);
      // evaluationScenarios[i].priceline.printHotel();

      float bank = 0;
      float cost = 0;
      TACCollection hown = new TACCollection(repository.getOwnCollection());

      for (int j = 0; j < bids.size(); j++) {
        Bid b = bids.get(j);
        int auction = b.getAuction();

        switch (Constants.auctionType(auction)) {
          case Constants.TYPE_FLIGHT:
            for (int k = 0; k < b.getNoBidPoints(); k++) {
              // float currentPrice = m_dr.getQuote(auction).getAskPrice();
              float currentPrice =
                  evaluationScenarios[i]
                      .currBuyPrice[auction]; // expected min price - lower than current price
              if (b.getPrice(k) >= currentPrice) {
                int q = b.getQuantity(k);
                Misc.myassert(1 == q); // comment out if causes problems - vn
                hown.setOwn(auction, hown.getOwn(auction) + q);
                bank -= q * currentPrice;
                cost += q * currentPrice;
              }
            }
            break;

          case Constants.TYPE_HOTEL:
            // It can be happen if the calculation takes more than 1 minute.
            // In that case, we just ignore the bid. sjlee.
            // Because it is not a serious bug and it can happen frequently,
            // it would be innocuous to continue this algorithm.
            if (repository.isAuctionClosed(auction)) {
              Misc.error(
                  "we are bidding on a closed hotel. a "
                      + auction
                      + " we own "
                      + hown.getOwn(auction));
              break;
              // Misc.myassert(false);
            }

            for (int k = 0; k < b.getNoBidPoints(); k++) {
              float closingPrice = evaluationScenarios[i].currBuyPrice[auction];
              if (b.getPrice(k) >= closingPrice) {
                int q = b.getQuantity(k);
                Misc.myassert(1 == q); // comment out if causes problems - vn
                hown.setOwn(auction, hown.getOwn(auction) + q);
                bank -= q * closingPrice;
                cost += q * closingPrice;
              }
            }
            break;

          case Constants.TYPE_EVENT:
            // ignore!!
            break;
        }
      }

      TACCollection forsale = Constants.forSale();
      for (int j = 0; j < Constants.AUCTION_MAX; j++) {
        forsale.setOwn(j, 0);
      }

      Completion c =
          completer.computeCompletion(
              repository.getClientPrefs(), hown, forsale, evaluationScenarios[i]);

      for (int a = 0; a < Constants.AUCTION_MAX; a++) {
        Misc.myassert(0 == c.getBidPolicy().getQuantity(a));
        Misc.myassert(0 == c.getAskPolicy().getQuantity(a));
      }

      bank += c.objectiveValue;
      ret += bank;
    }

    return (ret / (float) numEvaluations);
  }