时间:2021-07-01 10:21:17 帮助过:5人阅读
这是循环赛还是什么么?忘了怎么称呼了。排赛是抽签呢?还是直接指定?
鉴于有主场和客场,同时,比赛是两队之间的,一队是主场,另一队必定是客场。如果是指定的话,我觉得可以这样来:
先定一半球队即其中三个球队为主场,跟剩下的三队循环一下。
然后反一下,再来一次。
这是循环赛还是什么么?忘了怎么称呼了。排赛是抽签呢?还是直接指定?
鉴于有主场和客场,同时,比赛是两队之间的,一队是主场,另一队必定是客场。如果是指定的话,我觉得可以这样来:
先定一半球队即其中三个球队为主场,跟剩下的三队循环一下。
然后反一下,再来一次。
你好 不是那么简单的!求解!
$a = array('A1', 'A2', 'A3', 'A4', 'A5', 'A6');berger_method($a);function berger_method($ar) { if(count($ar) %2) $ar[] = ' '; $t = array_merge(range(1, count($ar)-1), range(1, count($ar)-1)); $len = count($ar); $m = range(1, $len); $lun = 0; $last = 0; $k = $len <= 4 ? 1 : ($len - 4) / 2 + 1; while($lun++ < $len-1) { $s = array_values($m); echo "== $lun ==\n"; for($i=0; $i<$len/2; $i++) printf("%s -- %s\n", $ar[$s[$i]-1], $ar[$s[$len-1-$i]-1]); echo "\n"; list($m[0], $m[$len-1]) = array($m[$len-1], $m[0]); for($i=0; $i<$k; $i++) { if($m[++$last % $len] == $len) $last++; } $n = $last %= $len; for($i=1; $i<$len; $i++) { if(($m[$n]) == $len) $n = ($n + 1) % $len; $m[$n] = $i; $n = ($n + 1) % $len; } }}
== 1 ==A1 -- A6A2 -- A5A3 -- A4== 2 ==A6 -- A4A5 -- A3A1 -- A2== 3 ==A2 -- A6A3 -- A1A4 -- A5== 4 ==A6 -- A5A1 -- A4A2 -- A3== 5 ==A3 -- A6A4 -- A2A5 -- A1这是单循环的
比如 第一天 A1-A2 A3-A4 A5-A6
第二轮 可能是A2-A1 A4-A3 A6-A5
就是每个队 跟对手 都有两场比赛
但是 主场一次 客场一次!
当然不是那么简单,否则赛事组委会也太轻松了
目前世界性单循环赛都采用“贝格尔编排方法”,就是我介绍的这种。当然你也可以采用“逆时针轮转方法”,虽然存在一些问题,但算法要简单的多
我也搜索了双循环赛的编排方法,但遗憾的是无法找到。
于是我做了一下测试,结果发现把单循环的算法推广到双循环时。成功的概率只有万分之36,这也就是都不愿公开双循环编排方法的原因吧。
$a = array('A1', 'A2', 'A3', 'A4', 'A5', 'A6');$last = berger_method($a);set_time_limit(60);$x = 10000;$double = array();do { shuffle($a); $r = array_merge($last, berger_method($a)); $res = array_combine($a, array_fill(0, count($a), array('场数' => 0, '主场' => 0, '客场' => 0))); foreach($r as $item) { $res[$item['主场']]['场数']++; $res[$item['主场']]['主场']++; $res[$item['客场']]['场数']++; $res[$item['客场']]['客场']++; } if(! array_filter($res, function($v) { return $v['主场'] != $v['客场']; })) { $double[] = join(',', $a); }}while($x--);print_r(array_values(array_unique($double)));可知,当初始序列为 A1,A2,A3,A4,A5,A6 时
[0] => A4,A5,A6,A2,A3,A1 [1] => A5,A6,A4,A1,A2,A3 [2] => A5,A4,A6,A3,A2,A1 [3] => A4,A6,A5,A3,A1,A2 [4] => A5,A6,A4,A2,A3,A1 [5] => A6,A5,A4,A1,A2,A3 [6] => A6,A5,A4,A1,A3,A2 [7] => A6,A4,A5,A1,A2,A3 [8] => A4,A6,A5,A2,A3,A1 [9] => A5,A4,A6,A2,A3,A1 [10] => A6,A5,A4,A2,A1,A3 [11] => A5,A4,A6,A1,A2,A3 [12] => A4,A6,A5,A2,A1,A3 [13] => A4,A5,A6,A1,A2,A3 [14] => A6,A5,A4,A3,A2,A1 [15] => A5,A4,A6,A1,A3,A2 [16] => A6,A5,A4,A3,A1,A2 [17] => A4,A5,A6,A3,A2,A1 [18] => A6,A4,A5,A2,A1,A3 [19] => A4,A5,A6,A2,A1,A3 [20] => A5,A6,A4,A2,A1,A3 [21] => A6,A4,A5,A3,A2,A1 [22] => A5,A6,A4,A3,A1,A2 [23] => A4,A6,A5,A1,A2,A3 [24] => A5,A6,A4,A3,A2,A1 [25] => A4,A6,A5,A1,A3,A2 [26] => A6,A4,A5,A2,A3,A1 [27] => A5,A4,A6,A2,A1,A3 [28] => A4,A6,A5,A3,A2,A1 [29] => A4,A5,A6,A3,A1,A2 [30] => A5,A4,A6,A3,A1,A2 [31] => A6,A4,A5,A3,A1,A2 [32] => A6,A4,A5,A1,A3,A2 [33] => A5,A6,A4,A1,A3,A2 [34] => A6,A5,A4,A2,A3,A1 [35] => A4,A5,A6,A1,A3,A2
?注一下。
来看看!
楼主的问题太有趣了,让我们来玩个填表游戏吧!我假设固定6只球队,只打一场且队伍号码小的占主场!
要打客场?让队号大的打主场就OK!
要打10场,主客各5场?把上一步的2个表复制5遍!
这么简单肯定有问题
当然不是那么简单,否则赛事组委会也太轻松了
目前世界性单循环赛都采用“贝格尔编排方法”,就是我介绍的这种。当然你也可以采用“逆时针轮转方法”,虽然存在一些问题,但算法要简单的多
我也搜索了双循环赛的编排方法,但遗憾的是无法找到。
于是我做了一下测试,结果发现把单循环的算法推广到双循环时。成功的概率只有万分之36,这也就是都不愿公开双循环编排方法的原因吧。
$a = array('A1', 'A2', 'A3', 'A4', 'A5', 'A6');$last = berger_method($a);set_time_limit(60);$x = 10000;$double = array();do { shuffle($a); $r = array_merge($last, berger_method($a)); $res = array_combine($a, array_fill(0, count($a), array('场数' => 0, '主场' => 0, '客场' => 0))); foreach($r as $item) { $res[$item['主场']]['场数']++; $res[$item['主场']]['主场']++; $res[$item['客场']]['场数']++; $res[$item['客场']]['客场']++; } if(! array_filter($res, function($v) { return $v['主场'] != $v['客场']; })) { $double[] = join(',', $a); }}while($x--);print_r(array_values(array_unique($double)));可知,当初始序列为 A1,A2,A3,A4,A5,A6 时
[0] => A4,A5,A6,A2,A3,A1 [1] => A5,A6,A4,A1,A2,A3 [2] => A5,A4,A6,A3,A2,A1 [3] => A4,A6,A5,A3,A1,A2 [4] => A5,A6,A4,A2,A3,A1 [5] => A6,A5,A4,A1,A2,A3 [6] => A6,A5,A4,A1,A3,A2 [7] => A6,A4,A5,A1,A2,A3 [8] => A4,A6,A5,A2,A3,A1 [9] => A5,A4,A6,A2,A3,A1 [10] => A6,A5,A4,A2,A1,A3 [11] => A5,A4,A6,A1,A2,A3 [12] => A4,A6,A5,A2,A1,A3 [13] => A4,A5,A6,A1,A2,A3 [14] => A6,A5,A4,A3,A2,A1 [15] => A5,A4,A6,A1,A3,A2 [16] => A6,A5,A4,A3,A1,A2 [17] => A4,A5,A6,A3,A2,A1 [18] => A6,A4,A5,A2,A1,A3 [19] => A4,A5,A6,A2,A1,A3 [20] => A5,A6,A4,A2,A1,A3 [21] => A6,A4,A5,A3,A2,A1 [22] => A5,A6,A4,A3,A1,A2 [23] => A4,A6,A5,A1,A2,A3 [24] => A5,A6,A4,A3,A2,A1 [25] => A4,A6,A5,A1,A3,A2 [26] => A6,A4,A5,A2,A3,A1 [27] => A5,A4,A6,A2,A1,A3 [28] => A4,A6,A5,A3,A2,A1 [29] => A4,A5,A6,A3,A1,A2 [30] => A5,A4,A6,A3,A1,A2 [31] => A6,A4,A5,A3,A1,A2 [32] => A6,A4,A5,A1,A3,A2 [33] => A5,A6,A4,A1,A3,A2 [34] => A6,A5,A4,A2,A3,A1 [35] => A4,A5,A6,A1,A3,A2
楼主的问题太有趣了,让我们来玩个填表游戏吧!我假设固定6只球队,只打一场且队伍号码小的占主场!
要打客场?让队号大的打主场就OK!
要打10场,主客各5场?把上一步的2个表复制5遍!
这么简单肯定有问题
答案我已经给你了
只要在下一个但循环的时候变化一下参赛队的次序就可以了
总纠结这种小事的没有意义的
$a = array('A1', 'A2', 'A3', 'A4', 'A5', 'A6');berger_method($a);function berger_method($ar) { if(count($ar) %2) $ar[] = ' '; $t = array_merge(range(1, count($ar)-1), range(1, count($ar)-1)); $len = count($ar); $m = range(1, $len); $lun = 0; $last = 0; $k = $len <= 4 ? 1 : ($len - 4) / 2 + 1; while($lun++ < $len-1) { $s = array_values($m); echo "== $lun ==\n"; for($i=0; $i<$len/2; $i++) printf("%s -- %s\n", $ar[$s[$i]-1], $ar[$s[$len-1-$i]-1]); echo "\n"; list($m[0], $m[$len-1]) = array($m[$len-1], $m[0]); for($i=0; $i<$k; $i++) { if($m[++$last % $len] == $len) $last++; } $n = $last %= $len; for($i=1; $i<$len; $i++) { if(($m[$n]) == $len) $n = ($n + 1) % $len; $m[$n] = $i; $n = ($n + 1) % $len; } }}
== 1 ==A1 -- A6A2 -- A5A3 -- A4== 2 ==A6 -- A4A5 -- A3A1 -- A2== 3 ==A2 -- A6A3 -- A1A4 -- A5== 4 ==A6 -- A5A1 -- A4A2 -- A3== 5 ==A3 -- A6A4 -- A2A5 -- A1这是单循环的
算法才是软件的灵魂呀