Нужна помощь с логикой, сделайте трехмерный массив (PHP)

Мне нужна помощь, например, у меня есть массив с 4 именами команд.

array('logiX.L4d22','Lust','Marat and Friends','Pandas of Belgium');

Я хочу создать трехмерный массив, где первый - раунд, второй - матч, а третий - команды, которые играют друг с другом, всегда будет 2 команды.

логика должна заключаться в том, что все команды должны играть вместе со всеми другими, и в одном раунде любая команда сыграет только один матч, поэтому, если у нас 5 команд, то в каком-то раунде одна команда должна просто дождаться следующего раунда.

он должен произвести что-то вроде этого:

array
  0 => 
    array
      0 => 
        array
          0 => string 'logiX.L4D2' (length=10)
          1 => string 'Lust' (length=4)
      1 => 
        array
          0 => string 'Marat and Friends' (length=17)
          1 => string 'Pandas of Belgium' (length=17)
  1 => 
    array
      0 => 
        array
          0 => string 'logiX.L4D2' (length=10)
          1 => string 'Marat and Friends' (length=17)
      1 => 
        array
          0 => string 'Lust' (length=4)
          1 => string 'Pandas of Belgium' (length=17)
  2 => 
    array
      0 => 
        array
          0 => string 'logiX.L4D2' (length=10)
          1 => string 'Pandas of Belgium' (length=17)
      1 => 
        array
          0 => string 'Lust' (length=4)
          1 => string 'Marat and Friends' (length=17)

Работать надо с 2,3,5 ... 10 ... 12 командами.

Надеюсь, вы мне поможете, я уже потратил на это полтора дня.


person Kuido    schedule 30.03.2011    source источник
comment
Действительно нечетко сформулировано. Что именно вы ищете? Предложение структуры массива? Решение сценария PHP?   -  person Gerben Jacobs    schedule 30.03.2011
comment
Мне нужно решение для PHP-скрипта ... извините за это непонятно   -  person Kuido    schedule 30.03.2011
comment
Возможный дубликат stackoverflow.com/questions/658727/   -  person Frosty Z    schedule 30.03.2011
comment
это хорошая ссылка для меня .. спасибо, но любые сообщения здесь по-прежнему приветствуются   -  person Kuido    schedule 30.03.2011


Ответы (2)


Поиск в Google по циклическому алгоритму PHP дает следующее:

http://speedtech.it/blog/2009/03/15/round-robin-algorithm-php/

http://www.phpbuilder.com/board/showthread.php?t=10300945

Надеюсь, ты найдешь то, что ищешь.

ИЗМЕНИТЬ

Добавляю свою попытку для этого, следуя циклическому алгоритму, описанному в Википедии.

Если номер команды нечетный, он добавляет команду в массив (нулевое значение), так что вы можете получить «ожидающую команду» для каждого раунда.

<?php

$teams = range('a', 'g');

function make_rounds($teams)
{
  $nb_teams = count($teams);

  if ($nb_teams % 2 != 0)
  {
    $teams[] = null;
    $nb_teams++;
  }

  $nb_rounds = $nb_teams - 1;
  $nb_matches = $nb_teams / 2;

  $rounds = array();

  for($round_index = 0; $round_index < $nb_rounds; $round_index++)
  {
    $matches = array();

    for($match_index = 0; $match_index < $nb_matches; $match_index++)
    {
      if ($match_index == 0)
        $first_team = $teams[0];
      else
        $first_team = $teams[(($nb_teams-2) + $match_index - $round_index) % ($nb_teams-1) + 1];

      $second_team = $teams[(($nb_teams*2) - $match_index - $round_index - 3) % ($nb_teams-1) + 1];

      $matches[] = array($first_team, $second_team);
    }

    $rounds[] = $matches;
  }

  return $rounds;
}

print_r(make_rounds($teams));
person Frosty Z    schedule 30.03.2011

Моя версия решения. Я бы назвал это грубой силой. Однако как-то работает. (Или так выглядит.)

<?php

$a = array('a','b','c','d','e','f','g');

function do_array($a)
{
    $lim = sizeof($a) - 1;

    # Create an array of all matches to play.
    $cross = array(array());
    foreach (range(0,$lim) as $k_row):
        foreach (range(0,$lim) as $k_col):
            if ($k_row >= $k_col):
                $toput = false; 
            else:
                $toput = array($a[$k_row],$a[$k_col]);
            endif;
            $cross[$k_row][$k_col] = $toput;
        endforeach;
    endforeach;

    $ret = array();
    foreach (range(0,$lim) as $k_round):
        $round = array();
        # $tmp array holds all possible matches
        # to play in current round.
        $tmp = $cross;
        $i = 0;
        foreach (range(0,$lim) as $k_row):
            foreach (range(0,$lim) as $k_col):
                if ($math = $tmp[$k_row][$k_col]):
                    $cross[$k_row][$k_col] = false;
                    # These matches are not possible
                    # in the current round.
                    foreach (range(0,$lim) as $k):
                        $tmp[$k][$k_col] = false;
                        $tmp[$k][$k_row] = false;
                        $tmp[$k_col][$k] = false;
                        $tmp[$k_row][$k] = false;
                    endforeach;
                    $round[] = $math;
                endif;
            endforeach;
        endforeach;
        if ($round):
            $ret[] = $round;
        endif;
    endforeach;

    return $ret;
}

print_r (do_array($a));

?>
person Michas    schedule 30.03.2011
comment
Маленькая деталь: здесь я бы посоветовал использовать for(...) вместо foreach(range(...)). См. Этот комментарий: php.net/manual/fr/function.range. php # 85331 - person Frosty Z; 30.03.2011
comment
Я знаю, что это не так быстро. Однако я думаю, что это более читабельно. - person Michas; 30.03.2011