こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

締切り済みの質問

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

テニス大会の乱数表(プログラミング)作成をお手伝いいただけませんか?

大会開催に関して、下記の比較的、複雑な条件下で大会を運営しています。
そこでテニス大会の乱数表(プログラミング)作成していただける方を探しています。

対戦表(~班~ペア 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)の条件については,
手作業で満たしているかどうか確認を行うので省いても大丈夫です。

投稿日時 - 2014-08-15 06:30:45

QNo.8717361

困ってます

このQ&Aは役に立ちましたか?

11人が「このQ&Aが役に立った」と投票しています

回答(22)

ANo.22

お役にたてたようで何よりです。

>余談ですが、やはり予想通り怪我人が多くいたため、いくつも条件を変更できる仕様で本当に助かりました。

日程への割り付けの方は、そこまでは考えていなかったのですが、スムーズにできましたでしょうか?
実際には使ってみないと分からない事がいろいろある思いますので、こんな機能があれば良かったのにと思う事がありましたら、書き込んでください。簡単にできることでしたらこの際修正します。

また、この機能が便利だったいうこともあれば書き込んでください。

GLPK は整数計画法という数学分野のものですし、経済学分野のOR(オペレーションリサーチ)など利用されているものです。このような分野に興味のある人を騙して?勉強させてみてください。そうすれば自分たちで改良しながずっと使い続けることができます。

投稿日時 - 2014-09-09 12:12:51

ANo.21

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;
をコメントにしておいてください。
それぞれの行の頭に#を追加するか、/*と*/で挟むとその間(複数行)がコメントになります。

投稿日時 - 2014-08-25 08:50:34

お礼

遅くなりましたが、無事大会を終えることができました。

本当に感謝しております。
余談ですが、やはり予想通り怪我人が多くいたため、いくつも条件を変更できる仕様で本当に助かりました。
プログラムの効果は十二分に発揮することができたと思います。

いつも複数人の運営スタッフが夜通しで考えているような我々とって革命的なプログラムとなったことは間違いありません。
とあるテニスサークルという規模ではありますが、これからも着実に伝え残し、受け継がれるものにしていこうと思います。

重ね重ねではありますが、
本当にありがとうございましたm(_ _)m

投稿日時 - 2014-09-08 23:23:04

ANo.20

こちらもデータ領域だけの書き換えで可能です。
対戦データは先のプログラムの出力の一部をそのままコピペで使えます。
この質問は作業が終わるまで閉め切らないでください。
ご存知だと思いますが、プログラムの実行は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;

投稿日時 - 2014-08-22 23:31:23

補足

非常に恐縮なのですが、訂正した条件の検討をお願いしたいのです。
というのも、少し私の条件提示の表現にミスがありました。

条件(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)の部分)を書き換えることで
上手く対応することはできるのでしょうか?

投稿日時 - 2014-08-25 04:37:55

お礼

まずは、ここまでのプログラムを作っていただいたこと、ありがとうございます。

ただいま運用についての試行錯誤(データからの条件の調節)を行っております。

・条件を縮めすぎたり、辻褄が合わなくなると、パターンがなくなりエラーがでる。
かといって 
・条件が緩すぎると、パターンが多く、出力に時間がかかる。
ということでしょうかね。


第1段階の振り分けプログラムに関してですが、
さらに振り分ける材料を考えたところ、班ごとの対戦傾向に偏りをできるだけなくしたいと思いました。
そこで、今までは (ある班 対 ある班 の割合の限界を50パーセント)としていましたが
これを(20パーセント)にまで下げることでかなり時間を絞ることができました。
おまけに各対戦班にも隔たりがなくなりましたので結果的に一石二鳥となりました。


第二段階の、並び替えについては仰るとおりにするしかないようです。
朝ABの試合数をいじり、あとはどの試合をどのあたりに入れるのかをおおよそ決めておけば、
出力しやすそうです。

正直、ここまで融通の利く内容であれば、むしろ多少の条件の手作業は当然と考えるしかないですね。



お世話になりすぎて、感謝してもしきれないほどのものでございます。

実際に大会で運用できるまでこの質問は残す予定ですので
また何か疑問点等ございましたら恐縮ながら書き込むかもしれません。
本当に本当に、ありがとうございます。

投稿日時 - 2014-08-23 07:57:52

ANo.19

# 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 "";}
}

投稿日時 - 2014-08-22 23:20:25

ANo.18

一日の作成するものも書き込んでおきます
# 一日のスケジュールを作成
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;

投稿日時 - 2014-08-22 23:18:14

ANo.17

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

投稿日時 - 2014-08-22 19:01:37

ANo.16

続きです。

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 " ";
}
}

投稿日時 - 2014-08-22 18:47:26

ANo.15

試合の日程を振り分けるものを書き込みます。
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]]; # 同日開催

投稿日時 - 2014-08-22 18:43:36

ANo.14

パズル大好きなのですが、かなり難しいパズルですね。
2つに分けたプログラム(とは言っても条件を並べただけの簡単なものですが)ができています。両方ともに実用的な時間で動くのですが、条件を満たす答えはないとつれない結果になります。どうも朝ABに出場できない人がの処理が足を引っ張っているいるようです。

朝ABに出場できない人を割り当てる時には何かコツがあるのでしょうか?それを入れておかないとかなりの試行錯誤が必要する。まずはこれをある程度解決しておかないと使えないような気がします。

これまでの一日分でも条件を満たすものがあれば書き込んでください。またコツがあったら教えてください。

最終的には完全自動化は無理で、並べ方についてはある程度人が関与が必要です。
手でやっていたのに比べれば遥かに時間短縮ができるものになっています。
要するに、試合をいつに割り当てるとか手でも指定でき、指定していないところは自動で割り当ててくれるものです。
条件を満たしているかは瞬時で判断してくれますので、かなりはかどると思います。上の朝ABに出れない人の試合割当を有る程度のメドがつけば使えるようになるのですが。

投稿日時 - 2014-08-21 21:46:56

補足

朝A,Bに出れない人の制限は今まで、
コツというよりかは、妥協できる範囲は妥協して成立させていたのが実情です。

緩和できそうな人は条件を解除して、朝Bに出場させることで何とか対応してきました。

※ここで提案なのですが「朝A、Bに不可」という条件から変更して

「(朝A、朝B-1、朝B-2、朝B-3)は出場不可」という条件
もしくは、「朝Aは出場不可」という条件

に条件を緩和してみるとどうなりますかね?

傾向としては
夜Aに出場する人たちは例外なく、朝A,Bの条件に引っかかりますので
条件そのものを緩和させる方向だとどうなるでしょうか?

サンプルについてはちょっと今用意できませんが、見つけ次第出してみようと思います
ご検討お願いします。

投稿日時 - 2014-08-21 22:30:53

ANo.13

結構楽しんでやっております。
時々GLPKは使っていたのですが、前に書き込んだ様にいい加減なものでも今までは答えが出てきていたのですが、今回は結構複雑な条件ですので実用的な時間ではまだなようです。

任意の日単位(1日単位でもできるし、2日、3日、それ以上でも)並び替えができるのがほぼ完成しました。
前に書き込んだのを分かりやすい形に書き替えただけなのですが、副次的に出上がりました。

だいぶ速度は速くなってきましたが、3日間でやると何時間で答えがでるのかは分かりません。
ただし、条件を全てを満たす答えは無いよという返事は数秒で出てきます。現実的は条件の緩和をしないと無理なようです。

1) 昼A3試合を一ゲームとして時間を空けるが、昼休みを1ゲーム分として休憩にカウントできないか。
2) 朝Aも同時開始で一ゲームとしてカウントしますよね。
3)試合の間隔ですが、今は出場すると次の6ゲーム分を出場できないとしていますが、実際にはどうなのでしょうか?

今できているものは、特定の試合を何番目の試合から何番目の試合までの間にするか指定できます。
夜の試合と、最終試合を指定するために追加したのですが、これを利用して、何試合かを何日目の朝にやりたいとか、午後にやりたいなどをある程度していていくと速度的にはかなり速くなるように思います。
金曜日の夜でも、もう一度書き込みますので、実際にはどうするか考えましょう。まだ試してはいませんが、一日単位ではできそうな感じです。

投稿日時 - 2014-08-20 22:11:25

補足

お返事ありがとうございます。

まず件緩和の質問についてですが、非常に我儘な回答になってしまいますがご勘弁ください。

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分割に整理してお伝えした方がわかりやすいでしょうか?
基本的な条件そのものはあまり変更はないかとは思われますが、必要なもの、不必要なものはそれぞれあるかと思いますので。

投稿日時 - 2014-08-20 23:14:57

お礼

続きです。勝手ながら、≪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パターン、ないしは、エラー

投稿日時 - 2014-08-21 00:43:49

ANo.12

たびたびすみません。3日間の振り分けもプログラムを作ってしましましょう。
先ほどのプログラムを少し修正する程度ですので。

やり方として、三日間に振り分ける→日ごとのスケジュールを作る。うまく行かなければ3日間の振り分けを修正になると思います。
あくまでも、頭のなかで出来そうに思っているだけですが。

投稿日時 - 2014-08-19 00:11:56

補足

とんでもございません。
プログラムを2つの行程に分けるということですね。

お時間取らせるようでしたら
第二段階である、1日単位での並び替えだけでも十分です。

本当にお手数おかけします。
よろしくお願いいたします。

投稿日時 - 2014-08-19 00:33:39

お礼

No13のコメント返信の続きです。

《1》のプログラムで、これは条件ではなく仮の案ですが
もし上記の条件でも現実的に難しそうであれば検討ください。

《1》における条件(3)についてです。

1日の試合数を手作業で振り分けているならば、
それに対応する(朝B、昼A、昼B)の試合数についても始めに決めてしまうというのはいかがでしょう。

【~試合のとき⇒朝A、朝B、朝C、昼A、昼B、夜A】というふうに試合数を固定します。

具体例を出すと、、、
【~試合のとき⇒3、?、4、?、?、2】としておいて

【25試合のとき⇒3、6、4、2、8、2】
【28試合のとき⇒3、6、4、3、10、2】
【31試合のとき⇒3、7、4、3、12、2】

というような感じで「~」の部分と「?」の部分をこちらで先に指定してしまうのはどうでしょうか?
(1日分の試合数に辻褄が合うように入力する)

投稿日時 - 2014-08-21 03:19:04

ANo.11

ちょっと思いついたのですが、3日間一度にやらずに、手で一日ずつに分けることは可能ですか?
そうすると計算量はだいぶ少なくなるように思います。

投稿日時 - 2014-08-18 23:20:47

補足

全ての試合を手作業で、あらかじめ
1日目、2日目、3日目に振り分けておくということですよね?

でしたら可能ですよ。

というのも、今までの手作業の場合
第一段階:1,2,3日目への試合の振り分け
第二段階:各日ごとに、振り分けた試合の並び替え

という行程で行っていたからです。

ただ、第一段階でも割と時間を要していたので、第一段階と、第二段階をまとめたプログラムにしたいと欲を出してしまっていたんです。申し訳ありません^^;

投稿日時 - 2014-08-18 23:47:51

ANo.10

何かすごい量ですね。書き込んでみて初めて気がつきました。データ部分です。
data;
## グループのリスト
set GroupNameSet := n o j y;
## Playerの所属するグループ
param : PlayerSet : AssighnedGroup :=
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 Limit :=
N1 2
N4 2
N5 2
O1 2
O4 2
O6 2
O7 2
J1 2
J2 2
J3 2
Y1 2
Y2 2
Y4 2
;
## ABの試合に出られないPlayer名
set AvoidABTeamSet :=
N1
N2
N3
N4
N5
O1
O2
O3
O4
O7
O12
J1
J2
J3
J4
J11
Y1
Y2
Y3
Y4
Y8
;
## 試合の組み合わせとPlayer4人と所属グループ名
param Players : 1 2 3 4 :=
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
;
end;

投稿日時 - 2014-08-18 22:59:45

ANo.9

なかなか、

# 連続した9試合中1試合以下であること
s.t. one_or_zero_in_9_matches{ms in check_9_matches, py in PlayerSet}:
sum{k in 0..8}MatchScheduleID_PlayerName_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_PlayerName_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_PlayerName_table[ms-k, py]<=1;

## 試合のスケジュールが固定されている場合
s.t. night1a: MatchScheduleID_MatchPairID_table[30, 31]=1; # 決まっている試合番号と対戦番号 30試合目が対戦番号31
s.t. night1b: MatchScheduleID_MatchPairID_table[31, 46]=1; # 夜の試合の指定に使う
s.t. night2a: MatchScheduleID_MatchPairID_table[61, 61]=1;
s.t. night2b: MatchScheduleID_MatchPairID_table[62, 16]=1;
s.t. night3a: MatchScheduleID_MatchPairID_table[89, 79]=1;
s.t. night3b: MatchScheduleID_MatchPairID_table[90, 3]=1;
## 最終試合が決っている組み合わせを最終日の後ろの方に指定
s.t. third_day1: MatchScheduleID_MatchPairID_table[83, 1]=1;
s.t. third_day2: MatchScheduleID_MatchPairID_table[84, 52]=1;
s.t. third_day3: MatchScheduleID_MatchPairID_table[86, 11]=1;
s.t. third_day4: MatchScheduleID_MatchPairID_table[87, 87]=1;
## その他の試合もなるべく指定
/*
s.t. schedule1: MatchScheduleID_MatchPairID_table[13, 6]=1;
s.t. schedule2: MatchScheduleID_MatchPairID_table[14, 27]=1;
s.t. schedule3: MatchScheduleID_MatchPairID_table[15, 49]=1;
s.t. schedule4: MatchScheduleID_MatchPairID_table[45, 17]=1;
s.t. schedule5: MatchScheduleID_MatchPairID_table[46, 68]=1;
*/
# s.t. reject1: MatchScheduleID_MatchPairID_table[93, 93]=0; # 逆に指定した試合番号に入れたくない場合は0に

solve;
# 出力
for{ms in MatchScheduleIDSet}
{for {mp in MatchPairIDSet : MatchScheduleID_MatchPairID_table[ms, mp]=1}
{printf "%s %s %s %s (%s) %s %s (%s)\n", ms, mp, Players[mp, 1], Players[mp, 2], AssighnedGroup[Players[mp, 1]], Players[mp, 3], Players[mp, 4], AssighnedGroup[Players[mp, 3]];}
}

投稿日時 - 2014-08-18 22:57:48

ANo.8

続きです。
# 対戦番号とPlayer名の対応表
param MatchPairID_PlayerName{mp in MatchPairIDSet, py in PlayerSet} binary :=
if Players[mp, 1]=py or Players[mp, 2]=py or Players[mp, 3]=py or Players[mp, 4]=py then 1 else 0;
# 対戦番号とグループ名の対応表
param MatchPairID_Group2{mp in MatchPairIDSet, group1 in GroupNameSet, group2 in GroupNameSet} binary :=
if (AssighnedGroup[Players[mp, 1]]=group1 and AssighnedGroup[Players[mp, 3]]=group2) or
(AssighnedGroup[Players[mp, 3]]=group1 and AssighnedGroup[Players[mp, 1]]=group2) then 1 else 0;

# display MatchPairID_Group2;

# 試合でPlayerが重複していないかチェック
check{mp in MatchPairIDSet}: sum{py in PlayerSet}MatchPairID_PlayerName[mp, py]=4;
# 同じグループ間の対戦が無いかチェック
check{mp in MatchPairIDSet}: sum{g in GroupNameSet}MatchPairID_Group2[mp, g, g]=0;

var MatchScheduleID_MatchPairID_table{MatchScheduleIDSet, MatchPairIDSet} binary;
var MatchScheduleID_Group2_table{MatchScheduleIDSet, GroupNameSet, GroupNameSet} binary;
var MatchScheduleID_PlayerName_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;

# MatchScheduleID_PlayerName_tableを書き換え
s.t. update_MatchScheduleID_Player_table{ms in MatchScheduleIDSet, py in PlayerSet}:
sum{mp in MatchPairIDSet : MatchPairID_PlayerName[mp, py]=1}MatchScheduleID_MatchPairID_table[ms,mp]=MatchScheduleID_PlayerName_table[ms, py];
# MatchScheduleID_Group2_tableを書き換え
s.t. update_MatchScheduleID_Group2_table{ms in MatchScheduleIDSet, group1 in GroupNameSet, group2 in GroupNameSet}:
sum{mp in MatchPairIDSet: MatchPairID_Group2[mp, group1, group2]=1}MatchScheduleID_MatchPairID_table[ms,mp]=MatchScheduleID_Group2_table[ms, group1, group2];

# 一日1以上指定した試合数以下の試合数制限
s.t. limit1s{py in PlayerSet}: sum{ms in First_day_matches}MatchScheduleID_PlayerName_table[ms, py] <= Limit[py];
s.t. limit1l{py in PlayerSet}: sum{ms in First_day_matches}MatchScheduleID_PlayerName_table[ms, py] >=1;
s.t. limit2s{py in PlayerSet}: sum{ms in Second_day_matches}MatchScheduleID_PlayerName_table[ms, py] <= Limit[py];
s.t. limit2l{py in PlayerSet}: sum{ms in Second_day_matches}MatchScheduleID_PlayerName_table[ms, py] >=1;
s.t. limit3s{py in PlayerSet}: sum{ms in Third_day_matches}MatchScheduleID_PlayerName_table[ms, py] <= Limit[py];
s.t. limit3l{py in PlayerSet}: sum{ms in Third_day_matches}MatchScheduleID_PlayerName_table[ms, py] >=1;

# グループの同じ組み合わせが対戦の1/2以下
s.t. limit_sama_group_pair1{group1 in GroupNameSet, group2 in GroupNameSet}:
sum{ms in First_day_matches}MatchScheduleID_Group2_table[ms, group1, group2]<=n_matches_in_first_day/2;
s.t. limit_sama_group_pair2{group1 in GroupNameSet, group2 in GroupNameSet}:
sum{ms in Second_day_matches}MatchScheduleID_Group2_table[ms, group1, group2]<=n_matches_in_second_day/2;
s.t. limit_sama_group_pair3{group1 in GroupNameSet, group2 in GroupNameSet}:
sum{ms in Third_day_matches}MatchScheduleID_Group2_table[ms, group1, group2]<=n_matches_in_third_day/2;

# ABに試合ができないチームの処理
set Match_AB := First_day_start_match..n_ABmatches_in_first_day union # ABに属する試合番号
Second_day_start_match..(Second_day_start_match+n_ABmatches_in_second_day-1) union
Third_day_start_match..(Third_day_start_match+n_ABmatches_in_third_day-1);
s.t. avoid1{ms in Match_AB, py in AvoidABTeamSet}: MatchScheduleID_PlayerName_table[ms ,py]=0;
/*
# 同じグループの組み合わせが3回連続しない 夜は含めない
set group_exception3 := (First_day_start_match+2)..(First_day_end_match-n_night_matches_in_first_day) union
(Second_day_start_match+2)..(Second_day_end_match-n_night_matches_in_second_day) union
(Third_day_start_match+2)..(Third_day_end_match-n_night_matches_in_second_day);
s.t. group_exception{ms in group_exception3, group1 in GroupNameSet, group2 in GroupNameSet}:
sum{k in 0..2}MatchScheduleID_Group2_table[ms-k, group1, group2]<=2;

投稿日時 - 2014-08-18 22:55:41

ANo.7

定義部分です。
param n_matches_in_first_day := 31; ## 初日の総試合数
param n_ABmatches_in_first_day := 10; ## 初日のABの試合数合計
param n_morning_matches_in_first_day := 12; ## 初日の午前中の試合数
param n_night_matches_in_first_day := 2; ## 初日の夜の試合数
param n_matches_in_second_day := 31; ## 二日目の総試合数
param n_ABmatches_in_second_day := 10; ## 二日目のABの試合数合計
param n_morning_matches_in_second_day := 13; ## 二日目の午前中の試合数
param n_night_matches_in_second_day := 2; ## 二日目の夜の試合数
# 三日目の総試合数は自動的に求まる
param n_ABmatches_in_third_day := 9; ## 三日目のABの試合数合計
param n_morning_matches_in_third_day := 11; ## 三日目の午前中の試合数
param n_night_matches_in_third_day := 2; ## 三日目の夜の試合数

set MatchPairIDSet := 1..90; ## 対戦組み合わせの番号の集合

# 以上を必要に応じて修正

set GroupNameSet; # グループ名の集合
set PlayerSet; # Player名の集合
set AvoidABTeamSet; # ABの試合ができないチームの集合

# 各日の開始、終了試合番号
param n_matches_in_third_day := card(MatchPairIDSet)-n_matches_in_first_day-n_matches_in_second_day;
param First_day_start_match := 1;
param First_day_end_match := n_matches_in_first_day;
param Second_day_start_match := n_matches_in_first_day+1;
param Second_day_end_match := n_matches_in_first_day+n_matches_in_second_day;
param Third_day_start_match := n_matches_in_first_day+n_matches_in_second_day+1;
param Third_day_end_match := card(MatchPairIDSet);

set MatchScheduleIDSet := 1..card(MatchPairIDSet); # 試合番号1~
set First_day_matches := First_day_start_match..First_day_end_match; # 初日の試合番号の集合
set Second_day_matches := Second_day_start_match..Second_day_end_match; # 二日目の試合番号の集合
set Third_day_matches := Third_day_start_match..Third_day_end_match; # 三日目の試合番号の集合

# 試合へ出る間隔
# その試合と前8試合中で1回出場できる、朝第9試合、昼第3~第9試合
set check_9_matches := {First_day_start_match+8} union
First_day_start_match+n_morning_matches_in_first_day+2..First_day_start_match+n_morning_matches_in_first_day+8 union
{Second_day_start_match+8} union
Second_day_start_match+n_morning_matches_in_second_day+2..Second_day_start_match+n_morning_matches_in_second_day+8 union
{Third_day_start_match+8} union
Third_day_start_match+n_morning_matches_in_third_day+2..Third_day_start_match+n_morning_matches_in_third_day+8;
# その試合と前7試合中で1回出場できる、昼第2試合
set check_8_matches := {First_day_start_match+n_morning_matches_in_first_day+1,
Second_day_start_match+n_morning_matches_in_second_day+1,
Third_day_start_match+n_morning_matches_in_third_day+1};
# その試合と前6試合中で1回出場できる、その他
set check_7_matches := (First_day_start_match+9..First_day_end_match union
Second_day_start_match+9..Second_day_end_match union
Third_day_start_match+9..Third_day_end_match) diff (check_9_matches union check_8_matches);

# Playerとその所属グループ
param AssighnedGroup{PlayerSet} symbolic;
param Players{MatchPairIDSet, 1..4} symbolic; # 対戦番号とPlayerの紐付け
param Limit{PlayerSet} default 3; ## Playerの一日の最高試合数、指定していない時はこの数値を使う

# Players[1], Player[2]が同じグループかチェック
check{mp in MatchPairIDSet}: AssighnedGroup[Players[mp, 1]]=AssighnedGroup[Players[mp, 2]];
# Players[3], Player[4]が同じグループかチェック
check{mp in MatchPairIDSet}: AssighnedGroup[Players[mp, 3]]=AssighnedGroup[Players[mp, 4]];

# 個人別の試合数を出力
printf "Plaayer Group 試合数\n";
for{py in PlayerSet}
{printf "%s %s %d\n", py, AssighnedGroup[py],
sum{mp in MatchPairIDSet:
Players[mp,1]=py or Players[mp,2]=py or Players[mp,3]=py or Players[mp,4]=py}1;}

投稿日時 - 2014-08-18 22:54:06

ANo.6

ちょっと苦戦しております。
最初の質問で、グループ内ペアは固定でやるのをGLPKで作成し5分ほどで答えが出てきたので、出来たものだと思っていましたが、今回条件を追加していくと計算時間がかかり過ぎ(2時間経っても答えがでない)てしまいます。
また、サンプルデータは結構条件が厳しく解けないようなメッセージも出ております。プログラムのミスが有りそうにも思いますが、
もしかしたら一日2試合しか出れない人が3日間フルに出場しているとか、8試合出る人がいるなどが原因しているのかもしれません。
もう少し考えますが、取りあえずプログラムを書き込んできます。

定義部分とデータ部分の2つに分けて書き込みますが、一つにつなげて動かしてください。
/* */の間がコメントで、取りあえず動かすためにプログラムの一部を動かないようにしています。

時間がかかりすぎることの一つの解決方法として、試合スケジュールを入れやすいところをいくつか手で入れてしまい、コンピュータが決める部分を少なくすることも考えられますが、もう少し後で考えましょう。こんなもんだという程度のつもりでまず見てください。

動かしてもなかなか答えがでませんので、無謀なことはやらないように。

31日の試合は3日間でしょうか?、計算量からすると2日の方が楽なのですが。

投稿日時 - 2014-08-18 22:52:02

補足

ひとまず、ありがとうございます。
これほどの内容とは、、感謝してもしきれません。

サンプルデータについてですが、個々人の制約(以下)については多少いじってみて構いません。

●毎日2試合縛り(= 一日3試合出場不可、かつ、合計試合数6試合)
●朝A朝Bに出られない人

については三試合出させたり、朝に出場させたり、適宜いじって組むことになりそうですね。
実際、手作業で組んでいても、この2つの制約はいくらか緩和せざるを得ない状況になることが多かったです。

我儘になってしまうのですが、31日からの試合は3日間ですね。
ですが、2日間で動作する仕様、も必要といえば必要というところですね。
怪我人が出たときの2日目、3日目のスケジュールを組みなおす際に有効だと思います

投稿日時 - 2014-08-18 23:34:50

ANo.5

何か横槍が入っていますが、まあ

興味でやっていますし、プログラムなどの書き込みは備忘録のつもりですので、自由にお使いください。

ちょっと時間がとれませんでしたが、頭の中では完成しております。明日の夜には書き込めると思いますので、もうしばらくお待ちください。

主に通勤の電車の中の暇な時間を利用してやっていますので、休みで電車に乗らなかったのでやる時間が無かったと言い訳をしております。

投稿日時 - 2014-08-17 21:12:56

お礼

とんでもございません。
お世話になり恐縮です。

GLPK(windows)についてですがインストールと作動を確認できました。
教えていただいた練習問題等についても無事出力できる程度にはなったところです。

投稿日時 - 2014-08-18 21:30:08

こういうものは普通金を払って雇うようなものだと思うのだが.

投稿日時 - 2014-08-16 22:42:06

ANo.3

データありがとうございます。
これからプログラムを改良します。
すぐには時間があまりとれないので、2、3日お待ちください。

それとGLPKを使いますので、インストールしてサンプルでも試してみてください。
Windows用は多分これだと思うのですが、手元にWindowsがないので確かめられません。
http://sourceforge.net/projects/winglpk/

練習用サンプルとしてこのあたりはいかがでしょうか?
http://www21.tok2.com/home/kainaga11/glpk/glpk.htm
数独でGLPKの使い方を勉強しました。
例えば数独の場合、end;までのファイルsudoku.modを作成し
glpsol -m sudoku.mod  (Windowsの場合は glpsol.exeのはず)
で答えが即座にでます。もしエラーが出る場合には、パスが通っていないとかだと思います。
Windowsのことは私は力量不足ですので他の質問にして他の方に教えてもらってください。

投稿日時 - 2014-08-15 23:12:43

お礼

本当に助かります。

お返事いただけるまでに、GLPKについてはある程度勉強しておこうと思っています。
お気遣いいただきありがとうございます。

結果によっては対価のお支払いも検討しておりますので、
別途スカイプア等アカウントを作成いただけるとありがたいです。

投稿日時 - 2014-08-17 00:20:16

ANo.2

>よろしければスカイプIDを連絡いたします。

以前からいろいろ考えていたのですが、どうも個人的に送る手段は無いようです。
私はSkypeのIDを持っていませんが、質問者さんがここにIDを書かないと私に伝わらないので、ちょっとまずいのです。

さて、補足欄かお礼欄に差し支えない程度のデータを書き込んでもらえないでしょうか?
テスト用に使います。

エクセルの画面で範囲を指定して、そのまま貼付ければテキスト形式で書き込めるはずです。
あるいは、適当なテキスト形式(CSV形式でもタブ区切りでも何でも構いません)で出力して貼付けても構いません。

追加の(12)は考えないといけないのと、チームが固定ではないので個人単位で管理する(こちらは簡単)の変更が必要ですが、
それ以外は問題なく動いております。

こちらで変更した事項は、
それぞれの日の試合数は自動ではなく、予め決めておく必要がある。
午後の試合の始めから8試合は、午前の試合から8ゲームあけることにしています(ゲーム数は変更可)
それと出力されるスケジュールは1つだけです。他の候補を出す場合は条件を微妙に変えれば出てきます(操作は簡単)
となっています。多分問題はないと思います。

やってみて感じたのですが、これを手でできていたのでしょうか??すごい根気がいりそうです。

投稿日時 - 2014-08-15 13:59:30

補足

できれば

ファイルはこの2種類です。
1、参加者の名簿、とその各人の情報 
2、試合の内容、と条件に関連した情報

・・・・以下「参加者名簿」のファイルについて・・・・・

●参加者の個人名は、「アルファベット+数字」によって1人1人を区別しています。

●今回は4つの班を(n,o,y,j)の4つとし、各人所属の班を記載しています。

●禁止事項について

1→ 朝A,Bの試合に出場禁止の人
2→ 一日分に3試合を禁止されている人
3→ 1と2を両方満たす人
0→ 1,2,3について特に指定の無い人

●条件(12)についての項目
参加者各々にとって、最終試合を必ず指定する場合は、その「試合番号」を記載しました。
試合番号と、その内容については、対戦表のファイルに記載しています。
「0」と記入されているのは、条件(12)について特に指定の無い人です。



・・・・以下「対戦組み合わせ」のファイルについて・・・・

●試合の通し番号について
計画している試合について、通し番号をつけました。この順番 に関して法則はありません。

●出場者1.2.3.4、と、その所属班について
そのダブルスにおける四名を記載しました。
試合内容とそのペアは(出場者1&2)vs(出場者3&4)となります。

●夜Aの試合の有無について
0→指定なし
3→3日目の夜Aに固定
2→2日目の夜Aに固定
1→1日目の夜Aに固定

●条件(13)について
名簿に記載した内容と対応するものなので不要かもしれませんが一応記載しました。
0→特に指定なし
1→出場者(4名)の誰かにとって、最終試合に指定されている

●誰にとっての最終試合か
こちらも名簿ファイルに記載して いる内容と対応しています。
その試合で最終試合を迎える個人名をカンマで区切って記載しています。

・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・

以下「参加者名簿のファイル」

左から
個人名/所属班/禁止事項/最終試合の試合番号
N1n31
N2n11
N3n10
N4n30
N5n30
N6n00
N7n00
N8n00
N9n00
N10n011
N11n011
N12n00
N13n00
N14n00
N15n00
O1o31
O2o11
O3o10
O4o30
O5o00
O6o20
O7o352
O8o052
O9o00
O10o011
O11o011
O12o10
O13o00
O14o00
O15o00
J1j30
J2j30
J3j379
J4j10
J5j079
J6j052
J7j00
J8j052
J9j00
J10j00
J11j10
J12j087
J13j087
J14j00
Y1y30
Y2y379
Y3y10
Y4y30
Y5y079
Y6y00
Y7y00
Y8y10
Y9y00
Y10y00
Y11y00
Y12y087
Y13y087
Y14y00


次に、対戦組み合わせのエクセルです



左から

試合番号/出場者1/出場者2/出場者3/出場者4/出場者1と2の所属/出場者3、4の所属/夜Aの有無/最終試合か/誰にとっての最終試合か

1N1N2O1O2no31 N1,N2,O1,O2
2N1N3O1O3no00
3N2N4O2O4no00
4N3N5O3O5no00
5N4N5O4O5no00
6N6N7O6O7no00
7N6N8O6O8no00
8N7N8O7O8no00
9N9N10O9O10no00
10N9N11O9O11no00
11N10N11O10O11no01 N10,N11,O10,O11
12N12N13O12O13no00
13N12N14O12O14no00
14N13N15O13O15no00
15N14N15O14O15no00
16N1N2J1J2nj20
17N1N4J1J4nj00
18N2N3J2J3nj00
19N3N4J3J4nj00
20N5N6J5J6nj00
21N5N7J5J7nj00
22N6N7J6J7nj00
23N8N9J8J9nj00
24N8N10J8J10nj00
25N9N10J9J10nj00
26N11N12J10J11nj00
27N11N13J11J12nj00
28N12N15J11J13nj00
29N13N14J12J15nj00
30N14N15J13J15nj00
31N1N2Y1Y2ny10
32N1N3Y1Y3ny00
33N2N3Y2Y3ny00
34N4N5Y4Y5ny00
35N4N6Y4Y6ny00
36N5N6Y5Y6ny00
37N7N8Y7Y8ny00
38N7N9Y7Y9ny00
39N8N9Y8Y9ny00
40N10N11Y10Y11ny00
41N10N12Y10Y12ny00
42N11N12Y11Y12ny00
43N13N14Y13Y14ny00
44N13N15Y13Y15ny00
45N14N15Y14Y15ny00
46J1J2O1O2jo10
47J1J3O1O3jo00
48J2J3O2O3jo00
49J4J5O4O5jo00
50J4J6O4O6jo00
51J5J7O5O6jo00
52J6J8O7O8jo01 J6,J8,O7,O8
53J7J9O7O9jo00
54J8J9O8O9jo00
55J10J11O10O11jo00
56J10J12O10O12jo00
57J11J15O11O12jo00
58J12J13O13O14jo00
59J13J15O13O15jo00
60J13J15O14O15jo00
61Y1Y2O1O2yo20
62Y1Y4O1O4yo00
63Y2Y3O2O3yo00
64Y3Y4O3O4yo00
65Y5Y6O5O6yo00
66Y5Y7O5O7yo00
67Y6Y7O6O7yo00
68Y8Y9O8O9yo00
69Y8Y10O8O10yo00
70Y9Y10O9O10yo00
71Y11Y12O11O12yo00
72Y11Y13O11O13yo00
73Y12Y15O12O15yo00
74Y13Y14O13O14yo00
75Y14Y15O14O15yo00
76J1J2Y1Y2jy00
77J1J3Y1Y3jy00
78J2J4Y3Y4jy00
79J3J5Y2Y5jy31 J3,J5,Y2,Y5
80J4J5Y4Y5jy00
81J6J7Y6Y7jy00
82J6J8Y6Y8jy00
83J7J88Y7Y8jy00
84J9J10Y9Y10jy00
85J9J10Y9Y11jy00
86J10J11Y10Y11jy00
87J12J13Y12Y13jy01 J12,Y12,Y13
88J12J15Y12Y14jy00
89J13J15Y13Y15jy00
90J12J15Y14Y15jy00



以上です。



見にくければ、私のスカイプID(fjbxr275)までお願いいたします。
これは捨てIDなので大丈夫です。またスカイプといても、LINEのようなチャットです

投稿日時 - 2014-08-15 15:27:19

お礼

もう少しわかりやすく区切っておきますね。


以下「参加者名簿のファイル」


左から
個人名/所属班/禁止事項/最終試合の試合番号
N1/n/3/1
N2/n/1/1
N3/n/1/0
N4/n/3/0
N5/n/3/0
N6/n/0/0
N7/n/0/0
N8/n/0/0
N9/n/0/0
N10/n/0/11
N11/n/0/11
N12/n/0/0
N13/n/0/0
N14/n/0/0
N15/n/0/0
O1/o/3/1
O2/o/1/1
O3/o/1/0
O4/o/3/0
O5/o/0/0
O6/o/2/0
O7/o/3/52
O8/o/0/52
O9/o/0/0
O10/o/0/11
O11/o/0/11
O12/o/1/0
O13/o/0/0
O14/o/0/0
O15/o/0/0
J1/j/3/0
J2/j/3/0
J3/j/3/79
J4/j/1/0
J5/j/0/79
J6/j/0/52
J7/j/0/0
J8/j/0/52
J9/j/0/0
J10/j/0/0
J11/j/1/0
J12/j/0/87
J13/j/0/87
J14/j/0/0
Y1/y/3/0
Y2/y/3/79
Y3/y/1/0
Y4/y/3/0
Y5/y/0/79
Y6/y/0/0
Y7/y/0/0
Y8/y/1/0
Y9/y/0/0
Y10/y/0/0
Y11/y/0/0
Y12/y/0/87
Y13/y/0/87
Y14/y/0/0






次に、対戦組み合わせのエクセルです



左から

試合番号/出場者1/出場者2/出場者3/出場者4/出場者1と2の所属/出場者3、4の所属
/夜Aの有無/最終試合か/誰にとっての最終試合か

1/N1/N2/O1/O2/n/o/3/1/N1,N2,O1,O2
2/N1/N3/O1/O3/n/o/0/0
3/N2/N4/O2/O4/n/o/0/0
4/N3/N5/O3/O5/n/o/0/0
5/N4/N5/O4/O5/n/o/0/0
6/N6/N7/O6/O7/n/o/0/0
7/N6/N8/O6/O8/n/o/0/0
8/N7/N8/O7/O8/n/o/0/0
9/N9/N10/O9/O10/n/o/0/0
10/N9/N11/O9/O11/n/o/0/0
11/N10/N11/O10/O11/n/o/0/1/N10,N11,O10,O11
12/N12/N13/O12/O13/n/o/0/0
13/N12/N14/O12/O14/n/o/0/0
14/N13/N15/O13/O15/n/o/0/0
15/N14/N15/O14/O15/n/o/0/0
16/N1/N2/J1/J2/n/j/2/0
17/N1/N4/J1/J4/n/j/0/0
18/N2/N3/J2/J3/n/j/0/0
19/N3/N4/J3/J4/n/j/0/0
20/N5/N6/J5/J6/n/j/0/0
21/N5/N7/J5/J7/n/j/0/0
22/N6/N7/J6/J7/n/j/0/0
23/N8/N9/J8/J9/n/j/0/0
24/N8/N10/J8/J10/n/j/0/0
25/N9/N10/J9/J10/n/j/0/0
26/N11/N12/J10/J11/n/j/0/0
27/N11/N13/J11/J12/n/j/0/0
28/N12/N15/J11/J13/n/j/0/0
29/N13/N14/J12/J15/n/j/0/0
30/N14/N15/J13/J15/n/j/0/0
31/N1/N2/Y1/Y2/n/y/1/0
32/N1/N3/Y1/Y3/n/y/0/0
33/N2/N3/Y2/Y3/n/y/0/0
34/N4/N5/Y4/Y5/n/y/0/0
35/N4/N6/Y4/Y6/n/y/0/0
36/N5/N6/Y5/Y6/n/y/0/0
37/N7/N8/Y7/Y8/n/y/0/0
38/N7/N9/Y7/Y9/n/y/0/0
39/N8/N9/Y8/Y9/n/y/0/0
40/N10/N11/Y10/Y11/n/y/0/0
41/N10/N12/Y10/Y12/n/y/0/0
42/N11/N12/Y11/Y12/n/y/0/0
43/N13/N14/Y13/Y14/n/y/0/0
44/N13/N15/Y13/Y15/n/y/0/0
45/N14/N15/Y14/Y15/n/y/0/0
46/J1/J2/O1/O2/j/o/1/0
47/J1/J3/O1/O3/j/o/0/0
48/J2/J3/O2/O3/j/o/0/0
49/J4/J5/O4/O5/j/o/0/0
50/J4/J6/O4/O6/j/o/0/0
51/J5/J7/O5/O6/j/o/0/0
52/J6/J8/O7/O8/j/o/0/1/J6,J8,O7,O8
53/J7/J9/O7/O9/j/o/0/0
54/J8/J9/O8/O9/j/o/0/0
55/J10/J11/O10/O11/j/o/0/0
56/J10/J12/O10/O12/j/o/0/0
57/J11/J15/O11/O12/j/o/0/0
58/J12/J13/O13/O14/j/o/0/0
59/J13/J15/O13/O15/j/o/0/0
60/J13/J15/O14/O15/j/o/0/0
61/Y1/Y2/O1/O2/y/o/2/0
62/Y1/Y4/O1/O4/y/o/0/0
63/Y2/Y3/O2/O3/y/o/0/0
64/Y3/Y4/O3/O4/y/o/0/0
65/Y5/Y6/O5/O6/y/o/0/0
66/Y5/Y7/O5/O7/y/o/0/0
67/Y6/Y7/O6/O7/y/o/0/0
68/Y8/Y9/O8/O9/y/o/0/0
69/Y8/Y10/O8/O10/y/o/0/0
70/Y9/Y10/O9/O10/y/o/0/0
71/Y11/Y12/O11/O12/y/o/0/0
72/Y11/Y13/O11/O13/y/o/0/0
73/Y12/Y15/O12/O15/y/o/0/0
74/Y13/Y14/O13/O14/y/o/0/0
75/Y14/Y15/O14/O15/y/o/0/0
76/J1/J2/Y1/Y2/j/y/0/0
77/J1/J3/Y1/Y3/j/y/0/0
78/J2/J4/Y3/Y4/j/y/0/0
79/J3/J5/Y2/Y5/j/y/3/1/J3,J5,Y2,Y5
80/J4/J5/Y4/Y5/j/y/0/0
81/J6/J7/Y6/Y7/j/y/0/0
82/J6/J8/Y6/Y8/j/y/0/0
83/J7/J8/Y7/Y8/j/y/0/0
84/J9/J10/Y9/Y10/j/y/0/0
85/J9/J10/Y9/Y11/j/y/0/0
86/J10/J11/Y10/Y11/j/y/0/0
87/J12/J13/Y12/Y13/j/y/0/1/J12,Y12,Y13
88/J12/J15/Y12/Y14/j/y/0/0
89/J13/J15/Y13/Y15/j/y/0/0
90/J12/J15/Y14/Y15/j/y/0/0

投稿日時 - 2014-08-15 16:08:26

ANo.1

前の質問
http://oshiete1.nifty.com/qa8712468.html

からの追加が(12)だけでしょうか?

ちょっと疑問点ですが、

グループ内のペア(チーム)は試合期間中を通して変わらないのでしょうか?
例えばグループnのAさんは Cさんとしかペアを組まないのでしょうか?
こちらだとチーム単位で考えれば良いのですが、
参加者に均等に試合数を割り当てるとすると、グループ内のペア(チーム)は変動する(AさんはCさんと組むこともあるし、Dさんとのこともある)のでしょうか?


>8月31日の大会に間に合わせたいと考えています。

間に合うかは質問者さんのレスポンスが早く行われかによって決まります。
ただし一ヶ月もかかりませんので。

前回のものについてはほぼ完成しております。

投稿日時 - 2014-08-15 07:40:09

補足

そうですね、(12)が大きく変わったポイントになります。
(3)についても若干、数字を緩和させましたが、前回の数値のままでも構いません。
あとは、条件の言い回し等わかりやすくならないかと少し変えている程度ですね。
一応すべて見てもらえるとありがたいです。

疑問点についてですが

>グループ内のペア(チーム)は試合期間中を通して変わらないのでしょうか?
>例えばグループnのAさんは Cさんとしかペアを組まないのでしょうか?
>こちらだとチーム単位で考えれば良いのですが、
>参加者に均等に試合数を割り当てるとすると、グループ内のペア(チーム)は変動する(AさんはCさんと組むこともあるし、Dさんとのこともある)のでしょうか?

こちらについては、いいえ。です。
各人ごと複数種類のペアと組みます。また、複数回組むペアもいます。
ですので、均等に試合数を割り当てるということはしておりません。

参考程度にエクセルですが、対戦組み合わせ表(制約情報込)と、大会参加者の名簿(制約情報込)、を2つで用意しておりますので
ご覧いただくことはできますか?(個人情報に触れる要素は無くしております)
あくまで過去の例で、これからの大会とは無関係ですが。

よろしければスカイプIDを連絡いたします。

投稿日時 - 2014-08-15 07:54:03

お礼

ちなみに今まではすべて手作業でかなりの時間を要していました。

また、お作りりいただいているプログラムは「3日間の大会」「2日間の大会」
の両方に対応しているのでしょうか?
なんにせよ非常にありがたいです(^^)

投稿日時 - 2014-08-15 15:31:22

あなたにオススメの質問