Chain-Load: handle node seed and recalculation
- with the new pruning option, start-Nodes can now be anywhere - introduce predicates to detect start-Nodes and exit-Nodes - ensure each new seed node gets the global seed on graph construction - provide functionality to re-propagate a seed and clear hashes - provide functionality to recalculate the hashes over the graph
This commit is contained in:
parent
1ff9225086
commit
619a5173b0
4 changed files with 124 additions and 9 deletions
|
|
@ -1647,6 +1647,13 @@ namespace lib {
|
|||
return IterExplorer::reduce ([](const reference val){ return val; });
|
||||
}
|
||||
|
||||
/** simplified _terminal builder_ to count number of elements from this sequence. */
|
||||
size_t
|
||||
count()
|
||||
{
|
||||
return IterExplorer::reduce ([](auto){ return size_t(1); });
|
||||
}
|
||||
|
||||
/** simplified _terminal builder_ to check if any result yields `true` (short-circuit) */
|
||||
bool
|
||||
has_any()
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ namespace test {
|
|||
verify_Node();
|
||||
verify_Topology();
|
||||
control_Topology();
|
||||
reseed_recalculate();
|
||||
|
||||
witch_gate();
|
||||
}
|
||||
|
|
@ -215,21 +216,51 @@ namespace test {
|
|||
|
||||
|
||||
/** @test flexible control of generated topology
|
||||
* @todo WIP 11/23 🔁 define ⟶ implement
|
||||
* @todo WIP 11/23 🔁 define ⟶ 🔁 implement
|
||||
*/
|
||||
void
|
||||
control_Topology()
|
||||
{
|
||||
auto graph = TestChainLoad<32>{};
|
||||
|
||||
graph.expansionRule(graph.rule().probability(0.25).maxVal(4).shuffle())
|
||||
.pruningRule(graph.rule().probability(0.2).shuffle())
|
||||
graph.expansionRule(graph.rule().probability(0.8).maxVal(1))
|
||||
.pruningRule(graph.rule().probability(0.6))
|
||||
.buildToplolgy()
|
||||
.printTopologyDOT();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** @test set and propagate seed values and recalculate all node hashes
|
||||
* @todo WIP 11/23 🔁 define ⟶ implement
|
||||
*/
|
||||
void
|
||||
reseed_recalculate()
|
||||
{
|
||||
auto graph = TestChainLoad<32>{};
|
||||
graph.expansionRule(graph.rule().probability(0.8).maxVal(1))
|
||||
.pruningRule(graph.rule().probability(0.6))
|
||||
.buildToplolgy();
|
||||
|
||||
using Node = TestChainLoad<32>::Node;
|
||||
auto isStartNode = [](Node& n){ return isStart(n); };
|
||||
auto isExitNode = [](Node& n){ return isExit(n); };
|
||||
|
||||
CHECK (8 == graph.allNodes().filter(isStartNode).count());
|
||||
CHECK (15 == graph.allNodes().filter(isExitNode).count());
|
||||
|
||||
CHECK (graph.getHash() == 14172386810742845390u);
|
||||
|
||||
graph.setSeed(55).clearNodeHashes();
|
||||
CHECK (graph.getSeed() == 55);
|
||||
CHECK (graph.getHash() == 0);
|
||||
|
||||
graph.recalculate();
|
||||
CHECK (graph.getHash() == 6093128458724583708u);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** @test TODO diagnostic blah
|
||||
* @todo WIP 11/23 🔁 define ⟶ implement
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -237,6 +237,12 @@ namespace test {
|
|||
hash_combine (hash, entry->hash);
|
||||
return hash;
|
||||
}
|
||||
|
||||
friend bool isStart (Node const& n) { return isnil (n.pred); };
|
||||
friend bool isStart (Node const* n) { return n and isnil (n->pred); };
|
||||
|
||||
friend bool isExit (Node const& n) { return isnil (n.succ); };
|
||||
friend bool isExit (Node const* n) { return n and isnil (n->succ); };
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -336,10 +342,12 @@ namespace test {
|
|||
auto moreNext = [&]{ return next->size() < maxFan; };
|
||||
auto moreNodes = [&]{ return node < &nodes_->back(); };
|
||||
auto spaceLeft = [&]{ return moreNext() and moreNodes(); };
|
||||
auto addNode = [&]{
|
||||
auto addNode = [&](size_t seed =0)
|
||||
{
|
||||
Node* n = *next->add (node++);
|
||||
n->clear();
|
||||
n->level = level;
|
||||
n->hash = seed;
|
||||
return n;
|
||||
};
|
||||
auto apply = [&](Rule& rule, Node* n)
|
||||
|
|
@ -364,8 +372,7 @@ namespace test {
|
|||
size_t toExpand = apply (expansionRule,o);
|
||||
while (0 < toSeed and spaceLeft())
|
||||
{ // start a new chain from seed
|
||||
Node* n = addNode();
|
||||
n->hash = this->getSeed();
|
||||
addNode(this->getSeed());
|
||||
--toSeed;
|
||||
}
|
||||
while (0 < toExpand and spaceLeft())
|
||||
|
|
@ -391,8 +398,8 @@ namespace test {
|
|||
}
|
||||
}
|
||||
ENSURE (not isnil(next) or spaceLeft());
|
||||
if (isnil(next))
|
||||
addNode(); // ensure parent
|
||||
if (isnil(next)) // ensure graph continues
|
||||
addNode(this->getSeed());
|
||||
ENSURE (not next->empty());
|
||||
++level;
|
||||
}
|
||||
|
|
@ -411,6 +418,47 @@ namespace test {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the overall seed value.
|
||||
* @note does not propagate seed to consecutive start nodes
|
||||
*/
|
||||
TestChainLoad&&
|
||||
setSeed (size_t seed = rand())
|
||||
{
|
||||
nodes_->front().hash = seed;
|
||||
return move(*this);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Recalculate all node hashes and propagate seed value.
|
||||
*/
|
||||
TestChainLoad&&
|
||||
recalculate()
|
||||
{
|
||||
size_t seed = this->getSeed();
|
||||
for (Node& n : allNodes())
|
||||
{
|
||||
n.hash = isStart(n)? seed : 0;
|
||||
n.calculate();
|
||||
}
|
||||
return move(*this);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clear node hashes and propagate seed value.
|
||||
*/
|
||||
TestChainLoad&&
|
||||
clearNodeHashes()
|
||||
{
|
||||
size_t seed = this->getSeed();
|
||||
for (Node& n : allNodes())
|
||||
n.hash = isStart(n)? seed : 0;
|
||||
return move(*this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ===== Operators ===== */
|
||||
|
||||
|
|
|
|||
|
|
@ -98722,6 +98722,12 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node CREATED="1701013395009" ID="ID_532861011" MODIFIED="1701013411163" TEXT="⟹ Corrolar: die erste Start-Node entsteht dann von selbst"/>
|
||||
<node COLOR="#338800" CREATED="1701029194543" ID="ID_428563573" MODIFIED="1701029206980" TEXT="Seed aus erster Seed-Node entnehmen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1701029211699" ID="ID_1504750686" MODIFIED="1701029216727" TEXT="Programmiertrick.."/>
|
||||
<node CREATED="1701029217650" ID="ID_820767620" MODIFIED="1701029224237" TEXT="wenn es die erste Node ist..."/>
|
||||
<node CREATED="1701029224849" ID="ID_178091052" MODIFIED="1701029238572" TEXT="dann verstecken wir den aktuellen Seed im Aufrufparameter"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1699805890752" ID="ID_604823204" MODIFIED="1699827731274" TEXT="Limitierungen einhalten">
|
||||
|
|
@ -99438,9 +99444,32 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<linktarget COLOR="#42b360" DESTINATION="ID_1175949615" ENDARROW="Default" ENDINCLINATION="334;0;" ID="Arrow_ID_357935660" SOURCE="ID_479859970" STARTARROW="None" STARTINCLINATION="-103;5;"/>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1700105549294" ID="ID_1778641158" MODIFIED="1700105554766" TEXT="Neuberechnung">
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1700105549294" ID="ID_1778641158" MODIFIED="1701033551086" TEXT="Neuberechnung">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#435e98" CREATED="1701033351833" ID="ID_133315306" MODIFIED="1701033556660" TEXT="clearNodeHashes()">
|
||||
<node CREATED="1701033364791" ID="ID_442706492" MODIFIED="1701033368037" TEXT="besucht alle Nodes"/>
|
||||
<node CREATED="1701033368583" ID="ID_244375144" MODIFIED="1701033384649" TEXT="überträgt den seed-Hash in die »startNodes«"/>
|
||||
<node CREATED="1701033387653" ID="ID_1025656772" MODIFIED="1701033395879" TEXT="alle anderen Hashes werden auf 0 gesetzt"/>
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1701033359408" ID="ID_1025063671" MODIFIED="1701033556660" STYLE="fork" TEXT="recalculate()">
|
||||
<node CREATED="1701033439613" ID="ID_1016987047" MODIFIED="1701033554697" TEXT="gleiches Schema"/>
|
||||
<node CREATED="1701033450252" ID="ID_1730538159" MODIFIED="1701033554697" TEXT="stößt aber zudem die Berechnung der Nodes an"/>
|
||||
<node COLOR="#435e98" CREATED="1701033564378" ID="ID_1444681023" MODIFIED="1701033638235" TEXT="Warum Löschen der Hashes?">
|
||||
<node CREATED="1701033583314" ID="ID_571057687" MODIFIED="1701033594728" TEXT="weil die Hash-Berechnung nicht idempotent ist"/>
|
||||
<node CREATED="1701033595585" ID="ID_1443626199" MODIFIED="1701033611274" TEXT="das liegt an der Aufrufstruktur von boost::hash"/>
|
||||
<node CREATED="1701033623128" ID="ID_1915341389" MODIFIED="1701033635439" TEXT="durch das Löschen wird ein sehr naheliegender Fehler vermieden"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1701033495195" ID="ID_193483520" MODIFIED="1701033506285" TEXT="Ergebnisse im Test verifizieren">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#338800" CREATED="1701033509532" ID="ID_1793560814" MODIFIED="1701033521653" TEXT="Filter-Prägdikate: isStart und isExit">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1701033523034" ID="ID_1580648658" MODIFIED="1701033543744" TEXT="irgendwie geschickt auf die Nodes zugreifen und prüfen">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1700105555476" ID="ID_587761135" MODIFIED="1700105558876" TEXT="Scheduling">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
|
|
|
|||
Loading…
Reference in a new issue