質問するログイン新規登録

質問編集履歴

3

どういう風にしたいかわからないとのご指摘を頂いたので直させていただきました。力になっていただければ幸いです。

2019/07/16 01:49

投稿

naberyo
naberyo

スコア10

title CHANGED
File without changes
body CHANGED
@@ -1,11 +1,41 @@
1
1
  C言語で2部グラフのマッチングを求めるプログラムを利用してラテン方陣を書きたいのですが、マッチングする行をfor文で回せばいいということがわかるのですが、マッチングしたものを保存して、再度マッチングさせるのがどうすれば上手く行くのかわかりませんでした。プログラムは6×6行列です。またマッチングしたものを最後行列として表示する方法についても悩んでいます。
2
2
  下記は1つの2部グラフマッチングを求めるプログラムです。
3
+ 一番下は元のプログラムで、教えてもらったもので
4
+ 0123 4 5
5
+ 67891011の点でのマッチングを表しています。
6
+
7
+ ですが配列内の動きを見たかったと、少しマッチングしたものが見にくかったので表示を
8
+ 123456
9
+ 123456の点として表示を考えたのが上のプログラムです。
10
+
11
+ 方法としては
12
+ 2部グラフでのマッチングを求めるプログラムですので、マッチングした下の点を保存して、上の点として扱い再度マッチングすべきもとの点を探す様にしたいです。
13
+
14
+ さらに要領としては回目は1={2,3,4,5,6}の点とマッチングが可能で2を選んだ場合2回めでは2={3,4,5,6}の点から選べるという様に1回ずつ各点が選べる回数が減っていけば最終的に決定すると考えられます。なので、はじめは上の一つの点から自身を除いた全ての点にパスが出ている状態から、回数を重ねるごとにパスが減っていく様にすれば自然とラテン方陣としてできると考えられます。
15
+
16
+ 例えば
17
+ 12345で作った場合で、2行目で
18
+ 54231となった場合
19
+
20
+ 54231の結果を元にマッチングを行い
21
+ 31452とマッチングさせる
22
+ という様にすれば
23
+ 求めたい行の回数分行う事によってラテン方陣ができると思います。
24
+ 最終的には
25
+
26
+ 12345
27
+ 54231
28
+ 31452
29
+ 45123
30
+ 23514
31
+
32
+ というような形に表示をしたいです。
33
+
3
34
  教えてくださる方がいたらよろしくお願いします。
4
35
 
5
36
 
6
-
37
+ ```ここに言語を入力
7
- ```
38
+ コード
8
- /*2部グラフマッチング*/
9
39
  #include <stdio.h>
10
40
  #include <stdlib.h>
11
41
  #define V 12
@@ -59,7 +89,7 @@
59
89
  for(p=0;p<V;p++){
60
90
  for(q=0;q<V;q++){
61
91
  if(q%r==0)printf("|");
62
- printf("%2d",A[q][p]);
92
+      printf("%2d",A[q][p]);
63
93
  }
64
94
  printf("\n");
65
95
  }
@@ -113,5 +143,107 @@
113
143
  return(0); // could not find augmenting path
114
144
  }
115
145
  }
146
+
147
+ ```
148
+ 元のプログラム
149
+
150
+ ```ここに言語を入力
116
151
  コード
152
+ #include <stdio.h>
153
+ #include <stdlib.h>
154
+ #define V 12
155
+ #define L_IDX 6
156
+ int A[V][V];
157
+ int MV[V];
158
+ int P[V];
159
+ int aug(int, int *);
160
+
161
+ int main(){
162
+ int i, j, p, q;
163
+ int find;
164
+
165
+ for(i=0;i<V;i++){
166
+ for(j=0;j<V;j++){
167
+ A[i][j] = 0;
168
+ }
169
+ }
170
+ /*
171
+ A[0][6] = 1, A[0][7] = 1;
172
+ A[1][6] = 1, A[1][7] = 1;
173
+ A[2][6] = 1, A[2][7] = 1;
174
+ A[3][5] = 1, A[3][6] = 1;
175
+ A[4][5] = 1, A[4][7] = 1, A[4][8] = 1, A[4][9] = 1;
176
+ */
177
+ A[0][6] = 1, A[0][7] = 1;
178
+ A[1][6] = 1, A[1][7] = 1, A[1][9] = 1;
179
+ A[2][6] = 1, A[2][7] = 1, A[2][8] = 1;
180
+ A[3][8] = 1, A[3][9] = 1, A[3][10] = 1;
181
+ A[4][8] = 1, A[4][9] = 1, A[4][11] = 1;
182
+ A[5][10] = 1, A[5][11] = 1;
183
+
184
+ for(i=0;i<V;i++){MV[i] = 0;}
185
+
186
+ find = 1;
187
+ while(find){
188
+ find = 0;
189
+ for(i=0;i<V;i++){P[i] = 0;}
190
+
191
+ for(i=0;i<L_IDX;i++){
192
+ if(MV[i]==0){
193
+ P[i] = 1;
194
+ find = aug(i,P);
195
+ if(find){
196
+ //***********************************************************
197
+ for(p=L_IDX;p<V;p++){
198
+ for(q=0;q<L_IDX;q++){
199
+ printf("%d ",A[p][q]);
200
+ }
201
+ printf("\n");
202
+ }
203
+ printf("++++++++++++++++++++++++++\n");
204
+ //***********************************************************
205
+ MV[i] = 1;
206
+ break;
207
+ }
208
+ P[i] = 0;
209
+ }
210
+ }
211
+ }
212
+
213
+ for(i=L_IDX;i<V;i++){
214
+ for(j=0;j<L_IDX;j++){
215
+ if(A[i][j]==1){ printf("A[%d][%d]=%d ",i,j,A[i][j]);}
216
+ }
217
+ }
218
+ printf("\n");
219
+
220
+ }
221
+
222
+ int aug(int v, int P[]){
223
+ int i,j,k;
224
+ int find,v1,v2;
225
+
226
+ for(j=0;j<V;j++){
227
+
228
+ if(A[v][j]==1&&P[j]==0){
229
+ P[j] = 1;
230
+ find = aug(j,P);
231
+ if(find==1){ //found augmenting path
232
+ A[v][j] = 0, A[j][v] = 1, MV[j] = 1;
233
+ return(1);
234
+ }
235
+ P[j] = 0;
236
+ }
237
+
238
+ }// end for j
239
+
240
+ if(v>=L_IDX&&MV[v]==0){
241
+ return(1); // found augmenting path
242
+ }else{
243
+ return(0); // could not find augmenting path
244
+ }
245
+
246
+ }
247
+
248
+ ```
117
249
  ```

2

少し書き方を修正しました

2019/07/16 01:49

投稿

naberyo
naberyo

スコア10

title CHANGED
File without changes
body CHANGED
@@ -52,20 +52,19 @@
52
52
  if(MV[i]==0){
53
53
  P[i] = 1;
54
54
  find = aug(i,P);
55
+
55
- if(find){
56
+ if(find){
56
57
  //***********************************************************
57
58
 
58
59
  for(p=0;p<V;p++){
59
- for(q=0;q<V;q++){
60
+ for(q=0;q<V;q++){
60
- if(q%r==0)printf("|");
61
+ if(q%r==0)printf("|");
61
- //if(p%r==0)printf("-");
62
- // if(p%r==0)printf("-");
63
- printf("%2d",A[q][p]);
62
+ printf("%2d",A[q][p]);
64
- }
63
+ }
65
64
  printf("\n");
66
- }
65
+ }
67
- printf("+++++++++++++++++++++++++++\n");
66
+ printf("+++++++++++++++++++++++++++\n");
68
- printf("\n");
67
+ printf("\n");
69
68
  //***********************************************************
70
69
  MV[i] = 1;
71
70
  break;
@@ -77,19 +76,17 @@
77
76
 
78
77
  for(i=r;i<V;i++){
79
78
  for(j=0;j<r;j++){
80
- if(A[i][j]==1){ printf("A[%d][%d]=%d ",i%6+1,j,A[i][j]);}
79
+ if(A[i][j]==1){ printf("A[%d][%d]=%d ",i%6+1,j,A[i][j]);} //マッチングしてる箇所を表示
81
80
  }
82
81
  }
83
82
  printf("\n");
84
83
 
85
- for(i=r;i<V;i++){
84
+ for(i=r;i<V;i++){
86
- for(j=0;j<r;j++){
85
+ for(j=0;j<r;j++){
87
- if(A[i][j]==1){ printf("%10d",j);
86
+ if(A[i][j]==1){ printf("%3d",j);//マッチング後を表示
88
-
89
87
  }
88
+ }
90
89
  }
91
- }
92
-
93
90
  }
94
91
 
95
92
  int aug(int v, int P[]){
@@ -114,9 +111,7 @@
114
111
  return(1); // found augmenting path
115
112
  }else{
116
113
  return(0); // could not find augmenting path
117
- }
114
+ }
118
-
119
-
120
115
  }
121
116
  コード
122
117
  ```

1

コードの書き方修正します

2019/07/12 09:09

投稿

naberyo
naberyo

スコア10

title CHANGED
File without changes
body CHANGED
@@ -1,7 +1,10 @@
1
1
  C言語で2部グラフのマッチングを求めるプログラムを利用してラテン方陣を書きたいのですが、マッチングする行をfor文で回せばいいということがわかるのですが、マッチングしたものを保存して、再度マッチングさせるのがどうすれば上手く行くのかわかりませんでした。プログラムは6×6行列です。またマッチングしたものを最後行列として表示する方法についても悩んでいます。
2
2
  下記は1つの2部グラフマッチングを求めるプログラムです。
3
+ 教えてくださる方がいたらよろしくお願いします。
3
4
 
4
5
 
6
+
7
+ ```
5
8
  /*2部グラフマッチング*/
6
9
  #include <stdio.h>
7
10
  #include <stdlib.h>
@@ -31,7 +34,7 @@
31
34
  A[3][5] = 1, A[3][6] = 1;
32
35
  A[4][5] = 1, A[4][7] = 1, A[4][8] = 1, A[4][9] = 1;
33
36
  */
34
- A[0][6] = 1, A[0][7] = 1;          //マッチングする点
37
+ A[0][6] = 1, A[0][7] = 1;
35
38
  A[1][6] = 1, A[1][7] = 1, A[1][9] = 1;
36
39
  A[2][6] = 1, A[2][7] = 1, A[2][8] = 1;
37
40
  A[3][8] = 1, A[3][9] = 1, A[3][10] = 1;
@@ -41,7 +44,7 @@
41
44
  for(i=0;i<V;i++){MV[i] = 0;}
42
45
 
43
46
  find = 1;
44
- while(find){ //マッチング
47
+ while(find){
45
48
  find = 0;
46
49
  for(i=0;i<V;i++){P[i] = 0;}
47
50
 
@@ -114,4 +117,6 @@
114
117
  }
115
118
 
116
119
 
117
- }
120
+ }
121
+ コード
122
+ ```