1
0
mirror of https://github.com/paboyle/Grid.git synced 2025-12-29 08:54:43 +00:00

Hadrons: significant overhaul of the object registration system, previous version didn't allow dry runs

This commit is contained in:
2016-05-07 13:19:38 -07:00
parent 2c226753ab
commit bb580ae077
21 changed files with 364 additions and 249 deletions

View File

@@ -52,7 +52,7 @@ public:
typedef std::pair<T, T> Edge;
public:
// constructor
Graph(void) = default;
Graph(void);
// destructor
virtual ~Graph(void) = default;
// access
@@ -71,7 +71,7 @@ public:
std::vector<T> getParents(const T &value) const;
std::vector<T> getRoots(void) const;
std::vector<Graph<T>> getConnectedComponents(void) const;
std::vector<T> topoSort(void);
std::vector<T> topoSort(const bool randomize = false);
std::vector<std::vector<T>> allTopoSort(void);
// I/O
friend std::ostream & operator<<(std::ostream &out, const Graph<T> &g)
@@ -97,7 +97,9 @@ private:
void unmarkAll(void);
bool isMarked(const T &value) const;
const T * getFirstMarked(const bool isMarked = true) const;
const T * getRandomMarked(const bool isMarked = true);
const T * getFirstUnmarked(void) const;
const T * getRandomUnmarked(void);
// prune marked/unmarked vertices
void removeMarked(const bool isMarked = true);
void removeUnmarked(void);
@@ -105,8 +107,9 @@ private:
void depthFirstSearch(void);
void depthFirstSearch(const T &root);
private:
std::map<T, bool> isMarked_;
std::set<Edge> edgeSet_;
std::map<T, bool> isMarked_;
std::set<Edge> edgeSet_;
std::mt19937 gen_;
};
// build depedency matrix from topological sorts
@@ -121,6 +124,15 @@ makeDependencyMatrix(const std::vector<std::vector<T>> &topSort);
* in the worst case E = V^2
*/
// constructor /////////////////////////////////////////////////////////////////
template <typename T>
Graph<T>::Graph(void)
{
std::random_device rd;
gen_.seed(rd());
}
// access //////////////////////////////////////////////////////////////////////
// complexity: log(V)
template <typename T>
@@ -297,6 +309,37 @@ const T * Graph<T>::getFirstMarked(const bool isMarked) const
}
}
// complexity: O(log(V))
template <typename T>
const T * Graph<T>::getRandomMarked(const bool isMarked)
{
auto pred = [&isMarked](const std::pair<T, bool> &v)
{
return (v.second == isMarked);
};
std::uniform_int_distribution<unsigned int> dis(0, size() - 1);
auto rIt = isMarked_.begin();
std::advance(rIt, dis(gen_));
auto vIt = std::find_if(rIt, isMarked_.end(), pred);
if (vIt != isMarked_.end())
{
return &(vIt->first);
}
else
{
vIt = std::find_if(isMarked_.begin(), rIt, pred);
if (vIt != rIt)
{
return &(vIt->first);
}
else
{
return nullptr;
}
}
}
// complexity: O(log(V))
template <typename T>
const T * Graph<T>::getFirstUnmarked(void) const
@@ -304,6 +347,13 @@ const T * Graph<T>::getFirstUnmarked(void) const
return getFirstMarked(false);
}
// complexity: O(log(V))
template <typename T>
const T * Graph<T>::getRandomUnmarked(void)
{
return getRandomMarked(false);
}
// prune marked/unmarked vertices //////////////////////////////////////////////
// complexity: O(V^2*log(V))
template <typename T>
@@ -462,10 +512,10 @@ std::vector<Graph<T>> Graph<T>::getConnectedComponents(void) const
return res;
}
// topological sort using Tarjan's algorithm
// topological sort using a directed DFS algorithm
// complexity: O(V*log(V))
template <typename T>
std::vector<T> Graph<T>::topoSort(void)
std::vector<T> Graph<T>::topoSort(const bool randomize)
{
std::stack<T> buf;
std::vector<T> res;
@@ -479,16 +529,20 @@ std::vector<T> Graph<T>::topoSort(void)
{
HADRON_ERROR("cannot topologically sort a cyclic graph");
}
if (!this->isMarked(v))
if (!isMarked(v))
{
std::vector<T> child = this->getChildren(v);
std::vector<T> child = getChildren(v);
tmpMarked[v] = true;
if (randomize)
{
std::shuffle(child.begin(), child.end(), gen_);
}
for (auto &c: child)
{
visit(c);
}
this->mark(v);
mark(v);
tmpMarked[v] = false;
buf.push(v);
}
@@ -501,11 +555,26 @@ std::vector<T> Graph<T>::topoSort(void)
}
// loop on unmarked vertices
vPt = getFirstUnmarked();
unmarkAll();
if (randomize)
{
vPt = getRandomUnmarked();
}
else
{
vPt = getFirstUnmarked();
}
while (vPt)
{
visit(*vPt);
vPt = getFirstUnmarked();
if (randomize)
{
vPt = getRandomUnmarked();
}
else
{
vPt = getFirstUnmarked();
}
}
unmarkAll();
@@ -522,7 +591,7 @@ std::vector<T> Graph<T>::topoSort(void)
// generate all possible topological sorts
// Y. L. Varol & D. Rotem, Comput. J. 24(1), pp. 8384, 1981
// http://comjnl.oupjournals.org/cgi/doi/10.1093/comjnl/24.1.83
// complexity: O(V*log(V))
// complexity: O(V*log(V)) (from the paper, but really ?)
template <typename T>
std::vector<std::vector<T>> Graph<T>::allTopoSort(void)
{