91 lines
3.5 KiB
C++
91 lines
3.5 KiB
C++
#include "backpack.h"
|
|
#include <algorithm>
|
|
#include <cmath>
|
|
|
|
/* Optimized insertion sort algorithm utilizing the Item's getRatio() function
|
|
*/
|
|
void Backpack::sortAvailableItems() {
|
|
int i = 0;
|
|
while (i < (int)this->availableItems.size()) {
|
|
Item x = this->availableItems[i];
|
|
int j = i - 1;
|
|
while (j >= 0 && this->availableItems[j].getRatio() < x.getRatio()) {
|
|
this->availableItems[j + 1] = this->availableItems[j];
|
|
j--;
|
|
}
|
|
this->availableItems[j + 1] = x;
|
|
i++;
|
|
}
|
|
}
|
|
|
|
/* Iterates through all packed items and returns the total value */
|
|
int Backpack::getValuePacked() {
|
|
int total = 0;
|
|
for (int i = 0; i < (int)this->packedItems.size(); i++) {
|
|
total += this->packedItems[i].value;
|
|
}
|
|
return total;
|
|
}
|
|
|
|
/* the algorithm to pack the backpack */
|
|
void Backpack::greedyPack(bool continuous) {
|
|
this->packedItems
|
|
.clear(); /* resets the packedItems -> removes all elements! */
|
|
this->currentWeight = 0; /* ...and also sets the current weight to 0.0 */
|
|
|
|
this->sortAvailableItems(); // sort the available items first!
|
|
const char *text = "";
|
|
float partialValue = 0.0f;
|
|
float partialWeight = 0.0f;
|
|
if (!continuous) {
|
|
text = "non-";
|
|
}
|
|
std::cout << "Backpack has been packed " << text
|
|
<< "continuously:\n"; // output
|
|
std::cout << "\t\tWeight\tValue\n"; // output
|
|
std::cout << "---------------------------------------------\n"; // output
|
|
|
|
for (int i = 0; i < (int)this->availableItems.size();
|
|
i++) { // iterate through all available items
|
|
if (this->currentWeight + (float)this->availableItems[i].weight <=
|
|
this->maxWeight) { // check if the item still fits in the backpack
|
|
this->packedItems.push_back(
|
|
this->availableItems[i]); // and if so, put it in there (by adding it
|
|
// to this->packedItems)
|
|
currentWeight +=
|
|
this->availableItems[i].weight; // adjust currentWeight accordingly
|
|
std::cout << "\t" << this->availableItems[i].name << ":\t"
|
|
<< this->availableItems[i].weight << "\t"
|
|
<< this->availableItems[i].value
|
|
<< "\t Factor: 1.00\n"; // output
|
|
} else if (continuous) {
|
|
float factor = (float)(this->maxWeight - this->currentWeight) /
|
|
this->availableItems[i].weight;
|
|
factor = std::round(factor * 100) / 100;
|
|
std::cout << "\t" << this->availableItems[i].name << ":\t"
|
|
<< this->availableItems[i].weight << "\t"
|
|
<< this->availableItems[i].value << "\t Factor: " << factor
|
|
<< std::endl;
|
|
partialWeight = this->availableItems[i].weight * factor;
|
|
partialValue = this->availableItems[i].value * factor;
|
|
break;
|
|
}
|
|
if ((this->currentWeight - this->maxWeight) ==
|
|
0) { // if the backpack is completely full, the loop can be exited -
|
|
// small optimization
|
|
break;
|
|
}
|
|
}
|
|
std::cout << "---------------------------------------------\n"; // output
|
|
std::cout << "\tTotal:\t" << this->currentWeight + partialWeight << "\t"
|
|
<< this->getValuePacked() + partialValue << "\n"; // output
|
|
}
|
|
|
|
void Backpack::printItems() {
|
|
for (int i = 0; i < (int)this->availableItems.size(); i++) {
|
|
std::cout << this->availableItems[i].name << "\t"
|
|
<< this->availableItems[i].weight << "\t"
|
|
<< this->availableItems[i].value << "\t"
|
|
<< this->availableItems[i].getRatio() << "\n";
|
|
}
|
|
} |