Esempio n. 1
0
void branchAndBound(knapsack &k, int maxTime)
// Implement a Branch and Bound search for an optimal solution.
// Searches for the best decision for objects n and greater, as long
// as more than maxTime seconds have not elapsed.  Tries
// to keep or not keep object n, and then iterates to n+1.  Stores
// the best solution found so far in bestSolution.  
{
	clock_t endTime, startTime = clock();

	deque<knapsack> problem;
	deque<knapsack>::iterator itr;
	int number,bestValue=0;
	knapsack bestSolution;
	double time=0;

	cout<<"Branching and Bounding"<<endl;

	// Initially, decisions have not been made about any objects,
	// so set num = 0.
	k.setNum(0);

	// Add the empty knapsack subproblem to the list
	problem.push_front(k);

	// Branch and Bound search goes here
	while (!(problem.empty()) && (time<=maxTime)) //for each object in the deque
	{
		k = problem.back(); // current instance is now the last object in the deque
		while((k.getNum()!=k.getNumObjects()) && (k.bound()> bestValue) && (time<=maxTime))
			/*if we haven't considered all the objects left and the bound of the current instance 
			is not worse than our best-so-far solution and we are not out of time*/
		{
			//delete the last object from the deque because we are currently solving it
			problem.pop_back(); 
			number=k.getNum();
			k.setNum(number+1); //we are now considering the next object
			if(k.getCostBound()-k.getCurrentCost()>k.getCost(number))
			{
				problem.push_back(k); //push the 'don't select' instacne before the take instance
				k.select(number);
			}
			problem.push_back(k); //push the remaining instance

			endTime=clock();//update current time
			time=((double)(endTime-startTime))/CLOCKS_PER_SEC;
		}
		if (k.getCurrentValue() > bestValue){// replace best values if current ones are better
			bestValue = k.getCurrentValue();
			bestSolution = k;
		}
		problem.pop_back(); //delete the last object from the deque since it is fathomed
	}


	cout << "Best value found: " << bestValue << endl;
	cout << bestSolution;
	k.outFile(bestSolution);
}
knapsack::knapsack(const knapsack &k)
// Knapsack copy constructor
{
   numObjects = k.getNumObjects();
   costBound = k.getCostBound();

   value.resize(numObjects);
   cost.resize(numObjects);
   index.resize(numObjects);
   selected.resize(numObjects);

   for (int i = 0; i < numObjects; i++)
   {
      setValue(i,k.getValue(i));
      setCost(i,k.getCost(i));
      setIndex(i,k.getIndex(i));

      if (k.isSelected(i))
	 select(i);
      else
	 unSelect(i);
   }

   setNum(k.getNum());
   currentValue = k.getCurrentValue();
   currentCost = k.getCurrentCost();
}
double greedyKnapsack(knapsack &k){
	MaxHeap<float, int>* heap = new MaxHeap<float, int>(&compare);
	for(int counter = 0; counter < k.getNumObjects(); counter++){
		double key = (double) k.getValue(counter) / k.getCost(counter);
		heap->add(key, counter);
	}
	while(! heap->empty()){
		int next = heap->extractMaxHeapMaximum();
		if(k.getCost(next) + k.getCurrentCost() <= k.getCostBound()){
			k.select(next);
		}
	}
	return k.getCurrentValue();
}
void printSolution(knapsack &k, string filename)
// Prints out the solution.
{
	ofstream myfile;
	myfile.open (filename.c_str());
	myfile << "------------------------------------------------" << endl;

	myfile << "Total value: " << k.getCurrentValue() << endl;
	myfile << "Total cost: " << k.getCurrentCost() << endl << endl;

   // Print out objects in the solution
   for (int i = 0; i < k.getNumObjects(); i++)
      if (k.isSelected(i))
    	  myfile << i << "  " << k.getValue(i) << " " << k.getCost(i) << endl;

   myfile << endl;
   myfile.close();
}