###実現したいこと
Step1: 出発のノードnに対し(n null c) をOpenリストに追加する。ただし初めなのでc = h(n) = f(n)
Step2: Openリストからcが最⼩の要素(n p c) を⼀つ選択。nがゴールであれば成功として終了。Openリストが空集合なら失敗として終了。
Step3: ノードnを展開し、⼦ノードの集合を作る。nをCLOSEDリストに追加する。
Step4: ⼦ノードの集合からCLOSEDリストに含まれないノードn’ に対して、(n’ n c’ )をOpenリストに追加する(なお、c’= f(n’) = h(n’) + g(n) + c(n n’),c(n n’) はnからn’へのコストである) である。このときすでに(n’ m c’’ )がOpenリストに⼊っており、c’<c’’ なら新しいものに置き換え、そうでなければOpenリストには追加しない。さらに、CLOSEDリストに含まれるn’ に対して、そのときに探索した(n’ m c’’ ) について、c’ < c’’ならn’をCLOSEDリストから削除し、(n’ n c’ ) をオープンリストに加える。
Step5: Step2へ。
次に具体的な目標が記載されているサイトを記す.
3.ヒューリステック関数の仕様という部分を同じく8パズルにおいて行おうとしている.
参考サイト
###実装方針
リストの要素を削除するのはリンクを張り替えればよいので,方法としては
子ノードを生成したときに,すでにそのstateがcloseリストに無いとき,コストを計算し,openリストにもないもしくは同一のstateでも今回の方がコストが小さい場合,openリストに格納し,openリストを一周して最小コストをグローバル関数min_costで取っていく,
その後,もう一度openリストを初めから見ていき,最小コストと一致する状態から子ノードを展開し,
その展開を行ったノードに貼っているリンクを子ノードにつなぎなおす.代わりにcloseリストにそのノードを入れる.
h1()が0となるまでこれを繰り返す.
###現状のコード
・構造体によってopenリストとcloseリストを生成した,
・探索を行うsearch関数の条件の構造までは記述した.
・searchにおいて,openリスト中のmin_costを見つけるものを作成.
・min_costをもつnodeをopenリストから削除できるようにした.
・プログラム終了時にリストを破棄する関数を作成した.
・ヒューリスティック関数h1を作成した.
・探索にかかった時間を出力する.
コードを編集いたしましたので追記にて記します.
###質問内容
・次にあげる部分を現状のコードに組み込んで子ノードを生成させたいのですが,私が考えている組み込み方の直す点を教えていただきたいです.反復深化という方法で子ノードを生成するときに用いています.
反復深化
説明を加えます.
adjacentは
0|1|2
3|4|5
6|7|8
と配置したときの隣り合う数字を示しています.例えば0ならば1, 3とのみ隣り合っています.隣り合う数字がもう出尽くしたという意味で-1を用いています.
print_answerは下位にたどり着くまでに動かした数字を格納しています.
深さ優先では厳しいので幅優先にします,内容派追記にて書かせていただきます.
####組みこもうとしているもの
上のコードでのnの扱いが上手くできていません..
これでは一パターンの子ノードしか作れない.
と私は考えています
追記にて記します.
`
####残っているやるべきこと
・子ノードの生成
・木の生成
##追記
####現状のコード全体
C
1#include <stdlib.h> 2#include <stdio.h> 3#include <string.h> 4#include <time.h> 5 6#define TRUE 1 7#define FALSE 0 8#define GOAL 2 9#define SIZE 9 10#define S 0 11#define MAX_STATE 181440 12#define MAX_MOVE 31 13#define EXIST 1 14#define NOEXIST 0 15 16char init_state[SIZE1] = {'8', '6', '7', '2', '5', '4', '3', '0', '1'}; 17char final_state[SIZE] = {'1', '2', '3', '4', '5', '6', '7', '8', '0'}; 18//最初のノードは親ノードを持たないのでこのあり得ないNULL_stateを親とする 19char NULL_state[SIZE] = {'9', '9', '9' ,'9', '9', '9', '9', '9', '9'}; 20 21typedef struct List{ 22 int cost; 23 char state[SIZE]; 24 char parent_state[SIZE]; 25 struct List* next; //次の要素のポインタ 26 27} List; 28 29/* リストを追加する為の関数*/ 30List *ListAdd(List* ls, int cost, char state[], char parent_state[]){ 31 /*メモリの確保*/ 32 List* node = (List*)malloc(sizeof(List)); 33 if(node == NULL) 34 return NULL; 35 36 /*データの追加*/ 37 node->cost = cost; 38 memcpy(node->state,state, SIZE); 39 memcpy(node->parent_state,parent_state,SIZE); 40 node->next = NULL; 41 42 //test 43 printf("node state\n"); 44 for(int i = 0; i < SIZE; i++){ 45 printf("%c ",node->state[i]); 46 } 47 printf("\n"); 48 49 /*データをリストに追加する*/ 50 if(ls == NULL) 51 return node; 52 List* search = ls; 53 while (search->next != NULL) 54 search = search->next; 55 search->next = node; 56 return ls; 57} 58 59/* リストを削除する為の関数*/ 60void ListAllDelete(List* ls){ 61 List *tmp = ls; 62 while (ls->next != NULL){ 63 tmp = ls->next; 64 ls->next = tmp->next; 65 free(tmp); 66 } 67 free(ls); 68} 69 70int h1(char state[]){ 71 int count = 0; 72 for(int i = 0;i < 9;i++){ 73 if(state[i] != final_state[i]) count++; 74 } 75 return count; 76} 77 78int min_cost; 79List* olist = NULL; 80List* clist = NULL; 81 82//動かした数字 83//int move_piece[MAX_MOVE + 1]; 84 85char space_postion[MAX_STATE]; 86char pre_state[SIZE]; 87int same_state_cost; 88int succeed_flag = 0; 89 90int adjacent[SIZE][5] = { 91 {1, 3, -1}, // 0 92 {0, 2, 4, -1}, // 1 93 {1, 5, -1}, // 2 94 {0, 4, 6, -1}, // 3 95 {1, 3, 5, 7, -1}, // 4 96 {2, 4, 8, -1}, // 5 97 {3, 7, -1}, // 6 98 {4, 6, 8, -1}, // 7 99 {5, 7, -1} // 8 100}; 101 102int List_search(List* list, char state[]){ 103 104 for(List* node = list; node != NULL; node = node->next){ 105 if(memcmp(node->state, state, SIZE) == 0){ 106 same_state_cost = node->cost; 107 return EXIST; 108 } 109 } 110 return NOEXIST; 111} 112 113//char -> int 114int ctoi(char c) { 115 if (c >= '0' && c <= '9') { 116 return c - '0'; 117 } 118 return -1; 119} 120 121//空きマス(0)の取得 122int get_space(char state[]){ 123 for(int i = 0;i < 9;i++){ 124 if(ctoi(state[i]) == 0){ 125 printf("space:%d\n",i); 126 return i; 127 } 128 } 129} 130 131void generate_node(char state[], int p_cost){ 132 int space = get_space(state); 133 134 //test 135 printf("(g_n)space:%d\n",space); 136 137 int n; 138 memcpy(pre_state, state, SIZE); //親となるstateの保存 139 140 //test 141 printf("p_node:%s\n",pre_state); //ok 142 143 for(int i = 0; (n = adjacent[space][i]) != -1; i++ ){ 144 //test 145 printf("n:%d\n",n); //OK 146 147 /* 移動 */ 148 state[space] = state[n]; //スペースがあった場所にnにあったものを移動 149 state[n] = '0'; //nをスペースにする 150 151 //test 152 printf("state[space]:%c\n", state[space]); 153 printf("state[n]:%c\n", state[n]); 154 printf("after move state:%s\n",state); 155 156 if(memcmp(state, final_state, SIZE) == 0){ 157 printf("succeed\n"); 158 succeed_flag++; 159 return ; 160 } 161 162 if( List_search(clist, state) == NOEXIST ){ 163 if( List_search(olist, state) == NOEXIST ){ 164 //olistにもclistにも存在しないstateなら即olistに追加 165 ListAdd(olist, h1(state)+p_cost, state, pre_state); 166 }else{ 167 //olistにのみ存在するときは,同じstateよりもコストが小さいなら追加 168 if(h1(state)+p_cost < same_state_cost){ 169 //同じstateのnodeを削除するためにolistを最初から見ていく 170 for(List* node = olist; node != NULL; node = node->next){ 171 if(memcmp(node->next->state, state, SIZE) == 0){ 172 node->next = (node->next)->next; //同じstateのnodeを削除 173 ListAdd(olist, h1(state)+p_cost, state, pre_state); //olistに追加 174 } 175 } 176 } 177 } 178 } 179 } 180} 181 182 183//ここで探索を行う. 184void search(){ 185 int count = 0; 186 while(count < MAX_STATE){ 187 for(List* node = olist; node != NULL; node = node->next){ 188 if(node->cost < min_cost){ 189 min_cost = node->cost; 190 191 //test 192 printf("min_cost:%d\n"); 193 } 194 } 195 196 for(List* node = olist; node != NULL; node = node->next){ 197 if(node->cost == min_cost){ 198 generate_node(node->state, node->cost); 199 break; 200 } 201 } 202 203 //test 204 //printf("%d ",count); しっかり回っている 205 min_cost = MAX_STATE; 206 if(succeed_flag > 0) break; 207 count++; //無限ループを防ぐ 208 } 209 210 //test 211 //for(List* node = olist; node != NULL; node = node->next) printf("%s\n", node->state); 212 //for(List* node = clist; node != NULL; node = node->next) printf("%s\n", node->state); 213 214 printf("search failed\n"); 215 216} 217 218void main(){ 219 220 min_cost = h1(init_state); 221 222 //test 223 //printf("init min_cost:%d\n",min_cost); OK 224 225 //headを入れる 226 olist = ListAdd(olist, MAX_STATE, NULL_state, NULL_state); 227 clist = ListAdd(clist, MAX_STATE, NULL_state, NULL_state); 228 229 olist = ListAdd(olist, h1(init_state), init_state, NULL_state); //最初の親はNULLにしたいが怒られている 230 231 printf("Search start\n"); 232 clock_t time = clock(); 233 search(); 234 double result = (double)(clock() - time)/CLOCKS_PER_SEC; 235 printf("%.3fsec\n", result); //探索にかかった時間を表示 236 237 ListAllDelete(olist); 238 ListAllDelete(clist); 239 return; 240} 241
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/06/07 12:39
2021/06/07 13:26
2021/06/09 01:41 編集
2021/06/08 14:43 編集
2021/06/09 01:40