質問編集履歴

2

タグを追加しました #アルゴリズム のタグを追加しました

2015/09/25 06:22

投稿

shigemi_sano
shigemi_sano

スコア17

test CHANGED
File without changes
test CHANGED
File without changes

1

ソースを追加しました、遺伝情報の並びについて重複を許さない場合も掲載してあります。

2015/09/25 06:21

投稿

shigemi_sano
shigemi_sano

スコア17

test CHANGED
File without changes
test CHANGED
@@ -1,31 +1,27 @@
1
- 言語はrubyを使って巡回セールスマン問題を解くプログラムを作成しました。遺伝的アルゴリズムを用い、遺伝情報などアルゴリズムで用いる固有の変数や配列をクラスを用いてひとまとめにしてあります。
1
+ 言語はrubyを使って巡回セールスマン問題を解くプログラムを作成しました。遺伝的アルゴリズムを用い、遺伝情報などアルゴリズムで用いる固有の変数や配列をクラスを用いてひとまとめにしてあります。
2
-
3
-
4
-
2
+
3
+
4
+
5
- アルゴリズムとしては基本的なスタイルは踏襲し、また遺伝情報の交叉もテストにて正しく交叉されていることは確認できました(交叉の点数は4点交叉です)。また適合度の高い順にソートも出来ています。次の世代にはその中から上位50%を残し、ルーレット式で次世代の遺伝情報を選択しています。
5
+ アルゴリズムとしては基本的なスタイルは踏襲し、また遺伝情報の交叉もテストにて正しく交叉されていることは確認できました(交叉の点数は4点交叉です)。また適合度の高い順にソートも出来ています。次の世代にはその中から上位50%を残し、ルーレット式で次世代の遺伝情報を選択しています。
6
-
7
-
8
-
6
+
7
+
8
+
9
- 一通り作成し、実際に動作させてみました。個体数256、世代数30世代にわたって回し、結果を出力させました。30世代までだいたい距離45から40の間を行ったり来たりしており、参考書に書かれているようにきれいに収束する様子が見られません。(解答は 35.626)
9
+ 一通り作成し、実際に動作させてみました。個体数256、世代数30世代にわたって回し、結果を出力させました。30世代までだいたい距離45から40の間を行ったり来たりしており、参考書に書かれているようにきれいに収束する様子が見られません。(解答は 35.626)
10
-
11
-
12
-
10
+
11
+
12
+
13
- 選択の方法に問題があるのかと思っています。また突然変異の確率も調整が必要かもしれません。
13
+ 選択の方法に問題があるのかと思っています。また突然変異の確率も調整が必要かもしれません。
14
-
15
-
16
-
14
+
15
+
16
+
17
- ソースに関してはもう少しシンプルに書きたいと思っています。なんとなくC言語 like なソースになっています。500業務
17
+ ソースに関してはもう少しシンプルに書きたいと思っています。なんとなくC言語 like なソースになっています。500行は長すぎな気がしています。
18
-
19
-
20
-
18
+
19
+
20
+
21
- ソースと出力結果の画像を添付しますので、ご回答をよろしくお願いいたします。ソースは最初に作成した genetic クラスのみ添付します。
21
+ ソースを添付しますので、ご回答をよろしくお願いいたします。ソースは最初に作成した genetic クラスのみ添付します。
22
-
23
-
24
22
 
25
23
  ```ruby
26
24
 
27
- コード
28
-
29
25
  #------------------------------------------------------------------------------------#
30
26
 
31
27
  #Geneticsクラス(genesの生成と、交叉)
@@ -192,6 +188,242 @@
192
188
 
193
189
 
194
190
 
191
+ #重複を認めない場合
192
+
193
+ else
194
+
195
+ stack = 0
196
+
197
+
198
+
199
+ one_to_two = 0
200
+
201
+ two_to_one = 0
202
+
203
+
204
+
205
+ #親から子へそのままコピー
206
+
207
+ for i in 0..(number_of_genes-1) do
208
+
209
+ child1.genes[i] = self.genes[i]
210
+
211
+ child2.genes[i] = other.genes[i]
212
+
213
+ end
214
+
215
+
216
+
217
+ for i in 0..cross do
218
+
219
+
220
+
221
+ #交差点が偶数で crossの値が(ラスト)でない場合はそのまま
222
+
223
+ if (i != cross) && ( (i / 2) == 0 )
224
+
225
+ next
226
+
227
+
228
+
229
+ #交差点が奇数で crossの値が(ラスト)でない場合は遺伝情報を交換
230
+
231
+ elsif ( i != cross) && ( (i / 2) != 0 )
232
+
233
+ for j in (division * i)..( (division * (i+1)) -1 ) do
234
+
235
+ one_to_two = child1.genes[j]
236
+
237
+ two_to_one = child2.genes[j]
238
+
239
+
240
+
241
+ if child1.genes[j] == child2.genes[j]
242
+
243
+ child1.genes[j] = two_to_one
244
+
245
+ child2.genes[j] = one_to_two
246
+
247
+ else
248
+
249
+ #2つの個体の遺伝情報が異なる場合、各個体間で入れ替え(重複を避けるため)
250
+
251
+ for k in 0..(number_of_genes-1) do
252
+
253
+ if child1.genes[k] == two_to_one && (k != j)
254
+
255
+ child1.genes[k] = child1.genes[j]
256
+
257
+ child1.genes[j] = two_to_one
258
+
259
+ break
260
+
261
+ end
262
+
263
+ end
264
+
265
+
266
+
267
+ for k in 0..(number_of_genes-1) do
268
+
269
+ if child2.genes[k] == one_to_two && (k != j)
270
+
271
+ child2.genes[k] = child2.genes[j]
272
+
273
+ child2.genes[j] = one_to_two
274
+
275
+ break
276
+
277
+ end
278
+
279
+ end
280
+
281
+
282
+
283
+ end #if文終了(遺伝情報が同じかどうかの判定)
284
+
285
+ end #for文終了(遺伝情報の交換)
286
+
287
+
288
+
289
+ #交差点が偶数で cross(ラスト)の場合はループ終了
290
+
291
+ elsif (i == cross) && ( (i / 2) == 0 )
292
+
293
+ break
294
+
295
+
296
+
297
+ #交差点が奇数で cross(ラスト)の場合は最後(number_of_genes -1)まで遺伝情報を交換
298
+
299
+ elsif (i == cross) && ( (i / 2) != 0 )
300
+
301
+ for j in (division * i)..( number_of_genes -1 ) do
302
+
303
+ one_to_two = child1.genes[j]
304
+
305
+ two_to_one = child2.genes[j]
306
+
307
+
308
+
309
+ if child1.genes[j] == child2.genes[j]
310
+
311
+ child1.genes[j] = two_to_one
312
+
313
+ child2.genes[j] = one_to_two
314
+
315
+ else
316
+
317
+ #2つの個体の遺伝情報が異なる場合、各個体間で入れ替え(重複を避けるため)
318
+
319
+ for k in 0..(number_of_genes-1) do
320
+
321
+ if child1.genes[k] == two_to_one && (k != j)
322
+
323
+ child1.genes[k] = child1.genes[j]
324
+
325
+ child1.genes[j] = two_to_one
326
+
327
+ break
328
+
329
+ end
330
+
331
+ end
332
+
333
+
334
+
335
+ for k in 0..(number_of_genes-1) do
336
+
337
+ if child2.genes[k] == one_to_two && (k != j)
338
+
339
+ child2.genes[k] = child2.genes[j]
340
+
341
+ child2.genes[j] = one_to_two
342
+
343
+ break
344
+
345
+ end
346
+
347
+ end
348
+
349
+
350
+
351
+ end #if文終了(遺伝情報が同じかどうか判定)
352
+
353
+ end #for文終了 (遺伝情報の交換)
354
+
355
+
356
+
357
+ end #if文終了 (crossが偶数か奇数か)
358
+
359
+ end #for文終了(cross=交叉点数の分だけ)
360
+
361
+
362
+
363
+ #突然変異(各個体について、1つの遺伝子を書き換え)
364
+
365
+ index = Random.rand(number_of_genes * 10) % number_of_genes
366
+
367
+ stack = child1.genes[index]
368
+
369
+ child1.genes[index] = Random.rand(max_value)
370
+
371
+
372
+
373
+ for j in 0..(number_of_genes-1) do
374
+
375
+ if child1.genes[j] == stack && (j != index)
376
+
377
+ child1.genes[j] = stack
378
+
379
+ break
380
+
381
+ end
382
+
383
+ end
384
+
385
+
386
+
387
+ index = Random.rand(number_of_genes * 10) % number_of_genes
388
+
389
+ stack = child2.genes[index]
390
+
391
+ child2.genes[index] = Random.rand(max_value)
392
+
393
+
394
+
395
+ for j in 0..(number_of_genes-1) do
396
+
397
+ if child2.genes[j] == stack && (j != index)
398
+
399
+ child2.genes[j] = stack
400
+
401
+ break
402
+
403
+ end
404
+
405
+ end
406
+
407
+
408
+
409
+ stack = 0
410
+
411
+ index = 0
412
+
413
+
414
+
415
+ end #overwrapによる場合分け終了
416
+
417
+ end #crossメソッド終了
418
+
419
+
420
+
421
+ end
422
+
423
+ #Geneticクラス定義ここまで
424
+
425
+ #---------------------------------------------------------------------------------#
426
+
195
427
 
196
428
 
197
429
  ```