This code implements both the First-Fit algorithm (from A-Level Further Decision) amd the First-Fit-Decreasing algorithm.
The First-Fit decreasing algorithm also relies on a sorting algorithm, for this, I implemented the Bubble Sort (warning, this has an O(n^2) difficulty, not for production workplaces)
Virtually the whole main() function can be ignore if you are going to use the different classes and functions that I've written here!
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class Obj
{
public:
int size = 0;
std::string name = "0";
explicit Obj() {}
explicit Obj(int size, std::string name)
{
this->size = size;
this->name = name;
}
};
class Bin
{
public:
int capacity = 0;
int total_used = 0;
vector<Obj> objects = std::vector<Obj>(0);
explicit Bin() {}
explicit Bin(int capacity)
{
this->capacity = capacity;
this->total_used = 0;
}
template <typename T>
bool RoomFor(T obj)
{
if (total_used + obj.size <= capacity)
{
return true;
}
else
{
return false;
}
}
bool RoomForInt(int obj)
{
if (total_used + obj <= capacity)
{
return true;
}
else
{
return false;
}
}
template <typename T>
void Append(T obj)
{
if (!this->RoomFor(obj))
{
throw std::invalid_argument("No room left in bin.");
}
if (typeid(T) == typeid(int))
{
Obj temp_Obj = Obj(obj);
this->objects.push_back(obj);
}
else if (typeid(T) == typeid(obj))
{
this->objects.push_back(obj);
}
}
friend auto operator<<(std::ostream &os, Bin const &b) -> std::ostream &
{
std::string rtstring = "";
for (int i = 0; i < b.objects.size(); i++)
{
if (i != 0)
{
rtstring += ", ";
}
rtstring += b.objects[i].name;
}
return os << rtstring;
}
};
float lowerBound(vector<Obj> objs, int bin_size)
{
int sum = 0;
for (int i = 0; i < bin_size; i++)
{
sum += objs[i].size;
}
return (float)sum / (float)bin_size;
}
void FirstFitFunctioning(vector<Obj> objs, vector<Bin> bins)
{
bool appended = false;
for (int i = 0; i < objs.size(); i++)
{
appended = false;
std::cout << objs[i].size << std::endl;
for (int j = 0; j < bins.size(); j++)
{
if (bins[j].RoomFor(objs[i]))
{
appended = true;
bins[j].Append(objs[i]);
break;
}
}
if (appended == false)
{
throw std::invalid_argument("ERROR COULDNT FIT");
}
}
for (int i = 0; i < bins.size(); i++)
{
std::cout << i << ": " << bins[i] << std::endl;
}
}
vector<Obj> ReOrder(vector<Obj> objs)
{
bool sorted = false;
int swapped = 0;
while (!sorted)
{
sorted = false;
swapped = 0;
for (int i = 0; i < objs.size() - 1; i++)
{
if (objs[i].size < objs[i + 1].size)
{
swapped += 1;
swap(objs[i], objs[i + 1]);
}
}
if (swapped == 0)
{
sorted = true;
}
}
return objs;
}
void FirstFitDecreasingFunctioning(vector<Obj> objs, vector<Bin> bins)
{
objs = ReOrder(objs);
FirstFitFunctioning(objs, bins);
}
int main()
{
std::cout << "Hello World" << std::endl;
std::cout << "How many objects do you have? ";
int num_objs;
std::cin >> num_objs;
std::cout << std::endl;
int temp_size;
std::string temp_size_str;
std::string temp_str_name;
vector<Obj> objects = std::vector<Obj>(0);
for (int i = 0; i < num_objs; i++)
{
std::cout << i << ": ";
std::cin.ignore();
std::getline(std::cin, temp_str_name);
if (temp_str_name.empty())
{
temp_str_name = std::to_string(i);
}
std::cout << i << " size: ";
std::getline(std::cin, temp_size_str);
// https://www.systutorials.com/how-to-remove-newline-characters-from-a-string-in-c/
temp_size_str.erase(std::remove(temp_size_str.begin(), temp_size_str.end(), '\n'), temp_size_str.end());
temp_size = std::stoi(temp_size_str);
objects.push_back(Obj(temp_size, temp_str_name));
}
std::cout << "How many bins do you have? ";
std::string bin_num_str;
std::getline(std::cin, bin_num_str);
int bin_num;
bin_num = std::stoi(bin_num_str);
std::cout << "How big are the bins? ";
std::string bin_size_str;
std::getline(std::cin, bin_size_str);
int bin_size;
bin_size = std::stoi(bin_size_str);
vector<Bin> bins = std::vector<Bin>(0);
for (int i = 0; i < bin_num; i++)
{
bins.push_back(Bin(bin_size));
}
std::cout << "Total Capacity: " << bin_size * bin_num << std::endl;
std::cout << "Lower Bound: " << lowerBound(objects, bin_size) << std::endl;
std::cout << "First Fit: " << std::endl;
FirstFitFunctioning(objects, bins);
std::cout << "First Fit: " << std::endl;
FirstFitDecreasingFunctioning(objects, bins);
return 0;
}