排序循环赛比赛

时间:2015-04-27 08:12:37

标签: php

我有一个循环算法,用于在团队之间创建匹配数组。每场比赛都在属于主队的位置进行。

创建比赛后,我想移动那些两支球队在第一轮比赛中拥有相同主位的球员。

团队示例:

$teams = array(
  'Team A' => 'Green Field',
  'Team B' => 'Blue Field',
  'Team C' => 'Green Field',
  'Team D' => 'Red Field',
  'Team E' => 'Blue Field',
);

匹配:

- Round 1
Team A vs Team D (Green Field)
Team B vs Team E (Blue Field)

- Round 2
Team A vs Team B (Green Field)
Team C vs Team D (Green Field)

- Round 2
Team A vs Team C (Green Field)
Team E vs Team D (Blue Field)

- Round 2
Team E vs Team C (Blue Field)
Team D vs Team B (Red Field)

- Round 2
Team A vs Team E (Green Field)
Team B vs Team C (Blue Field)

在这种情况下,我们会将 A队与C队移至第1轮,因为他们都有相同的位置(绿色区域)。但是,我们需要在其他地方移动 A队与D队,因为每支球队每轮只能进行一场比赛。在这个例子中,可能不会对工作进行很多调整,但是当涉及10个以上的团队时,它会变得相当棘手。特别是当有超过2支球队拥有相同的主场位置时。

这是我目前实施的实际循环算法。

// Participant IDs are unique integer identifiers for teams.
// Example array: $participants = array(1 => 'Joe', 2 => 'Marc') etc.
$ids = array_keys($participants);

$count = count($ids);

// We must add a dummy participant for odd numbers
if ($count % 2) {
  $ids[] = 0;
  $count++;
}

// There are n/2 matches per round
$match_count = $count / 2;

// Create matches for each round.
// Example array: $rounds = array(1 => '01/01/2015', 2 => '02/01/2015') etc.
foreach ($rounds as $round => $date) {
  $temp_ids = $ids;
  for ($i=0;$i<$match_count;$i++) {
    // Pick 2 competitors
    $a = array_shift($temp_ids);
    $b = array_pop($temp_ids);

    // Only create matches without dummy participants
    if ($a && $b) {
      // Initialize the match
      $match = array(
        'date' => $date,
        'participants' => array($a, $b),
        'location' => get_location($a),
      );

      $matches[] = $match;
    }
  }

  // Move the last id from participants after the first
  $id = array_pop($ids);
  array_splice($ids, 1, 0, $id);
}

1 个答案:

答案 0 :(得分:1)

这就是我要用的:

定义9个团队:

$teams = array(
    'Team A' => 'Green Field',
    'Team B' => 'Blue Field',
    'Team C' => 'Green Field',
    'Team D' => 'Red Field',
    'Team E' => 'Blue Field',
    'Team F' => 'Green Field',
    'Team G' => 'Yellow Field',
    'Team H' => 'Blue Field',
    'Team I' => 'Red Field',
);

创建3个数组来存储所有匹配项,所有主页位置以及最后所有轮次。

$matches = array();

$locations = array();

$rounds = array();

这就是你所说的:获取所有比赛。 (我也会存储团队的家庭位置供以后使用)

foreach($teams as $team1 => $home1) {
    if (!array_key_exists($home1,$locations)) $locations[$home1] = array();
    array_shift($teams);
    foreach($teams as $team2 => $home2) {
        array_push($matches,array($team1 => $home1,$team2 => $home2));
    }
}

然后我们对$matches数组进行排序,因此所有拥有相同家庭位置的团队都位于最前面。

usort($matches, function($a, $b) {
    $keysA = array_keys($a);
    $keysB = array_keys($b);
    return ($b[$keysB[0]] === $b[$keysB[1]]) - ($a[$keysA[0]] === $a[$keysA[1]]);
});

然后我们可以循环所有比赛,只要还剩下一些比赛。我们只是将可能的位置用作指标,如果它们仍然是免费的。

while(!empty($matches)) {
    array_push($rounds,$locations);
    foreach($rounds[max(array_keys($rounds))] as $location => &$match) {
        foreach($matches as $key => $val) {
            $keys = array_keys($val);
            if($val[$keys[0]] === $location || $val[$keys[1]] === $location) {
                $match = $matches[$key];
                unset($matches[$key]);
                continue 2;
            }
        }
    }
}

注意:如果您无法理解我在此处所做的事情,请询问并添加一些说明:)

而且:

print_r($rounds);

会给你这个怪物:

Array
(
    [0] => Array
        (
            [Green Field] => Array
                (
                    [Team C] => Green Field
                    [Team F] => Green Field
                )

            [Blue Field] => Array
                (
                    [Team B] => Blue Field
                    [Team H] => Blue Field
                )

            [Red Field] => Array
                (
                    [Team D] => Red Field
                    [Team I] => Red Field
                )

            [Yellow Field] => Array
                (
                    [Team E] => Blue Field
                    [Team G] => Yellow Field
                )

        )

    [1] => Array
        (
            [Green Field] => Array
                (
                    [Team A] => Green Field
                    [Team F] => Green Field
                )

            [Blue Field] => Array
                (
                    [Team E] => Blue Field
                    [Team H] => Blue Field
                )

            [Red Field] => Array
                (
                    [Team D] => Red Field
                    [Team H] => Blue Field
                )

            [Yellow Field] => Array
                (
                    [Team D] => Red Field
                    [Team G] => Yellow Field
                )

        )

    [2] => Array
        (
            [Green Field] => Array
                (
                    [Team A] => Green Field
                    [Team C] => Green Field
                )

            [Blue Field] => Array
                (
                    [Team B] => Blue Field
                    [Team E] => Blue Field
                )

            [Red Field] => Array
                (
                    [Team D] => Red Field
                    [Team F] => Green Field
                )

            [Yellow Field] => Array
                (
                    [Team F] => Green Field
                    [Team G] => Yellow Field
                )

        )

    [3] => Array
        (
            [Green Field] => Array
                (
                    [Team E] => Blue Field
                    [Team F] => Green Field
                )

            [Blue Field] => Array
                (
                    [Team H] => Blue Field
                    [Team I] => Red Field
                )

            [Red Field] => Array
                (
                    [Team A] => Green Field
                    [Team D] => Red Field
                )

            [Yellow Field] => Array
                (
                    [Team G] => Yellow Field
                    [Team I] => Red Field
                )

        )

    [4] => Array
        (
            [Green Field] => Array
                (
                    [Team F] => Green Field
                    [Team I] => Red Field
                )

            [Blue Field] => Array
                (
                    [Team G] => Yellow Field
                    [Team H] => Blue Field
                )

            [Red Field] => Array
                (
                    [Team D] => Red Field
                    [Team E] => Blue Field
                )

            [Yellow Field] => Array
                (
                    [Team B] => Blue Field
                    [Team G] => Yellow Field
                )

        )

    [5] => Array
        (
            [Green Field] => Array
                (
                    [Team F] => Green Field
                    [Team H] => Blue Field
                )

            [Blue Field] => Array
                (
                    [Team E] => Blue Field
                    [Team I] => Red Field
                )

            [Red Field] => Array
                (
                    [Team C] => Green Field
                    [Team I] => Red Field
                )

            [Yellow Field] => Array
                (
                    [Team C] => Green Field
                    [Team G] => Yellow Field
                )

        )

    [6] => Array
        (
            [Green Field] => Array
                (
                    [Team B] => Blue Field
                    [Team F] => Green Field
                )

            [Blue Field] => Array
                (
                    [Team B] => Blue Field
                    [Team D] => Red Field
                )

            [Red Field] => Array
                (
                    [Team A] => Green Field
                    [Team I] => Red Field
                )

            [Yellow Field] => Array
                (
                    [Team A] => Green Field
                    [Team G] => Yellow Field
                )

        )

    [7] => Array
        (
            [Green Field] => Array
                (
                    [Team B] => Blue Field
                    [Team C] => Green Field
                )

            [Blue Field] => Array
                (
                    [Team A] => Green Field
                    [Team H] => Blue Field
                )

            [Red Field] => Array
                (
                    [Team B] => Blue Field
                    [Team I] => Red Field
                )

            [Yellow Field] => Array
                (
                )

        )

    [8] => Array
        (
            [Green Field] => Array
                (
                    [Team A] => Green Field
                    [Team E] => Blue Field
                )

            [Blue Field] => Array
                (
                    [Team C] => Green Field
                    [Team H] => Blue Field
                )

            [Red Field] => Array
                (
                    [Team C] => Green Field
                    [Team D] => Red Field
                )

            [Yellow Field] => Array
                (
                )

        )

    [9] => Array
        (
            [Green Field] => Array
                (
                    [Team A] => Green Field
                    [Team B] => Blue Field
                )

            [Blue Field] => Array
                (
                    [Team C] => Green Field
                    [Team E] => Blue Field
                )

            [Red Field] => Array
                (
                )

            [Yellow Field] => Array
                (
                )

        )

)

由于你每轮只想要2场比赛,你可以使用以下内容(而不是最后一个while

// set matches per round
$mPerR = 2;

while(!empty($matches)) {
    $keys = array_keys($matches[0]);
    $taken = array($matches[0][$keys[0]]);
    array_push($rounds,array($matches[0][$keys[0]] => $matches[0]));
    array_shift($matches);
    for($i=1;$i<$mPerR;$i++) {
        foreach($matches as $key => $val) {
            $keys = array_keys($val);
            switch(true) {
                case(!in_array($val[$keys[0]],$taken)):
                    $location = $val[$keys[0]];
                    break;
                case(!in_array($val[$keys[1]],$taken)):
                    $location = $val[$keys[1]];
                    break;
                default:
                    continue 2;
            }
            array_push($taken,$location);
            $rounds[max(array_keys($rounds))][$location] = $matches[$key];
            unset($matches[$key]);
            $matches = array_values($matches);
            continue 2;
        }
    }
}

这将为您提供(使用您的数组示例):

Array
(
    [0] => Array
        (
            [Blue Field] => Array
                (
                    [Team B] => Blue Field
                    [Team E] => Blue Field
                )

            [Green Field] => Array
                (
                    [Team A] => Green Field
                    [Team C] => Green Field
                )

        )

    [1] => Array
        (
            [Green Field] => Array
                (
                    [Team C] => Green Field
                    [Team D] => Red Field
                )

            [Red Field] => Array
                (
                    [Team D] => Red Field
                    [Team E] => Blue Field
                )

        )

    [2] => Array
        (
            [Green Field] => Array
                (
                    [Team C] => Green Field
                    [Team E] => Blue Field
                )

            [Blue Field] => Array
                (
                    [Team B] => Blue Field
                    [Team C] => Green Field
                )

        )

    [3] => Array
        (
            [Green Field] => Array
                (
                    [Team A] => Green Field
                    [Team D] => Red Field
                )

            [Blue Field] => Array
                (
                    [Team A] => Green Field
                    [Team E] => Blue Field
                )

        )

    [4] => Array
        (
            [Green Field] => Array
                (
                    [Team A] => Green Field
                    [Team B] => Blue Field
                )

            [Blue Field] => Array
                (
                    [Team B] => Blue Field
                    [Team D] => Red Field
                )

        )

)