trueskill/src/TrueSkill/Layers/IteratedTeamDifferencesInnerLayer.php

197 lines
8.1 KiB
PHP
Raw Normal View History

2022-07-05 15:55:47 +02:00
<?php
namespace DNW\Skills\TrueSkill\Layers;
2022-07-05 15:33:34 +02:00
use DNW\Skills\FactorGraphs\ScheduleLoop;
use DNW\Skills\FactorGraphs\ScheduleSequence;
use DNW\Skills\FactorGraphs\ScheduleStep;
use DNW\Skills\TrueSkill\TrueSkillFactorGraph;
2022-07-05 15:55:47 +02:00
use Exception;
// The whole purpose of this is to do a loop on the bottom
class IteratedTeamDifferencesInnerLayer extends TrueSkillFactorGraphLayer
{
2023-08-01 13:35:44 +00:00
public function __construct(
TrueSkillFactorGraph $parentGraph,
2023-08-01 13:53:19 +00:00
private readonly TeamPerformancesToTeamPerformanceDifferencesLayer $TeamPerformancesToTeamPerformanceDifferencesLayer,
private readonly TeamDifferencesComparisonLayer $TeamDifferencesComparisonLayer
2023-08-01 13:35:44 +00:00
) {
parent::__construct($parentGraph);
}
2023-08-01 11:26:38 +00:00
public function getLocalFactors(): array
{
2023-08-01 13:53:19 +00:00
return array_merge(
$this->TeamPerformancesToTeamPerformanceDifferencesLayer->getLocalFactors(),
$this->TeamDifferencesComparisonLayer->getLocalFactors()
);
}
2023-08-02 12:39:42 +00:00
public function buildLayer(): void
{
$inputVariablesGroups = $this->getInputVariablesGroups();
2023-08-01 13:53:19 +00:00
$this->TeamPerformancesToTeamPerformanceDifferencesLayer->setInputVariablesGroups($inputVariablesGroups);
$this->TeamPerformancesToTeamPerformanceDifferencesLayer->buildLayer();
2023-08-01 13:53:19 +00:00
$teamDifferencesOutputVariablesGroups = $this->TeamPerformancesToTeamPerformanceDifferencesLayer->getOutputVariablesGroups();
$this->TeamDifferencesComparisonLayer->setInputVariablesGroups($teamDifferencesOutputVariablesGroups);
$this->TeamDifferencesComparisonLayer->buildLayer();
}
2023-08-02 14:14:10 +00:00
public function createPriorSchedule(): ?ScheduleSequence
{
2022-07-05 16:21:06 +02:00
switch (is_countable($this->getInputVariablesGroups()) ? count($this->getInputVariablesGroups()) : 0) {
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
2023-08-02 13:29:14 +00:00
$totalTeamDifferences = count($this->TeamPerformancesToTeamPerformanceDifferencesLayer->getLocalFactors());
2023-08-01 13:53:19 +00:00
$localFactors = $this->TeamPerformancesToTeamPerformanceDifferencesLayer->getLocalFactors();
$firstDifferencesFactor = $localFactors[0];
$lastDifferencesFactor = $localFactors[$totalTeamDifferences - 1];
2022-07-05 16:21:06 +02:00
return new ScheduleSequence(
2022-07-05 15:55:47 +02:00
'inner schedule',
[
$loop,
new ScheduleStep(
2022-07-05 15:55:47 +02:00
'teamPerformanceToPerformanceDifferenceFactors[0] @ 1',
2023-08-01 13:53:19 +00:00
$firstDifferencesFactor,
1
),
new ScheduleStep(
2022-07-05 15:55:47 +02:00
sprintf('teamPerformanceToPerformanceDifferenceFactors[teamTeamDifferences = %d - 1] @ 2', $totalTeamDifferences),
2023-08-01 13:53:19 +00:00
$lastDifferencesFactor,
2
),
2022-07-05 15:55:47 +02:00
]
);
}
2023-08-02 14:14:10 +00:00
private function createTwoTeamInnerPriorLoopSchedule(): ScheduleSequence
{
2023-08-01 13:53:19 +00:00
$teamPerformancesToTeamPerformanceDifferencesLayerLocalFactors = $this->TeamPerformancesToTeamPerformanceDifferencesLayer->getLocalFactors();
$teamDifferencesComparisonLayerLocalFactors = $this->TeamDifferencesComparisonLayer->getLocalFactors();
2010-09-18 15:24:36 -04:00
$firstPerfToTeamDiff = $teamPerformancesToTeamPerformanceDifferencesLayerLocalFactors[0];
$firstTeamDiffComparison = $teamDifferencesComparisonLayerLocalFactors[0];
2022-07-05 15:55:47 +02:00
$itemsToSequence = [
new ScheduleStep(
2022-07-05 15:55:47 +02:00
'send team perf to perf differences',
$firstPerfToTeamDiff,
2023-08-01 13:53:19 +00:00
0
),
new ScheduleStep(
2022-07-05 15:55:47 +02:00
'send to greater than or within factor',
$firstTeamDiffComparison,
2023-08-01 13:53:19 +00:00
0
),
2022-07-05 15:55:47 +02:00
];
return $this->scheduleSequence(
$itemsToSequence,
2023-08-01 13:53:19 +00:00
'loop of just two teams inner sequence'
);
}
2023-08-02 14:14:10 +00:00
private function createMultipleTeamInnerPriorLoopSchedule(): ScheduleLoop
{
2023-08-02 14:14:10 +00:00
$totalTeamDifferences = count($this->TeamPerformancesToTeamPerformanceDifferencesLayer->getLocalFactors());
2022-07-05 15:55:47 +02:00
$forwardScheduleList = [];
for ($i = 0; $i < $totalTeamDifferences - 1; $i++) {
2023-08-01 13:53:19 +00:00
$teamPerformancesToTeamPerformanceDifferencesLayerLocalFactors = $this->TeamPerformancesToTeamPerformanceDifferencesLayer->getLocalFactors();
$teamDifferencesComparisonLayerLocalFactors = $this->TeamDifferencesComparisonLayer->getLocalFactors();
2010-09-18 15:24:36 -04:00
$currentTeamPerfToTeamPerfDiff = $teamPerformancesToTeamPerformanceDifferencesLayerLocalFactors[$i];
$currentTeamDiffComparison = $teamDifferencesComparisonLayerLocalFactors[$i];
$currentForwardSchedulePiece =
$this->scheduleSequence(
2022-07-05 15:55:47 +02:00
[
new ScheduleStep(
2022-07-05 15:55:47 +02:00
sprintf('team perf to perf diff %d', $i),
2023-08-01 13:53:19 +00:00
$currentTeamPerfToTeamPerfDiff,
0
),
new ScheduleStep(
2022-07-05 15:55:47 +02:00
sprintf('greater than or within result factor %d', $i),
2023-08-01 13:53:19 +00:00
$currentTeamDiffComparison,
0
),
new ScheduleStep(
2022-07-05 15:55:47 +02:00
sprintf('team perf to perf diff factors [%d], 2', $i),
2023-08-01 13:53:19 +00:00
$currentTeamPerfToTeamPerfDiff,
2
),
],
sprintf('current forward schedule piece %d', $i)
);
2010-09-30 08:25:31 -04:00
$forwardScheduleList[] = $currentForwardSchedulePiece;
}
2022-07-05 15:55:47 +02:00
$forwardSchedule = new ScheduleSequence('forward schedule', $forwardScheduleList);
2022-07-05 15:55:47 +02:00
$backwardScheduleList = [];
for ($i = 0; $i < $totalTeamDifferences - 1; $i++) {
2023-08-01 13:53:19 +00:00
$teamPerformancesToTeamPerformanceDifferencesLayerLocalFactors = $this->TeamPerformancesToTeamPerformanceDifferencesLayer->getLocalFactors();
$teamDifferencesComparisonLayerLocalFactors = $this->TeamDifferencesComparisonLayer->getLocalFactors();
2010-09-18 15:24:36 -04:00
$differencesFactor = $teamPerformancesToTeamPerformanceDifferencesLayerLocalFactors[$totalTeamDifferences - 1 - $i];
$comparisonFactor = $teamDifferencesComparisonLayerLocalFactors[$totalTeamDifferences - 1 - $i];
$performancesToDifferencesFactor = $teamPerformancesToTeamPerformanceDifferencesLayerLocalFactors[$totalTeamDifferences - 1 - $i];
2010-09-30 08:25:31 -04:00
$currentBackwardSchedulePiece = new ScheduleSequence(
2022-07-05 15:55:47 +02:00
'current backward schedule piece',
[
new ScheduleStep(
2022-07-05 15:55:47 +02:00
sprintf('teamPerformanceToPerformanceDifferenceFactors[totalTeamDifferences - 1 - %d] @ 0', $i),
2023-08-01 13:53:19 +00:00
$differencesFactor,
0
2023-08-01 13:35:44 +00:00
),
new ScheduleStep(
2022-07-05 15:55:47 +02:00
sprintf('greaterThanOrWithinResultFactors[totalTeamDifferences - 1 - %d] @ 0', $i),
2023-08-01 13:53:19 +00:00
$comparisonFactor,
0
2023-08-01 13:35:44 +00:00
),
new ScheduleStep(
2022-07-05 15:55:47 +02:00
sprintf('teamPerformanceToPerformanceDifferenceFactors[totalTeamDifferences - 1 - %d] @ 1', $i),
2023-08-01 13:53:19 +00:00
$performancesToDifferencesFactor,
1
2023-08-01 13:35:44 +00:00
),
2023-08-01 13:53:19 +00:00
]
);
2010-09-30 08:25:31 -04:00
$backwardScheduleList[] = $currentBackwardSchedulePiece;
}
2022-07-05 15:55:47 +02:00
$backwardSchedule = new ScheduleSequence('backward schedule', $backwardScheduleList);
$forwardBackwardScheduleToLoop =
new ScheduleSequence(
2022-07-05 15:55:47 +02:00
'forward Backward Schedule To Loop',
2023-08-01 13:35:44 +00:00
[$forwardSchedule, $backwardSchedule]
);
$initialMaxDelta = 0.0001;
2022-07-05 16:21:06 +02:00
return new ScheduleLoop(
2022-07-05 15:55:47 +02:00
sprintf('loop with max delta of %f', $initialMaxDelta),
$forwardBackwardScheduleToLoop,
2023-08-01 13:35:44 +00:00
$initialMaxDelta
);
}
2022-07-05 15:55:47 +02:00
}