Расширение кругового турнира 1 на 1 до 1 на 1 на 1 на 1

Я пытаюсь расширить и улучшить алгоритм циклического перебора от группы 1 на 1 до группы 1 на 1 на 1 (что-то вроде бесплатного для всех). Я сделал саму функцию, чтобы сделать расписание, но когда я попытался расширить его, некоторые команды отступили. Например, у меня 16 команд, и я хочу провести 5 раундов, команда 1 появляется 7 раз за 5 раундов, а команда 2 появляется 3 раза за 5 раундов. Мне нужно, чтобы они появлялись максимум 5 раз. Я действительно не могу понять, как я могу это сделать. Любые советы приветствуются и ссылки.

function make_schedule(array $teams, int $rounds = null, bool $shuffle = true, int $seed = null): array
{


$teamCount = count($teams);


if($teamCount < 4) {
return [];
}
//Account for odd number of teams by adding a bye
if($teamCount % 2 === 1) {
array_push($teams, null);
$teamCount += 1;
}
if($shuffle) {
//Seed shuffle with random_int for better randomness if seed is null
srand($seed ?? random_int(PHP_INT_MIN, PHP_INT_MAX));
shuffle($teams);
} elseif(!is_null($seed)) {
//Generate friendly notice that seed is set but shuffle is set to false
trigger_error('Seed parameter has no effect when shuffle parameter is set to false');
}
$quadTeamCount = $teamCount / 4;
if($rounds === null) {
$rounds = $teamCount - 1;
}

$schedule = [];

for($round = 1; $round <= $rounds; $round += 1) {
$matchupPrev = null;

foreach($teams as $key => $team) {
if($key >= $quadTeamCount ) {
break;
}

$keyCount = $key + $quadTeamCount;
$keyCount2 = $key + $quadTeamCount + 1;
$keyCount3 = $key + $quadTeamCount + 2;


$team1 = $team;
$team2 = $teams[$keyCount];
$team3 = $teams[$keyCount2];
$team4 = $teams[$keyCount3];


//echo "<pre>Round #{$round}: {$team1} - {$team2} - {$team3} - {$team4} == KeyCount: {$keyCount} == KeyCount2: {$keyCount2} == KeyCount3: {$keyCount3}</pre>";

//Home-away swapping
$matchup = $round % 2 === 0 ? [$team1, $team2, $team3, $team4 ] : [$team2, $team1, $team4, $team3];

$schedule[$round][] = $matchup ;
}
rotate($teams);
}

return $schedule;
}

Поверните функцию:

   function rotate(array &$items)
{
$itemCount = count($items);
if($itemCount < 3) {
return;
}
$lastIndex = $itemCount - 1;
/**
* Though not technically part of the round-robin algorithm, odd-even
* factor differentiation included to have intuitive behavior for arrays
* with an odd number of elements
*/
$factor = (int) ($itemCount % 2 === 0 ? $itemCount / 2 : ($itemCount / 2) + 1);
$topRightIndex = $factor - 1;
$topRightItem = $items[$topRightIndex];
$bottomLeftIndex = $factor;
$bottomLeftItem = $items[$bottomLeftIndex];
for($i = $topRightIndex; $i > 0; $i -= 1) {
$items[$i] = $items[$i - 1];
}
for($i = $bottomLeftIndex; $i < $lastIndex; $i += 1) {
$items[$i] = $items[$i + 1];
}
$items[1] = $bottomLeftItem;
$items[$lastIndex] = $topRightItem;
}

Например:

Если я поставлю 5 раундов, каждая команда сыграет 5 матчей.
Пример массива

Работа с 5-м туром:

Что ж, после того, как я немного подумал, может быть, у них нет способа играть без повтора, но если его снизить до минимума, как каждая команда должна играть только 5 раз — это означает один раз за раунд. Это то, что я имел в виду. И что я имел в виду под «они повторяют», так это то, что есть 16 команд, 5 раундов, и некоторые команды идут как 7 раз за все эти раунды, а другие команды собираются 3 раза за эти 5 раундов. Я хочу избежать этого и заставить каждую команду играть не более 5 раундов.

1

Решение

Ваш foreach() с выбором остальных 3 команд это неправильно. Один из них должен сделать шаги с кратным 4, Если вы этого не сделаете, вы выберете команды в начале больше, чем одна, и вообще не будете выбирать команды в конце массива. Это приведет к неправильным командным матчам, подобным этому (команды — это буквы здесь):

abcd
bcde
cdef
defg

А потом твой break; хиты.

Вместо этого это должно выглядеть примерно так:

for ($i=0; $i<4; $i++) {
$matchup = array();
for ($j=0; $j<4; $j++) {
$matchup[] = $teams[4*$i+$j];
}
$schedule[$round][] = $matchup ;
}

Таким образом, вы получите следующее соединение (опять же, используя буквы как команды):

abcd
efgh
ijkl
mnop

Этот алгоритм разделит список команд на четыре группы:

abcd|efgh|ijkl|mnop

Имейте в виду, что в зависимости от перетасовки $teams массив для следующего раунда вы можете получить один и тот же противник дважды.

adei|klnf|gjmc|pobh

Здесь команды ad, kl а также op снова столкнется.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]