mirror of
https://github.com/paboyle/Grid.git
synced 2025-04-09 05:30:46 +01:00
Hadrons: algorithm to determine all possible topological ordering
This commit is contained in:
parent
bb195607ab
commit
20ce7e0270
@ -59,6 +59,8 @@ void Application::run(void)
|
|||||||
|
|
||||||
g.addEdge("A", "B");
|
g.addEdge("A", "B");
|
||||||
g.addEdge("B", "D");
|
g.addEdge("B", "D");
|
||||||
|
g.addEdge("B", "X1");
|
||||||
|
g.addEdge("X1", "X2");
|
||||||
g.addEdge("D", "E");
|
g.addEdge("D", "E");
|
||||||
g.addEdge("E", "C");
|
g.addEdge("E", "C");
|
||||||
g.addEdge("Z", "Y");
|
g.addEdge("Z", "Y");
|
||||||
@ -75,13 +77,16 @@ void Application::run(void)
|
|||||||
}
|
}
|
||||||
for (auto &h: vec)
|
for (auto &h: vec)
|
||||||
{
|
{
|
||||||
auto top = h.topoSort();
|
auto top = h.allTopoSort();
|
||||||
while (!top.empty())
|
for (auto &s: top)
|
||||||
{
|
{
|
||||||
cout << top.top() << " ";
|
for (auto &v: s)
|
||||||
top.pop();
|
{
|
||||||
|
cout << v << " ";
|
||||||
|
}
|
||||||
|
cout << endl;
|
||||||
}
|
}
|
||||||
cout << endl;
|
cout << "--------" << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,12 +58,13 @@ public:
|
|||||||
// tests
|
// tests
|
||||||
bool gotValue(const T &value) const;
|
bool gotValue(const T &value) const;
|
||||||
// graph topological manipulations
|
// graph topological manipulations
|
||||||
std::vector<T> getAdjacentVertices(const T &value) const;
|
std::vector<T> getAdjacentVertices(const T &value) const;
|
||||||
std::vector<T> getChildren(const T &value) const;
|
std::vector<T> getChildren(const T &value) const;
|
||||||
std::vector<T> getParents(const T &value) const;
|
std::vector<T> getParents(const T &value) const;
|
||||||
std::vector<T> getRoots(void) const;
|
std::vector<T> getRoots(void) const;
|
||||||
std::vector<Graph<T>> getConnectedComponents(void) const;
|
std::vector<Graph<T>> getConnectedComponents(void) const;
|
||||||
std::stack<T> topoSort(void);
|
std::vector<T> topoSort(void);
|
||||||
|
std::vector<std::vector<T>> allTopoSort(void);
|
||||||
// I/O
|
// I/O
|
||||||
friend std::ostream & operator<<(std::ostream &out, const Graph<T> &g)
|
friend std::ostream & operator<<(std::ostream &out, const Graph<T> &g)
|
||||||
{
|
{
|
||||||
@ -96,8 +97,8 @@ private:
|
|||||||
void depthFirstSearch(void);
|
void depthFirstSearch(void);
|
||||||
void depthFirstSearch(const T &root);
|
void depthFirstSearch(const T &root);
|
||||||
private:
|
private:
|
||||||
std::map<T, bool> isMarked_;
|
std::map<T, bool> isMarked_;
|
||||||
std::set<Edge> edgeSet_;
|
std::set<Edge> edgeSet_;
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
@ -422,12 +423,13 @@ std::vector<Graph<T>> Graph<T>::getConnectedComponents(void) const
|
|||||||
|
|
||||||
// topological sort using Tarjan's algorithm
|
// topological sort using Tarjan's algorithm
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::stack<T> Graph<T>::topoSort(void)
|
std::vector<T> Graph<T>::topoSort(void)
|
||||||
{
|
{
|
||||||
std::stack<T> res;
|
std::stack<T> buf;
|
||||||
|
std::vector<T> res;
|
||||||
const T *vPt;
|
const T *vPt;
|
||||||
std::map<T, bool> tmpMarked(isMarked_);
|
std::map<T, bool> tmpMarked(isMarked_);
|
||||||
|
|
||||||
// visit function
|
// visit function
|
||||||
std::function<void(const T &)> visit = [&](const T &v)
|
std::function<void(const T &)> visit = [&](const T &v)
|
||||||
{
|
{
|
||||||
@ -446,7 +448,7 @@ std::stack<T> Graph<T>::topoSort(void)
|
|||||||
}
|
}
|
||||||
this->mark(v);
|
this->mark(v);
|
||||||
tmpMarked[v] = false;
|
tmpMarked[v] = false;
|
||||||
res.push(v);
|
buf.push(v);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -455,6 +457,7 @@ std::stack<T> Graph<T>::topoSort(void)
|
|||||||
{
|
{
|
||||||
tmpMarked.at(v.first) = false;
|
tmpMarked.at(v.first) = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// loop on unmarked vertices
|
// loop on unmarked vertices
|
||||||
vPt = getFirstUnmarked();
|
vPt = getFirstUnmarked();
|
||||||
while (vPt)
|
while (vPt)
|
||||||
@ -464,6 +467,92 @@ std::stack<T> Graph<T>::topoSort(void)
|
|||||||
}
|
}
|
||||||
unmarkAll();
|
unmarkAll();
|
||||||
|
|
||||||
|
// create result vector
|
||||||
|
while (!buf.empty())
|
||||||
|
{
|
||||||
|
res.push_back(buf.top());
|
||||||
|
buf.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// generate all possible topological sorts
|
||||||
|
// Y. L. Varol & D. Rotem, Comput. J. 24(1), pp. 83–84, 1981
|
||||||
|
// http://comjnl.oupjournals.org/cgi/doi/10.1093/comjnl/24.1.83
|
||||||
|
template <typename T>
|
||||||
|
std::vector<std::vector<T>> Graph<T>::allTopoSort(void)
|
||||||
|
{
|
||||||
|
std::vector<std::vector<T>> res;
|
||||||
|
std::map<T, std::map<T, bool>> iMat;
|
||||||
|
|
||||||
|
// create incidence matrix
|
||||||
|
for (auto &v1: isMarked_)
|
||||||
|
for (auto &v2: isMarked_)
|
||||||
|
{
|
||||||
|
iMat[v1.first][v2.first] = false;
|
||||||
|
}
|
||||||
|
for (auto &v: isMarked_)
|
||||||
|
{
|
||||||
|
auto cVec = getChildren(v.first);
|
||||||
|
|
||||||
|
for (auto &c: cVec)
|
||||||
|
{
|
||||||
|
iMat[v.first][c] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// generate initial topological sort
|
||||||
|
res.push_back(topoSort());
|
||||||
|
|
||||||
|
// generate all other topological sorts by permutation
|
||||||
|
std::vector<T> p = res[0];
|
||||||
|
const unsigned int n = size();
|
||||||
|
std::vector<unsigned int> loc(n);
|
||||||
|
unsigned int i, k, k1;
|
||||||
|
T obj_k, obj_k1;
|
||||||
|
bool isFinal;
|
||||||
|
|
||||||
|
for (unsigned int j = 0; j < n; ++j)
|
||||||
|
{
|
||||||
|
loc[j] = j;
|
||||||
|
}
|
||||||
|
i = 0;
|
||||||
|
while (i < n-1)
|
||||||
|
{
|
||||||
|
k = loc[i];
|
||||||
|
k1 = k + 1;
|
||||||
|
obj_k = p[k];
|
||||||
|
if (k1 >= n)
|
||||||
|
{
|
||||||
|
isFinal = true;
|
||||||
|
obj_k1 = obj_k;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
isFinal = false;
|
||||||
|
obj_k1 = p[k1];
|
||||||
|
}
|
||||||
|
if (iMat[res[0][i]][obj_k1] or isFinal)
|
||||||
|
{
|
||||||
|
for (unsigned int l = k; l >= i + 1; --l)
|
||||||
|
{
|
||||||
|
p[l] = p[l-1];
|
||||||
|
}
|
||||||
|
p[i] = obj_k;
|
||||||
|
loc[i] = i;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p[k] = obj_k1;
|
||||||
|
p[k1] = obj_k;
|
||||||
|
loc[i] = k1;
|
||||||
|
i = 0;
|
||||||
|
res.push_back(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user