Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Breadth-first search #36

Merged
merged 16 commits into from
Sep 26, 2018
11 changes: 5 additions & 6 deletions docs/choice-dictionary.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,14 @@ delete cd;
```
<br>

Iterator
ChoiceDictionaryIterator
===

An Iterator is used to iterate through all bits set to 1 in a choice dictionary.
It supports the so-called *more* operation that returns true if the choice dictionary contains more bits set to 1, aswell as the *next* operation that returns the index of the next arbitrary bit.<br>
If there are changes made to the choice dictionary during the iteration process, the iterator may return wrong results.
A ChoiceDictionaryIterator is used to iterate through all bits set to 1 in a choice dictionary.
It supports the so-called *more* operation that returns true if the choice dictionary contains more bits set to 1, aswell as the *next* operation that returns the index of the next arbitrary bit.

## Operations
* init: Initializes the Iterator.
* init: Initializes the ChoiceDictionaryIterator.
* more: Returns true if there are more bits set to 1.
* next: Returns the next arbitrary bit position that is set to 1.

Expand All @@ -49,7 +48,7 @@ If there are changes made to the choice dictionary during the iteration process,

```cpp
ChoiceDictionary* cd = new ChoiceDictionary(12);
Iterator* it = new Iterator(cd);
ChoiceDictionaryIterator* it = new ChoiceDictionaryIterator(cd);
cd->insert(0); // Indexing beginns with 0
cd->insert(4);
cd->insert(7);
Expand Down
13 changes: 11 additions & 2 deletions include/sealib/_types.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
#ifndef SEALIB__TYPES_H_
#define SEALIB__TYPES_H_
#include <tuple>

// the standard numeric type (used mainly for node names)
typedef unsigned int uint;

// a pair of numbers (used mainly for stack management)
typedef std::tuple<uint, uint> Pair;
// typedef std::tuple<uint, uint> Pair;
class Pair {
private:
uint v1, v2;

public:
Pair() : v1(), v2() {}
Pair(uint a, uint b) : v1(a), v2(b) {}
uint head() { return v1; }
uint tail() { return v2; }
};

#endif // SEALIB__TYPES_H_
2 changes: 2 additions & 0 deletions include/sealib/basicgraph.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ class Basicgraph : public Graph {
*/
Basicgraph(Node *_nodes, unsigned int _order);

~Basicgraph();

/**
* Getter for a specific node in the nodes array.
* @param u index in the nodes array.
Expand Down
85 changes: 85 additions & 0 deletions include/sealib/bfs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
#ifndef SEALIB_BFS_H_
#define SEALIB_BFS_H_
#include <stdexcept>
#include <vector>
#include "sealib/_types.h"
#include "sealib/compactarray.h"
#include "sealib/graph.h"
#include "sealib/iterator.h"

#define BFS_WHITE 0
#define BFS_GRAY1 1
#define BFS_GRAY2 2
#define BFS_BLACK 3

typedef void (*UserFunc1)(uint);
typedef void (*UserFunc2)(uint, uint);

#define BFS_NOP_PROCESS (UserFunc1)0
#define BFS_NOP_EXPLORE (UserFunc2)0

namespace Sealib {
/**
* Run a breadth-first search over a given graph, while executing the two
* given user functions.
* EFFICIENCY: O(n+m) time, O(n) bits
*
* The BFS is implemented as an iterator. To start the iterator, call init().
* To see if there are more results in this component, call more().
* To get the next result, call next().
* To move the search to a possible next component, call nextComponent().
*/
class BFS : Iterator<Pair> {
public:
/**
* Initialize or reset the BFS to the beginning.
*/
void init() override;

/**
* Check if there is a component that has not been evaluated. If so, the BFS
* will continue there.
* @return true if a component was found, false if all nodes have been
* evaluated
*/
bool nextComponent();

/**
* @return true if this component has unevaluated nodes, false if the
* component is all black
*/
bool more() override;

/**
* Get the next node from the current component.
* @return a tuple (u,d) where d is the distance of u to the component's
* starting node
* @throws std::logic_error if no next node is available
*/
Pair next() override;

/**
* Create a new BFS iterator.
* @param g the graph to run the BFS over
* @param preprocess to be executed before processing a node u
* @param preexplore to be executed before exploring an edge (u,v)
*/
BFS(Graph *graph, UserFunc1 pp, UserFunc2 pe);

~BFS();

private:
Graph *g;
uint n;
CompactArray *color;
uint u, dist;
unsigned innerGray, outerGray;
UserFunc1 preprocess;
UserFunc2 preexplore;

bool hasGrayNode();
uint getGrayNode();
};

} // namespace Sealib
#endif // SEALIB_BFS_H_
61 changes: 61 additions & 0 deletions include/sealib/choicedictionaryiterator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#ifndef SEALIB_CHOICEDICTIONARYITERATOR_H_
#define SEALIB_CHOICEDICTIONARYITERATOR_H_

#include "sealib/iterator.h"
#include "sealib/choicedictionary.h"

#define SHIFT_OFFSET 1UL

namespace Sealib {
/**
* Iteration class to return all bit positions of a choice dictionary that
* are set to 1.
*
* @author Dennis Appel
*/
class ChoiceDictionaryIterator : Iterator<unsigned long int> {
private:
/**
* @param primaryWord Value of the currently used word in primary.
* @param secondaryWord Value of the currently used word in secondary.
* @param primaryIndex Index of the currently used word in primary.
* @param secondaryIndex Index of the currently used word in secondary.
* @param pointer currently used pointer Position.
* @param choicedictionary Pointer to an existing choice dictionary.
*/
unsigned long int primaryWord, secondaryWord, pointer, primaryIndex, secondaryIndex;
ChoiceDictionary *choicedictionary;

bool hasNextSecondary();

void setNextSecondaryWord();

void setNextPrimaryWord();

public:
/**
* Creates an Iterator for a choice dictionary.
* @param _choicedictionary Pointer to an existing choice dictionary.
*/
explicit ChoiceDictionaryIterator(ChoiceDictionary *_choicedictionary);

/**
* Initializes the iterator.
*/
void init();

/**
* Returns true when there are more bits that are set to 1 in the choice
* dictionary and updates the used words if neccessary.
*/
bool more();

/**
* Returns the next index of a bit set to 1.
*/
unsigned long int next();

~ChoiceDictionaryIterator();
};
} // namespace Sealib
#endif // SEALIB_CHOICEDICTIONARYITERATOR_H_
24 changes: 14 additions & 10 deletions include/sealib/dfs.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#ifndef SEALIB_DFS_H_
#define SEALIB_DFS_H_

#include <sstream>
#include <stack>
#include <tuple>
#include "sealib/_types.h"
#include "sealib/compactarray.h"
#include "sealib/graph.h"
Expand Down Expand Up @@ -37,7 +37,6 @@ namespace Sealib {
* - standardDFS: the normal DFS, uses implicit recursion stack
* - nBitDFS: space-efficient DFS, explicit segmented stack
*
* @author Simon Heuser
*/
class DFS {
public:
Expand All @@ -49,6 +48,7 @@ class DFS {
* @param preexplore to be executed before exploring an edge (u,v)
* @param postexplore to be executed after exploring an edge (u,v)
* @param postprocess to be executed after processing a node u
* @author Simon Heuser
*/
static void standardDFS(Graph *g, UserFunc1 preprocess, UserFunc2 preexplore,
UserFunc2 postexplore, UserFunc1 postprocess);
Expand All @@ -61,18 +61,22 @@ class DFS {
* @param preexplore to be executed before exploring an edge (u,v)
* @param postexplore to be executed after exploring an edge (u,v)
* @param postprocess to be executed after processing a node u
* @author Simon Heuser
*/
static void nBitDFS(Graph *g, UserFunc1 preprocess, UserFunc2 preexplore,
UserFunc2 postexplore, UserFunc1 postprocess);

/**
* Runs an inplace DFS in linear time over a graph that is given in a special representation. <br>
* EFFICIENCY: O(n+m) time, O(log n) bits
* @param graph Graph A graph in a swapped begin pointer representation.
* @param startVertex startVertex The begin of the DFS tree.
*/
static void runLinearTimeInplaceDFS(unsigned int* graph, UserFunc1 preProcess,
UserFunc1 postProcess, unsigned int startVertex);
/**
* Runs an inplace DFS in linear time over a graph that is given in a special
* representation. <br>
* EFFICIENCY: O(n+m) time, O(log n) bits
* @param graph Graph A graph in a swapped begin pointer representation.
* @param startVertex startVertex The begin of the DFS tree.
* @author Simon Schniedenharn
*/
static void runLinearTimeInplaceDFS(unsigned int *graph, UserFunc1 preProcess,
UserFunc1 postProcess,
unsigned int startVertex);
};
} // namespace Sealib
#endif // SEALIB_DFS_H_
2 changes: 2 additions & 0 deletions include/sealib/graph.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ class Graph {
* @return Returns the order of the graph, i.e, the total number of vertices.
*/
virtual unsigned int getOrder() = 0;

virtual ~Graph() {}
};
} // namespace Sealib
#endif // SEALIB_GRAPH_H_
2 changes: 1 addition & 1 deletion include/sealib/graphcreator.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class GraphCreator {
* @param order number of nodes the graph should contain
* @param degreePerNode the degree of each node; the edges will go to any
* random node
* @return the resulting graph G: n = order, m = degreePerNode * order
* @return the resulting graph G (n = order, m = degreePerNode*order)
* @author Simon Heuser
*/
static Basicgraph *createRandomFixed(unsigned int order,
Expand Down
71 changes: 23 additions & 48 deletions include/sealib/iterator.h
Original file line number Diff line number Diff line change
@@ -1,59 +1,34 @@
#ifndef SEALIB_ITERATOR_H_
#define SEALIB_ITERATOR_H_

#include "sealib/choicedictionary.h"

#define SHIFT_OFFSET 1UL

namespace Sealib {
/**
* Iteration class to return all bit positions of a choice dictionary that
* are set to 1.
* @author Dennis Appel
* An iterator interface to be used by several classes in this library.
* @param T the element type that this iterator iterates over
* @author Simon Heuser
*/
template <class T>
class Iterator {
private:
/**
* @param primaryWord Value of the currently used word in primary.
* @param secondaryWord Value of the currently used word in secondary.
* @param primaryIndex Index of the currently used word in primary.
* @param secondaryIndex Index of the currently used word in secondary.
* @param pointer currently used pointer Position.
* @param choicedictionary Pointer to an existing choice dictionary.
*/
unsigned long int primaryWord, secondaryWord, pointer, primaryIndex, secondaryIndex;
ChoiceDictionary *choicedictionary;

bool hasNextSecondary();

void setNextSecondaryWord();

void setNextPrimaryWord();

public:
/**
* Creates an Iterator for a choice dictionary.
* @param _choicedictionary Pointer to an existing choice dictionary.
*/
explicit Iterator(ChoiceDictionary *_choicedictionary);

/**
* Initializes the iterator.
*/
void init();

/**
* Returns true when there are more bits that are set to 1 in the choice
* dictionary and updates the used words if neccessary.
*/
bool more();

/**
* Returns the next index of a bit set to 1.
*/
unsigned long int next();

~Iterator();
/**
* Initialize the iterator.
*/
virtual void init();

/**
* Check if the iterator has another element that can be retrieved.
* @return true if there is another element, false otherwise
*/
virtual bool more();

/**
* Get the next element from this iterator
* @return the next element
* @throws std::logic_error if there are no more elements
*/
virtual T next();

virtual ~Iterator() {}
};
} // namespace Sealib
#endif // SEALIB_ITERATOR_H_
4 changes: 4 additions & 0 deletions src/basicgraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,7 @@ unsigned int Basicgraph::getOrder() {
}

Basicgraph::Basicgraph(Node *_nodes, unsigned int _order) : nodes(_nodes), order(_order) { }

Basicgraph::~Basicgraph() {
delete nodes;
}
Loading