システムwiki

vba:チーム割り当てのすべての可能なソリューションを決定します

jjmader 受付中 最終更新日:2022-06-26 08:45

みなさん、こんにちは-

次の表があります:

人/チーム

アルファ

ブラボー

チャーリー

デルタ

echo

Foxtrot

ゴルフ

サリー

X

X

X

X

X

X

X

フレッド

X

X

X

ベッキー

X

X

アンドリュー

X

X

X

X

サム

X

X

X

最初の行はTeamsAlphaからGolfを表し、最初の列はプレーヤー名です.ルールでは、各チームに割り当てることができるのは1人のプレーヤーのみで、残りは予備リストに入れられます.

VBAスクリプトを使用してリストを確認し、誰がどのチームに割り当てられ、誰が予備であるかなど、問題に対するすべての可能な解決策を出力したいと思います.

実際のリストには約45の名前と40のチームがあるため、かなり複雑ですが、一般化されたスクリプトを期待していることに注意してください.私は何かに取り組んでいますが、ここの誰かが私よりもVBAの方が確かに優れていて、おそらく簡単な解決策があると思いました.

返信リスト(回答:6)

6 #
Andreas

この問題のキーワードは組み合わせ論です.この場合、繰り返しのない組み合わせが決定されます 7つのうち5つ.

結果は21の組み合わせです:

A B C D E

A B C D F

A B C D G

A B C E F

A B C E G

A B C F G

A B D E F

A B D E G

A B D F G

A B E F G

A C D E F

A C D E G

A C D F G

A C E F G

A D E F G

B C D E F

B C D E G

B C D F G

B C E F G

B D E F G

C D E F G

45のうち40の組み合わせの数は1.221.759であり、Excelの制限を超えているため、不可能です.

アンドレアス.

サブExample_combinations()
Dim C As Collection、Item、i As Integer
Debug.Print
Debug.Print "KombinationenohneZurücklegen:"; 組み合わせカウント(7、5)
C=の組み合わせを設定します(Array( "A"、 "B"、 "C"、 "D"、 "E"、 "F"、 "G")、5)
Cの各アイテムについて
i= i + 1
Debug.Print i; ":"、Join(Item)
次へ
サブの終了

関数combinationsCount(ByVal n As Integer、ByVal k As Integer)As Double
'Kombinationenohnezurücklegen
'N!/((N--k)!* k!)
n組み合わせカウント=PermutationsCount(n)/(PermutationsCount(n--k)* PermutationsCount(k))
終了機能

関数PermutationsCount(ByVal n As Integer)As Double
'Permutationen ohne Wiederholungen
'N!
Dim i As Integer
n<0の場合、関数を終了します
PermutationsCount= 1
i=2からn
の場合 PermutationsCount= PermutationsCount* i
次へ
終了機能

関数の組み合わせ(Arr、ByVal Count As Integer)As Collection
'Gibt alle Kombinationen von Count Elementen in Arr alsArraysineinerCollectionzurück
'Arr内のCount要素のすべての組み合わせをコレクション内の配列として返します
Dim Index()As Long
Dim Result()
Dim i As Long、j As Integer
'コレクションを作成する
セットの組み合わせ=新しいコレクション
'カウントがArrの境界を超えた場合、空のコレクションを返します
LBound(Arr)+ Count-1>UBound(Arr)またはCount<1の場合、関数を終了します
'インデックスと結果配列のセットアップスペース
ReDim Index(1 To Count)As Long
ReDim Result(1 To Count)
'最初の組み合わせのインデックスを設定
i=1の場合カウントする
Index(i)= LBound(Arr)+ i-1
次へ
行う
'組み合わせを構築する
i=1の場合カウントする
Result(i)= Arr(Index(i))
次へ
'保存する
組み合わせ.結果を追加
'次のインデックスを取得
i=カウント
j= 0
行う
'最大.このインデックスの位置に達しましたか?
Index(i)= UBound(Arr)の場合-カウント+ i Then
j= j + 1
'次のループの1ステップ前にインデックスを移動します
i= i-1
i<1の場合、関数を終了します
それ以外の場合
'増分位置
Index(i)= Index(i)+ 1
'次のインデックスを設定する
j=1の場合j
i= i + 1
Index(i)= Index(i-1)+ 1
次へ
Doを終了します
Ifを終了
ループ
ループ
終了機能

応答6# ->にスキップ
5 #
jjmader

うーん、私は大学時代から組み合わせ論を知っていますが、これはすべてに完全に答えるわけではありません.私の問題は、すべての組み合わせが必要なわけではなく、上記のようなルールに適合する組み合わせが必要なことです.

たとえば、ルールから、フレッドは1、2、6、または7の位置にいることができないことがわかります.

ありがとう-これは始まりです.

応答5# ->にスキップ
4 #
Rand220

>... フレッドは1、2、6、または7の位置にいることはできません

(Alpha-Golfの代わりにa-gを使用します)

フレッドはにしか参加できないということですか チームc、d、&e?

ベッキーはチームa&bにのみ参加できますか?

もしそうなら、108の解決策がありますか? IE 同じチームに2人はいない.(5つの別々のチーム)

(開始する7* 3* 2* 4* 3= 504ソリューションがありました)

それがあなたが望むものであるかどうかわからないので、ここにソリューションの10のランダムなサンプルがあります...それがあなたが望むものである場合.

応答4# ->にスキップ
2 #
jjmader

正解-Xは、人々が実際に参加できるチームを表します.フレッドはC、D、E、ベッキーはAまたはBにのみ参加できます.

したがって、ルールに準拠するすべての結果が必要です.

1)すべてのチームに1人のプレーヤーが割り当てられます.

2)すべてのプレーヤーは1つのチームにのみ割り当てることができます.

3)すべてのプレーヤーは、tableにXが含まれているチームにのみ割り当てることができます(上記のサンプル)

編集:5人のプレーヤーと7つのチームがあることに気づきました.これは、ルール1が真になることはできないことを意味します.申し訳ありませんが、A-GではなくTeamsA-Eを使用しましょう.

応答2# ->にスキップ
1 #
Andreas

この2つのルールは、Xがtable内にある場合に限定して、繰り返しのないバリエーションが必要であることを意味します.
したがって、7つのうち5つについては、2520のバリエーションを確認する必要があり、最初の投稿の表を使用すると、108の可能な解決策が得られます.結果は以下のとおりです.
45のうち40のシナリオは、9.96851840545668E + 53のバリエーションをチェックする必要があることを意味し、理論的には、上記のtableと同様のtable設定を想定すると、4.3E+52ソリューションになります.
これはマシンの限界をはるかに超えており、結果が出るまでコードは「永久に」実行されます.
アンドレアス.
1: A C B D F
2: A C B D G
3: A C B E D
4: A C B E F
5: A C B E G
6: A D B C F
7 : A D B C G
8: A D B E F
9: A D B E G
10: A E B C D
11: A E B C F
12: A E B C G
13: A E B D F
14: A E B D G
15: B C A D F
16: B C A D G
17: B C A E D
18: B C A E F
19: B C A E G
20: B D A C F
21: B D A C G
22: B D A E F
23: B D A E G
24: B E A C D
25: B E A C F
26: B E A C G
27: B E A D F
28: B E A D G
29: C D A B F
30: C D A B G
31: C D A E F
32: C D A E G
33: C D B E F
34: C D B E G
35: C E A B D
36: C E A B F
37: C E A B G
38: C E A D F
39: C E A D G
40: C E B D F
41: C E B D G
42: D C A B F
43: D C A B G
44: D C A E F
45: D C A E G
46: D C B E F
47: D C B E G
48: D E A B F
49: D E A B G
50: D E A C F
51: D E A C G
52: D E B C F
53: D E B C G
54: E C A B D
55: E C A B F
56: E C A B G
57: E C A D F
58: E C A D G
59: E C B D F
60: E C B D G
61: E D A B F
62: E D A B G
63: E D A C F
64: E D A C G
65: E D B C F
66: E D B C G
67: F C A B D
68: F C A B G
69: F C A D G
70: F C A E D
71: F C A E G
72: F C B D G
73: F C B E D
74: F C B E G
75: F D A B G
76: F D A C G
77: F D A E G
78: F D B C G
79: F D B E G
80: F E A B D
81: F E A B G
82: F E A C D
83: F E A C G
84: F E A D G
85: F E B C D
86: F E B C G
87: F E B D G
88: G C A B D
89: G C A B F
90: G C A D F
91: G C A E D
92: G C A E F
93: G C B D F
94: G C B E D
95: G C B E F
96: G D A B F
97: G D A C F
98: G D A E F
99: G D B C F
100: G D B E F
101: G E A B D
102: G E A B F
103: G E A C D
104: G E A C F
105: G E A D F
106: G E B C D
107: G E B C F
108: G E B D F

応答2# ->にスキップ
3 #
jjmader

したがって、これは非常に粗雑であり、抽象化しようとしていますが、Nx3の行列で機能します.私が言ったように、非常に厄介ですが、あなたは要点を理解します.nxnに抽象化する手助けをいただければ幸いです.

サブB2VMacro()
Debug.Print
countRunners
Debug.Print( "使用可能なレッグ割り当ては次のとおりです:")

i=2の場合countRunnersへ
cellValue= Cells(i、2).Value
runnerNameLeg1= Cells(i、1).Value
cellValue= "X"Then
の場合 j=1の場合countRunnersへ
cellValue2= Cells(j、3).Value
runnerNameLeg2= Cells(j、1).Value
cellValue2="X"の場合
If runnerNameLeg1runnerNameLeg2 Then
k=1の場合countRunnersへ
CellValue3= Cells(k、4).Value
runnerNameLeg3= Cells(k、1).Value
CellValue3="X"の場合
If runnerNameLeg1runnerNameLeg2 And runnerNameLeg2runnerNameLeg3 And runnerNameLeg1runnerNameLeg3 Then
Debug.Print(runnerNameLeg1&"、"&runnerNameLeg2&"、"&runnerNameLeg3)
Ifを終了
Ifを終了
次のk
Ifを終了
Ifを終了
次のj
Ifを終了
次は

サブの終了
関数countRunners()As Integer
countRunners= Worksheets( "Template").Range( "A:A").Cells.SpecialCells(xlCellTypeConstants).Count
終了機能