简体   繁体   English

排序循环赛

[英]Sorting Round Robin matches

I have a round robin algorithm for creating an array of matches between teams. 我有一个循环算法,用于在团队之间创建比赛数组。 Each match is played at the location belonging to the home team. 每场比赛都在主队所属位置进行。

Once the matches are created, I'd like to move those where both teams have the same home location up to the first round(s). 比赛创建完成后,我想将两支球队拥有相同主场位置的球队移动到第一轮。

Example array of teams: 团队示例:

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

And matches: 并匹配:

- 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)

In this case, we would move Team A vs Team C up to Round 1 because they both have the same location (Green Field). 在这种情况下,我们会将A队与C队移到第1轮,因为他们的位置相同(绿地)。 However, we'd then need to move Team A vs Team D somewhere else because each team can only play one match per round. 但是,我们随后需要将A队与D队移到其他地方,因为每个队每局只能打一场比赛。 In this example it probably wouldn't take many adjustments to work but when there is 10+ teams involved then it gets pretty sticky. 在此示例中,可能不需要太多调整即可工作,但是当涉及到10个以上的团队时,它会变得很粘。 Especially when there is more than 2 teams with the same home location. 尤其是当有两个以上的团队拥有相同的归属位置时。

Here is the actual round robin algorithm that I currently have implemented. 这是我当前已实现的实际循环算法。

// 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);
}

This is what I would use: 这就是我要使用的:

Define 9 teams: 定义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',
);

Create 3 arrays to store all matches, all home locations and finally all rounds. 创建3个数组来存储所有比赛,所有主场位置以及最终所有回合。

$matches = array();

$locations = array();

$rounds = array();

This is what you said you have: Get all matches. 这就是您说的:获得所有比赛。 (I do also store the home locations of the teams for later usage) (我还会存储团队的主场位置,以备后用)

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));
    }
}

Then we sort the $matches array, so all teams with the same home location are on top. 然后,我们对$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]]);
});

And then we can just loop over all matches as long as there are some left to play. 然后,只要剩下一些比赛,我们就可以循环所有比赛。 We just use the possible locations as an indicator, if they are still free. 如果可能的位置仍然免费,我们仅将其用作指标。

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;
            }
        }
    }
}

Note: If you have trouble understanding what I did here, just ask and I will add some description :) 注意:如果您在理解我在这里所做的事情时遇到困难,请问一下,我会添加一些描述:)

And this: 和这个:

print_r($rounds);

Will give you this monster: 会给你这个怪物:

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
                (
                )

        )

)

As you only want to have 2 games per round, you can use the following (instead of the last while : 由于您只希望每轮有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;
        }
    }
}

This will give you (using your array example): 这将给您(使用您的数组示例):

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
                )

        )

)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM