質問: テニス大会のタイムテーブルのプログラミングについて テニス大会の乱数表(プログラミング)作成をお手伝いいただけませんか? 大会開催に関して、下記の比較的、複雑な条件下で大会を運営しています。 そこでテニス大会の乱数表(プログラミング)作成していただける方を探しています。 対戦表(~班~ペア vs ~班~ペア)×(85~100試合) はこちらで作成いたします。 そこで、それらの試合を 以下の(1)~(17)の条件を満たしたうえで 試合投入できるようなスケジュール(順番と枠組みのみでok) を組めるプログラムを探しております。こちらosはウインドウズ7です。 ---------条件は以下です-------- (1)「3日」で完了する「ダブルス」のテニス大会 総人数は55~70名程のメンバーが、 あらかじめ「4つの班」 に分かれ、人数はほぼ均等に振り分けられている。 ここでは(o班、j班、n班、y班とする) (2)班内でペアを作り、他班のペアとダブルスの試合する。 一人あたりの試合数がおおよそ6試合前後になるように私が組んでいるが、 各人の試合数はその人によって異なる。 (大会の総試合数はおおよそ80~100試合ぐらい) レベル別に近い者同士がペアを組んで、他の班のおおよそ同レベルの相手と試合できるように事前に組んでいる。 なので、すべての対戦内容は(班内でのペアと、 その対戦相手の組み合わせ)は予め決まっているし、 各々の試合内容は大会内での他の試合の結果から変動することはない。 (3)大会プログラムは1日目、2日目、3日目ともに ・朝a (3試合) ・朝b (6~8試合) ・朝c (4試合) ・昼a (3試合) ・昼b (9~12試合) ・夜a (2試合) 以上のような予定で行うとする。 (4)コートについては、頃合いをみて運営スタッフが空いたコートに試合をコールする。 ゆえに最大のコート数や、コート番号はここでは無視する。 (5)3日目は、1、2日目のどちらよりも少ない試合数であるとする。 また、1日目と2日目の試合数の差は最大3つまでとする。 (6)1人が一日分として試合できる数は1~3試合である。 0試合と4試合以上は不可能とする。 (7)朝a,bでの試合を禁止される人もいる。各人について入力欄を設け制約の変更がきくようにしたい (8)一日分で3試合行うことがが禁止される人もいる。各人について入力欄を設け制約の変更がきくようにしたい (9)個々人にについて 試合間隔は「自分の入っていない6試合」 を空けなければ次の試合に入ってはならない。 「6試合分の時間」ではなく「必ず6試合あける」こととする。 この条件(9)は日にちごとに有効だが、日は跨がない。 (10)「朝a、昼a、夜a」 の(2試合または3試合)は、条件(9)の試合間隔を計算する際には、 まとめて1試合分としてでカウントする 例えば、、、 ・(朝a-1~朝a-3)のいずれかの試合に出場した選手は6試合の間隔をあけるため、 (朝b‐1 ~ 朝b-6)には出場できない。 ・朝c-4に出場した選手は6試合の間隔をあけるため、 (昼a-1~昼a-3、昼b-1~昼b-5)には出場できない。 (11)夜aで対戦を行うペアとその対戦相手ペアは初めから決まっていて固定である。 配置・内容は変動しない試合だが、試合出場者はその他の条件の対象としてカウントされる試合である。 (12)ある試合が「その試合の参加者(4名のうちの誰か1人、もしくは2~4人で複数の可能性もある)にとっての、 その大会内での最後の試合」となるように設定しなければならないことがある。 例えば、一人あたり6試合行う人がいたとしたら、その人にとって必ず6番目に持ってこなければならない試合 が存在する可能性がある。 (13)(n班のペア vs y班のペア)による対戦が3つ以上連続してはならない。 またこれは、(n班,o班,y班,j班) のすべての班同士についても同様とする。 ただし夜aの試合については考慮しない (14)n班全体で見たときに、 y班のペアとの対戦が一日分の試合の半分以上を占めてはならない 。 またこれは、(n班,o班,y班,j班) のすべての班同士についても同様とする。 (15)もし3日間の大会ではなく、 2日間の大会だと総試合数は60試合程度になる。 その場合、2日目の試合数が1日目より多くなってはいけない。 (16)大会が2日間のときでも、(1)~(17)を満たすスケジュールを出力できるプログラミングの仕様だと望ましい。 3日間用と2日間用が別々になっても大丈夫です。 (17)出力される3日間のスケジュールは以上の条件を満たす、ランダムに1パターンないしは、全パターンの出力が望ましい。 -------------条件は以上ですーーーーーーーーーーーーーー 8月31日の大会に間に合わせたいと考えています。 が、難しい場合については (12)(13)(14)(15)の条件については, 手作業で満たしているかどうか確認を行うので省いても大丈夫です。
回答: データ部分で、3つを全部つなげて使ってください。 data部分だけの変更で、何日でも対応できます。試合数は手で設定してください。条件に合わない設定だとすぐに止まりますので、一つずつ修正しないがら入れていくのが早いです。 主な設定は後ろの方に有り、試合日を固定、その日を避ける、同じ日、違う日に試合をするなどの設定ができます。 試行錯誤していくしか無いようですので、いろいろ設定しやすいことを優先しました。 このデータでは3分くらいで結果はでますが、条件を追加すると、候補がだんだん少なくなってくるので早くなります。 それといろいろ集計結果がでますので、手でやるよりは便利になっているのでは無いかと思いますが、どうでしょうか。 朝abに出られない人は試合上限を2として追加しています(#じるしがある) それと#から後はコメントですので、データを外したりするのに使ってみてください。 もう一つ、セミコロン(;)は区切りとして重要ですので、取ったり付けたりするとエラーになりますので注意してください。 # ------------ data; ## 試合日 その日の試合数 param : dateset : nmatches := 1 31 2 31 3 28 ; ## グループのリスト set groupset := n o j y; ## playerの所属するグループ param : playerset : assignedgroup := n1 n n2 n n3 n n4 n n5 n n6 n n7 n n8 n n9 n n10 n n11 n n12 n n13 n n14 n n15 n o1 o o2 o o3 o o4 o o5 o o6 o o7 o o8 o o9 o o10 o o11 o o12 o o13 o o14 o o15 o j1 j j2 j j3 j j4 j j5 j j6 j j7 j j8 j j9 j j10 j j11 j j12 j j13 j j15 j # j14からj15に間違いを修正 y1 y y2 y y3 y y4 y y5 y y6 y y7 y y8 y y9 y y10 y y11 y y12 y y13 y y14 y y15 y # 抜けていたため追加 ; ## 一日の最高試合数が標準と異なるplayerと試合数 param upperlimit := n1 2 n2 2 # n3 2 # n4 2 n5 2 o1 2 o2 2 # o3 2 # o4 2 o6 2 o7 2 o12 2 # j1 2 j2 2 j3 2 j4 2 # j11 2 # y1 2 y2 2 y3 2 # y4 2 y8 2 # ; ## 一日の最低試合数が標準と異なるplayerと試合数 param lowerlimit := ; ## abの試合に出られないplayer名 set avoidabplayerset := n1 n2 n3 n4 n5 o1 o2 o3 o4 o7 o12 j1 j2 j3 j4 j11 y1 y2 y3 y4 y8 ; ## 対戦番号とplayer4人 param : matchpairidset : player1 player2 player3 player4 := 1 n1 n2 o1 o2 2 n1 n3 o1 o3 3 n2 n4 o2 o4 4 n3 n5 o3 o5 5 n4 n5 o4 o5 6 n6 n7 o6 o7 7 n6 n8 o6 o8 8 n7 n8 o7 o8 9 n9 n10 o9 o10 10 n9 n11 o9 o11 11 n10 n11 o10 o11 12 n12 n13 o12 o13 13 n12 n14 o12 o14 14 n13 n15 o13 o15 15 n14 n15 o14 o15 16 n1 n2 j1 j2 17 n1 n4 j1 j4 18 n2 n3 j2 j3 19 n3 n4 j3 j4 20 n5 n6 j5 j6 21 n5 n7 j5 j7 22 n6 n7 j6 j7 23 n8 n9 j8 j9 24 n8 n10 j8 j10 25 n9 n10 j9 j10 26 n11 n12 j10 j11 27 n11 n13 j11 j12 28 n12 n15 j11 j13 29 n13 n14 j12 j15 30 n14 n15 j13 j15 31 n1 n2 y1 y2 32 n1 n3 y1 y3 33 n2 n3 y2 y3 34 n4 n5 y4 y5 35 n4 n6 y4 y6 36 n5 n6 y5 y6 37 n7 n8 y7 y8 38 n7 n9 y7 y9 39 n8 n9 y8 y9 40 n10 n11 y10 y11 41 n10 n12 y10 y12 42 n11 n12 y11 y12 43 n13 n14 y13 y14 44 n13 n15 y13 y15 45 n14 n15 y14 y15 46 j1 j2 o1 o2 47 j1 j3 o1 o3 48 j2 j3 o2 o3 49 j4 j5 o4 o5 50 j4 j6 o4 o6 51 j5 j7 o5 o6 52 j6 j8 o7 o8 53 j7 j9 o7 o9 54 j8 j9 o8 o9 55 j10 j11 o10 o11 56 j10 j12 o10 o12 57 j11 j15 o11 o12 58 j12 j13 o13 o14 59 j13 j15 o13 o15 60 j13 j15 o14 o15 61 y1 y2 o1 o2 62 y1 y4 o1 o4 63 y2 y3 o2 o3 64 y3 y4 o3 o4 65 y5 y6 o5 o6 66 y5 y7 o5 o7 67 y6 y7 o6 o7 68 y8 y9 o8 o9 69 y8 y10 o8 o10 70 y9 y10 o9 o10 71 y11 y12 o11 o12 72 y11 y13 o11 o13 73 y12 y15 o12 o15 74 y13 y14 o13 o14 75 y14 y15 o14 o15 76 j1 j2 y1 y2 77 j1 j3 y1 y3 78 j2 j4 y3 y4 79 j3 j5 y2 y5 80 j4 j5 y4 y5 81 j6 j7 y6 y7 82 j6 j8 y6 y8 83 j7 j8 y7 y8 84 j9 j10 y9 y10 85 j9 j10 y9 y11 86 j10 j11 y10 y11 87 j12 j13 y12 y13 88 j12 j15 y12 y14 89 j13 j15 y13 y15 90 j12 j15 y14 y15 ; # 特定の日に試合を設定 # 対戦番号 試合日 param : fixmatchidset : fixmatchdate := 31 1 46 1 61 2 16 2 79 3 3 3 1 3 52 3 11 3 87 3 50 3 51 3 10 1 15 2 ; # 特定の日に試合を避けたい設定 # 対戦番号 試合日 param : avoidmatchidset : avoidmatchdate := ; # 同じ日に開催する試合 # 通し番号 対戦番号1 対戦番号2 param : matchinsamedayserial : matchinsameday1 matchinsameday2 := 1 61 62 2 61 63 3 76 78 ; # 違う日に開催する試合 # 通し番号 対戦番号1 対戦番号2 param : matchinotherdayserial : matchinotherday1 matchinotherday2 := 1 46 47 2 47 48 3 76 77 ; end;