質問編集履歴

3

内容の充実化

2021/06/11 00:00

投稿

grape_ll
grape_ll

スコア83

test CHANGED
File without changes
test CHANGED
@@ -219,3 +219,497 @@
219
219
  }
220
220
 
221
221
  ```
222
+
223
+
224
+
225
+ ###追記
226
+
227
+ 関数の挙動が分からないものがあるとのご指摘を受けたので,
228
+
229
+ 以下にコード全体を載せます.
230
+
231
+ ```C
232
+
233
+ #include <stdlib.h>
234
+
235
+ #include <stdio.h>
236
+
237
+ #include <string.h>
238
+
239
+ #include <time.h>
240
+
241
+
242
+
243
+ #define TRUE 1
244
+
245
+ #define FALSE 0
246
+
247
+ #define GOAL 2
248
+
249
+ #define SIZE 9
250
+
251
+ #define S 0
252
+
253
+ #define MAX_STATE 181440
254
+
255
+ #define MAX_MOVE 31
256
+
257
+ #define EXIST 1
258
+
259
+ #define NOEXIST 0
260
+
261
+
262
+
263
+ char init_state[SIZE] = {'8', '6', '7', '2', '5', '4', '3', '0', '1'};
264
+
265
+ char final_state[SIZE] = {'1', '2', '3', '4', '5', '6', '7', '8', '0'};
266
+
267
+ //最初のノードは親ノードを持たないのでこのあり得ないNULL_stateを親とする
268
+
269
+ char NULL_state[SIZE] = {'9', '9', '9' ,'9', '9', '9', '9', '9', '9'};
270
+
271
+
272
+
273
+ typedef struct List{
274
+
275
+ int cost;
276
+
277
+ char state[SIZE+1];
278
+
279
+ char parent_state[SIZE+1];
280
+
281
+ struct List* next; //次の要素のポインタ
282
+
283
+
284
+
285
+ } List;
286
+
287
+
288
+
289
+ /* リストを追加する為の関数*/
290
+
291
+ List *ListAdd(List* ls, int cost, char state[], char parent_state[]){
292
+
293
+ /*メモリの確保*/
294
+
295
+ List* node = (List*)malloc(sizeof(List));
296
+
297
+ if(node == NULL)
298
+
299
+ return NULL;
300
+
301
+
302
+
303
+ /*データの追加*/
304
+
305
+ node->cost = cost;
306
+
307
+ memcpy(node->state,state, SIZE+1);
308
+
309
+ memcpy(node->parent_state,parent_state,SIZE+1);
310
+
311
+ node->next = NULL;
312
+
313
+
314
+
315
+ //test
316
+
317
+ printf("add node:%s\n",node->state);
318
+
319
+
320
+
321
+ /*データをリストに追加する*/
322
+
323
+ if(ls == NULL)
324
+
325
+ return node;
326
+
327
+ List* search = ls;
328
+
329
+ while (search->next != NULL)
330
+
331
+ search = search->next;
332
+
333
+ search->next = node;
334
+
335
+ return ls;
336
+
337
+ }
338
+
339
+
340
+
341
+ /* リストを削除する為の関数*/
342
+
343
+ void ListAllDelete(List* ls){
344
+
345
+ List *tmp = ls;
346
+
347
+ while (ls->next != NULL){
348
+
349
+ tmp = ls->next;
350
+
351
+ ls->next = tmp->next;
352
+
353
+ free(tmp);
354
+
355
+ }
356
+
357
+ free(ls);
358
+
359
+ }
360
+
361
+
362
+
363
+ int h1(char state[]){
364
+
365
+ int count = 0;
366
+
367
+ for(int i = 0;i < 9;i++){
368
+
369
+ if(state[i] != final_state[i]) count++;
370
+
371
+ }
372
+
373
+ return count;
374
+
375
+ }
376
+
377
+
378
+
379
+ int min_cost;
380
+
381
+ List* olist = NULL;
382
+
383
+ List* clist = NULL;
384
+
385
+
386
+
387
+
388
+
389
+ char space_postion[MAX_STATE];
390
+
391
+ char pre_state[SIZE];
392
+
393
+ int same_state_cost; //olistに同じstateがあり,コストの貼り換えが必要な際に使う
394
+
395
+ int succeed_flag = 0;
396
+
397
+
398
+
399
+ int adjacent[SIZE][5] = {
400
+
401
+ {1, 3, -1}, // 0
402
+
403
+ {0, 2, 4, -1}, // 1
404
+
405
+ {1, 5, -1}, // 2
406
+
407
+ {0, 4, 6, -1}, // 3
408
+
409
+ {1, 3, 5, 7, -1}, // 4
410
+
411
+ {2, 4, 8, -1}, // 5
412
+
413
+ {3, 7, -1}, // 6
414
+
415
+ {4, 6, 8, -1}, // 7
416
+
417
+ {5, 7, -1} // 8
418
+
419
+ };
420
+
421
+
422
+
423
+ int List_search(List* list, char state[]){
424
+
425
+
426
+
427
+ for(List* node = list; node != NULL; node = node->next){
428
+
429
+ if(memcmp(node->state, state, SIZE) == 0){
430
+
431
+ same_state_cost = node->cost;
432
+
433
+ return EXIST;
434
+
435
+ }
436
+
437
+ }
438
+
439
+ return NOEXIST;
440
+
441
+ }
442
+
443
+
444
+
445
+ //char -> int
446
+
447
+ int ctoi(char c) {
448
+
449
+ if (c >= '0' && c <= '9') {
450
+
451
+ return c - '0';
452
+
453
+ }
454
+
455
+ return -1;
456
+
457
+ }
458
+
459
+
460
+
461
+ //空きマス(0)の取得
462
+
463
+ int get_space(char state[]){
464
+
465
+ for(int i = 0;i < 9;i++){
466
+
467
+ if(ctoi(state[i]) == 0){
468
+
469
+ printf("space:%d\n",i);
470
+
471
+ return i;
472
+
473
+ }
474
+
475
+ }
476
+
477
+ }
478
+
479
+
480
+
481
+ void generate_node(char state[], int p_cost){
482
+
483
+ int space = get_space(state);
484
+
485
+ char work_state[SIZE+1];
486
+
487
+ int n;
488
+
489
+ memcpy(pre_state, state, SIZE+1); //親となるstateの保存
490
+
491
+ memcpy(work_state, state, SIZE+1); //状態を変えるstate
492
+
493
+
494
+
495
+ //test
496
+
497
+ printf("p_node:%s\n",pre_state); //ok
498
+
499
+
500
+
501
+ for(int i = 0; (n = adjacent[space][i]) != -1; i++ ){
502
+
503
+ /* 移動 */
504
+
505
+ work_state[space] = work_state[n]; //スペースがあった場所にnにあったものを移動
506
+
507
+ work_state[n] = '0'; //nをスペースにする
508
+
509
+
510
+
511
+ //test
512
+
513
+ printf("after move state:%s\n",work_state);
514
+
515
+
516
+
517
+ if(memcmp(work_state, final_state, SIZE) == 0){
518
+
519
+ //成功
520
+
521
+ printf("succeed\n"); succeed_flag++;
522
+
523
+ return ;
524
+
525
+ }
526
+
527
+
528
+
529
+
530
+
531
+
532
+
533
+ printf("S(clist, state):%d\n", List_search(clist, work_state));
534
+
535
+ printf("S(olist, state):%d\n", List_search(olist, work_state));
536
+
537
+
538
+
539
+ if( List_search(clist, work_state) == NOEXIST ){
540
+
541
+ if( List_search(olist, work_state) == NOEXIST ){
542
+
543
+ //olistにもclistにも存在しないstateなら即olistに追加
544
+
545
+ ListAdd(olist, h1(work_state)+p_cost, work_state, pre_state);
546
+
547
+ int number = 0;
548
+
549
+ for(List* node = olist; node != NULL;node = node->next){
550
+
551
+ printf("(%d)state:%s\n",number, node->state);
552
+
553
+ number++;
554
+
555
+ }
556
+
557
+ }else{
558
+
559
+ //olistにのみ存在するときは,同じstateよりもコストが小さいなら追加
560
+
561
+ if(h1(work_state)+p_cost < same_state_cost){
562
+
563
+ //同じstateのnodeを削除するためにolistを最初から見ていく
564
+
565
+ for(List* node = olist; node != NULL; node = node->next){
566
+
567
+ if(memcmp(node->next->state, work_state, SIZE) == 0){
568
+
569
+ node->next = (node->next)->next; //同じstateのnodeを削除
570
+
571
+ ListAdd(olist, h1(state)+p_cost, work_state, pre_state); //olistに追加
572
+
573
+ int number = 0;
574
+
575
+ for(List* node = olist; node != NULL;node = node->next){
576
+
577
+ printf("(%d)state:%s\n",number, node->state);
578
+
579
+ number++;
580
+
581
+ }
582
+
583
+ }
584
+
585
+ }
586
+
587
+ }
588
+
589
+ }
590
+
591
+ }
592
+
593
+ memcpy(work_state, state, SIZE+1);
594
+
595
+ }
596
+
597
+ }
598
+
599
+
600
+
601
+
602
+
603
+ //ここで探索を行う.
604
+
605
+ void search(){
606
+
607
+ int count = 0;
608
+
609
+ while(count < MAX_STATE){
610
+
611
+ for(List* node = olist; node != NULL; node = node->next){
612
+
613
+ if(node->cost < min_cost){
614
+
615
+ min_cost = node->cost;
616
+
617
+
618
+
619
+ //test
620
+
621
+ printf("min_cost:%d\n");
622
+
623
+ }
624
+
625
+ }
626
+
627
+
628
+
629
+ for(List* node = olist; node != NULL; node = node->next){
630
+
631
+ if(node->next->cost == min_cost){
632
+
633
+ generate_node(node->next->state, node->next->cost);
634
+
635
+ node->next = NULL;
636
+
637
+ break;
638
+
639
+ }
640
+
641
+ }
642
+
643
+
644
+
645
+ min_cost = MAX_STATE; //min_costを毎回大きい値にセット
646
+
647
+ if(succeed_flag > 0) break;
648
+
649
+ count++; //無限ループを防ぐ
650
+
651
+ printf("count:%d\n",count);
652
+
653
+ int number = 0;
654
+
655
+ for(List* node = olist; node != NULL;node = node->next){
656
+
657
+ printf("(%d)state:%s\n",number, node->state);
658
+
659
+ number++;
660
+
661
+ }
662
+
663
+ }
664
+
665
+ printf("search failed\n");
666
+
667
+
668
+
669
+ }
670
+
671
+
672
+
673
+ int main(void){
674
+
675
+
676
+
677
+ min_cost = h1(init_state);
678
+
679
+
680
+
681
+ //headを入れる
682
+
683
+ olist = ListAdd(olist, MAX_STATE, NULL_state, NULL_state);
684
+
685
+ clist = ListAdd(clist, MAX_STATE, NULL_state, NULL_state);
686
+
687
+
688
+
689
+ olist = ListAdd(olist, h1(init_state), init_state, NULL_state);
690
+
691
+
692
+
693
+ printf("Search start\n");
694
+
695
+ clock_t time = clock();
696
+
697
+ search();
698
+
699
+ double result = (double)(clock() - time)/CLOCKS_PER_SEC;
700
+
701
+ printf("%.3fsec\n", result); //探索にかかった時間を表示
702
+
703
+
704
+
705
+ ListAllDelete(olist);
706
+
707
+ ListAllDelete(clist);
708
+
709
+ return 0;
710
+
711
+ }
712
+
713
+
714
+
715
+ ```

2

情報が足りなかった

2021/06/11 00:00

投稿

grape_ll
grape_ll

スコア83

test CHANGED
File without changes
test CHANGED
@@ -176,4 +176,46 @@
176
176
 
177
177
  }
178
178
 
179
+
180
+
181
+ int main(void){
182
+
183
+
184
+
185
+ min_cost = h1(init_state);
186
+
187
+
188
+
189
+ //headを入れる
190
+
191
+ olist = ListAdd(olist, MAX_STATE, NULL_state, NULL_state);
192
+
193
+ clist = ListAdd(clist, MAX_STATE, NULL_state, NULL_state);
194
+
195
+
196
+
197
+ olist = ListAdd(olist, h1(init_state), init_state, NULL_state);
198
+
199
+
200
+
201
+ printf("Search start\n");
202
+
203
+ clock_t time = clock();
204
+
205
+ search();
206
+
207
+ double result = (double)(clock() - time)/CLOCKS_PER_SEC;
208
+
209
+ printf("%.3fsec\n", result); //探索にかかった時間を表示
210
+
211
+
212
+
213
+ ListAllDelete(olist);
214
+
215
+ ListAllDelete(clist);
216
+
217
+ return 0;
218
+
219
+ }
220
+
179
221
  ```

1

内容の充実化

2021/06/10 10:34

投稿

grape_ll
grape_ll

スコア83

test CHANGED
File without changes
test CHANGED
@@ -5,6 +5,26 @@
5
5
 
6
6
 
7
7
  試したみたこととしては,generate_nodeの返り値の型をList*にして,引数にもList* olist, List* clist を追加させてreturn olistとしたのですが,適用されませんでした.
8
+
9
+
10
+
11
+ 8パズルを解いていて,stateには
12
+
13
+ har init_state[SIZE] = {'8', '6', '7', '2', '5', '4', '3', '0', '1'};
14
+
15
+ char final_state[SIZE] = {'1', '2', '3', '4', '5', '6', '7', '8', '0'};
16
+
17
+ のように格納されています.
18
+
19
+ これは
20
+
21
+ 8|6|7
22
+
23
+ 2|5|4
24
+
25
+ 3|0|1
26
+
27
+ のパズル状態を表し,0は空いているマスです.
8
28
 
9
29
 
10
30