八數碼寬度優先演算法

2021-07-08 11:03:21 字數 2758 閱讀 2115

相關**要感謝網上的一些大神給予的分享

用來作為乙個結點的資料結構。

struct map

;用來列印乙個結點

cout函式用來擴充套件乙個結點的後繼結點(上、下、左、右)

}if(hasgetblankcell)

break;

}//移動數字,t_i,t_j為移動後0的座標

int t_i = i,t_j = j;

bool ablemove = true;

switch(direct)

;if(!ablemove)//不可以移動則返回原節點

if(createnewmap)

else

newmap = map;

/*移動即交換0與相應數字的位置*/

newmap->cell[i][j] = newmap->cell[t_i][t_j];

newmap->cell[t_i][t_j] = 0;

return newmap;

}函式用來隨機產生beginmap

struct map * randommap()//隨機產生八數碼陣列

}if(isre)

}for(int i = 0; i < n; i++)

}newmap->parent = null;

newmap->belockdirec = none;

return newmap;

}函式用來判斷某節點是否為目標結點

bool issuccess(struct map * map,struct map * target)

}if(!issuc)

break;

}return issuc;

}struct map * bnf_search(struct map * begin,struct map * target)

用來進行寬度搜尋(按照以下的流程)

因為closed表是只進不出的,所以這裡省略了closed表,用p1儲存closed表中的最新結點。而open表是乙個佇列,先進先出。程式是以鍊錶作為資料結構的,而不是陣列。所以可以通過指標回溯

//把begin結點放入open表中

struct map * p1, *p2, *p=null;//p1為要進入closed表中的結點,p2為p1擴充套件的結點,p為等於結果的結點

bool issucc = false;

queuequeue;

if(issuccess(begin,target))

return begin;

queue.push(begin);

//begin是否為目標結點    

if(issuccess(begin,target))

return begin;

//open表是否為空表,或是否已經找到結果              

while(!queue.empty() || p == null);

//把第乙個結點從open表中移出,放入closed表中(即p1中)

p1 = queue.front();//返回queue中的第乙個元素

queue.pop();

//擴充套件當前結點

for (int i = 1; i <= 4; i++)

//判斷後繼結點是否為目標結點,如果不是則將後繼結點放入open表中並迴圈從open表中pop,如果是則返回當前結點

if (issuccess(p2,target))

queue.push(p2);

n++;

函式返回乙個結點逆序數的奇偶性用來判斷八數碼是否可以後的結果

如果奇偶相同說明有解,否則無解

int hasresult(struct map *map)//返回逆序數的奇偶用來判斷是否有解

for(i=0;i<9;i++)

}return a%2;

}隨機生成begin結點,並定義target結點

定義a1,a2用來記錄begin和target逆序數的奇偶性用以判斷是否有解

int a1,a2;

map target;

map *begin,*t;

begin=new map;

//設定目標圖 [1 2 3],[8 0 4],[7 6 5]

target.cell[0][0] = 1;

target.cell[0][1] = 2;

target.cell[0][2] = 3;

target.cell[1][0] = 8;

target.cell[1][1] = 0;

target.cell[1][2] = 4;

target.cell[2][0] = 7;

target.cell[2][1] = 6;

target.cell[2][2] = 5;

begin = randommap();

cout<

cout<

a2=hasresult(begin);

if(a1!=a2)

cout<

else

cout<

cout<

cout<

}}有解:

無解:

廣度優先搜尋 八數碼問題

給定乙個一幅圖和乙個起點s,回答 從s到給定的頂點v是否存在一條路徑?如果有,找出其中最短的那條 所含邊數最少 邊數最少,很自然想到從從經過1條邊能到達的節點有哪些?然後經過這些邊再到達的節點有哪些?這樣我不就能夠想出來最短的路徑了嗎?沒錯,這是非常簡單的想法,然而真正的廣度優先演算法也是這樣,簡單...

八數碼(IDA 演算法)

八數碼 ida 就是迭代加深和a 估價的結合 在迭代加深的過程中,用估計函式剪枝優化 並以比較優秀的順序進行擴充套件,保證最早搜到最優解 需要空間比較小,有時跑得比a 還要快 include include include include include using namespace std in...

Python深度優先解決八數碼問題

在寬度優先解決八數碼問題基礎上對節點類增加深度屬性 import copy import numpy as np from datetime import datetime 字串列表化 defstring to ls str return i.split for i in str.split 獲取位...