CantidateSolution GenerateRandomStart() {
    // Hash set containing an entry for each bid
    HashSet<Integer> Avail = new HashSet<Integer>();
    Integer count = _bids.size();
    for (Integer index = 0; index < count; index++) {
      Avail.add(index);
    }

    // Generate Random Solution
    Random gen = new Random();

    // list of selected bids
    LinkedList<Integer> bidlist = new LinkedList<Integer>();

    // The total value of selected bids
    Double value = 0.0;

    // Here's the algorithym to select a random solution
    // 1. Choose a bid at random from the avaialble set.
    // 2. Put the chosen bid in the Bids list.
    // 3. Go through all the bids remaining in the available set and remove any colliding bids.
    // 4. Repeat from step 1 until no bids remain.
    // The bid list now contains a valid solution chosen at random.

    // Iterate as long as anything is left in the "available set"
    while (Avail.size() > 0) {

      // generate a random integer between 0 and the size of the Available set.
      Integer newbid = gen.nextInt(Avail.size());

      // Randomly choose an integer out of the Avail Set
      newbid = (Integer) Avail.toArray()[newbid];

      // Add the value of the chosen bid
      value += _bids.get(newbid).value;

      // Add the chosen bid to the bidList (a list of integers)
      bidlist.add(newbid);

      RemoveColidingBids(_bids.get(newbid), Avail);
    }

    CantidateSolution sol = new CantidateSolution();
    // Collections.sort(bidlist);
    sol.value = value;
    sol.bids = bidlist;
    return sol;
  }
  CantidateSolution AddOne(CantidateSolution sol, Double min) {
    CantidateSolution nextSol = (CantidateSolution) sol.clone();
    LinkedList<Integer> bidList = nextSol.bids;

    // Get the set of all available bids
    HashSet<Integer> Avail = new HashSet<Integer>();
    Integer count = _bids.size();
    for (Integer index = 0; index < count; index++) {
      Avail.add(index);
    }

    // Create the list of companies and regions
    HashSet<Integer> regions = new HashSet<Integer>();
    HashSet<Integer> companies = new HashSet<Integer>();
    Iterator<Integer> it = bidList.iterator();
    while (it.hasNext()) {
      Integer i = it.next();
      regions.addAll(_bids.get(i).region);
      companies.add(_bids.get(i).company);
    }

    RemoveColidingBids(regions, companies, min, Avail);

    Integer bestBid = -1;
    Double bestValue = 0.0;
    if (Avail.size() > 0) {
      Iterator<Integer> it2 = Avail.iterator();
      while (it2.hasNext()) {
        Integer newBid = it2.next();
        if (_bids.get(newBid).value > bestValue) {
          bestValue = _bids.get(newBid).value;
          bestBid = newBid;
        }
      }
      // Now we've got the largest extra bid
      bidList.addLast(bestBid);
      nextSol.value += bestValue;
      return nextSol;
    }
    // There were no additional coliding bids
    return sol;
  }
 void OutputResults(CantidateSolution sol) {
   try {
     sol.sort();
     BufferedWriter outFile = new BufferedWriter(new FileWriter(_outputFile));
     // outFile.write("Value : "+sol.value.toString()+"\n");
     Iterator<Integer> it = sol.bids.iterator();
     // outFile.write("Solution : ");
     while (it.hasNext()) {
       Integer i = it.next();
       outFile.write(i.toString() + " ");
     }
     outFile.write("#\n");
     outFile.close();
   } catch (IOException e) {
     System.out.println("Value : " + sol.value.toString());
     Iterator<Integer> it = sol.bids.iterator();
     System.out.print("Solution : ");
     while (it.hasNext()) {
       Integer i = it.next();
       System.out.print(i.toString() + " ");
     }
     System.out.print("#\n");
   }
 }
  // Remove one bid and add two more with a larger total
  CantidateSolution OneForTwo(CantidateSolution sol) {
    CantidateSolution nextSol = (CantidateSolution) sol.clone();
    LinkedList<Integer> bidList = nextSol.bids;
    Double value = nextSol.value;

    Integer stopBid = bidList.getFirst();
    do {
      // Hash set containing an entry for each bid
      HashSet<Integer> Avail = new HashSet<Integer>();
      Integer count = _bids.size();
      for (Integer index = 0; index < count; index++) {
        Avail.add(index);
      }

      // pull the first bid off the front
      Integer bid = bidList.removeFirst();

      // Remove that bid from the Available List
      Avail.remove(bid);
      bidList.remove(bid);
      Double removedBidValue = _bids.get(bid).value;
      value -= removedBidValue;

      // Now walk the list and remove any colisions from the Avail list
      HashSet<Integer> regions = new HashSet<Integer>();
      HashSet<Integer> companies = new HashSet<Integer>();
      Iterator<Integer> it = bidList.iterator();
      while (it.hasNext()) {
        Integer i = it.next();
        regions.addAll(_bids.get(i).region);
        companies.add(_bids.get(i).company);
      }

      // Remove coliding bids, but leave all bids irrespecive of value
      RemoveColidingBids(regions, companies, 0.0, Avail);

      if (Avail.size() > 0) {
        // This is the list of possible 1st bids
        // For each of these recalculate the colision list and see if the combination
        // of the two is bigger than the one we removed.
        Iterator<Integer> it2 = Avail.iterator();
        while (it2.hasNext()) {
          Integer oneBid = it2.next();
          Double oneValue = _bids.get(oneBid).value;
          HashSet<Integer> innerAvail = (HashSet<Integer>) Avail.clone();
          RemoveColidingBids(_bids.get(oneBid), innerAvail);
          if (innerAvail.size() > 0) {
            // Now we look for combinations that total more than the bid we removed
            Iterator<Integer> it3 = innerAvail.iterator();
            while (it3.hasNext()) {
              Integer twoBid = it3.next();
              Double twoValue = _bids.get(twoBid).value;
              if ((oneValue + twoValue) > removedBidValue) {
                // Found it
                bidList.addLast(oneBid);
                bidList.addLast(twoBid);
                value += oneValue;
                value += twoValue;
                return nextSol;
              }
            }
          }
        }
      }

      bidList.addLast(bid);
      value += removedBidValue;

    } while (bidList.getFirst() != stopBid);
    // There were no additional coliding bids
    return sol;
  }
  CantidateSolution neighborhood(CantidateSolution sol) {
    CantidateSolution nextSol = (CantidateSolution) sol.clone();

    // Now, walk through each bid in the cantidate solution
    // remove the bid from the solution
    // find the set of available bids to replace the current bid
    // If the resulting value is higher, then choose that as the next cantidate solution and
    // return

    Double value = nextSol.value;
    LinkedList<Integer> bidList = nextSol.bids;
    Integer stopBid = bidList.getFirst();

    do {
      // Hash set containing an entry for each bid
      HashSet<Integer> Avail = new HashSet<Integer>();
      Integer count = _bids.size();
      for (Integer index = 0; index < count; index++) {
        Avail.add(index);
      }

      // pull the first bid off the front
      Integer bid = bidList.removeFirst();

      // Remove that bid from the Available List
      Avail.remove(bid);
      value -= _bids.get(bid).value;
      bidList.remove(bid);
      Integer bestBid = bid;
      Double bestValue = _bids.get(bestBid).value;

      // Now walk the list and remove any colisions from the Avail list
      HashSet<Integer> regions = new HashSet<Integer>();
      HashSet<Integer> companies = new HashSet<Integer>();
      Iterator<Integer> it = bidList.iterator();
      while (it.hasNext()) {
        Integer i = it.next();
        regions.addAll(_bids.get(i).region);
        companies.add(_bids.get(i).company);
      }
      RemoveColidingBids(regions, companies, bestValue, Avail);

      if (Avail.size() > 0) {
        // We've got other bids that can replace the one removed
        // Look for one with a highestvalue
        Iterator<Integer> it2 = Avail.iterator();
        while (it2.hasNext()) {
          Integer newBid = it2.next();
          Double curValue = _bids.get(newBid).value;
          if (curValue > bestValue) {
            bestValue = curValue;
            bestBid = newBid;
          }
        }

        // If the highest-value bid is bigger than where we started then that is uphill
        if (bestValue > _bids.get(bid).value) {
          bidList.addLast(bestBid);
          value += bestValue;
          nextSol.value = value;
          // We're done!  We found some uphill
          return nextSol;
        }
      }

      bidList.addLast(bid);
      value += _bids.get(bid).value;

    } while (bidList.getFirst() != stopBid);

    // We didn't find any up-hill. Return the old best
    return sol;
  }
  CantidateSolution GenerateGoodStart(long offset) {
    // Hash set containing an entry for each bid
    HashSet<Integer> Avail = new HashSet<Integer>();
    Integer count = _bids.size();

    LinkedList<Integer> SortedBids = new LinkedList<Integer>();
    for (Integer index = 0; index < count; index++) {
      Avail.add(index);
      SortedBids.add(index);
    }

    if (offset < SortedBids.size()) {
      for (int remove = 0; remove < offset; remove++) {
        SortedBids.removeFirst();
      }
    }

    // Sort the bids
    Collections.sort(SortedBids, new RegionAvgCmp(_bids));

    // list of selected bids
    LinkedList<Integer> bidlist = new LinkedList<Integer>();

    // The total value of selected bids
    Double value = 0.0;

    Random gen = new Random();
    while (Avail.size() > 0) {
      Integer newbid;
      if (SortedBids.size() > 0) {
        newbid = SortedBids.removeFirst();
      } else {
        // generate a random integer between 0 and the size of the Available set.
        newbid = gen.nextInt(Avail.size());

        // Randomly choose an integer out of the Avail Set
        newbid = (Integer) Avail.toArray()[newbid];
      }

      // Add the value of the chosen bid
      value += _bids.get(newbid).value;

      // Add the chosen bid to the bidList (a list of integers)
      bidlist.add(newbid);

      RemoveColidingBids(_bids.get(newbid), Avail);

      // clean out our SortedBidsList
      Iterator<Integer> li = SortedBids.iterator();
      while (li.hasNext()) {
        Integer bidItem = li.next();
        if (!Avail.contains(bidItem)) {
          li.remove();
        }
      }
    }

    CantidateSolution sol = new CantidateSolution();
    // Collections.sort(bidlist);
    sol.value = value;
    sol.bids = bidlist;
    return sol;
  }