• 締切済み
  • 困ってます

テニス大会のタイムテーブルのプログラミングについて

テニス大会の乱数表(プログラミング)作成をお手伝いいただけませんか? 大会開催に関して、下記の比較的、複雑な条件下で大会を運営しています。 そこでテニス大会の乱数表(プログラミング)作成していただける方を探しています。 対戦表(~班~ペア 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)の条件については, 手作業で満たしているかどうか確認を行うので省いても大丈夫です。

共感・応援の気持ちを伝えよう!

  • 回答数22
  • 閲覧数749
  • ありがとう数19

みんなの回答

  • 回答No.22
  • ki073
  • ベストアンサー率77% (491/634)

お役にたてたようで何よりです。 >余談ですが、やはり予想通り怪我人が多くいたため、いくつも条件を変更できる仕様で本当に助かりました。 日程への割り付けの方は、そこまでは考えていなかったのですが、スムーズにできましたでしょうか? 実際には使ってみないと分からない事がいろいろある思いますので、こんな機能があれば良かったのにと思う事がありましたら、書き込んでください。簡単にできることでしたらこの際修正します。 また、この機能が便利だったいうこともあれば書き込んでください。 GLPK は整数計画法という数学分野のものですし、経済学分野のOR(オペレーションリサーチ)など利用されているものです。このような分野に興味のある人を騙して?勉強させてみてください。そうすれば自分たちで改良しながずっと使い続けることができます。

共感・感謝の気持ちを伝えよう!

関連するQ&A

  • スポーツ大会のタイムテーブル作成について

    テニス大会のタイムテーブルに関する 乱数表(プログラミング)作成をお願いできないかと思い相談致しました。 テニス大会開催に関して、 下記の比較的、複雑な条件下で大会を運営しているゆえに、試合投入の順番(タイムテーブル)を組む仕事に困っています。何通りも組み合わせを試しては、詰んでやり直しの繰り返しで、毎度困らされています。 対戦をルールに合わせて順番に並べる、 簡素なプログラムで構わないので是非作っていただけるとありがたいです。 ---------条件-------------- (1)「3日」で完了する「ダブルス」のバドミントン大会 総人数は55~70名ほどが、「4つの班」 に分けられている。 各班およそ15名~17名程度でほぼ均等に振り分けらる。 ここでは(W 班、X班、Y班、Z班とする) (2)班内でペアを作り、他班のペアとダブルスの試合する。 一人あたりの試合数がおおよそ6試合前後になるように私が組んで いるため、試合数は個々にばらつきがある。(3日間の総試合数は75~100試合程度) レベル別に近い者同士がペアを組んで、 他の班のおおよそ同レベルの相手と試合できるようにしている。 ゆえに対戦内容は(班内でのペアと、 その対戦相手の組み合わせ)は予め決まっていて かつ、各々の試合内容は、 大会内での他の試合の結果に左右されて変動することはない。 (3)コートについては、 頃合いをみて運営スタッフが空いたコートに試合をコールする。 ゆえに最大のコート数やコート番号はここでは無視してよい。 (4)大会プログラムは1日目、2日目、3日目ともに以下のような予定で行う。 朝A (2~3試合) 朝B (7~8試合) 朝C (3~4試合) 昼A (2~3試合) 昼B (9~12試合) 夜A (2試合) (5)3日目の全体の試合数は、1・ 2日目のどちらよりも少ない試合数とする。 また、1日目と2日目の試合数の差は最大3試合までとする。 (6)、空いたコートから次の試合を順次入れてゆく。 朝B・昼Bの試合は試合を入れる順番を決めなければならない。 (例、朝A、朝B-1、朝B-2、朝B-3・・・・ という順で行ってゆく。昼Aから昼B-1への進行も同じ) ただし朝A、昼A、夜Aの試合は複数同時に開始させるため、 開始前はコートがすべて空くまで待機する。 (7)1人が一日分として試合できる数は1~3試合である。 0試合と4試合以上は不可。 (8)朝A,Bでの試合を禁止される人もいるため、 すべての人に確認をとる。 (9)一日分で3試合行うことがが禁止される人もいるため、 すべての人に確認を取る。 (10)同一人物における試合間隔は、「自分の入っていない6試合」 を空けなければ次の試合に入ってはならない。朝A、昼A、夜A、 の直前の待機時間は試合間隔にカウントしない。 (11)「朝A、昼A、夜A」 の試合は一斉にスタートするため、(10) の試合間隔を計算する際には、複数試合があっても、まとめて1試合分で考える。 例・・(10)と(11)より (朝A)で試合に入った人が次に試合に参加できるのは、(朝B-7)から。 (昼A)で試合に入った人が次に試合に参加できるのは、(昼B-7)から。 (朝Cの最後)で試合に入った人が次に試合に参加できるのは、(昼B-6)から。 (12)夜Aで対戦を行うペアとその対戦相手ペアの8名は( 夜Aは2試合あるので合計8名)は初めから決まっていて、 固定である。 順序配置・内容は変動しない。ただし、 個々人の制限はカウント対象である。 例えば、夜Aに出場する人が、(7)や(9) の制限に該当する可能性もあるし、(10)の6試合間隔など、 他の条件もその通りに守らねばならない。 (13)(X班のペア vs Y班のペア)による対戦が3つ以上連続してはならない。 これは、(W班,X班,Y班,Z班) のすべての班同士についても同様とする。 ただし夜Aの試合については考慮しない (14) X班全体で見たときに、 Y班のペアとの対戦が一日分の試合の半分以上を占めてはならない 。これは、(W班,X班,Y班,Z班) のすべての班同士についても同様とする。 (15)もし3日間の大会ではなく、 2日間の大会だと総試合数は60試合程度になる。 その場合、2日目の試合数が1日目より多くなってはいけない。 ----条件は以上---- ●まとめ● 「入力する情報」 ・班名(W、X、Y、Z班) ・出場者各々の名前(ペア2名 と、それに対応する、 対戦ペア2名)を(約80~100試合分) ・出場者各々の禁止事項の確認 「知りたい情報」 条件、ルールを満たしつつ、 ・1~3日目の、試合を入れる順番(3日間の大会のとき) を「すべてのパターン」ないしは「ランダムに1パターン」 での出力を求める。 ※人物名を省略して出力の例を書くと 【朝A】同時開始 X班(あ&い) vs Y班(さ&し) Y班(や&よ) vs Z班(な&に) W班(ぺ&び)vs Z班(わ&を) 【朝B-1】 W班(ぬ&ね)vs X班(う&え) 【朝B-2】 Z班(の&は) vs W班(ひ&ふ) という感じの 単純に投入の順序がわかればOKです ついでに 1~2日目の、試合を入れる順番(2日間の大会のとき) も求められる仕様もあれば、さらに助かります 長文失礼いたしました。 お返事いただけると幸いです。よろしくお願いいたします。

  • スポーツ大会のタイムテーブル作成について

    テニス大会のタイムテーブルに関する 乱数表(プログラミング)作成をお願いできないかと思い相談致しました。 テニス大会開催に関して、 下記の比較的、複雑な条件下で大会を運営しています。 そのため試合投入のスケジュール(順番)を組む仕事が手作業になり困っています。 簡素なプログラムで構わないのでなんでも是非お願いします。 ---------条件-------- (1)「3日」で完了する「ダブルス」のバドミントン大会 総人数は55~70名ほどが、あらかじめ「4つの班」 に分かれている。 各班およそ15名~17名程度でほぼ均等に振り分けられている。 ここでは(W 班、X班、Y班、Z班とする) (2)班内でペアを作り、他班のペアとダブルスの試合する。 行う試合の数はその人によって異なる。 一人あたりの試合数がおおよそ6試合前後になるように私が組んで いる。 (総試合数は75~100試合程度) レベル別に近い者同士がペアを組んで、 他の班のおおよそ同レベルの相手と試合できるように組んでいる。 つまり、対戦内容は(班内でのペアと、 その対戦相手の組み合わせ)は予め決まっていて かつ、各々の試合内容は、 大会内での他の試合の結果に左右されて変動することはない。 (3)コートについては、 頃合いをみて運営スタッフが空いたコートに試合をコールする。 ゆえに最大のコート数やコート番号はここでは無視してよい。 (4)大会プログラムは1日目、2日目、3日目ともに 朝A (2~3試合) 朝B (7~8試合) 朝C (3~4試合) 昼A (2~3試合) 昼B (9~12試合) 夜A (2試合) 以上のような予定で行う。 (5)3日目の全体の試合数は、1・ 2日目のどちらよりも少ない試合数とする。 また、1日目と2日目の試合数の差は最大3試合までとする。 (6)試合が終わり、空いたコートから次の試合を順次入れてゆく 朝B・昼Bの試合は、 それぞれについて試合を入れる順番を決めなければならない。 (例、朝A、朝B-1、朝B-2、朝B-3・・・・ という順に行う。昼も同様) ただし朝A、昼A、夜Aの試合は複数同時に開始させるため、 開始前はコートがすべて空くまで待機する。 (7)1人が一日分として試合できる数は1~3試合である。 0試合と4試合以上は不可。 (8)朝A,Bでの試合を禁止される人もいるため、 すべての人に確認をとる。 (9)一日分で3試合行うことがが禁止される人もいるため、 すべての人に確認を取る。 (10)同一人物における試合間隔は、「自分の入っていない6試合」 を空けなければ次の試合に入ってはならない。 また朝A、昼A、夜A、 の直前の待機時間は試合間隔にカウントしない。 (11)「朝A、昼A、夜A」 の試合は一斉にスタートするため、(10) の試合間隔を計算する際には、複数試合があっても、まとめて1試合分で考える。 例・・(10)と(11)より (朝A)で試合に入った人が次に試合に参加できるのは、(朝B-7)から。 (昼A)で試合に入った人が次に試合に参加できるのは、(昼B-7)から。 (朝Cの最後)で試合に入った人が次に試合に参加できるのは、(昼B-6)から。 (12)夜Aで対戦を行うペアとその対戦相手ペアの8名は( 夜Aは2試合あるので合計8名)は初めから決まっていて、 固定である。 配置・内容は変動しない。ただし、 個々人の制限はカウント対象である。 例えば、夜Aに出場する人が、(7)や(9) の制限に該当する可能性もあるし、(10)の6試合間隔など、 他の条件もその通りに守らねばならない。 (13)(X班のペア vs Y班のペア)による対戦が3つ以上連続してはならない。 またこれは、(W班,X班,Y班,Z班) のすべての班同士についても同様とする。 ただし夜Aの試合については考慮しない (14) X班全体で見たときに、 Y班のペアとの対戦が一日分の試合の半分以上を占めてはならない 。 またこれは、(W班,X班,Y班,Z班) のすべての班同士についても同様とする。 (15)もし3日間の大会ではなく、 2日間の大会だと総試合数は60試合程度になる。 その場合、2日目の試合数が1日目より多くなってはいけない。 ----条件は以上です---- ●まとめ● 「入力する情報」 ・班名(W、X、Y、Z班) ・出場者各々の名前(ペア2名 と、それに対応する、 対戦ペア2名)を(約80~100試合分) ・夜A以外の、順序固定試合の有無 ・出場者各々の禁止事項の確認 「知りたい情報」 条件、ルールを満たしつつ、 ・1~3日目の、試合を入れる順番(3日間の大会のとき) を「すべてのパターン」ないしは「ランダムに1パターン」 での出力を求める。 ※人物名を省略して例を書くと 【朝A】同時開始 X班(あ&い) vs Y班(さ&し) Y班(や&よ) vs Z班(な&に) W班(ぺ&び)vs Z班(わ&を) 【朝B-1】 W班(ぬ&ね)vs X班(う&え) 【朝B-2】 Z班(の&は) vs W班(ひ&ふ) ・ ・ という感じの 単純な投入の順番がわかればOKです。 ついでに 1~2日目の、試合を入れる順番(2日間の大会のとき) も求められる仕様もあれば、さらに助かります 長文失礼いたしました。 お返事いただけると幸いです。よろしくお願いいたします。

    • ベストアンサー
    • Java
  • テニス大会ダブルスの乱数表の作成をお願いしたい

    テニス大会開催のため、プレーヤーの組み合わせに乱数表を使うことになり、過去の質問・回答を検索しテニス乱数表の作成法を2件見つけたのですが、1件は同じプレーヤーの組み合わせ(ペア)が複数組できてしまい、もう1件は一人当たりのゲーム数が同数にならない(一定の試合数で、ある人は2ゲーム、ある人は5ゲームなどバラつきが出る)ことがわかりました。 そこで以下の条件で乱数表の作成をお願いしたいのですが。 1.1日で完了するダブルスのテニス大会 2.参加者(プレーヤー)は、10-30人程度 3.コートは2面を並行使用の予定なので、一人が同時に2面に入らない 4.全員が一人あたり4ゲーム行う 5.全員が4ゲームともそれぞれ別の人とペアを組む(同じペアを複数回作らない) 6.対戦相手はそれ以前のゲームと同じ人でも構わない(5.があるので同じペアとの再戦はない) よろしくお願いします。

  • 回答No.21
  • ki073
  • ベストアンサー率77% (491/634)

No.20の補足欄について 「補足欄」に書かれた場合はここに見にこないと書かれたことが知ることができません、「お礼欄」の場合は回答者にメールがきますので。可能な限り「お礼欄」でお願いします。たまたま気になって見に来たので気がついたのです。 さて、今の条件では(n,y)→(n,y) →(n,j)→(n,j)はOKとなっています。 要するに(n,y)の組み合わせが3回連蔵しない条件と解釈しました。(n,j)は別の組み合わせと判断しています。 質問者さんは、同じグループの人(ここではn班)が4回続かないということのようですね。 # 同じグループが4回連続しない、夜は含めない param MatchPairID_Group{mp in MatchPairIDSet, group in GroupSet} binary := if exists{i in 1..4}(AssignedGroup[Players[mp, i]]=group) then 1 else 0; var MatchScheduleID_Group_table{MatchScheduleIDSet, GroupSet} binary; s.t. update_MatchScheduleID_Group_table{ms in MatchScheduleIDSet, group in GroupSet}: sum{mp in MatchPairIDSet: MatchPairID_Group[mp, group]=1}MatchScheduleID_MatchPairID_table[ms,mp]=MatchScheduleID_Group_table[ms, group]; s.t. group_exception4{ms in StartMatchID+3..EndMatchID-nMatchesNight, group in GroupSet}: sum{k in 0..3}MatchScheduleID_Group_table[ms-k, group]<=3; を # 同じグループの組み合わせが3回連続しない 夜は含めない の行の前に追加してください。条件が追加されます。 「同じグループの組み合わせが3回連続しない」の条件が必要ないなら その次の2行 s.t. group_exception{ms in group_exception3, (group1, group2) in GroupPairofMatches}: sum{k in 0..2}MatchScheduleID_Group2_table[ms-k, group1, group2]<=2; をコメントにしておいてください。 それぞれの行の頭に#を追加するか、/*と*/で挟むとその間(複数行)がコメントになります。

共感・感謝の気持ちを伝えよう!

質問者からのお礼

遅くなりましたが、無事大会を終えることができました。 本当に感謝しております。 余談ですが、やはり予想通り怪我人が多くいたため、いくつも条件を変更できる仕様で本当に助かりました。 プログラムの効果は十二分に発揮することができたと思います。 いつも複数人の運営スタッフが夜通しで考えているような我々とって革命的なプログラムとなったことは間違いありません。 とあるテニスサークルという規模ではありますが、これからも着実に伝え残し、受け継がれるものにしていこうと思います。 重ね重ねではありますが、 本当にありがとうございましたm(_ _)m

  • 回答No.20
  • ki073
  • ベストアンサー率77% (491/634)

こちらもデータ領域だけの書き換えで可能です。 対戦データは先のプログラムの出力の一部をそのままコピペで使えます。 この質問は作業が終わるまで閉め切らないでください。 ご存知だと思いますが、プログラムの実行はcontrolキーを押したままcキーを押すと止まります(Windowsも多分) こちらの方は朝ABを避ける試合が出来るだけ後ろになるような結果を出力します。 また先のものは各プレーヤーの試合日間の試合数ができるだけ同じになるようになるようにしています。 このデータでは第6試合から朝ABを避ける試合が入っていますので、もう少し試合日間の割当を変える必要がありそうです。 data; param nMatchesAB := 5; # ABの試合数 param nMatchesMorning := 11; # 午前中の試合数 param nMatchesNight := 2; # 夜の試合数 ## グループのリスト 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 # 抜けていたため追加 ; ## 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 # (n : o) 朝AB避ける 3 N2 N4 O2 O4 # (n : o) 朝AB避ける 4 N3 N5 O3 O5 # (n : o) 朝AB避ける 11 N10 N11 O10 O11 # (n : o) 12 N12 N13 O12 O13 # (n : o) 朝AB避ける 13 N12 N14 O12 O14 # (n : o) 朝AB避ける 32 N1 N3 Y1 Y3 # (n : y) 朝AB避ける 35 N4 N6 Y4 Y6 # (n : y) 朝AB避ける 36 N5 N6 Y5 Y6 # (n : y) 朝AB避ける 37 N7 N8 Y7 Y8 # (n : y) 朝AB避ける 38 N7 N9 Y7 Y9 # (n : y) 39 N8 N9 Y8 Y9 # (n : y) 朝AB避ける 40 N10 N11 Y10 Y11 # (n : y) 45 N14 N15 Y14 Y15 # (n : y) 47 J1 J3 O1 O3 # (j : o) 朝AB避ける 50 J4 J6 O4 O6 # (j : o) 朝AB避ける 51 J5 J7 O5 O6 # (j : o) 52 J6 J8 O7 O8 # (j : o) 朝AB避ける 53 J7 J9 O7 O9 # (j : o) 朝AB避ける 54 J8 J9 O8 O9 # (j : o) 55 J10 J11 O10 O11 # (j : o) 朝AB避ける 60 J13 J15 O14 O15 # (j : o) 76 J1 J2 Y1 Y2 # (j : y) 朝AB避ける 78 J2 J4 Y3 Y4 # (j : y) 朝AB避ける 79 J3 J5 Y2 Y5 # (j : y) 朝AB避ける 86 J10 J11 Y10 Y11 # (j : y) 朝AB避ける 87 J12 J13 Y12 Y13 # (j : y) 88 J12 J15 Y12 Y14 # (j : y) ; # 試合を特定の試合番号に指定 # 対戦番号 試合番号の範囲(始め、終わり) param : FixedMatchPairID : FixedMatchRangeStart FixedMatchRangeEnd := 79 27 28 # 夜の試合の範囲27~28 3 27 28 1 20 26 # 昼最後の7試合に設定することで最終出場に必ずなる 52 20 26 11 20 26 87 20 26 ; end;

共感・感謝の気持ちを伝えよう!

質問者からのお礼

まずは、ここまでのプログラムを作っていただいたこと、ありがとうございます。 ただいま運用についての試行錯誤(データからの条件の調節)を行っております。 ・条件を縮めすぎたり、辻褄が合わなくなると、パターンがなくなりエラーがでる。 かといって  ・条件が緩すぎると、パターンが多く、出力に時間がかかる。 ということでしょうかね。 第1段階の振り分けプログラムに関してですが、 さらに振り分ける材料を考えたところ、班ごとの対戦傾向に偏りをできるだけなくしたいと思いました。 そこで、今までは (ある班 対 ある班 の割合の限界を50パーセント)としていましたが これを(20パーセント)にまで下げることでかなり時間を絞ることができました。 おまけに各対戦班にも隔たりがなくなりましたので結果的に一石二鳥となりました。 第二段階の、並び替えについては仰るとおりにするしかないようです。 朝ABの試合数をいじり、あとはどの試合をどのあたりに入れるのかをおおよそ決めておけば、 出力しやすそうです。 正直、ここまで融通の利く内容であれば、むしろ多少の条件の手作業は当然と考えるしかないですね。 お世話になりすぎて、感謝してもしきれないほどのものでございます。 実際に大会で運用できるまでこの質問は残す予定ですので また何か疑問点等ございましたら恐縮ながら書き込むかもしれません。 本当に本当に、ありがとうございます。

質問者からの補足

非常に恐縮なのですが、訂正した条件の検討をお願いしたいのです。 というのも、少し私の条件提示の表現にミスがありました。 条件(13)についてを訂正したく思っています。 今までは (13)(n班のペア vs y班のペア)による対戦が3つ以上連続してはならない。 またこれは、(n班,o班,y班,j班) のすべての班同士についても同様とする。 ただし夜Aの試合については考慮しない としていましたが、 これを以下に変更したいのです。 (13)(n班のペア)が参加している対戦が4つ以上連続してはならない。 またこれは、(n班,o班,y班,j班) のすべての班についても同様とする。 ただし夜Aの試合については考慮しない 例えば・・・ (n班 VS y班)→(o班 VS n班)→(n班 VS j班)→(n班 VS j班) という試合投入の順だと、n班が4回連続で出場しているため、条件を満たしていないとみなす。 ということで、 今あるプログラムの一部(条件(13)の部分)を書き換えることで 上手く対応することはできるのでしょうか?

  • 回答No.19
  • ki073
  • ベストアンサー率77% (491/634)

# MatchScheduleID_Player_tableを書き換え s.t. update_MatchScheduleID_Player_table{ms in MatchScheduleIDSet, py in PlayerSet}: sum{mp in MatchPairIDSet : MatchPairID_Player[mp, py]=1}MatchScheduleID_MatchPairID_table[ms,mp]=MatchScheduleID_Player_table[ms, py]; # ABに試合ができないPlayerの処理 s.t. avoidAB{ms in MatchScheduleIDAB, py in AvoidABPlayerSet}: MatchScheduleID_Player_table[ms ,py]=0; # MatchScheduleID_Group2_tableを書き換え s.t. update_MatchScheduleID_Group2_table{ms in MatchScheduleIDSet, (group1, group2) in GroupPairofMatches}: sum{mp in MatchPairIDSet: MatchPairID_Group2[mp, group1, group2]=1}MatchScheduleID_MatchPairID_table[ms,mp]=MatchScheduleID_Group2_table[ms, group1, group2]; s.t. uniq_group{ms in MatchScheduleIDSet}: sum{(group1, group2) in GroupPairofMatches}MatchScheduleID_Group2_table[ms, group1, group2]=1; # 同じグループの組み合わせが3回連続しない 夜は含めない s.t. group_exception{ms in group_exception3, (group1, group2) in GroupPairofMatches}: sum{k in 0..2}MatchScheduleID_Group2_table[ms-k, group1, group2]<=2; # 連続した9試合中1試合以下であること s.t. one_or_zero_in_9_matches{ms in check_9_matches, py in PlayerSet}: sum{k in 0..8}MatchScheduleID_Player_table[ms-k, py]<=1; # 連続した8試合中1試合以下であること s.t. one_or_zero_in_8_matches{ms in check_8_matches, py in PlayerSet}: sum{k in 0..7}MatchScheduleID_Player_table[ms-k, py]<=1; # 連続した7試合中1試合以下であること s.t. one_or_zero_in_7_matches{ms in check_7_matches, py in PlayerSet}: sum{k in 0..6}MatchScheduleID_Player_table[ms-k, py]<=1; solve; # 出力 for{(group1, group2) in GroupPairofMatches} {printf "# %s : %s %s 試合\n", group1, group2, sum{mp in MatchPairIDSet}MatchPairID_Group2[mp, group1, group2];} for{ms in MatchScheduleIDSet} {for {mp in MatchPairIDSet : MatchScheduleID_MatchPairID_table[ms, mp]=1} {printf "%s %s %s %s %s %s (%s : %s) %s\n", ms, mp, Player1[mp], Player2[mp], Player3[mp], Player4[mp], AssignedGroup[Player1[mp]], AssignedGroup[Player3[mp]], if mp in avoidABMatchPairIDSet then " 朝ABを避ける試合" else "";} }

共感・感謝の気持ちを伝えよう!

  • 回答No.18
  • ki073
  • ベストアンサー率77% (491/634)

一日の作成するものも書き込んでおきます # 一日のスケジュールを作成 param nMatchesAB; # ABの試合数 param nMatchesMorning; # 午前中の試合数 param nMatchesNight; # 夜の試合数 set MatchPairIDSet; # 対戦番号の集合 set MatchScheduleIDSet := 1..card(MatchPairIDSet); # 試合番号の集合 param StartMatchID := 1; # 開始試合番号 param EndMatchID := card(MatchPairIDSet); # 最終試合番号 param StartMatchIDofAfternoon := StartMatchID+nMatchesMorning; # 午後の開始試合番号 set GroupSet; # グループ名の集合 set PlayerSet; # Player名の集合 set AvoidABPlayerSet; # ABの試合ができないPlayerの集合 set GroupPairofMatches := {group1 in GroupSet, group2 in GroupSet: group1<group2}; set FixedMatchPairID; # 試合番号が決っている対戦番号 param FixedMatchRangeStart{FixedMatchPairID}; param FixedMatchRangeEnd{FixedMatchPairID}; set FixedMatchRange{mp in FixedMatchPairID} := FixedMatchRangeStart[mp]..FixedMatchRangeEnd[mp]; # 試合を設定する試合番号の範囲 param AssignedGroup{PlayerSet} symbolic; # Playerとその所属グループ param Player1{MatchPairIDSet} symbolic; # 対戦番号とPlayer param Player2{MatchPairIDSet} symbolic; param Player3{MatchPairIDSet} symbolic; param Player4{MatchPairIDSet} symbolic; param Players{mp in MatchPairIDSet, i in 1..4} symbolic := # 配列に if i=1 then Player1[mp] else if i=2 then Player2[mp] else if i=3 then Player3[mp] else Player4[mp]; # Player1とPlayer2,Player3とPlayer4同じグループかチェック check{mp in MatchPairIDSet}: AssignedGroup[Players[mp, 1]]=AssignedGroup[Players[mp, 2]]; check{mp in MatchPairIDSet}: AssignedGroup[Players[mp, 3]]=AssignedGroup[Players[mp, 4]]; # 同じグループ間の対戦は無いかチェック check{mp in MatchPairIDSet}: AssignedGroup[Players[mp, 1]]<>AssignedGroup[Players[mp, 3]]; # 対戦番号とPlayer名の対応表 param MatchPairID_Player{mp in MatchPairIDSet, py in PlayerSet} binary := if exists{i in 1..4}(Players[mp, i]=py) then 1 else 0; # 対戦番号とグループ名の対応表 param MatchPairID_Group2{mp in MatchPairIDSet, (group1, group2) in GroupPairofMatches} binary := if (AssignedGroup[Players[mp, 1]]=group1 and AssignedGroup[Players[mp, 3]]=group2) or (AssignedGroup[Players[mp, 3]]=group1 and AssignedGroup[Players[mp, 1]]=group2) then 1 else 0; # 試合でPlayerが重複していないかチェック check{mp in MatchPairIDSet}: sum{py in PlayerSet}MatchPairID_Player[mp, py]=4; # 朝ABに出場できないPlayerがいる対戦番号 set avoidABMatchPairIDSet := {mp in MatchPairIDSet : exists{py in AvoidABPlayerSet}MatchPairID_Player[mp, py]=1}; param coefficients{mp in avoidABMatchPairIDSet} := round(Uniform(100, 150)); # 高速化のため優先度をランダムに指定 # 個人別の試合数を出力 printf "Player Group 試合数\n"; for{py in PlayerSet} {printf "%s %s %d\n", py, AssignedGroup[py], sum{mp in MatchPairIDSet}MatchPairID_Player[mp, py];} # 試合へ出る間隔のための準備 # その試合と前8試合中で1回出場できる、朝第9試合、昼第3~第9試合 set check_9_matches := {StartMatchID+8} union StartMatchIDofAfternoon+2..StartMatchIDofAfternoon+8; # その試合と前7試合中で1回出場できる、昼第2試合 set check_8_matches := {StartMatchIDofAfternoon+1} ; # その試合と前6試合中で1回出場できる、その他 set check_7_matches := StartMatchID+9..EndMatchID; # 試合ABの範囲 set MatchScheduleIDAB := StartMatchID..nMatchesAB-1; # 各試合日の第3試合から夜の試合の前までの範囲、グループの連続性を調べるために使う set group_exception3 := StartMatchID+2..EndMatchID-nMatchesNight; var MatchScheduleID_MatchPairID_table{MatchScheduleIDSet, MatchPairIDSet} binary; var MatchScheduleID_Group2_table{MatchScheduleIDSet, GroupPairofMatches} binary; var MatchScheduleID_Player_table{MatchScheduleIDSet, PlayerSet} binary; s.t. uniq_MatchPairID{ms in MatchScheduleIDSet}: sum{mp in MatchPairIDSet}MatchScheduleID_MatchPairID_table[ms, mp]=1; s.t. uniq_MatchScheduleID{mp in MatchPairIDSet}: sum{ms in MatchScheduleIDSet}MatchScheduleID_MatchPairID_table[ms, mp]=1; # 朝ABを避けるplayerの試合をできるだけ後ろになるように maximize lateScheduleforAviodABMembers: sum{ms in MatchScheduleIDSet, mp in avoidABMatchPairIDSet}MatchScheduleID_MatchPairID_table[ms, mp]*coefficients[mp]*ms*ms; # 試合番号が決められている試合 s.t. fixmatch{mp in FixedMatchPairID}: sum{ms in FixedMatchRange[mp]}MatchScheduleID_MatchPairID_table[ms, mp]=1;

共感・感謝の気持ちを伝えよう!

  • 回答No.17
  • ki073
  • ベストアンサー率77% (491/634)

データ部分で、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;

共感・感謝の気持ちを伝えよう!

  • 回答No.16
  • ki073
  • ベストアンサー率77% (491/634)

続きです。 s.t. otherdayMatch{day in DateSet, i in MatchinOtherDaySerial}: Date_MatchPairID_table[day, MatchinOtherDay1[i]]+Date_MatchPairID_table[day, MatchinOtherDay2[i]]<=1; # 違う日開催 # Date_Player_tableを書き換え s.t. update_Date_Player_table{day in DateSet, py in PlayerSet}: sum{mp in MatchPairIDSet : MatchPairID_Player[mp, py]=1}Date_MatchPairID_table[day,mp]=Date_Player_table[day, py]; # 一日の試合数制限 s.t. limit1s{py in PlayerSet, day in DateSet}: LowerLimit[py]<= Date_Player_table[day, py]; s.t. limit1u{py in PlayerSet, day in DateSet}: Date_Player_table[day, py] <=UpperLimit[py]; # Date_Group2_tableを書き換え s.t. update_Date_Group2_table{day in DateSet, (group1, group2) in GroupPairofMatches}: sum{mp in MatchPairIDSet: MatchPairID_Group2[mp, group1, group2]=1}Date_MatchPairID_table[day,mp]=Date_Group2_table[day, group1, group2]; # グループの同じ組み合わせが対戦の50%以下 s.t. limit_sama_group_pair{day in DateSet, (group1, group2) in GroupPairofMatches}: Date_Group2_table[day, group1, group2]<=nMatches[day]*0.5; solve; # 結果出力 printf "Playerの試合日別試合数\n"; for {py in PlayerSet} {printf "%s ", py; for{day in DateSet}{printf " %d", Date_Player_table[day, py];} printf " %d\n", sum{day in DateSet}Date_Player_table[day, py];} printf "対戦の試合日割当表\n"; for{mp in MatchPairIDSet} {printf "%s %s\n", mp, sum{day in DateSet : Date_MatchPairID_table[day, mp]=1}day;} printf "試合日ごとの対戦表\n"; for{day in DateSet} {printf "# 試合日 %s\n", day; for{(group1, group2) in GroupPairofMatches}{printf "# %s : %s %s 試合\n", group1, group2, Date_Group2_table[day, group1, group2];} for {mp in MatchPairIDSet : Date_MatchPairID_table[day, mp]=1} {printf "%s %s %s %s %s # (%s : %s) %s\n", mp, Players[mp, 1], Players[mp, 2], Players[mp, 3], Players[mp, 4], AssignedGroup[Players[mp, 1]], AssignedGroup[Players[mp, 3]], if exists{i in 1..4}(Players[mp, i] in AvoidABPlayerSet) then " 朝AB避ける" else " "; } }

共感・感謝の気持ちを伝えよう!

  • 回答No.15
  • ki073
  • ベストアンサー率77% (491/634)

試合の日程を振り分けるものを書き込みます。 set DateSet; # 試合日の集合 param nMatches{DateSet}; # 試合日ごとの試合数 set GroupSet; # グループ名の集合 set PlayerSet; # Player名の集合 set AvoidABPlayerSet; # 朝ABの試合ができないPlayerの集合 set FixMatchIDSet; # 特定の日に行う対戦 param FixMatchDate{FixMatchIDSet}; # 設定日 set AvoidMatchIDSet; # 特定の日に避けたい対戦 param AvoidMatchDate{AvoidMatchIDSet}; # 避けたい日 param AssignedGroup{PlayerSet} symbolic; # Playerとその所属グループ set MatchPairIDSet; # 対戦番号 set MatchinSameDaySerial; param MatchinSameDay1{MatchinSameDaySerial}; # 同日開催対戦 param MatchinSameDay2{MatchinSameDaySerial}; set MatchinOtherDaySerial; param MatchinOtherDay1{MatchinOtherDaySerial}; # 違う日開催対戦 param MatchinOtherDay2{MatchinOtherDaySerial}; param Player1{MatchPairIDSet} symbolic; # 対戦番号とPlayer param Player2{MatchPairIDSet} symbolic; param Player3{MatchPairIDSet} symbolic; param Player4{MatchPairIDSet} symbolic; param Players{mp in MatchPairIDSet, i in 1..4} symbolic := # 配列に if i=1 then Player1[mp] else if i=2 then Player2[mp] else if i=3 then Player3[mp] else Player4[mp]; param LowerLimit{PlayerSet} default 1; # 一日あたりの最低試合数 param UpperLimit{PlayerSet} default 3; # 最高試合数 param coefficients{py in PlayerSet} := round(Uniform(1000, 1500)+(if py in AvoidABPlayerSet then 2000 else 0)); # 優先度指定 set GroupPairofMatches := {group1 in GroupSet, group2 in GroupSet: group1<group2}; # 試合日ごとの試合数合計が全体の試合数と一致するか check: sum{day in DateSet}nMatches[day]=card(MatchPairIDSet); # Player1, Player2が同じグループかチェック check{mp in MatchPairIDSet}: AssignedGroup[Players[mp, 1]]=AssignedGroup[Players[mp, 2]]; # Player3, Player4が同じグループかチェック check{mp in MatchPairIDSet}: AssignedGroup[Players[mp, 3]]=AssignedGroup[Players[mp, 4]]; # 同じグループ間の対戦は無いかチェック check{mp in MatchPairIDSet}: AssignedGroup[Players[mp, 1]]<>AssignedGroup[Players[mp, 3]]; # 対戦番号とPlayer名の対応表 param MatchPairID_Player{mp in MatchPairIDSet, py in PlayerSet} binary := if exists{i in 1..4}(Players[mp, i]=py) then 1 else 0; # 対戦番号とグループ名の対応表 param MatchPairID_Group2{mp in MatchPairIDSet, (group1, group2) in GroupPairofMatches} binary := if (AssignedGroup[Players[mp, 1]]=group1 and AssignedGroup[Players[mp, 3]]=group2) or (AssignedGroup[Players[mp, 3]]=group1 and AssignedGroup[Players[mp, 1]]=group2) then 1 else 0; # 試合でPlayerが重複していないかチェック check{mp in MatchPairIDSet}: sum{py in PlayerSet}MatchPairID_Player[mp, py]=4; # 個人別の試合数を出力 printf "Player Group 総試合数\n"; for{py in PlayerSet} {printf "%s %s %d\n", py, AssignedGroup[py], sum{mp in MatchPairIDSet}MatchPairID_Player[mp, py];} # 対戦番号間でPlayer数の一致数 param PlayerCorrelation{mp1 in MatchPairIDSet, mp2 in MatchPairIDSet} := sum{py in PlayerSet}MatchPairID_Player[mp1, py]*MatchPairID_Player[mp2, py]; var Date_MatchPairID_table{DateSet, MatchPairIDSet} binary; var Date_Group2_table{DateSet, GroupPairofMatches} integer >=0; var Date_Player_table{DateSet, PlayerSet} integer >=0; var T{PlayerSet} integer >=0; minimize diffnMatches: sum{py in PlayerSet}T[py]*coefficients[py]; # 目的関数:Playerの試合数差が小さくなるように s.t. diffnMatches1{py in PlayerSet, day1 in DateSet, day2 in DateSet: day1>day2}: Date_Player_table[day1, py]-Date_Player_table[day2, py]<=T[py]; s.t. diffnMatches2{py in PlayerSet, day1 in DateSet, day2 in DateSet: day1>day2}: -(Date_Player_table[day1, py]-Date_Player_table[day2, py])>=-T[py]; s.t. restrict_MatchPairID{day in DateSet}: sum{mp in MatchPairIDSet}Date_MatchPairID_table[day, mp]=nMatches[day]; # 日ごとの試合数 s.t. uniq_Date{mp in MatchPairIDSet}: sum{day in DateSet}Date_MatchPairID_table[day, mp]=1; s.t. restrictMatchDay{mp in FixMatchIDSet}: Date_MatchPairID_table[FixMatchDate[mp], mp]=1; # 試合日が決っている場合 s.t. avoidMatchDay{mp in AvoidMatchIDSet}: Date_MatchPairID_table[AvoidMatchDate[mp], mp]=0; # 試合を避けたい日 s.t. samedayMatch{day in DateSet, i in MatchinSameDaySerial}: Date_MatchPairID_table[day, MatchinSameDay1[i]]=Date_MatchPairID_table[day, MatchinSameDay2[i]]; # 同日開催

共感・感謝の気持ちを伝えよう!

  • 回答No.14
  • ki073
  • ベストアンサー率77% (491/634)

パズル大好きなのですが、かなり難しいパズルですね。 2つに分けたプログラム(とは言っても条件を並べただけの簡単なものですが)ができています。両方ともに実用的な時間で動くのですが、条件を満たす答えはないとつれない結果になります。どうも朝ABに出場できない人がの処理が足を引っ張っているいるようです。 朝ABに出場できない人を割り当てる時には何かコツがあるのでしょうか?それを入れておかないとかなりの試行錯誤が必要する。まずはこれをある程度解決しておかないと使えないような気がします。 これまでの一日分でも条件を満たすものがあれば書き込んでください。またコツがあったら教えてください。 最終的には完全自動化は無理で、並べ方についてはある程度人が関与が必要です。 手でやっていたのに比べれば遥かに時間短縮ができるものになっています。 要するに、試合をいつに割り当てるとか手でも指定でき、指定していないところは自動で割り当ててくれるものです。 条件を満たしているかは瞬時で判断してくれますので、かなりはかどると思います。上の朝ABに出れない人の試合割当を有る程度のメドがつけば使えるようになるのですが。

共感・感謝の気持ちを伝えよう!

質問者からの補足

朝A,Bに出れない人の制限は今まで、 コツというよりかは、妥協できる範囲は妥協して成立させていたのが実情です。 緩和できそうな人は条件を解除して、朝Bに出場させることで何とか対応してきました。 ※ここで提案なのですが「朝A、Bに不可」という条件から変更して 「(朝A、朝B-1、朝B-2、朝B-3)は出場不可」という条件 もしくは、「朝Aは出場不可」という条件 に条件を緩和してみるとどうなりますかね? 傾向としては 夜Aに出場する人たちは例外なく、朝A,Bの条件に引っかかりますので 条件そのものを緩和させる方向だとどうなるでしょうか? サンプルについてはちょっと今用意できませんが、見つけ次第出してみようと思います ご検討お願いします。

  • 回答No.13
  • ki073
  • ベストアンサー率77% (491/634)

結構楽しんでやっております。 時々GLPKは使っていたのですが、前に書き込んだ様にいい加減なものでも今までは答えが出てきていたのですが、今回は結構複雑な条件ですので実用的な時間ではまだなようです。 任意の日単位(1日単位でもできるし、2日、3日、それ以上でも)並び替えができるのがほぼ完成しました。 前に書き込んだのを分かりやすい形に書き替えただけなのですが、副次的に出上がりました。 だいぶ速度は速くなってきましたが、3日間でやると何時間で答えがでるのかは分かりません。 ただし、条件を全てを満たす答えは無いよという返事は数秒で出てきます。現実的は条件の緩和をしないと無理なようです。 1) 昼A3試合を一ゲームとして時間を空けるが、昼休みを1ゲーム分として休憩にカウントできないか。 2) 朝Aも同時開始で一ゲームとしてカウントしますよね。 3)試合の間隔ですが、今は出場すると次の6ゲーム分を出場できないとしていますが、実際にはどうなのでしょうか? 今できているものは、特定の試合を何番目の試合から何番目の試合までの間にするか指定できます。 夜の試合と、最終試合を指定するために追加したのですが、これを利用して、何試合かを何日目の朝にやりたいとか、午後にやりたいなどをある程度していていくと速度的にはかなり速くなるように思います。 金曜日の夜でも、もう一度書き込みますので、実際にはどうするか考えましょう。まだ試してはいませんが、一日単位ではできそうな感じです。

共感・感謝の気持ちを伝えよう!

質問者からのお礼

続きです。勝手ながら、≪1≫≪2≫で分けるとする場合に 以前の条件を通し番号そのままに分けて、緩和できそうなところを緩和しました。 もし楽になりそうであればお返事いただけるとありがたいです。 見やすく省略した部分もありますが、大会の前提条件そのものはあまり変わっていません 【とくに変更してみた部分は※つけてます。】 ------------------------------------------------------------------------ ≪1≫のプログラムに必要な条件 (1)参加者は「4つの班」 に分かれ(o班、j班、n班、y班とする)、 班内でペアを作り他班のペアとダブルスの試合する。 各人の試合数はその人によって異なる(1~3試合のどれか) (3)大会プログラムは(1日あたり25~32試合) ・朝A (3試合) ・朝B (6~8試合) ・朝C (4試合) ・昼A (2~3試合)←※少し変更してますが、難しければ3に戻します ・昼B (8~12試合) ・夜A (2試合) (7)朝A,Bでの試合を禁止される人もいる。 (9)試合間隔は「自分の入っていない6試合」 を空けなければ次の試合に入ってはならない。 (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)ある試合が、その中のある出場者にとっての、 ※「その日における最後の試合」となるように設定しなければならない可能性がある。 その人がその日において2試合行うなら、必ず2番目になる試合のこと (13)(n班のペア vs y班のペア)による対戦が3つ以上連続してはならない。←※4つ以上に緩和可能 またこれは、(n班,o班,y班,j班) のすべての班同士についても同様とする。ただし夜Aの試合については考慮しない (14)n班全体で見たときに、 y班のペアとの対戦が一日分の試合の半数以上を占めてはならない 。←※60%に緩和可能 またこれは、(n班,o班,y班,j班) のすべての班同士についても同様とする。 (17)出力されるスケジュールは、ランダムに1パターン、または、エラー(満たすパターンなし。) ≪2≫のプログラムに必要な条件(あくまで《1》を優先ですが) (1)「2~3日」で完了する「ダブルス」のテニス大会 メンバーが「4つの班」 に分かれ、班内でペアを作り他班のペアとダブルスの試合する。 ここでは(o班、j班、n班、y班とする) (5) ※3日間の大会の時、各日にちの試合数はこちらで入力指定する※ 3日目の試合数は、○○試合とする。 2日目は○○試合とする。 1日目は○○試合とする。 例:合計90試合なら上から(26-32-32)のように また、これは2日間のときも同様である。 (6)1人が一日分として試合できる数は1~3試合のみ (8)一日分で3試合行うことがが禁止される人もいる ←個人単位で緩和可 (12)※「3日目にのみ振り分けないといけない試合」がある。※ 同様に「2日目に行う試合」、「1日目に行う試合」も存在する。 (14)n班全体で見たとき、y班のペアとの対戦が一日分の試合の半分以上を占めてはならない。(6割に緩和可能) またこれは、(n班,o班,y班,j班) のすべての班同士についても同様とする。 (17)出力される3日間の振り分けは、ランダムに1パターン、ないしは、エラー

質問者からの補足

お返事ありがとうございます。 まず件緩和の質問についてですが、非常に我儘な回答になってしまいますがご勘弁ください。 1) 昼A3試合を一ゲームとして時間を空けるが、昼休みを1ゲーム分として休憩にカウントできないか。 運営の都合上、昼休みとしてまとまった時間をとることができないのでカウントできそうにありません。。 2) 朝Aも同時開始で一ゲームとしてカウントしますよね。 はい。カウントいたします。 3)試合の間隔ですが、今は出場すると次の6ゲーム分を出場できないとしていますが、実際にはどうなのでしょうか? 実際にその通りです。最低6試合空けてから試合に入るよう運営しております。 ところで、先日のレスにも記載したのですが、 あまり苦労を掛けてしまうのもなんですし まず前提として、1、2、3日目の試合振り分けはこちらで手作業で行うことにして 《1》「1日単位に限定した上で、(30試合程度を)並べ替えることのできるプログラム」 を教えていただくことは現状可能でしょうか? その後に、もしご協力いただけるなら、 それとは別個に 《2》「(2)3日間(約90)の試合を3分割するのみのプログラム(スケジュールの並び替えは不要)」 というものにするのではいかがでしょう。 プログラムそのものは2種類作成することになりそうですが、 その方が時間効率はよさそうに感じましたが実際のところはいかがでしょう? 素人感覚になってしまい恐縮です。 もし《1》《2》の2つのプログラム作成にするとすれば、 今ある条件は《1》用と《2》用で、2分割に整理してお伝えした方がわかりやすいでしょうか? 基本的な条件そのものはあまり変更はないかとは思われますが、必要なもの、不必要なものはそれぞれあるかと思いますので。

関連するQ&A

  • テニス大会の組合せの作り方その2

    先程、テニス大会の組合せの作り方を質問しました。 1.10人参加で各自4試合 2.試合はダブルスで、同じペアは組まない 3.相手も毎回違うペア 以上の条件でしたが、[matunatoko]さんから、13人以上が必要と教えていただきました。有難うございました。 そこで、再度質問させていただきます。 3の毎回違うペアとの組合せが無理ならば、出来るだけ違う相手と対戦するような組合せの作り方を教えてください。よろしくお願いします。

  • バレーボールのリーグ戦の表

    現実に起きている問題なのですが、よろしくお願いいたします。 バレーボールのチームが7チームあります。 7チームでリーグ戦をすることになりました。 すべてのチームとあたるようにすると、それぞれのチームが6試合することになります。その場合は、すべての試合数は21試合です。 しかし、21試合をするだけの時間はありません。 そこで、それぞれのチームが4試合するリーグ戦を考えることになりました。 どんな対戦表になるでしょうか。 また、3試合や5試合の場合はどうなるでしょうか。 よろしくお願いいたします。

  • テニスのダブルス8人での対戦組合せ

    ダブルスのテニス乱数表をネットで入手したのですが、 組むペアについては【条件1】を満たしているのですが、 対戦相手については【条件2】を満たしているものが無く、 自分で試行錯誤して作成してもなかなか納得のいくものが出来ません。 【条件1】:自分以外の人と1回だけペアを組む 【条件2】:自分以外の人と必ず2回対戦する 1の人を軸に【条件1】及び【条件2】を満たす対戦表を作りましたが、 その後がなかなか難しくて完成には至りません。 合計試合数は14(7×8÷2÷2)になります。 12-34  13-78 23-15 14-67 24-?? 34-12 15-23 25-?? 35-?? 45-17 16-28 26-?? 36-?? 46-?? 56-18 17-45 27-?? 37-?? 47-?? 57-?? 67-14 18-56 28-16 38-?? 48-?? 58-?? 68-?? 78-13 このような対戦表を作成するのに お詳しい方のご教示を頂ければ幸いです。

  • 数列の問題について教えてください。

    数列の問題について教えてください。 総当たり戦の試合をするとき、2チームだと1試合、3チームだと3試合、4チームだと6試合になる。 m個チームがあると試合数がn回になる場合、m+1個のときの試合数をmとnを用いた式で表せ。 あまり学力の高くない中学3年生にわかるように教えたいのですが、そのレベルでの回答をお待ちしています。

  • テニス大会の組合せの作り方・その2

    先程テニス大会の組合せの作り方を質問し、matumotokさんから条件が合わないとの答えを頂きました。有難うございます。そこで改めてお尋ねします。 次のような条件のテニス大会の組合せの作り方を教えてください。 1.参加者は、10名で、各自ダブルスを4試合します。 2.ペアは、その都度、異なる人と組みます。 3.対戦相手は、出来るだけ異なる組合せとして、同じ対戦相手は2回までとします。 以上のような条件で、組合せの作り方を教えてください。よろしくお願いします。

  • サークル内でのテニスの試合 チーム分など

    私はとあるテニスサークルを仕切っている者です。 参加者のほとんどは私を含めて初心者ばかりで試合に関する知識が乏しいのです。 いろいろご教授いただければと思います。 夏に1泊2日の合宿を開くのですが、せっかくなので2日目に試合をしようと思います。 コートは3時間×2面の予定です。 参加者は16名で男女比率は1:1なので、男女混合のダブルスにしようと思っています。 単純に考えるとペア8組が出来上がるのですが、ささやかですが順位により賞品なども出したいので、 力の差などを考えるとどのようにチームを組んでいいのか悩んでいます。 上のことを踏まえて、質問・相談させていただきたいのは以下のことです。 1:チームの組み方はどのようにすればいいと思われますか?  力量をなるべく均一にするためにはペア8組よりも4人×4チームとかのほうが良いでしょうか?(チーム内でペアを変えながら対戦する) 2:試合のルールはどのようにしたらよいでしょう?   (1セットマッチだとか○ゲームマッチだとか)  1試合あたりをあまり長くしたくはないのですが、かといってあっさり終わりすぎるのも・・・と思っています。  少なくとも1人3試合はしたいと思っています。  ですので、そのルールの場合の平均的な1試合にかかる時間なども参考に聞かせていただければと思っています。 不足の情報があれば捕捉させていただきます。 回答宜しくお願い致します。

  • テニス大会の組合せの作り方

    仲間内のテニス大会の幹事をしています。 以下の条件の組合せの作り方を教えてください。 1.参加者は10名で、各自4試合します。 2.ペアはその都度変えて、同じ人とは2度は組みません。 3.相手もその都度変えて、同じ相手とは2度は対戦しません。 以上です。よろしくお願いします。

  • これの解き方を教えてください。(場合の数)

    Aさんのクラスで腕相撲大会を行う。選手は、必ずほかの選手全員と一回ずつ対戦するものとする。選手が2人のとき、行われる試合の数は1である。 選手が1人増えて3人になると、試合の数は2試合増えて全部で3試合となる。 以下の問いに答えなさい。 行われる試合数が55試合になるとき、選手は何人か。その人数を答えなさい。 求め方がわからないので教えてください。お願いします。

  • テニス・・

    テニス・・ 私は半年ほど前から 数歳年下のテニススクールの同じクラスの女の子と草トーナメントや市民大会にでるようになりました。だいたい月に2回ほどは 一緒にでかけていたので、私も彼女も正規ペアのつもりでいました。 実は私は たまにいろんな人といろんな試合にエントリーしていたのです。(草トーに限る) それというのも 私は誘われたら断らない主義なので 私の得意のサイドに入らせてくれるペアの人であれば、日にちさえ合えばOKしていたんです。 で、市民大会に関しては必ずその正規ペアの子に頼んで 休みをとってもらって一緒にでてもらっていました。草トーナメントに関しても、平日のほうが休みをとれやすいらしいので、私が色々探して、よく一緒にでていたんですが、 先日、知り合いのペアが解消してしまい、市民大会の申し込みギリギリのところで私にでてもらえないかどうか打診されたのです。 私は最初、自分の得意なサイドに入れない条件なので、かなり渋っていたんですが、つきあいもあり、一度だけと思って、エントリーしたら かなりいいところまでいけたのです。 さて、問題はそれからです。 たしかにその大会で想像以上にいい結果がでたのはうれしいのですが、私はそれまでずっとその正規ペアの子と市民大会で結果を出すためにがんばってきたので、結果がでたからといって、その人とペアをこれからも組もうとは思っていないのです。 なにより、結果はでたけれど、私ががんばったというより、ペアの人が調子がよかっただけで。 私の得意サイドではないので、もしでるなら、今度は一つレベルが上の試合にエントリーしなくてはいけないのですが、私が活躍できるとは到底思えません。 ドロー運もかなりあった試合でしたので・・ その人は 前の人より 私の方が組みやすかったらしく(←単純に私が腰が低いからだとおもうのですが)よい成績をとれて、すごく喜んでくれたのですが、やっぱり今までのつきあいも大事だし、私が今までがんばってこれたのも、最終的には一番大事な大会では、その数歳年下の子といい結果を出したい、と思っていたからなんです。 なんだかんだと短い間にかなり試合に出ていて、下の級ではありますが、優勝経験も何回かありますし、今度こそ市民大会で結果を出そうとお互い思っていたところなんです。 (その問題の大会は、私が申し込み期限を勘違いしていたので、もう申し込めないと思って、次の試合に二人ででようと思っていたのです。急にその子は休みがとれないし・・・) 二人で一緒のウェアを着たりしているし、その大会の後も、その正規ペアの子と草トーに出続けているののも折に触れて、なんとなく話をしたりしていたので、その人にはわかってもらえるかなあ、と思っていたのですが、このあいだ 次の試合(同じ市の大会)一緒にでてくれない?といわれて、思わず はい、と答えてしまいました。なんといって断ったら、いいかわからなくて・・・ちなみに正規ペアの子はその日は休みがとれないのです。 まだエントリーは正式にはしていないのですが、ほんとに困っています。(その人も、私が相当迷っているのは感じているとは思います。だからエントリーをまだしていないのだと思います。) とりとめのない話でいったい何がいいたいのかわからないと思いますが。。 前回の試合で たいした成績が残らなければ 自然消滅になっていたのに。。と、どうしたらいいのかわからない状態です。 自分が優柔不断すぎて、情けないです・・・ みなさんならどうしますか。

  • 草野球大会

    うちのチームは一度も草野球大会に出場したことがないのですが, 来年度から出場したいと思っております. 以下の条件を満たす大会を探しているのですが,     ・主に横浜市内で試合が行われる.     ・公式大会の経験がないチームでも出場できる. ご存知の方は,大会名や大会のホームページなどを教えて下さるとありがたいです. また,『草野球 大会 横浜市』とネット検索してもなかなか良い情報が集まらないのですが,よい検索方法および探し方をご存知であれば,教えて下さい. よろしくお願い致します.