Initial commit
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
add_executable(knapsack
|
||||
./main.cpp
|
||||
./knapsack.cpp
|
||||
)
|
||||
target_include_directories(knapsack PUBLIC ${CMAKE_CURRENT_LIST_DIR})
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user