Skip to content

Commit

Permalink
Revised graph to have adjacency matrix instead of list for way more e…
Browse files Browse the repository at this point in the history
…fficient allocation
  • Loading branch information
rowanG077 committed Nov 12, 2018
1 parent 0f6b6c8 commit 104db9d
Show file tree
Hide file tree
Showing 14 changed files with 332 additions and 248 deletions.
26 changes: 16 additions & 10 deletions include/BoxNesting/Algorithm.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#pragma once

#include <BoxNesting/Box.hpp>
#include <Graph/Graph.hpp>
#include <Graph/BipartiteGraph.hpp>

/**
* @brief Contains code for the boxnesting problem
Expand All @@ -14,11 +14,6 @@ namespace BoxNesting
class Algorithm
{
public:
/**
* @brief Construct a new Algorithm object with the default constructor
*/
Algorithm() = default;

/**
* @brief function that runs the boxNesting algorithm and returns the number
* of visible boxes
Expand All @@ -38,9 +33,9 @@ class Algorithm
*
* @param boxes the set of boxes that will be used to create the graph
*
* @return Graph::Graph<Box> the graph of type BoxNesting::Box
* @return the graph of type BoxNesting::Box
*/
[[nodiscard]] Graph::Graph<Box> createGraphFromBoxes(const std::vector<Box>& boxes) const;
[[nodiscard]] Graph::BipartiteGraph<Box> createGraphFromBoxes(const std::vector<Box>& boxes) const;

private:
/**
Expand All @@ -53,8 +48,19 @@ class Algorithm
*
* @return Whether pairs could be made
*/
bool kuhn(
const Graph::Graph<Box>& graph, uint16_t vertex, std::vector<bool>& used, std::vector<int32_t>& pairs) const;
bool kuhn(uint16_t vertex) const;

private:
/**
* @brief Graph generated by the boxes
*/
mutable Graph::BipartiteGraph<Box> graph;

/**
* @brief Contains
*/
mutable std::vector<bool> used;
mutable std::vector<int32_t> pairs;
};

} // namespace BoxNesting
4 changes: 1 addition & 3 deletions include/BoxNesting/Box.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,7 @@ class Box
*
* @return array containing the side lengths ordered from smallest to largest
*/
[[nodiscard]] const std::array<float, 3>& getSideLengths() const {
return this->sideLengths;
}
[[nodiscard]] const std::array<float, 3>& getSideLengths() const { return this->sideLengths; }

/**
* @brief The minimum length that a side of a box may have
Expand Down
84 changes: 84 additions & 0 deletions include/Graph/AdjacencyMatrix.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
#pragma once

#include <exception>
#include <vector>

/**
* @brief Contains generic code that represents a graph and its properties
*/
namespace Graph
{
/**
* @brief Class that can be used to store a 2d array continously in memory
*
* @tparam T The type to store in the array
*/
template<class T> class AdjacencyMatrix
{
public:
/**
* @brief Construct a new empty AdjacencyMatrix object
*/
AdjacencyMatrix() : data(0)
{

}

/**
* @brief Construct a new AdjacencyMatrix object
*
* @param l The amount of left vertices
* @param r The amount of right vertices
*/
AdjacencyMatrix(size_t l, size_t r) : data(l * r), leftCount(l), rightCount(r)
{

}

/**
* @brief Get element at specified indices
*
* @param l The left vertex index
* @param r The right vertex index
*
* @throws std::out_of_range if index is out of range
*
* @return Value at that index
*/
[[nodiscard]] T& at(size_t l, size_t r)
{
return this->data.at(l * this->rightCount + r);
}

/**
* @brief Get const element at specified indices
*
* @param l The left vertex index
* @param r The right vertex index
*
* @throws std::out_of_range if index is out of range
*
* @return Const value at that index
*/
[[nodiscard]] const T& at(size_t l, size_t r) const {
return this->data.at(l * this->rightCount + r);
}

private:
/**
* @brief Contains the data of the adjacencyMatrix
*/
std::vector<T> data;

/**
* @brief Contains the amount of left vertices
*/
size_t leftCount = 0;

/**
* @brief Contains the amount of right vertices
*/
size_t rightCount = 0;
};

} // namespace Graph
96 changes: 96 additions & 0 deletions include/Graph/BipartiteGraph.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
#pragma once

#include <Graph/AdjacencyMatrix.hpp>
#include <Graph/Vertex.hpp>

#include <vector>

/**
* @brief Contains generic code that represents a graph and its properties
*/
namespace Graph
{
/**
* @brief template class representing a Bipartite graph
*
* @tparam T The type of the value to contain in the vertices.
*/
template<class T> class BipartiteGraph
{
public:
/**
* @brief Construct a new empty bipartite graph
*/
BipartiteGraph() = default;

/**
* @brief Construct a new Bipartite Graph object from two sets of vertices
*
* @param leftVertices The left part of the bipartite graph
* @param rightVertices The right aprt of the bipartite graph
*/
BipartiteGraph(std::vector<Vertex<T>> leftVertices, std::vector<Vertex<T>> rightVertices);

/**
* @brief function that adds an edge to the graph
*
* @throw std::logic_error If v1 or v2 are vertices that are not in the graph.
*
* @param v1 source vertex index of the edge must be in the left vertices
* @param v2 destination vertex index of the edge must be in the right vertices
*/
void addEdge(uint16_t v1, uint16_t v2);

/**
* @brief function that checks if there is an edge between two vertices.
*
* @throw std::logic_error If v1 or v2 are vertices that are not in the graph.
*
* @param v1 the source vertex index of the edge must be in the left vertices
* @param v2 the destination vertex index of the edge must be in the left vertices
* @return true if there is an edge
* @return false if there is no edge
*/
[[nodiscard]] bool isEdgeBetween(uint16_t v1, uint16_t v2) const;

/**
* @brief Getter for the adjacency list object
*
* @return The adjacency list by reference
*/
[[nodiscard]] const AdjacencyMatrix<uint8_t>& getAdjacencyMatrix() const noexcept;

/**
* @brief Get the left Vertices of the bipartite graph
*
* @return The left vertices of the bipartite graph
*/
[[nodiscard]] const std::vector<Vertex<T>>& getLeftVertices() const noexcept;
/**
* @brief Get the rigt Vertices of the bipartite graph
*
* @return The right vertices of the bipartite graph
*/
[[nodiscard]] const std::vector<Vertex<T>>& getRightVertices() const noexcept;

private:
/**
* @brief Contains the left vertices of the graph
*/
std::vector<Vertex<T>> leftVertices;

/**
* @brief Contains the rights vertices of the graph
*/
std::vector<Vertex<T>> rightVertices;

/**
* @brief Contains the edges between the left and right vertices
* The vector specialization of bool is broken so we use uint8_t instead of bool
*/
AdjacencyMatrix<uint8_t> adjacencyMatrix;
};

} // namespace Graph

#include <Graph/BipartiteGraph.ipp>
48 changes: 48 additions & 0 deletions include/Graph/BipartiteGraph.ipp
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#include <Graph/BipartiteGraph.hpp>

#include <algorithm>
#include <exception>

namespace Graph
{

template <class T>
BipartiteGraph<T>::BipartiteGraph(std::vector<Vertex<T>> leftVertices, std::vector<Vertex<T>> rightVertices)
: leftVertices(std::move(leftVertices)),
rightVertices(std::move(rightVertices)),
adjacencyMatrix(AdjacencyMatrix<uint8_t>(this->leftVertices.size(), this->rightVertices.size()))
{

}

template <class T>
void BipartiteGraph<T>::addEdge(uint16_t v1, uint16_t v2)
{
this->adjacencyMatrix.at(v1, v2) = true;
}

template <class T>
bool BipartiteGraph<T>::isEdgeBetween(uint16_t v1, uint16_t v2) const
{
return this->adjacencyMatrix.at(v1, v2);
}

template <class T>
const AdjacencyMatrix<uint8_t>& BipartiteGraph<T>::getAdjacencyMatrix() const noexcept
{
return this->adjacencyMatrix;
}

template <class T>
const std::vector<Vertex<T>>& BipartiteGraph<T>::getLeftVertices() const noexcept
{
return this->leftVertices;
}

template <class T>
const std::vector<Vertex<T>>& BipartiteGraph<T>::getRightVertices() const noexcept
{
return this->rightVertices;
}

} // namespace Graph
80 changes: 0 additions & 80 deletions include/Graph/Graph.hpp

This file was deleted.

Loading

0 comments on commit 104db9d

Please sign in to comment.