spread heavy workload days
This commit is contained in:
parent
85e2c33c31
commit
6dc2ccbb55
2 changed files with 65 additions and 53 deletions
|
|
@ -18,15 +18,7 @@ class EvenDistributionScheduler
|
||||||
$differenceInDays = $startDate->diff($targetDate)->days;
|
$differenceInDays = $startDate->diff($targetDate)->days;
|
||||||
$dayCount = $differenceInDays + 1;
|
$dayCount = $differenceInDays + 1;
|
||||||
|
|
||||||
if ($workloadPlacement === WorkloadPlacement::Spread) {
|
return $this->distributedDates(
|
||||||
return $this->sparseDates(
|
|
||||||
assignmentCount: $assignmentCount,
|
|
||||||
dayCount: $dayCount,
|
|
||||||
startDate: $startDate,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->groupedDates(
|
|
||||||
assignmentCount: $assignmentCount,
|
assignmentCount: $assignmentCount,
|
||||||
dayCount: $dayCount,
|
dayCount: $dayCount,
|
||||||
startDate: $startDate,
|
startDate: $startDate,
|
||||||
|
|
@ -37,33 +29,7 @@ class EvenDistributionScheduler
|
||||||
/**
|
/**
|
||||||
* @return list<DateTimeImmutable>
|
* @return list<DateTimeImmutable>
|
||||||
*/
|
*/
|
||||||
private function sparseDates(
|
private function distributedDates(
|
||||||
int $assignmentCount,
|
|
||||||
int $dayCount,
|
|
||||||
DateTimeImmutable $startDate,
|
|
||||||
): array {
|
|
||||||
if ($assignmentCount === 1) {
|
|
||||||
return [$startDate];
|
|
||||||
}
|
|
||||||
|
|
||||||
$dates = [];
|
|
||||||
for ($assignmentIndex = 0;
|
|
||||||
$assignmentIndex < $assignmentCount;
|
|
||||||
$assignmentIndex++
|
|
||||||
) {
|
|
||||||
$scaledIndex = $assignmentIndex * ($dayCount - 1)
|
|
||||||
/ ($assignmentCount - 1);
|
|
||||||
$dayIndex = (int) floor($scaledIndex + 0.5);
|
|
||||||
$dates[] = $startDate->modify("+{$dayIndex} days");
|
|
||||||
}
|
|
||||||
|
|
||||||
return $dates;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return list<DateTimeImmutable>
|
|
||||||
*/
|
|
||||||
private function groupedDates(
|
|
||||||
int $assignmentCount,
|
int $assignmentCount,
|
||||||
int $dayCount,
|
int $dayCount,
|
||||||
DateTimeImmutable $startDate,
|
DateTimeImmutable $startDate,
|
||||||
|
|
@ -71,19 +37,18 @@ class EvenDistributionScheduler
|
||||||
): array {
|
): array {
|
||||||
$assignmentsPerDay = intdiv($assignmentCount, $dayCount);
|
$assignmentsPerDay = intdiv($assignmentCount, $dayCount);
|
||||||
$remainderDayCount = $assignmentCount % $dayCount;
|
$remainderDayCount = $assignmentCount % $dayCount;
|
||||||
$remainderBlockStart = $this->remainderBlockStart(
|
$remainderDayIndexes = $this->remainderDayIndexes(
|
||||||
|
assignmentsPerDay: $assignmentsPerDay,
|
||||||
dayCount: $dayCount,
|
dayCount: $dayCount,
|
||||||
remainderDayCount: $remainderDayCount,
|
remainderDayCount: $remainderDayCount,
|
||||||
workloadPlacement: $workloadPlacement,
|
workloadPlacement: $workloadPlacement,
|
||||||
);
|
);
|
||||||
|
$remainderDays = array_fill_keys($remainderDayIndexes, true);
|
||||||
$dates = [];
|
$dates = [];
|
||||||
|
|
||||||
for ($dayIndex = 0; $dayIndex < $dayCount; $dayIndex++) {
|
for ($dayIndex = 0; $dayIndex < $dayCount; $dayIndex++) {
|
||||||
$assignmentCountForDay = $assignmentsPerDay;
|
$assignmentCountForDay = $assignmentsPerDay;
|
||||||
if (
|
if (isset($remainderDays[$dayIndex])) {
|
||||||
$dayIndex >= $remainderBlockStart
|
|
||||||
&& $dayIndex < $remainderBlockStart + $remainderDayCount
|
|
||||||
) {
|
|
||||||
$assignmentCountForDay++;
|
$assignmentCountForDay++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -96,6 +61,65 @@ class EvenDistributionScheduler
|
||||||
return $dates;
|
return $dates;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return list<int>
|
||||||
|
*/
|
||||||
|
private function remainderDayIndexes(
|
||||||
|
int $assignmentsPerDay,
|
||||||
|
int $dayCount,
|
||||||
|
int $remainderDayCount,
|
||||||
|
WorkloadPlacement $workloadPlacement,
|
||||||
|
): array {
|
||||||
|
if ($remainderDayCount === 0) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($workloadPlacement === WorkloadPlacement::Spread) {
|
||||||
|
return $this->spreadRemainderDayIndexes(
|
||||||
|
assignmentsPerDay: $assignmentsPerDay,
|
||||||
|
dayCount: $dayCount,
|
||||||
|
remainderDayCount: $remainderDayCount,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$blockStart = $this->remainderBlockStart(
|
||||||
|
dayCount: $dayCount,
|
||||||
|
remainderDayCount: $remainderDayCount,
|
||||||
|
workloadPlacement: $workloadPlacement,
|
||||||
|
);
|
||||||
|
|
||||||
|
return range($blockStart, $blockStart + $remainderDayCount - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return list<int>
|
||||||
|
*/
|
||||||
|
private function spreadRemainderDayIndexes(
|
||||||
|
int $assignmentsPerDay,
|
||||||
|
int $dayCount,
|
||||||
|
int $remainderDayCount,
|
||||||
|
): array {
|
||||||
|
if ($remainderDayCount === 1) {
|
||||||
|
if ($assignmentsPerDay === 0) {
|
||||||
|
return [0];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [intdiv($dayCount - 1, 2)];
|
||||||
|
}
|
||||||
|
|
||||||
|
$dayIndexes = [];
|
||||||
|
for ($remainderIndex = 0;
|
||||||
|
$remainderIndex < $remainderDayCount;
|
||||||
|
$remainderIndex++
|
||||||
|
) {
|
||||||
|
$scaledIndex = $remainderIndex * ($dayCount - 1)
|
||||||
|
/ ($remainderDayCount - 1);
|
||||||
|
$dayIndexes[] = (int) floor($scaledIndex + 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $dayIndexes;
|
||||||
|
}
|
||||||
|
|
||||||
private function remainderBlockStart(
|
private function remainderBlockStart(
|
||||||
int $dayCount,
|
int $dayCount,
|
||||||
int $remainderDayCount,
|
int $remainderDayCount,
|
||||||
|
|
|
||||||
|
|
@ -248,9 +248,6 @@ class CreateSchedule
|
||||||
return $workloadPlacement;
|
return $workloadPlacement;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @throws BadRequestException
|
|
||||||
*/
|
|
||||||
private function resolvedWorkloadPlacement(
|
private function resolvedWorkloadPlacement(
|
||||||
?WorkloadPlacement $requestedWorkloadPlacement,
|
?WorkloadPlacement $requestedWorkloadPlacement,
|
||||||
int $assignmentCount,
|
int $assignmentCount,
|
||||||
|
|
@ -267,15 +264,6 @@ class CreateSchedule
|
||||||
: WorkloadPlacement::Middle;
|
: WorkloadPlacement::Middle;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
|
||||||
$requestedWorkloadPlacement === WorkloadPlacement::Spread
|
|
||||||
&& ! $isSparse
|
|
||||||
) {
|
|
||||||
throw new BadRequestException(
|
|
||||||
'spread placement requires fewer assignments than days',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $requestedWorkloadPlacement;
|
return $requestedWorkloadPlacement;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue