我试图制作一个随机的名单。我遇到了麻烦。
我需要1 C 2 P SS CF 3 LF RF
创建9个随机顺序,它们不按顺序重复,一个值也不会两次相同的位置。就像一个网格,每个位置使用9次,最多9次。但我希望能够将它随机化。所以它并不总是一样的。我的意思是我想我可以随机化这些名字,但名字通常是按照特定的顺序排列,而这些位置不一定是,但不是骗子。
123456789
234567891
345678912
456789123
567891234
678912345
789123456
891234567
912345678
我从这开始,但没有任何意义。起初,我确保不重复任何职位,但我意识到它并非如此,我有点卡住了。
shuffle($positions);
$p1 = $positions;
echo '<table style="width:100%;"><tr>';
foreach($p1 as $pA){
echo '<td>'.$pA.'</td>';
}
echo '</tr>';
shuffle($positions);
$p2 = $positions;
if($p2 === $p1){
while($p2 === $p1){
shuffle($positions);
$p2 = $positions;
$a++;
echo '<br>=a=<br>'.$a.'<br>==<br>';
//if($p2 == $p1){continue;}else{break;}
}
}
echo '<tr>';
foreach($p2 as $pB){
echo '<td>'.$pB.'</td>';
}
echo '</tr>';
shuffle($positions);
$p3 = $positions;
if($p3 === ($p1 || $p2)){
while($p3 === ($p1 || $p2)){
shuffle($positions);
$p3 = $positions;
$b++;
echo '<br>=b=<br>'.$b.'<br>==<br>';
//if($p2 == ($p1 || $p2)){continue;}else{break;}
}
}
echo '<tr>';
foreach($p3 as $pC){
echo '<td>'.$pC.'</td>';
}
echo '</tr>';
shuffle($positions);
$p4 = $positions;
if($p4 === ($p1 || $p2 || $p3)){
while($p4 === ($p1 || $p2 || $p3)){
shuffle($positions);
$p4 = $positions;
$c++;
echo '<br>=c=<br>'.$c.'<br>==<br>';
//if($p2 == ($p1 || $p2)){continue;}else{break;}
}
}
echo '<tr>';
foreach($p4 as $pD){
echo '<td>'.$pD.'</td>';
}
echo '</tr>';
shuffle($positions);
$p5 = $positions;
if($p5 === ($p1 || $p2 || $p3 || $p4)){
while($p5 === ($p1 || $p2 || $p3 || $p4)){
shuffle($positions);
$p5 = $positions;
$d++;
echo '<br>=d=<br>'.$d.'<br>==<br>';
//if($p2 == ($p1 || $p2)){continue;}else{break;}
}
}
echo '<tr>';
foreach($p5 as $pE){
echo '<td>'.$pE.'</td>';
}
echo '</tr>';
shuffle($positions);
$p6 = $positions;
if($p6 === ($p1 || $p2 || $p3 || $p4 || $p5)){
while($p6 === ($p1 || $p2 || $p3 || $p4 || $p5)){
shuffle($positions);
$p6 = $positions;
$e++;
echo '<br>=d=<br>'.$e.'<br>==<br>';
//if($p2 == ($p1 || $p2)){continue;}else{break;}
}
}
echo '<tr>';
foreach($p6 as $pF){
echo '<td>'.$pF.'</td>';
}
echo '</tr>';
shuffle($positions);
$p7 = $positions;
if($p7 === ($p1 || $p2 || $p3 || $p4 || $p5 || $p6)){
while($p7 === ($p1 || $p2 || $p3 || $p4 || $p5 || $p6)){
shuffle($positions);
$p7 = $positions;
$f++;
echo '<br>=d=<br>'.$f.'<br>==<br>';
//if($p2 == ($p1 || $p2)){continue;}else{break;}
}
}
echo '<tr>';
foreach($p7 as $pG){
echo '<td>'.$pG.'</td>';
}
echo '</tr>';
shuffle($positions);
$p8 = $positions;
if($p8 === ($p1 || $p2 || $p3 || $p4 || $p5 || $p6 || $p7)){
while($p8 === ($p1 || $p2 || $p3 || $p4 || $p5 || $p6 || $p7)){
shuffle($positions);
$p8 = $positions;
$g++;
echo '<br>=d=<br>'.$g.'<br>==<br>';
//if($p2 == ($p1 || $p2)){continue;}else{break;}
}
}
echo '<tr>';
foreach($p8 as $pH){
echo '<td>'.$pH.'</td>';
}
echo '</tr>';
shuffle($positions);
$p9 = $positions;
if($p9 === ($p1 || $p2 || $p3 || $p4 || $p5 || $p6 || $p7 || $p8)){
while($p9 === ($p1 || $p2 || $p3 || $p4 || $p5 || $p6 || $p7 || $p8)){
shuffle($positions);
$p9 = $positions;
$h++;
echo '<br>=d=<br>'.$h.'<br>==<br>';
//if($p2 == ($p1 || $p2)){continue;}else{break;}
}
}
echo '<tr>';
foreach($p9 as $pI){
echo '<td>'.$pI.'</td>';
}
echo '</tr>';
shuffle($positions);
$p10 = $positions;
if($p10 === ($p1 || $p2 || $p3 || $p4 || $p5 || $p6 || $p7 || $p8 || $p9)){
while($p10 === ($p1 || $p2 || $p3 || $p4 || $p5 || $p6 || $p7 || $p8 || $p9)){
shuffle($positions);
$p10 = $positions;
$i++;
echo '<br>=d=<br>'.$i.'<br>==<br>';
//if($p2 == ($p1 || $p2)){continue;}else{break;}
}
}
echo '<tr>';
foreach($p10 as $pJ){
echo '<td>'.$pJ.'</td>';
}
echo '</tr>';
echo '</table>';
?>
答案 0 :(得分:1)
詹姆斯,我知道当你拥有一堆allstars并且你想成为一个公平的教练时会很难,这样每个人都能得到同样的机会。随机化代码以拯救。这张桌子唯一没有考虑的是名单波动 - 如果你有一个生病/受伤的球员,你将不得不进行调整。
此代码将输出您要查找的网格。虽然它没有针对速度进行优化,但只需要约0.25秒即可完成 - 因此性能不会成为您的问题。 Performance Test
<?php
$players=array(
"Mickey Mantle",
"Babe Ruth",
"Yogi Berra",
"Lou Gehrig",
"Joe DiMaggio",
"Derek Jeter",
"Whitey Ford",
"Roger Maris",
"Reggie Jackson"
);
$positions=array("P","C","1","2","SS","3","LF","CF","RF");
$batch=array();
echo "<table border=1>";
echo "<tr><th>#</th><th>",implode("</th><th>",$players),"</th></tr>";
for($week=1; $week<11; ++$week){
if($week==9){
// see what's missing (use remaining value versus needless looping)
foreach($players as $i=>$v){
$batch[$week][$i]=current(array_diff($positions,array_column($batch,$i)));
}
}elseif($week==10){
// purely random, as every player has played every position by now.
shuffle($positions);
$batch[$week]=$positions;
}else{ // weeks 1 - 8
while(!isset($batch[$week])){
shuffle($positions);
$batch[$week]=$positions;
//echo "<tr><td>",implode("</td><td>",$batch[$week]),"</td></tr>";
if($week>1){ // check for no duplicate positions for any player
foreach($batch[$week] as $i=>$v){
//echo "<tr><td colspan=9>",implode(', ',array_column($batch,$i)),"</td></tr>";
if(sizeof(array_unique(array_column($batch,$i)))<$week){ // if vertical duplicates
unset($batch[$week]); // trash the week, trigger rerun of loop
break; // don't bother to assign positions for remaining players
}
}
}
}
}
echo "<tr><th>$week</th><td>",implode("</td><td>",$batch[$week]),"</td></tr>";
}
echo "</table>";
?>
输出:
如果我的代码没有获得批准的绿色标记,请通过编辑澄清您的问题。如果您有疑问,我很乐意解释任何问题。事实是,我喜欢这个挑战;我每周都喜欢其中一个!
答案扩展 - 具有更高灵活性和效率的功能
说实话,我从来没有真正放弃过这方面的工作 - 我只是不太擅长让事情无法解决。您的发票在邮件中;)
这完全没有意义 - 不要去尝试卖掉它!我已经使用9个局/周期,9个位置和(9,13和18)球员测试了以下功能/代码,我无法打破它。
当我将时间段设置为4而名单和位置要高得多时,它确实会中断。这可能是一个逻辑问题,数学家可以详细解释 - 我不会去那个兔子洞。
我将留下所有评论和调试回声,以防将来有人需要了解/修改/改进它。
请在函数调用之前阅读fineprint。
function fairRotation($roster=[],$positions=[],$rotations=9,$off="X"){
$roster_count=sizeof($roster);
$positions_count=sizeof($positions);
echo "<div>roster_count=$roster_count, positions_count=$positions_count</div>";
$ons_avg=$positions_count/$roster_count;
$ons_max=ceil($ons_avg);
$ons_min=floor($ons_avg);
echo "<div>ons_avg=$ons_avg, ons_max=$ons_max, ons_min=$ons_min</div>";
$off_avg=($roster_count-$positions_count)*$rotations/$roster_count;
$off_max=ceil($off_avg);
$off_min=floor($off_avg);
echo "<div>off_avg=$off_avg, off_max=$off_max, off_min=$off_min</div><br>";
$positions=array_pad($positions,$roster_count,$off); // sync positions with roster using sub identifier
$positions_count=sizeof($positions); // overwrite with updated count
for($r=0; $r<$rotations; ++$r){
shuffle($positions);
$result[$r]=$positions;
}
//$color_result=$result;
// unfiltered result:
/*echo "<table border=1>";
echo "<tr><th>#</th><th>",implode("</th><th>",$roster),"</th></tr>";
foreach($result as $key=>$row){
echo "<tr><th>",($key+1),"</th><td>",implode("</td><td>",$row),"</td></tr>";
}
echo "</table>"; */
// Assess result and address conflicts...
$iterations=0;
$fair="?";
$must_drop_count=0;
$must_gain_count=0;
while($fair!="true" && $iterations<500){
$must_gain=$must_drop=$may_gain=$may_drop=[]; // reset
for($c=0; $c<$roster_count; ++$c){ // triage each column
$col=array_column($result,$c);
$val_counts[$c]=array_merge(array_fill_keys($positions,0),array_count_values($col));
foreach($val_counts[$c] as $pos=>$cnt){
if(($pos!=$off && $cnt<$ons_min) || ($pos==$off && $cnt<$off_min)){
$must_gain[$c][$pos]=array_keys($col,$pos); // column/player must gain this position, but not where row = value(s)
}elseif(($pos!=$off && $cnt>$ons_max) || ($pos==$off && $cnt>$off_max)){
$must_drop[$c][$pos]=array_keys($col,$pos); // column/player must drop this position, but only where row = value(s)
}elseif(($pos!=$off && $cnt<$ons_max) || ($pos==$off && $cnt<$off_max)){
$may_gain[$c][$pos]=array_keys($col,$pos); // column/player may gain this position, but not where row = value(s)
}elseif(($pos!=$off && $cnt>$ons_min) || ($pos==$off && $cnt>$off_min)){
$may_drop[$c][$pos]=array_keys($col,$pos); // column/player may drop this position, but only where row = value(s)
}
}
}
if(sizeof($must_gain)==0 && sizeof($must_drop)==0){
$fair="true";
}elseif(sizeof($must_drop)==$must_drop_count && sizeof($must_gain)==$must_gain_count){
//var_export($must_drop);
//echo "<br>Program Deadlock @ $iterations Iterations.";
//echo "<br>Desperately reshuffle one of the deadlocked rows.";
shuffle($positions);
if($must_drop_count>0){
$result[current(current(current($must_drop)))]=$positions;
//$color_result[current(current(current($must_drop)))]=$positions;
}else{
$result[current(current(current($must_gain)))]=$positions;
//$color_result[current(current(current($must_gain)))]=$positions;
}
}else{
$must_drop_count=sizeof($must_drop);
$must_gain_count=sizeof($must_gain);
//echo "<br><div>MustDrop:$must_drop_count , MustGain:$must_gain_count</div>";
foreach($must_drop as $d1col=>$d1array){ // $must_drop1[0]["SS"]=array(3,8);
++$iterations;
//echo "<div>({$iterations}x): {$roster[$d1col]} must drop ";
//var_export($d1array);
foreach($d1array as $d1pos=>$d1keys){
foreach(array_diff_key($must_drop,array($d1col=>"")) as $d2col=>$d2array){ // dual-solution swap
foreach($d2array as $d2pos=>$d2keys){
//echo "<div>..seeking a new home for $d1pos</div>";
if($d1pos!=$d2pos && (isset($must_gain[$d1col][$d2pos]) || isset($may_gain[$d1col][$d2pos]))){
//echo "<div>{$roster[$d1col]} may drop $d1pos for {$roster[$d2col]}'s $d2pos</div>";
foreach($d2keys as $row){
//echo "<div>checking {$roster[$d2col]}'s row($row) holding $d2pos vs {$roster[$d1col]}'s $d1pos ";
//var_export($d1keys);
//echo "</div>";
if(in_array($row,$d1keys)){
//echo "<div>row match on $row between {$roster[$d1col]} & {$roster[$d2col]}</div>";
if(isset($must_gain[$d1col][$d2pos])){
//echo "<div>Success: {$roster[$d1col]} must gain holds $d2pos</div>";
//$color_result[$row][$d1col]="<span style='background-color:green;'>$d2pos</span>";
//$color_result[$row][$d2col]="<span style='background-color:blue;'>$d1pos</span>";
$result[$row][$d1col]=$d2pos;
$result[$row][$d2col]=$d1pos;
//var_export($result[$row]);
//echo "<br>";
//unset($must_drop[$d1col][$d1pos],$must_gain[$d2col][$d2pos],$must_gain[$d1col][$d2pos],$must_gain[$d2col][$d1pos]);
break(5);
}elseif(isset($may_gain[$d1col][$d2pos])){
//echo "<div>Success: {$roster[$d1col]} may gain holds $d2pos</div>";
//$color_result[$row][$d1col]="<span style='background-color:red;'>$d2pos</span>";
//$color_result[$row][$d2col]="<span style='background-color:orange;'>$d1pos</span>";
$result[$row][$d1col]=$d2pos;
$result[$row][$d2col]=$d1pos;
//var_export($result[$row]);
//echo "<br>";
//unset($must_drop[$d1col][$d1pos],$must_gain[$d2col][$d2pos],$may_gain[$d1col][$d2pos],$may_gain[$d2col][$d1pos]);
break(5);
}else{
//echo "<div>No Eligible Swap: {$roster[$d1col]} doesn't need/want $d2pos @ row$row";
//var_export(array_merge(array(),$must_gain[$d1col],$may_gain[$d1col]));
//echo "</div>";
}
}
//echo "<br>";
}
}
}
}
}
//echo "</div><br>";
}
}
}
if($fair=="true"){
echo "<div>FAIR! after $iterations adjustments</div>";
return $result; // $color_result for color
}else{
echo "Runaway Deadlock, Call Full Rerun<br>";
return false;
}
}
$roster=array(
"Mickey Mantle","Babe Ruth","Yogi Berra","Lou Gehrig","Joe DiMaggio",
"Derek Jeter","Whitey Ford","Roger Maris","Reggie Jackson","sub1","sub2","sub3","sub4","sub5","sub6","sub7","sub8","sub9");
$positions=array("P","C","1st","2nd","SS","3rd","LF","CF","RF");
$rotations=9; // rotating each inning of a 9 inning baseball game
// roster array must be larger than positions array
// if roster is short, remove positions which will be vacant
// values in the positions array MUST NOT be purely numeric, due to array_fill_keys() type-feature/glitch
// subs/inactive assignments will be marked by an X, unless otherwise declared in the function call
$result=false;
while(!$result){
$result=fairRotation($roster,$positions,$rotations);
}
echo "<table border=1>";
echo "<tr><th>#</th><th>",implode("</th><th>",$roster),"</th></tr>";
foreach($result as $key=>$row){
echo "<tr><th>",($key+1),"</th><td>",implode("</td><td>",$row),"</td></tr>";
}
echo "</table>";
显示如下内容: