Chain-Load: demonstrate pruning and separated graph segments
Through introduction of a ''pruning rule'', it is possible to create exit nodes in the middle of the graph. With increased intensity of pruning, it is possible to ''choke off'' the generation and terminate the graph; in such a case a new seed node is injected automatically. By combination with seed rules, an equilibrium of graph start and graph termination can be achieved. Following this path, it should be possible to produce a pattern, which is random but overall stable and well suited to simulate a realistic processing load. However, finding proper parameters turns out quite hard in practice, since the behaviour is essentially contingent and most combinations either lead to uninteresting trivial small graph chunks, or to large, interconnected and exponentially expanding networks
This commit is contained in:
parent
38f27f967f
commit
bb69cf02e3
3 changed files with 232 additions and 7 deletions
|
|
@ -231,6 +231,7 @@ namespace test {
|
|||
|
||||
|
||||
|
||||
|
||||
/** @test demonstrate shaping of generated topology
|
||||
* - the expansion rule injects forking nodes
|
||||
* - after some expansion, width limitation is enforced
|
||||
|
|
@ -302,6 +303,7 @@ namespace test {
|
|||
|
||||
|
||||
|
||||
|
||||
/** @test demonstrate impact of reduction on graph topology
|
||||
* - after one fixed initial expansion, reduction causes
|
||||
* all chains to be joined eventually
|
||||
|
|
@ -331,7 +333,6 @@ namespace test {
|
|||
CHECK (stat.indicators[STAT_NODE].cL == "0.37890625"_expect); // Nodes are concentrated towards the beginning
|
||||
|
||||
|
||||
|
||||
// expansion and reduction can counterbalance each other
|
||||
graph.expansionRule(graph.rule().probability(0.2).maxVal(3).shuffle(555))
|
||||
.reductionRule(graph.rule().probability(0.2).maxVal(3).shuffle(555))
|
||||
|
|
@ -350,7 +351,6 @@ namespace test {
|
|||
CHECK (stat.indicators[STAT_JOIN].cL == "0.66666667"_expect); // while joins need forks as prerequisite
|
||||
|
||||
|
||||
|
||||
// expansion bursts can be balanced with a heightened reduction intensity
|
||||
graph.expansionRule(graph.rule().probability(0.3).maxVal(4).shuffle(555))
|
||||
.reductionRule(graph.rule().probability(0.9).maxVal(2).shuffle(555))
|
||||
|
|
@ -373,6 +373,7 @@ namespace test {
|
|||
|
||||
|
||||
|
||||
|
||||
/** @test demonstrate shaping of generated topology by seeding new chains
|
||||
* - the seed rule allows to start new chains in the middle of the graph
|
||||
* - combined with with reduction, the emerging structure resembles
|
||||
|
|
@ -405,7 +406,6 @@ namespace test {
|
|||
CHECK (stat.indicators[STAT_JOIN].cL == "0.92857143"_expect); // while joining only happens at the end when connecting to exit
|
||||
|
||||
|
||||
|
||||
// combining random seed nodes with reduction leads to a processing pattern
|
||||
// with side-chaines successively joined into a single common result
|
||||
graph.seedingRule(graph.rule().probability(0.2).maxVal(3).shuffle())
|
||||
|
|
@ -430,6 +430,7 @@ namespace test {
|
|||
|
||||
|
||||
|
||||
|
||||
/** @test TODO demonstrate shaping of generated topology
|
||||
* - TODO the prune rule terminates chains randomly
|
||||
* - this can lead to fragmentation in several sub-graphs
|
||||
|
|
@ -438,7 +439,165 @@ namespace test {
|
|||
void
|
||||
verify_PruneChains()
|
||||
{
|
||||
ChainLoad32 graph;
|
||||
|
||||
// terminate chains randomly
|
||||
graph.pruningRule(graph.rule().probability(0.2))
|
||||
.buildToplolgy()
|
||||
// .printTopologyDOT()
|
||||
// .printTopologyStatistics()
|
||||
;
|
||||
|
||||
CHECK (graph.getHash() == 0xC4AE6EB741C22FCE);
|
||||
|
||||
auto stat = graph.computeGraphStatistics();
|
||||
CHECK (stat.levels == 32); // only a single line of connections...
|
||||
CHECK (stat.segments == 8); // albeit severed into 8 segments
|
||||
CHECK (stat.indicators[STAT_NODE].pS == 4); // with always 4 Nodes per segment
|
||||
CHECK (stat.indicators[STAT_NODE].pL == 1); // and only ever a single node per level
|
||||
CHECK (stat.indicators[STAT_SEED].cnt == 8); // consequently we get 8 »Seed« nodes
|
||||
CHECK (stat.indicators[STAT_EXIT].cnt == 8); // 8 »Exit« nodes
|
||||
CHECK (stat.indicators[STAT_LINK].cnt == 16); // and 16 interconnecting links
|
||||
|
||||
|
||||
// combined with expansion, several tree-shaped segments emerge
|
||||
graph.pruningRule(graph.rule().probability(0.2))
|
||||
.expansionRule(graph.rule().probability(0.6))
|
||||
.setSeed(10101)
|
||||
.buildToplolgy()
|
||||
// .printTopologyDOT()
|
||||
// .printTopologyStatistics()
|
||||
;
|
||||
|
||||
CHECK (graph.getHash() == 0xC515DB464FF76818);
|
||||
|
||||
stat = graph.computeGraphStatistics();
|
||||
CHECK (stat.levels == 15); //
|
||||
CHECK (stat.segments == 5); // this time the graph is segregated into 5 parts
|
||||
CHECK (stat.indicators[STAT_NODE].pS == 6.4); // with 4 Nodes per segment
|
||||
CHECK (stat.indicators[STAT_FORK].sL == 0.0); // where »Fork« is always placed at the beginning of each segment
|
||||
CHECK (stat.indicators[STAT_LINK].sL == 0.5); // carry-on »Link« nodes in the very middle of the segment
|
||||
CHECK (stat.indicators[STAT_EXIT].sL == 1.0); // and several »Exit« at the end
|
||||
CHECK (stat.indicators[STAT_EXIT].pS == 2.6); // averaging 2.6 exits per segment (4·3 + 1)/5
|
||||
CHECK (stat.indicators[STAT_SEED].cnt == 5); // so overall we get 8 »Seed« nodes
|
||||
CHECK (stat.indicators[STAT_FORK].cnt == 5); // 5 »Fork« nodes
|
||||
CHECK (stat.indicators[STAT_EXIT].cnt == 13); // 13 »Exit« nodes
|
||||
CHECK (stat.indicators[STAT_LINK].cnt == 14); // and 14 interconnecting links
|
||||
CHECK (stat.indicators[STAT_NODE].pL == "2.1333333"_expect); // leading to ∅ ~2 Nodes per level
|
||||
|
||||
|
||||
// however, by chance, with more randomised pruning points...
|
||||
graph.pruningRule(graph.rule().probability(0.2).shuffle(5))
|
||||
.expansionRule(graph.rule().probability(0.6))
|
||||
.setSeed(10101)
|
||||
.buildToplolgy()
|
||||
// .printTopologyDOT()
|
||||
// .printTopologyStatistics()
|
||||
;
|
||||
|
||||
CHECK (graph.getHash() == 0xEF172CC4B0DE2334);
|
||||
|
||||
stat = graph.computeGraphStatistics();
|
||||
CHECK (stat.segments == 1); // ...the graph can evade severing altogether
|
||||
CHECK (stat.indicators[STAT_FORK].cnt == 2); // with overall 2 »Fork«
|
||||
CHECK (stat.indicators[STAT_EXIT].cnt == 9); // and 9 »Exit« nodes
|
||||
CHECK (stat.indicators[STAT_EXIT].pL == "1.2857143"_expect); // ∅ 1.3 exits per level
|
||||
CHECK (stat.indicators[STAT_NODE].pL == "4.5714286"_expect); // ∅ 4.6 nodes per level
|
||||
|
||||
|
||||
graph.expansionRule(graph.rule()); // reset
|
||||
|
||||
|
||||
// combined with a special seeding rule,
|
||||
// which injects /another seed/ in the next level after each seed,
|
||||
// an equilibrium of chain seeding and termination can be achieved...
|
||||
graph.seedingRule(graph.rule_atStart(1))
|
||||
.pruningRule(graph.rule().probability(0.2))
|
||||
.setSeed(10101)
|
||||
.buildToplolgy()
|
||||
// .printTopologyDOT()
|
||||
// .printTopologyStatistics()
|
||||
;
|
||||
|
||||
CHECK (graph.getHash() == 0xD0A27C9B81058637);
|
||||
|
||||
// NOTE: this example produced 10 disjoint graph parts,
|
||||
// which however start and end interleaved
|
||||
stat = graph.computeGraphStatistics();
|
||||
CHECK (stat.levels == 13); // Generation carries on for 13 levels
|
||||
CHECK (stat.segments == 1); // NOTE: the detection of segments FAILS here (due to interleaved starts)
|
||||
CHECK (stat.indicators[STAT_SEED].cnt == 11); // 11 »Seed« nodes
|
||||
CHECK (stat.indicators[STAT_EXIT].cnt == 10); // 10 »Exit« nodes
|
||||
CHECK (stat.indicators[STAT_LINK].cnt == 10); // 10 interconnecting links
|
||||
CHECK (stat.indicators[STAT_JOIN].cnt == 1); // and one additional »Join«
|
||||
CHECK (stat.indicators[STAT_JOIN].cL == "0.91666667"_expect); // ....appended at graph completion
|
||||
CHECK (stat.indicators[STAT_NODE].pL == "2.4615385"_expect); // overall ∅ 2½ nodes per level
|
||||
CHECK (stat.indicators[STAT_NODE].cL == "0.48697917"_expect); // with generally levelled distribution
|
||||
CHECK (stat.indicators[STAT_SEED].cL == "0.41666667"_expect); // also for the seeds
|
||||
CHECK (stat.indicators[STAT_EXIT].cL == "0.55"_expect); // and the exits
|
||||
|
||||
|
||||
// The next example is »interesting« insofar it shows self-similarity
|
||||
// The generation is entirely repetitive and locally predictable,
|
||||
// producing an ongoing sequence of small graph segments,
|
||||
// partially overlapping with interwoven starts.
|
||||
graph.seedingRule(graph.rule().fixedVal(1))
|
||||
.pruningRule(graph.rule().probability(0.5))
|
||||
.reductionRule(graph.rule().probability(0.8).maxVal(4))
|
||||
.setSeed(10101)
|
||||
.buildToplolgy()
|
||||
// .printTopologyDOT()
|
||||
// .printTopologyStatistics()
|
||||
;
|
||||
CHECK (graph.getHash() == 0x1D56DF2FB0D4AF97);
|
||||
|
||||
stat = graph.computeGraphStatistics();
|
||||
CHECK (stat.levels == 9); // Generation carries on for 13 levels
|
||||
CHECK (stat.indicators[STAT_JOIN].pL == 1); // with one »Join« event per level on average
|
||||
CHECK (stat.indicators[STAT_SEED].cnt == 21); // seeds are injected with /fixed rate/, meaning that
|
||||
CHECK (stat.indicators[STAT_SEED].pL == "2.3333333"_expect); // there is one additional seed for every node in previous level
|
||||
|
||||
|
||||
TestChainLoad<256> gra_2;
|
||||
// The next example is »interesting« insofar it shows self-similarity
|
||||
// The generation is entirely repetitive and locally predictable,
|
||||
// producing an ongoing sequence of small graph segments,
|
||||
// partially overlapping with interwoven starts.
|
||||
// gra_2.seedingRule(gra_2.rule_atLink(1))
|
||||
// .pruningRule(gra_2.rule().probability(0.4))
|
||||
// .reductionRule(gra_2.rule().probability(0.6).maxVal(5).minVal(2))
|
||||
// .setSeed(23)
|
||||
// .buildToplolgy()
|
||||
// .printTopologyDOT()
|
||||
// .printTopologyStatistics()
|
||||
// ;
|
||||
|
||||
// this one goes into a stable repetition loop
|
||||
// gra_2.seedingRule(gra_2.rule_atLink(1))
|
||||
// .pruningRule(gra_2.rule().probability(0.5))
|
||||
// .reductionRule(gra_2.rule().probability(0.6).maxVal(5).minVal(2))
|
||||
// .setSeed(23)
|
||||
// .buildToplolgy()
|
||||
// .printTopologyDOT()
|
||||
// .printTopologyStatistics()
|
||||
// ;
|
||||
|
||||
// this one comes close to a relistic stable processing pattern
|
||||
// just the individual graph is still to complicated
|
||||
// and it the load increases over time
|
||||
gra_2.seedingRule(gra_2.rule().probability(0.5).maxVal(2))
|
||||
// .pruningRule(gra_2.rule().probability(0.55))
|
||||
.reductionRule(gra_2.rule().probability(0.5).maxVal(5))
|
||||
.pruningRule(gra_2.rule_atJoin(1))
|
||||
.setSeed(42)
|
||||
.buildToplolgy()
|
||||
.printTopologyDOT()
|
||||
.printTopologyStatistics()
|
||||
;
|
||||
//SHOW_EXPR(graph.getHash())
|
||||
|
||||
stat = gra_2.computeGraphStatistics();
|
||||
// CHECK (stat.levels == 9); // Generation carries on for 13 levels
|
||||
}
|
||||
//SHOW_EXPR(graph.getHash())
|
||||
//SHOW_EXPR(stat.indicators[STAT_NODE].pL)
|
||||
|
|
|
|||
|
|
@ -359,6 +359,38 @@ namespace test {
|
|||
});
|
||||
}
|
||||
|
||||
static Rule
|
||||
rule_atJoin (uint v)
|
||||
{
|
||||
return Rule().mapping([v](Node* n)
|
||||
{
|
||||
return isJoin(n) ? Rule().fixedVal(v)
|
||||
: Rule();
|
||||
});
|
||||
}
|
||||
|
||||
static Rule
|
||||
rule_atLink (uint v)
|
||||
{
|
||||
return Rule().mapping([v](Node* n)
|
||||
{ // NOTE: when applying these rules,
|
||||
// successors are not yet wired...
|
||||
return not (isJoin(n) or isStart(n))
|
||||
? Rule().fixedVal(v)
|
||||
: Rule();
|
||||
});
|
||||
}
|
||||
|
||||
static Rule
|
||||
rule_atJoin_else (double p1, double p2, uint v=1)
|
||||
{
|
||||
return Rule().mapping([p1,p2,v](Node* n)
|
||||
{
|
||||
return isJoin(n) ? Rule().probability(p1).maxVal(v)
|
||||
: Rule().probability(p2).maxVal(v);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -96296,15 +96296,49 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1701226052691" ID="ID_929780401" MODIFIED="1701226056300" TEXT="Prune">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1701226052691" ID="ID_929780401" MODIFIED="1701401958232" TEXT="Prune">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#338800" CREATED="1701401689510" ID="ID_453433047" MODIFIED="1701401733961" TEXT="Pruning allein ⟹ Graph zerlegt">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1701401742643" ID="ID_90185161" MODIFIED="1701401751675" TEXT="Prune + Expand ⟹ kleine Bäumchen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1701401765792" ID="ID_796883949" MODIFIED="1701401779784" TEXT="+ shuffle ⟹ Graph zerfällt nicht (mehr)">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node CREATED="1701401867273" ID="ID_1917139651" MODIFIED="1701401954627" TEXT="Seed + Prune + Reduce....">
|
||||
<arrowlink COLOR="#659b9f" DESTINATION="ID_633684852" ENDARROW="Default" ENDINCLINATION="-7;-31;" ID="Arrow_ID_1330203959" STARTARROW="None" STARTINCLINATION="-67;8;"/>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1701226061434" ID="ID_1246960546" MODIFIED="1701314215907" TEXT="Gleichgewicht">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1701314218952" ID="ID_959655971" MODIFIED="1701314254700" TEXT="Expansion ⟵⟶ Reduction"/>
|
||||
<node CREATED="1701401672045" ID="ID_277348330" MODIFIED="1701401686590" TEXT="Seed ⟵⟶ Reduction + Pruning"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1701226065633" ID="ID_633684852" MODIFIED="1701402052810" TEXT="Teilgraphen">
|
||||
<linktarget COLOR="#659b9f" DESTINATION="ID_633684852" ENDARROW="Default" ENDINCLINATION="-7;-31;" ID="Arrow_ID_1330203959" SOURCE="ID_1917139651" STARTARROW="None" STARTINCLINATION="-67;8;"/>
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#338800" CREATED="1701401801875" ID="ID_613538695" MODIFIED="1701401819064" TEXT="Seed + Prune ⟹ interleaved graphs">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1701401829056" ID="ID_623081988" MODIFIED="1701401856489" TEXT="Seed + Prune + Reduce ⟹ self similar structures">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node CREATED="1701401968501" ID="ID_1106827463" MODIFIED="1701401978487" TEXT="Suche nach realistischen Processing-Pattern">
|
||||
<node COLOR="#338800" CREATED="1701402009239" ID="ID_1542545632" MODIFIED="1701402022723" TEXT="Complex-interleaved">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1701402015035" ID="ID_427886072" MODIFIED="1701402022724" TEXT="semi-complex stable state">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1701402024221" ID="ID_656477574" MODIFIED="1701402035013" TEXT="simple-interleaved">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1701402036180" ID="ID_1920671782" MODIFIED="1701402046419" TEXT="will mir nicht recht gelingen">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1701226065633" ID="ID_633684852" MODIFIED="1701226072137" TEXT="Teilgraphen">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
|
|||
Loading…
Reference in a new issue