[英]Creating a game schedule with PHP _ Harder than I thought
我有一個未知長度的數組,它總是具有可均分的值,例如:
print_r($initialarray);
Array ( [0] => 30 [1] => 31 [2] => 32 [3] => 33 [4] => 34 [5] => 35 )
我需要創建集合:
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;
值的順序除以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;
}
所以這不起作用,我使它更加復雜,我不能再圍繞這個問題。 任何幫助,即使它意味着重新開始,將不勝感激!
我沒有直接的答案,但看起來你可能需要一點圖論。 http://en.wikipedia.org/wiki/Tournament_%28graph_theory%29
也許這段代碼可以解決你的問題,但它並不像它可能那么優雅,但似乎有效。 你應該知道ho 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);
你可以用它中的每個“游戲”構建一個數組,所以它就像
0 => 30 v 35
1 => 31 v 34
2 => 32 v 33
這應該很容易。 然后你只需要通過這個數組並將游戲放在第一排,其中沒有一支球隊已經在比賽。 可能會有更好更快的解決方案,但這是第一個出現在我腦海中的東西,我認為它很簡單。
這個問題有你想要的答案嗎?
$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/>";
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.