回答編集履歴

4

コード論理の間違い

2018/05/11 04:23

投稿

KSwordOfHaste
KSwordOfHaste

スコア18394

test CHANGED
@@ -90,15 +90,11 @@
90
90
 
91
91
  # itertools.permutationsを使えば単純にできるがあえて原始的に実装
92
92
 
93
- # 組み合わせはTC1 x TC2 = (11 * 10 * 9 * 8 * 7 * 5 * 4 * 3 * 2)通り
93
+ # 組み合わせはTC1 = 11 * 10 * 9 * 8 * 7
94
94
 
95
95
  S1 = [i for i in range(11, 6, -1)]
96
96
 
97
- S2 = [i for i in range(5, 0, -1)]
98
-
99
97
  TC1 = functools.reduce(operator.mul, S1)
100
-
101
- TC2 = functools.reduce(operator.mul, S2)
102
98
 
103
99
 
104
100
 
@@ -106,21 +102,15 @@
106
102
 
107
103
  i1 = iii(S1, tc1)
108
104
 
109
- for tc2 in range(TC2):
105
+ a = np.zeros((5, 11), dtype=np.uint8)
110
106
 
111
- i2 = iii(S2, tc2)
107
+ for i in range(5):
112
108
 
113
- a = np.zeros((5, 11), dtype=np.uint8)
109
+ # print(f'i2[i]={i2[i]}, i1[i]={i1[i]}')
114
110
 
115
- # print(f'i1={i1}, i2={i2}')
111
+ a[i, i1[i]] = 1
116
112
 
117
- for i in range(5):
118
-
119
- # print(f'i2[i]={i2[i]}, i1[i]={i1[i]}')
120
-
121
- a[i2[i], i1[i]] = 1
122
-
123
- yield a
113
+ yield a
124
114
 
125
115
 
126
116
 
@@ -150,7 +140,7 @@
150
140
 
151
141
  def main():
152
142
 
153
- count = 0
143
+ count = 1
154
144
 
155
145
  g = genp()
156
146
 
@@ -160,7 +150,7 @@
160
150
 
161
151
  if np.all(A2 == A3):
162
152
 
163
- print(f'match count={count}')
153
+ print(f'number of trials = {count}')
164
154
 
165
155
  print('p=')
166
156
 

3

コードを追記

2018/05/11 04:22

投稿

KSwordOfHaste
KSwordOfHaste

スコア18394

test CHANGED
@@ -11,3 +11,177 @@
11
11
 
12
12
 
13
13
  いずれにせよ少なくとも重複なく置換行列Pを生成するという論理が必要と思います。A1の大きさと重みありの個数を見ますと、まともに有り得る置換行列の全ての組み合わせを探索しても`9!×2 = 725760`となりますので素朴に総当たりしても(ご質問にある規模の問題なら)時間的には大丈夫な気がします。
14
+
15
+ (追記:最大30x30を想定しておられるとのことでまともに全探索するアプローチでは不十分と思いました)
16
+
17
+
18
+
19
+ ---
20
+
21
+ 追記:VBAではありませんが、ご要望があったので全探索をするPythonコードを参考までに挙げておきます。
22
+
23
+ 適当に書いたままなのであまりよいコードではありませんが。
24
+
25
+
26
+
27
+ ```Python
28
+
29
+ import numpy as np
30
+
31
+ import functools
32
+
33
+ import operator
34
+
35
+
36
+
37
+ A1=[
38
+
39
+ [0,1,1,1,1,0,0,0,0,0,0],
40
+
41
+ [1,0,0,0,0,1,0,0,0,0,0],
42
+
43
+ [1,0,0,0,0,0,1,1,1,0,0],
44
+
45
+ [1,0,0,0,0,0,0,0,0,0,0],
46
+
47
+ [1,0,0,0,0,0,0,0,0,0,0],
48
+
49
+ [0,1,0,0,0,0,0,0,0,2,1],
50
+
51
+ [0,0,1,0,0,0,0,0,0,0,0],
52
+
53
+ [0,0,1,0,0,0,0,0,0,0,0],
54
+
55
+ [0,0,1,0,0,0,0,0,0,0,0],
56
+
57
+ [0,0,0,0,0,2,0,0,0,0,0],
58
+
59
+ [0,0,0,0,0,1,0,0,0,0,0]
60
+
61
+ ]
62
+
63
+ A2 = [
64
+
65
+ [0,1,0,0,0],
66
+
67
+ [1,0,1,0,0],
68
+
69
+ [0,1,0,2,1],
70
+
71
+ [0,0,2,0,0],
72
+
73
+ [0,0,1,0,0]
74
+
75
+ ]
76
+
77
+
78
+
79
+ A1 = np.array(A1, dtype=np.uint8)
80
+
81
+ A2 = np.array(A2, dtype=np.uint8)
82
+
83
+
84
+
85
+ def genp():
86
+
87
+ # Pを次々に生成するジェネレーター
88
+
89
+ # Pは5 x 11とする。1の場所は11個の中から5個選ぶ
90
+
91
+ # itertools.permutationsを使えば単純にできるがあえて原始的に実装
92
+
93
+ # 組み合わせはTC1 x TC2 = (11 * 10 * 9 * 8 * 7 * 5 * 4 * 3 * 2)通り
94
+
95
+ S1 = [i for i in range(11, 6, -1)]
96
+
97
+ S2 = [i for i in range(5, 0, -1)]
98
+
99
+ TC1 = functools.reduce(operator.mul, S1)
100
+
101
+ TC2 = functools.reduce(operator.mul, S2)
102
+
103
+
104
+
105
+ for tc1 in range(TC1):
106
+
107
+ i1 = iii(S1, tc1)
108
+
109
+ for tc2 in range(TC2):
110
+
111
+ i2 = iii(S2, tc2)
112
+
113
+ a = np.zeros((5, 11), dtype=np.uint8)
114
+
115
+ # print(f'i1={i1}, i2={i2}')
116
+
117
+ for i in range(5):
118
+
119
+ # print(f'i2[i]={i2[i]}, i1[i]={i1[i]}')
120
+
121
+ a[i2[i], i1[i]] = 1
122
+
123
+ yield a
124
+
125
+
126
+
127
+ def iii(ss, t):
128
+
129
+ # t番目の組み合わせのインデックスを生成
130
+
131
+ i = [i for i in range(ss[0])]
132
+
133
+ r = []
134
+
135
+ for s in ss:
136
+
137
+ j = t % s
138
+
139
+ # print(f'j={j} i={i}')
140
+
141
+ r.append(i[j])
142
+
143
+ del i[j]
144
+
145
+ t //= s
146
+
147
+ return r
148
+
149
+
150
+
151
+ def main():
152
+
153
+ count = 0
154
+
155
+ g = genp()
156
+
157
+ for p in g:
158
+
159
+ A3 = p.dot(A1).dot(p.T)
160
+
161
+ if np.all(A2 == A3):
162
+
163
+ print(f'match count={count}')
164
+
165
+ print('p=')
166
+
167
+ print(p)
168
+
169
+ break
170
+
171
+ count += 1
172
+
173
+ # 探索の進捗具合の確認用
174
+
175
+ if count % 10000 == 0:
176
+
177
+ print(f'count={count}')
178
+
179
+
180
+
181
+ if __name__ == '__main__':
182
+
183
+ main()
184
+
185
+ ```
186
+
187
+ (Python 3.6.5)

2

誤記

2018/05/10 05:41

投稿

KSwordOfHaste
KSwordOfHaste

スコア18394

test CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
 
8
8
 
9
- p.9にUllmannの方法として「一定の約束事(行や列の順列など)で重複なく置換行列Pを生成する」と有りますが、この方法ではNP完全問題をまともに解く(有り得る様々なPを想定してしらみつぶしに調べてゆくしかないということのように思えました。またこのページ以降に置換行列Pの大きさをしぼれそうな様々な手法が書かれていますね。
9
+ p.9にUllmannの方法として「一定の約束事(行や列の順列など)で重複なく置換行列Pを生成する」と有りますが、この方法ではNP完全問題をまともに解く(有り得る様々なPを想定してしらみつぶしに調べてゆく)ということのように思えました。しかしこのページ以降に置換行列Pの大きさをしぼれそうな様々な手法が書かれていますね。
10
10
 
11
11
 
12
12
 

1

登録ミス

2018/05/09 05:30

投稿

KSwordOfHaste
KSwordOfHaste

スコア18394

test CHANGED
File without changes