Initial commit

This commit is contained in:
2023-07-25 22:59:09 -05:00
commit 26f1a0bd5a
11 changed files with 309 additions and 0 deletions
+5
View File
@@ -0,0 +1,5 @@
add_executable(knapsack
./main.cpp
./knapsack.cpp
)
target_include_directories(knapsack PUBLIC ${CMAKE_CURRENT_LIST_DIR})
+102
View File
@@ -0,0 +1,102 @@
#include "knapsack.hpp"
#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <fstream>
namespace knapsack
{
void CheckArgumentAmount(int argc)
{
if (argc == 2) { return; }
std::cerr << "usage: knapsack path/to/file.txt" << std::endl;
exit(1);
}
bool SortByItemNumber(PossibleObject* lhs, PossibleObject* rhs)
{
return lhs->itemNumber < rhs->itemNumber;
}
void User::ReadNewFile(const char* inputFilePath)
{
// Open file
std::ifstream inputFile(inputFilePath);
if (!inputFile.is_open())
{
std::cerr << "Error opening file: " << inputFilePath << std::endl;
exit(1);
}
// Read in number of items
inputFile >> itemCount;
// Read in backpack limit
inputFile >> limit;
// Read in weight of item, then value of item for all items
int toBeStoredWeight, toBeStoredValue;
for (int i = 0; inputFile >> toBeStoredWeight >> toBeStoredValue; ++i)
{ choices.emplace_back(toBeStoredWeight, toBeStoredValue, i); }
}
void User::InputSafety(void)
{
if (itemCount == choices.size()) { return; }
std::cout << "Warning! The given object amount differs from amount read in!";
std::cout << std::endl;
}
void User::RunKnapsack(void)
{
int knapsackMatrix[itemCount + 1][limit + 1];
// Build knapsack matrix
for (int i = 0; i <= itemCount; i++)
{
for (int w = 0; w <= limit; w++)
{
if (i == 0 || w == 0) { knapsackMatrix[i][w] = 0; }
else if (choices.at(i - 1).weight <= w)
{
knapsackMatrix[i][w] = std::max(choices.at(i - 1).value +
knapsackMatrix[i - 1][w - choices.at(i - 1).weight],
knapsackMatrix[i - 1][w]);
}
else { knapsackMatrix[i][w] = knapsackMatrix[i - 1][w]; }
}
}
// Store knapsack result
int bestTotal = knapsackMatrix[itemCount][limit];
int w = limit;
for (int i = itemCount; i > 0 && bestTotal > 0; i--)
{
if (bestTotal == knapsackMatrix[i - 1][w]) { continue; }
solution.push_back(&choices.at(i - 1));
bestTotal -= choices.at(i - 1).value;
w -= choices.at(i - 1).weight;
}
}
void User::PrintResult(void)
{
std::sort(solution.begin(), solution.end(), SortByItemNumber);
std::cout << "Items used (starting from 1):" << std::endl << '\t';
for (auto it : solution) { std::cout << it->itemNumber + 1 << ' '; }
std::cout << std::endl;
std::cout << "Resulting value: " << GetSolutionValue() << std::endl;
}
int User::GetSolutionValue(void)
{
int totalValue = 0;
for (auto it : solution) { totalValue += it->value; }
return totalValue;
}
PossibleObject::PossibleObject(int inputWeight, int inputValue, int i)
{
weight = inputWeight;
value = inputValue;
itemNumber = i;
}
}
+38
View File
@@ -0,0 +1,38 @@
#ifndef KNAPSACK_HPP
#define KNAPSACK_HPP
#include <vector>
namespace knapsack
{
void CheckArgumentAmount(int argc);
struct PossibleObject
{
PossibleObject(int inputWeight, int inputValue, int i);
int itemNumber;
int weight;
int value;
};
bool SortByItemNumber(PossibleObject* lhs, PossibleObject* rhs);
class User
{
public:
void ReadNewFile(const char* inputFilePath);
void InputSafety(void);
void RunKnapsack(void);
void PrintResult(void);
int GetSolutionValue(void);
void _TestFileReadIn(std::vector<PossibleObject> testChoices);
void _TestKnapsack(void);
private:
std::vector<PossibleObject> choices;
std::vector<PossibleObject*> solution;
int limit;
int itemCount;
};
}
#endif
+13
View File
@@ -0,0 +1,13 @@
#include "knapsack.hpp"
int main(int argc, char* argv[])
{
knapsack::CheckArgumentAmount(argc);
knapsack::User newUser;
newUser.ReadNewFile(argv[1]);
newUser.InputSafety();
newUser.RunKnapsack();
newUser.PrintResult();
return 0;
}