Files
trueskill/src/TrueSkill/Layers/IteratedTeamDifferencesInnerLayer.php
Jens True 063a64a4f6
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
Less Stringable
2024-03-19 16:24:19 +00:00

202 lines
7.9 KiB
PHP

<?php
declare(strict_types=1);
namespace DNW\Skills\TrueSkill\Layers;
use DNW\Skills\FactorGraphs\ScheduleLoop;
use DNW\Skills\FactorGraphs\ScheduleSequence;
use DNW\Skills\FactorGraphs\ScheduleStep;
use DNW\Skills\TrueSkill\TrueSkillFactorGraph;
use Exception;
// The whole purpose of this is to do a loop on the bottom
class IteratedTeamDifferencesInnerLayer extends TrueSkillFactorGraphLayer
{
public function __construct(
TrueSkillFactorGraph $parentGraph,
private readonly TeamPerformancesToTeamPerformanceDifferencesLayer $TeamPerformancesToTeamPerformanceDifferencesLayer,
private readonly TeamDifferencesComparisonLayer $TeamDifferencesComparisonLayer
)
{
parent::__construct($parentGraph);
}
public function getLocalFactors(): array
{
return array_merge(
$this->TeamPerformancesToTeamPerformanceDifferencesLayer->getLocalFactors(),
$this->TeamDifferencesComparisonLayer->getLocalFactors()
);
}
public function buildLayer(): void
{
$inputVariablesGroups = $this->getInputVariablesGroups();
$this->TeamPerformancesToTeamPerformanceDifferencesLayer->setInputVariablesGroups($inputVariablesGroups);
$this->TeamPerformancesToTeamPerformanceDifferencesLayer->buildLayer();
$teamDifferencesOutputVariablesGroups = $this->TeamPerformancesToTeamPerformanceDifferencesLayer->getOutputVariablesGroups();
$this->TeamDifferencesComparisonLayer->setInputVariablesGroups($teamDifferencesOutputVariablesGroups);
$this->TeamDifferencesComparisonLayer->buildLayer();
}
public function createPriorSchedule(): ?ScheduleSequence
{
switch (count($this->getInputVariablesGroups())) {
case 0:
case 1:
throw new Exception('InvalidOperation');
case 2:
$loop = $this->createTwoTeamInnerPriorLoopSchedule();
break;
default:
$loop = $this->createMultipleTeamInnerPriorLoopSchedule();
break;
}
// When dealing with differences, there are always (n-1) differences, so add in the 1
$totalTeamDifferences = count($this->TeamPerformancesToTeamPerformanceDifferencesLayer->getLocalFactors());
$localFactors = $this->TeamPerformancesToTeamPerformanceDifferencesLayer->getLocalFactors();
$firstDifferencesFactor = $localFactors[0];
$lastDifferencesFactor = $localFactors[$totalTeamDifferences - 1];
//inner schedule
return new ScheduleSequence(
[
$loop,
//teamPerformanceToPerformanceDifferenceFactors[0] @ 1
new ScheduleStep(
$firstDifferencesFactor,
1
),
//teamPerformanceToPerformanceDifferenceFactors[teamTeamDifferences = %d - 1] @ 2
new ScheduleStep(
$lastDifferencesFactor,
2
),
]
);
}
private function createTwoTeamInnerPriorLoopSchedule(): ScheduleSequence
{
$teamPerformancesToTeamPerformanceDifferencesLayerLocalFactors = $this->TeamPerformancesToTeamPerformanceDifferencesLayer->getLocalFactors();
$teamDifferencesComparisonLayerLocalFactors = $this->TeamDifferencesComparisonLayer->getLocalFactors();
$firstPerfToTeamDiff = $teamPerformancesToTeamPerformanceDifferencesLayerLocalFactors[0];
$firstTeamDiffComparison = $teamDifferencesComparisonLayerLocalFactors[0];
$itemsToSequence = [
//send team perf to perf differences
new ScheduleStep(
$firstPerfToTeamDiff,
0
),
//send to greater than or within factor
new ScheduleStep(
$firstTeamDiffComparison,
0
),
];
//loop of just two teams inner sequence
return $this->scheduleSequence(
$itemsToSequence
);
}
private function createMultipleTeamInnerPriorLoopSchedule(): ScheduleLoop
{
$totalTeamDifferences = count($this->TeamPerformancesToTeamPerformanceDifferencesLayer->getLocalFactors());
$forwardScheduleList = [];
for ($i = 0; $i < $totalTeamDifferences - 1; ++$i) {
$teamPerformancesToTeamPerformanceDifferencesLayerLocalFactors = $this->TeamPerformancesToTeamPerformanceDifferencesLayer->getLocalFactors();
$teamDifferencesComparisonLayerLocalFactors = $this->TeamDifferencesComparisonLayer->getLocalFactors();
$currentTeamPerfToTeamPerfDiff = $teamPerformancesToTeamPerformanceDifferencesLayerLocalFactors[$i];
$currentTeamDiffComparison = $teamDifferencesComparisonLayerLocalFactors[$i];
//current forward schedule piece $i
$currentForwardSchedulePiece =
$this->scheduleSequence(
[
//team perf to perf diff
new ScheduleStep(
$currentTeamPerfToTeamPerfDiff,
0
),
//greater than or within result factor
new ScheduleStep(
$currentTeamDiffComparison,
0
),
//'team perf to perf diff factors
new ScheduleStep(
$currentTeamPerfToTeamPerfDiff,
2
),
]
);
$forwardScheduleList[] = $currentForwardSchedulePiece;
}
//forward schedule
$forwardSchedule = new ScheduleSequence($forwardScheduleList);
$backwardScheduleList = [];
for ($i = 0; $i < $totalTeamDifferences - 1; ++$i) {
$teamPerformancesToTeamPerformanceDifferencesLayerLocalFactors = $this->TeamPerformancesToTeamPerformanceDifferencesLayer->getLocalFactors();
$teamDifferencesComparisonLayerLocalFactors = $this->TeamDifferencesComparisonLayer->getLocalFactors();
$differencesFactor = $teamPerformancesToTeamPerformanceDifferencesLayerLocalFactors[$totalTeamDifferences - 1 - $i];
$comparisonFactor = $teamDifferencesComparisonLayerLocalFactors[$totalTeamDifferences - 1 - $i];
$performancesToDifferencesFactor = $teamPerformancesToTeamPerformanceDifferencesLayerLocalFactors[$totalTeamDifferences - 1 - $i];
//current backward schedule piece
$currentBackwardSchedulePiece = new ScheduleSequence(
[
//teamPerformanceToPerformanceDifferenceFactors[totalTeamDifferences - 1 - %d] @ 0
new ScheduleStep(
$differencesFactor,
0
),
//greaterThanOrWithinResultFactors[totalTeamDifferences - 1 - %d] @ 0
new ScheduleStep(
$comparisonFactor,
0
),
//teamPerformanceToPerformanceDifferenceFactors[totalTeamDifferences - 1 - %d] @ 1
new ScheduleStep(
$performancesToDifferencesFactor,
1
),
]
);
$backwardScheduleList[] = $currentBackwardSchedulePiece;
}
//backward schedule
$backwardSchedule = new ScheduleSequence($backwardScheduleList);
$forwardBackwardScheduleToLoop =
//forward Backward Schedule To Loop
new ScheduleSequence(
[$forwardSchedule, $backwardSchedule]
);
$initialMaxDelta = 0.0001;
//loop with max delta
return new ScheduleLoop(
$forwardBackwardScheduleToLoop,
$initialMaxDelta
);
}
}