@@ -24,6 +24,8 @@ using namespace std;
24
24
#define DISPLAY_SOLUTION_BACKWARDS 0 // 显示后向步骤
25
25
#define DISPLAY_SOLUTION_INFO 1
26
26
#define DEBUG_LISTS 0 // 显示 DEBUG 列表
27
+ #define SPIRAL 1 // 目标状态:螺旋
28
+ #define NORMAL 0 // 目标状态:普通
27
29
28
30
// Astar 搜索类
29
31
#include " stlastar.h" // 查看头文件来获取版权信息和使用信息
@@ -135,6 +137,7 @@ class PuzzleState
135
137
136
138
void PrintNodeInfo ();
137
139
void WriteNodeInfo ();
140
+ void WriteDream ();
138
141
139
142
private:
140
143
// User stuff - Just add what you need to help you write the above functions...
@@ -150,27 +153,39 @@ class PuzzleState
150
153
// 目标状态
151
154
PuzzleState::TILE PuzzleState::g_goal[] =
152
155
{
156
+
157
+ #if SPIRAL // 螺旋
153
158
TL_1, TL_2, TL_3, TL_4, TL_5,
154
159
TL_16, TL_17, TL_18, TL_19, TL_6,
155
160
TL_15, TL_24, TL_SPACE, TL_20, TL_7,
156
161
TL_14, TL_23, TL_22, TL_21, TL_8,
157
162
TL_13, TL_12, TL_11, TL_10, TL_9
163
+
164
+ #elif NORMAL // 普通
165
+ TL_1, TL_2, TL_3, TL_4, TL_5,
166
+ TL_6, TL_7, TL_8, TL_9, TL_10,
167
+ TL_11,TL_12, TL_13,TL_14, TL_15,
168
+ TL_16,TL_17, TL_18, TL_19, TL_20,
169
+ TL_21, TL_22, TL_23, TL_24, TL_SPACE
170
+
171
+ #endif
172
+
158
173
};
159
174
160
175
// 一些好的初始状态
161
176
PuzzleState::TILE PuzzleState::g_start[] =
162
177
{
163
178
164
179
#if 0
165
- // ex a - 2 steps
180
+ // 螺旋 a - 2 steps
166
181
TL_1, TL_2, TL_3, TL_4, TL_5,
167
182
TL_16, TL_17, TL_18, TL_19, TL_6,
168
183
TL_15, TL_24, TL_20, TL_7, TL_SPACE,
169
184
TL_14, TL_23, TL_22, TL_21, TL_8,
170
185
TL_13, TL_12, TL_11, TL_10, TL_9
171
186
172
187
#elif 0
173
- // ex b - 4 steps
188
+ // 螺旋 b - 4 steps
174
189
TL_1, TL_2, TL_3, TL_4, TL_5,
175
190
TL_16, TL_17, TL_18, TL_19, TL_6,
176
191
TL_15, TL_24, TL_20, TL_7, TL_8,
@@ -179,7 +194,7 @@ PuzzleState::TILE PuzzleState::g_start[] =
179
194
180
195
181
196
#elif 1
182
- // ex c - 12000 steps
197
+ // 螺旋 c - 52 steps
183
198
TL_1, TL_3, TL_4, TL_19, TL_5,
184
199
TL_16, TL_2, TL_18, TL_6, TL_7,
185
200
TL_24, TL_17, TL_20, TL_21, TL_8,
@@ -188,8 +203,36 @@ PuzzleState::TILE PuzzleState::g_start[] =
188
203
189
204
190
205
#elif 0
191
- // nasty one - doesn't solve
206
+ // 正常 a - 2 steps
207
+ TL_1, TL_2, TL_3, TL_4, TL_5,
208
+ TL_6, TL_7, TL_8, TL_9, TL_10,
209
+ TL_11,TL_12, TL_13,TL_14, TL_15,
210
+ TL_16,TL_17, TL_18, TL_19, TL_20,
211
+ TL_21, TL_22, TL_SPACE, TL_23, TL_24
192
212
213
+ #elif 0
214
+ // 正常 b - 8 steps
215
+ TL_1, TL_3, TL_SPACE, TL_4, TL_5,
216
+ TL_6, TL_2, TL_8, TL_9, TL_10,
217
+ TL_11,TL_7, TL_12,TL_14, TL_15,
218
+ TL_16,TL_17, TL_13, TL_19, TL_20,
219
+ TL_21, TL_22, TL_18, TL_23, TL_24
220
+
221
+ #elif 0
222
+ // 正常 c - 30 steps
223
+ TL_SPACE, TL_2, TL_8, TL_4, TL_5,
224
+ TL_3, TL_1, TL_9, TL_10, TL_15,
225
+ TL_6,TL_7, TL_13,TL_14, TL_20,
226
+ TL_12,TL_22, TL_16, TL_17, TL_24,
227
+ TL_11, TL_21, TL_18, TL_19, TL_23
228
+
229
+ #elif 0
230
+ // 正常 d - 38 steps
231
+ TL_2, TL_8, TL_4, TL_5, TL_15,
232
+ TL_3, TL_1, TL_9, TL_10, TL_20,
233
+ TL_6,TL_7, TL_SPACE,TL_13, TL_14,
234
+ TL_12,TL_22, TL_16, TL_17, TL_24,
235
+ TL_11, TL_21, TL_18, TL_19, TL_23
193
236
194
237
#endif
195
238
@@ -231,25 +274,35 @@ void PuzzleState::PrintNodeInfo()
231
274
if ( tiles[(y*BOARD_WIDTH)+x] == TL_SPACE )
232
275
{
233
276
// 记录空白格运动路径
234
- Move.push_back (make_pair (x, y ));
277
+ Move.push_back (make_pair (y, x ));
235
278
}
236
279
}
237
280
}
238
281
239
282
}
240
283
284
+
285
+ ofstream out (" data.txt" );
286
+
241
287
// 输出节点信息到文件
242
288
void PuzzleState::WriteNodeInfo ()
243
289
{
244
- ofstream out (" 24puzzle_start.txt" );
245
290
out<<tiles[0 ]<<" " <<tiles[1 ]<<" " <<tiles[2 ]<<" " <<tiles[3 ]<<" " <<tiles[4 ]<<" " ;
246
291
out<<tiles[5 ]<<" " <<tiles[6 ]<<" " <<tiles[7 ]<<" " <<tiles[8 ]<<" " <<tiles[9 ]<<" " ;
247
292
out<<tiles[10 ]<<" " <<tiles[11 ]<<" " <<tiles[12 ]<<" " <<tiles[13 ]<<" " <<tiles[14 ]<<" " ;
248
293
out<<tiles[15 ]<<" " <<tiles[16 ]<<" " <<tiles[17 ]<<" " <<tiles[18 ]<<" " <<tiles[19 ]<<" " ;
249
294
out<<tiles[20 ]<<" " <<tiles[21 ]<<" " <<tiles[22 ]<<" " <<tiles[23 ]<<" " <<tiles[24 ]<<endl;
250
295
}
251
296
252
-
297
+ // 输出普通型目标状态
298
+ void PuzzleState::WriteDream ()
299
+ {
300
+ for (int i=0 ; i<BOARD_WIDTH * BOARD_HEIGHT; i++)
301
+ {
302
+ out<<this ->g_goal [i]<<" " ;
303
+ }
304
+ out<<endl;
305
+ }
253
306
254
307
255
308
// Here's the heuristic function that estimates the distance from a PuzzleState
@@ -259,6 +312,8 @@ void PuzzleState::WriteNodeInfo()
259
312
float PuzzleState::GoalDistanceEstimate ( PuzzleState &nodeGoal )
260
313
{
261
314
315
+ #if SPIRAL // 螺旋启发式分数
316
+
262
317
// Nilsson's sequence score 尼尔森序列分数
263
318
264
319
int i, cx, cy, ax, ay; // i: 迭代器 cx,cy: 方块目标位置 ax,ay: 方块当前位置
@@ -449,8 +504,6 @@ float PuzzleState::GoalDistanceEstimate( PuzzleState &nodeGoal )
449
504
// clockwise_tile_of[i]是索引为i的方块顺时针方向上第一个方块
450
505
s += 2 ;
451
506
}
452
-
453
-
454
507
}
455
508
456
509
// mult by 3 and add to h
@@ -459,6 +512,95 @@ float PuzzleState::GoalDistanceEstimate( PuzzleState &nodeGoal )
459
512
460
513
return (float ) t; // 返回当前节点的启发式分数 h
461
514
515
+
516
+
517
+ #elif NORMAL // 普通启发式函数
518
+
519
+ int i, cx, cy, ax, ay; // i: 迭代器 cx,cy: 方块目标位置 ax,ay: 方块当前位置
520
+ int h = 0 ; // 启发式分数
521
+
522
+ // 方块的目标位置的x坐标
523
+ int tile_x[ BOARD_WIDTH * BOARD_HEIGHT ] =
524
+ {
525
+ /* TL_SPACE */ 4 ,
526
+ /* TL_1 */ 0 ,
527
+ /* TL_2 */ 1 ,
528
+ /* TL_3 */ 2 ,
529
+ /* TL_4 */ 3 ,
530
+ /* TL_5 */ 4 ,
531
+ /* TL_6 */ 0 ,
532
+ /* TL_7 */ 1 ,
533
+ /* TL_8 */ 2 ,
534
+ /* TL_9 */ 3 ,
535
+ /* TL_10 */ 4 ,
536
+ /* TL_11 */ 0 ,
537
+ /* TL_12 */ 1 ,
538
+ /* TL_13 */ 2 ,
539
+ /* TL_14 */ 3 ,
540
+ /* TL_15 */ 4 ,
541
+ /* TL_16 */ 0 ,
542
+ /* TL_17 */ 1 ,
543
+ /* TL_18 */ 2 ,
544
+ /* TL_19 */ 3 ,
545
+ /* TL_20 */ 4 ,
546
+ /* TL_21 */ 0 ,
547
+ /* TL_22 */ 1 ,
548
+ /* TL_23 */ 2 ,
549
+ /* TL_24 */ 3
550
+ };
551
+
552
+ // 方块的目标位置的y坐标
553
+ int tile_y[ BOARD_WIDTH * BOARD_HEIGHT ] =
554
+ {
555
+ /* TL_SPACE */ 4 ,
556
+ /* TL_1 */ 0 ,
557
+ /* TL_2 */ 0 ,
558
+ /* TL_3 */ 0 ,
559
+ /* TL_4 */ 0 ,
560
+ /* TL_5 */ 0 ,
561
+ /* TL_6 */ 1 ,
562
+ /* TL_7 */ 1 ,
563
+ /* TL_8 */ 1 ,
564
+ /* TL_9 */ 1 ,
565
+ /* TL_10 */ 1 ,
566
+ /* TL_11 */ 2 ,
567
+ /* TL_12 */ 2 ,
568
+ /* TL_13 */ 2 ,
569
+ /* TL_14 */ 2 ,
570
+ /* TL_15 */ 2 ,
571
+ /* TL_16 */ 3 ,
572
+ /* TL_17 */ 3 ,
573
+ /* TL_18 */ 3 ,
574
+ /* TL_19 */ 3 ,
575
+ /* TL_20 */ 3 ,
576
+ /* TL_21 */ 4 ,
577
+ /* TL_22 */ 4 ,
578
+ /* TL_23 */ 4 ,
579
+ /* TL_24 */ 4
580
+ };
581
+
582
+ for ( i=0 ; i<(BOARD_HEIGHT*BOARD_WIDTH); i++ )
583
+ {
584
+ // 累计启发式分数
585
+
586
+ // get correct x and y of this tile
587
+ // 获取该方块的目标位置
588
+ cx = tile_x[tiles[i]];
589
+ cy = tile_y[tiles[i]];
590
+
591
+ // get actual
592
+ ax = i % BOARD_WIDTH;
593
+ ay = i / BOARD_WIDTH;
594
+
595
+ // add manhatten distance to h
596
+ // 计算 manhatten 距离加到 h 上
597
+ h += abs ( cx-ax );
598
+ h += abs ( cy-ay );
599
+ }
600
+
601
+ return (float )h;
602
+
603
+ #endif
462
604
}
463
605
464
606
@@ -706,7 +848,8 @@ int main( int argc, char *argv[] )
706
848
node->PrintNodeInfo (); // 输出到终端
707
849
cout<<endl;
708
850
709
- node->WriteNodeInfo (); // 输出到文件
851
+ node->WriteDream (); // 输出目标状态
852
+ node->WriteNodeInfo (); // 输出初始状态
710
853
711
854
#endif
712
855
cout << " 前向步骤:\n " ;
@@ -796,8 +939,6 @@ int main( int argc, char *argv[] )
796
939
797
940
int len_Move = Move.size ();
798
941
799
- // 输出到文件
800
- ofstream out (" 24puzzle_move.txt" );
801
942
802
943
// 输出空白格运动路径
803
944
for (int i=0 ; i<len_Move-3 ; i++)
@@ -808,7 +949,7 @@ int main( int argc, char *argv[] )
808
949
int c2 = Move[i+1 ].second ;
809
950
810
951
// cout<<"第"<<i<<"次移动:("<<r1<<","<<c1<<") -> ("<<r2<<","<<c2<<")"<<endl;
811
- out<<r1 <<" " <<c1 <<" " <<r2 <<" " <<c2 <<endl;
952
+ out<<r2 <<" " <<c2 <<" " <<r1 <<" " <<c1 <<endl;
812
953
}
813
954
}
814
955
0 commit comments