从平面数组生成循环赛时间表

发布于 2024-07-30 06:15:12 字数 1751 浏览 3 评论 0原文

我有一个长度未知的数组,它总是有可均匀整除的值,例如:

print_r($initialarray);

Array ( [0] => 30 [1] => 31 [2] => 32 [3] => 33 [4] => 34 [5] => 35 ) 

我需要创建集合:

第 1 组:30 v 35;   31 对 34;   32 对 33; 

  第2组:30对34;   31 对 33;   32 对 35; 

  第三组:30对33;   31 对 32;   34 对 35; 

  第4组:30对32;   33 对 34;   31 对 35; 

  第5组:30对31;   32 对 34;   33 对 35;  
  

值的顺序除以 v 表示它们是一个集合。 集合中值的顺序并不重要(我随机地将它们放在一起)。 正如您所看到的,任何其他集合或同一集合中都不能有重复的集合匹配。

我尝试了很多不同的方法来想出一些可行的方法。 我得到的最接近的是将初始值放入一个包含所有可能的有效匹配的级联数组中:

Array ( [0] => Array ( [0] => 35 [1] => 31 ) [1] => Array ( [0] => 34 [1] => 31 ) [2] => Array ( [0] => 33 [1] => 31 ) [3] => Array ( [0] => 32 [1] => 31 ) )

Array ( [0] => Array ( [0] => 35 [1] => 32 ) [1] => Array ( [0] => 34 [1] => 32 ) [2] => Array ( [0] => 33 [1] => 32 ) )

Array ( [0] => Array ( [0] => 35 [1] => 33 ) [1] => Array ( [0] => 34 [1] => 33 ) )

Array ( [0] => Array ( [0] => 35 [1] => 34 ) ) 

这些值是一个名为 $sched 的数组中的数组。 我在数组中留下了 30 个..哎呀

这些数字是团队。 每支球队需要与每支球队比赛一次。 赛程安排将确保每支球队每周只打一场比赛。 时间表需要在几周内设定,以便允许所有比赛都可以进行,而无需一支球队每周比赛多次。

我已经使用了排列函数,这就是我如何想出上面的数组的方法没有相同的匹配。 我现在需要弄清楚如何输出上面的集合中所示的时间表。 (请记住,只要没有球队在同一组中比赛两次,示例的顺序并不重要)

$count = count($initialarray);
$recount = $count -1;
for($u=0; $u < $count;$u++){
    for($d=0;$d<$recount;$d++){
         $vs[$u][$d] = $sched[$d][$u];
    }
$recount -= 1;
}

所以这不起作用,我使这超出了应有的复杂性,并且我无法包装我的不再关注这个问题了。 任何帮助,即使意味着重新开始,都将不胜感激!

I have an array of an unknown length which will always have an evenly divisible amount of values, for example:

print_r($initialarray);

Array ( [0] => 30 [1] => 31 [2] => 32 [3] => 33 [4] => 34 [5] => 35 ) 

I need to create sets:

Set 1: 30 v 35; 31 v 34; 32 v 33;

Set 2: 30 v 34; 31 v 33; 32 v 35;

Set 3: 30 v 33; 31 v 32; 34 v 35;

Set 4: 30 v 32; 33 v 34; 31 v 35;

Set 5: 30 v 31; 32 v 34; 33 v 35; 

The order of the values are divide by v to indicate they are a set. The ordering of the values in the set does not matter (I put that together at random out of my head). As you can see there can not be duplicate sets matching in any other set or within the same set.

I have tried many different things to come up with something that works.
The closest I've gotten was putting the initial values into a cascading array containing all possible valid matchups:

Array ( [0] => Array ( [0] => 35 [1] => 31 ) [1] => Array ( [0] => 34 [1] => 31 ) [2] => Array ( [0] => 33 [1] => 31 ) [3] => Array ( [0] => 32 [1] => 31 ) )

Array ( [0] => Array ( [0] => 35 [1] => 32 ) [1] => Array ( [0] => 34 [1] => 32 ) [2] => Array ( [0] => 33 [1] => 32 ) )

Array ( [0] => Array ( [0] => 35 [1] => 33 ) [1] => Array ( [0] => 34 [1] => 33 ) )

Array ( [0] => Array ( [0] => 35 [1] => 34 ) ) 

These values are arrays within one array called $sched.
I left 30 out of the array.. oops

The numbers are teams. Each team needs to play each team once. The schedule will be set so that each team only plays one game each week.
The schedule needs to be set over several weeks to allow all the games to be played without a team playing more than once in a week.

I have already used a permutations function and that is how I came up with array above which doesn't have identical match ups. I need to now figure out how to output the schedule as shown in the Sets above. (keeping in mind that the order the example is in doesn't matter as long as no team plays twice in the same set)

$count = count($initialarray);
$recount = $count -1;
for($u=0; $u < $count;$u++){
    for($d=0;$d<$recount;$d++){
         $vs[$u][$d] = $sched[$d][$u];
    }
$recount -= 1;
}

So that didn't work, I am complicating this beyond what it should be and I can't wrap my head around the issue anymore. Any help at all, even it means starting over, will be greatly appreciated!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

零度° 2024-08-06 06:15:12

也许这段代码可以解决您的问题,它并不那么优雅,但它似乎可以工作。
您应该知道arrangeGames 是如何工作的;)

也许您需要注意arrangePlayerforDays。 仅当双方球员当天都没有安排比赛时,它才会将各种比赛放在一天中。
另一个函数只是为了使代码更具可读性(并覆盖 arrangePlayerforDays 中的一对小故障)

function gamePrettyPrint($gamesOnADay, $glue) {
  $result=array();
  foreach ($gamesOnADay as $currentGame) 
      $result[]=join($glue,$currentGame);
  return $result;
}

function arrangeGamesOnAday($day) {
  $result=array();
  for ($k=0, $limit=count($day); $k<$limit; $k+=2)
      $result[]=array($day[$k+1], $day[$k]);
  return $result;
}

function arrangeGames($players) { 
  for ($i=0, $limit=count($players); $i < $limit; $i++) 
    for ($j=$i+1; $j<$limit;$j++) 
      $games[]=array($players[$i], $players[$j]);
  return $games;
}

function calculateTournamentDuration($players) {
  return  count($players)-1; // (n!)/(2!*(n-2)!) * (1/n)
}

function arrangePlayerforDays($games, $days) {
  $mem = array_pad(array(),$tournamentDays,array());
  for ($k=0;count($games);$k++)
    if ((array_search($games[0][0],$mem[$k%$days])=== false)  and
        (array_search($games[0][1],$mem[$k%$days])=== false))
      list($mem[$k%$days][], $mem[$k%$days][]) = array_shift($games);
  return ($mem);
}

function scatterGamesOnCalendar($games, $tournamentDays) {
  $days=arrangePlayerforDays($games, $tournamentDays);
  $calendar=array_map('arrangeGamesOnAday',$days);
  return $calendar;
}

//  $initialArray = array('a','b','c','d','e','f','g','h');
$initialArray = array(30,31,32,33,34,35);

$games= arrangeGames($initialArray);
$tournamentSpan = calculateTournamentDuration($initialArray);
$calendar = scatterGamesOnCalendar($games, $tournamentSpan);

while ($day=array_shift($calendar))
  $prettyCalendar[]=gamePrettyPrint($day,' v ');

print_r($prettyCalendar);

Maybe this code solve your problem, it is not as elegant as it could be but it seems to work.
You should know ho arrangeGames works ;)

Maybe you need to pay attention on arrangePlayerforDays. It put the various games in a day only if both of the players don't have a game already scheduled on that day.
The other function are just for make the code more readable (and cover a pair of glitches in arrangePlayerforDays)

function gamePrettyPrint($gamesOnADay, $glue) {
  $result=array();
  foreach ($gamesOnADay as $currentGame) 
      $result[]=join($glue,$currentGame);
  return $result;
}

function arrangeGamesOnAday($day) {
  $result=array();
  for ($k=0, $limit=count($day); $k<$limit; $k+=2)
      $result[]=array($day[$k+1], $day[$k]);
  return $result;
}

function arrangeGames($players) { 
  for ($i=0, $limit=count($players); $i < $limit; $i++) 
    for ($j=$i+1; $j<$limit;$j++) 
      $games[]=array($players[$i], $players[$j]);
  return $games;
}

function calculateTournamentDuration($players) {
  return  count($players)-1; // (n!)/(2!*(n-2)!) * (1/n)
}

function arrangePlayerforDays($games, $days) {
  $mem = array_pad(array(),$tournamentDays,array());
  for ($k=0;count($games);$k++)
    if ((array_search($games[0][0],$mem[$k%$days])=== false)  and
        (array_search($games[0][1],$mem[$k%$days])=== false))
      list($mem[$k%$days][], $mem[$k%$days][]) = array_shift($games);
  return ($mem);
}

function scatterGamesOnCalendar($games, $tournamentDays) {
  $days=arrangePlayerforDays($games, $tournamentDays);
  $calendar=array_map('arrangeGamesOnAday',$days);
  return $calendar;
}

//  $initialArray = array('a','b','c','d','e','f','g','h');
$initialArray = array(30,31,32,33,34,35);

$games= arrangeGames($initialArray);
$tournamentSpan = calculateTournamentDuration($initialArray);
$calendar = scatterGamesOnCalendar($games, $tournamentSpan);

while ($day=array_shift($calendar))
  $prettyCalendar[]=gamePrettyPrint($day,' v ');

print_r($prettyCalendar);
我最亲爱的 2024-08-06 06:15:12

你可以构建一个数组,其中包含每个“游戏”,所以它就像

0 => 30 v 35
1 => 31 v 34
2 => 32 v 33

这样,这应该很容易。 然后你只需浏览这个数组并将比赛放在第一行,那里没有球队正在比赛。 可能有更好更快的解决方案,但这是我首先想到的,我认为它写起来很简单。

You could build a array with each "game" in it so it is sth like

0 => 30 v 35
1 => 31 v 34
2 => 32 v 33

That should be quite easy. Then you just go through this array and put the game in the first row where none of the teams is already playing. There might be better and faster solutions but this is the first that came to my mind and i think its quite simple to write.

走过海棠暮 2024-08-06 06:15:12
$team = array( 1 => 30 , 2 => 31 , 3 => 32 , 4 => 33 , 5 => 34 , 6 => 35 );

$numplayers = count($team);
if ($numplayers % 2 != 0) $numplayers++; 
for ($round = 0;$round < $numplayers - 1;$round++) {
    echo 'Set ' . ($round+1) . ":\n\n{$team[1]}-";
    for ($i = 0;$i < $numplayers-1;$i++) {
        if ($i % 2 == 0) {
            $player = ($numplayers-2) - ($i/2) - $round;
        } else {
            $player = ((($i-1)/2) - $round);
        }
        if ($player < 0) $player += $numplayers - 1;
        echo $team[$player+2];
        echo ($i % 2 == 0) ? "\n" : '-';
    }
    echo "\n\n<br/>";
}
$team = array( 1 => 30 , 2 => 31 , 3 => 32 , 4 => 33 , 5 => 34 , 6 => 35 );

$numplayers = count($team);
if ($numplayers % 2 != 0) $numplayers++; 
for ($round = 0;$round < $numplayers - 1;$round++) {
    echo 'Set ' . ($round+1) . ":\n\n{$team[1]}-";
    for ($i = 0;$i < $numplayers-1;$i++) {
        if ($i % 2 == 0) {
            $player = ($numplayers-2) - ($i/2) - $round;
        } else {
            $player = ((($i-1)/2) - $round);
        }
        if ($player < 0) $player += $numplayers - 1;
        echo $team[$player+2];
        echo ($i % 2 == 0) ? "\n" : '-';
    }
    echo "\n\n<br/>";
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文