迷宮尋跡演算法
❶ 回溯演算法的基本思想
回溯演算法的基本思想是:從一條路往前走,能進則進,不能進則退回來,換一條路再試。八皇後問題就是回溯演算法的典型,第一步按照順序放一個皇後,然後第二步符合要求放第2個皇後,如果沒有位置符合要求,那麼就要改變第一個皇後的位置,重新放第2個皇後的位置,直到找到符合條件的位置就可以了。回溯在迷宮搜索中使用很常見,就是這條路走不通,然後返回前一個路口,繼續下一條路。回溯演算法說白了就是窮舉法。不過回溯演算法使用剪枝函數,剪去一些不可能到達 最終狀態(即答案狀態)的節點,從而減少狀態空間樹節點的生成。回溯法是一個既帶有系統性又帶有跳躍性的的搜索演算法。它在包含問題的所有解的解空間樹中,按照深度優先的策略,從根結點出發搜索解空間樹。演算法搜索至解空間樹的任一結點時,總是先判斷該結點是否肯定不包含問題的解。如果肯定不包含,則跳過對以該結點為根的子樹的系統搜索,逐層向其祖先結點回溯。否則,進入該子樹,繼續按深度優先的策略進行搜索。回溯法在用來求問題的所有解時,要回溯到根,且根結點的所有子樹都已被搜索遍才結束。而回溯法在用來求問題的任一解時,只要搜索到問題的一個解就可以結束。這種以深度優先的方式系統地搜索問題的解的演算法稱為回溯法,它適用於解一些組合數較大的問題。
❷ c語言走迷宮dfs用了迷宮,其中有回溯思想,就是走不通返回上一狀態,
遞歸了吧。使用了系統棧,在遞歸結束時用了返回。根據棧的先進後出原則,就是一步步的在回溯了。
❸ C語言編程求解啊!利用回溯演算法的迷宮搜索類型問題
#include "stdafx.h"
#include <iostream>
#include "cmath"
#include <fstream>
using namespace std ;
int ROW ;
int COL ;
int **g_pRoom ;
// 回溯法注意標記已訪問過的節點。。。。。不然就會進入重復操作將棧用空。。。。。。。。
struct Point
{
Point( int xx = 0, int yy = 0 ):x(xx),y(yy) { }
int x ;
int y ;
} ;
int g_nMax = 0 ;
Point g_pResult[100] ;
int g_nCount ;
Point g_pStart ;
Point g_pEnd ;
Point g_pOrient[4] = { Point(-1, 0 ) , Point( 0 ,1 ) , Point( 1 ,0 ) , Point( 0 , -1 ) } ;
bool Read_data( ifstream &file )
{
if( file.eof() )
return false ;
g_nMax = 0 ;
g_nCount = 0 ;
file>>ROW>>COL ;
g_pRoom = new int*[ROW] ;
g_pStart = g_pEnd = Point( -1, -1 ) ;
for( int i = 0 ; i < ROW ; i++ )
g_pRoom[i] = new int[COL] ;
for( int i = 0 ; i < ROW ; i++ )
for( int j = 0 ; j < COL ; j++ )
{
file>>g_pRoom[i][j] ;
if( g_pRoom[i][j] == -1 )
{
g_pStart.x = j ;
g_pStart.y = i ;
}
else if( g_pRoom[i][j] == -2 )
{
g_pEnd.x = j ;
g_pEnd.y = i ;
}
}
if( g_pStart.x == -1 || g_pEnd.x == -1 )
{
cout<<" the data errror !\n" ;
return false ;
}
return true ;
}
void Dateback( Point pStart )
{
static Point Stack[1000] ;
static int nTop = 0 ;
static int Apple = 0 ;
if( pStart.x == g_pEnd.x && pStart.y == g_pEnd.y )
{
if( Apple + 2 > g_nMax )
{
g_nMax = Apple + 2 ;
for( int i = 0 ; i < nTop ; i++ )
g_pResult[i] = Stack[i] ;
g_nCount = nTop ;
} // ....
}
else
{
for( int i = 0 ; i < 4 ; i++ )
{
Point s ;
s.x = pStart.x + g_pOrient[i].x ;
s.y = pStart.y + g_pOrient[i].y ;
if( s.x >= 0 && s.x < COL && s.y >= 0 && s.y < ROW && g_pRoom[s.y][s.x] != 0 )
{
Apple += g_pRoom[s.y][s.x] ;
Stack[nTop++] = s ;
int temp = g_pRoom[s.y][s.x] ;
g_pRoom[s.y][s.x] = 0;
Dateback( s ) ;
nTop-- ;
g_pRoom[s.y][s.x] = temp ;
Apple -= g_pRoom[s.y][s.x] ;
}
}
}
}
int main()
{
ifstream file("data.txt") ;
Read_data(file) ;
Dateback( g_pStart ) ;
cout<<g_nMax ;
cout<<"("<<g_pStart.y<<","<<g_pStart.x<<")"<<" " ;
for( int i = 0 ; i < g_nCount ; i++ )
cout<<"("<<g_pResult[i].y<<","<<g_pResult[i].x<<")"<<" " ;
return 0 ;
}
❹ 怎麼用回溯法來實現迷宮問題,其中用'*'來表示牆,用A來表示路徑!!1
愛蓮說
(宋)周敦頤
水陸草木之花,可愛者甚蕃。晉陶淵明獨愛菊;自李唐來,世人盛愛牡丹;予獨愛蓮之出淤泥而不染,濯清漣而不妖,中通外直,不蔓不枝,香遠益清,亭亭凈植,可遠觀而不可褻玩焉。予謂菊,花之隱逸者也;牡丹,花之富貴者也;蓮,花之君子者也。噫!菊之愛,陶後鮮有聞;蓮之愛,同予者何人;牡丹之愛,宜乎眾矣。
[注釋]:
(1)愛蓮說:選自《周元公集》。作者周敦頤著名的唯心主義哲學家。「說」,是古代論說文的一種體裁,可以說明事物,也可以論述道理。
(2)蕃:多。
(3)晉陶淵明獨愛菊:陶淵明(365-427),一名潛,字元亮,東晉潯陽(現在江西省九江縣)人,著名的詩人。他很愛菊花,常在詩里寫到,如《飲酒》詩里的「採菊東籬下,悠然見南山」,向來稱為名句。
(4)自李唐來,世人甚愛牡丹:唐朝以來,人們很愛牡丹。李唐,指唐朝。唐朝的皇帝姓李,所以稱為「李唐」。世人,社會上的一般人。唐人愛牡丹,古書里有不少記載,如唐朝李肇的《唐國史補》里說:「京城貴游,尚牡丹……每春暮,車馬若狂……種以求利,一本(一株)有直(同「值」)數萬(指錢)者。」
(5)予獨愛蓮之出淤泥而不染:我單單喜歡蓮花,喜歡它從污泥里生出卻不被沾染。淤泥,池塘里積存的污泥。
(6)濯(zhuó)清漣而不妖:在清水裡洗過卻不妖艷。濯,洗滌。清漣,水清而有微波的樣子,這里指清水。妖,美麗而不端莊。
(7)不蔓不枝:不牽牽連連的,不枝枝節節的。
(8)香遠益清:香氣越遠越清。益,更,越。
(9)亭亭:聳立的樣子。
(10)褻(xiè)玩:玩弄。褻,親近而不莊重。
(11)隱逸者:隱居的人。封建社會里,有些人不願意跟統治者同流合污,便隱居避世。
(12)牡丹,花之富貴者也:牡丹是花中的「富人」。
(13)君子:道德高尚的人。
(14)噫(yī):嘆詞,相當於「唉」。
(15)菊之愛:對於菊花的愛好。
(16)鮮(xiǎn)有聞:很少聽到。鮮,少。
(17)宜乎:宜,當,這里和「乎」連用,有「當然」的意思。
[譯文]:水上地上各種草和木的花,可愛的是很多的。晉朝陶淵明唯獨喜愛菊花。從唐朝以來,世上的人們非常喜愛牡丹。我唯獨喜愛蓮花,它從污泥中長出來,卻不受到污染,在清水裡洗滌過但是不顯得妖媚,它的莖中間貫通,外形挺直,不牽牽連連,不枝枝節節的,香氣遠播,更加清香,筆直地潔凈地立在那裡,可以遠遠地觀賞但是不能貼近去輕慢地玩弄啊。
我認為,菊花是花中的隱士;牡丹,是花中的富貴者;蓮花,是花中的君子。
唉!愛菊花的人,從陶淵明以後很少聽到過。愛蓮花的人,像我一樣的人還有什麼人呢?至於愛牡丹的人,人數當然就很多了!
「說」,古代文體之一,它往往借描繪事物以抒情言志。周敦頤的《愛蓮說》正是這種托物言志的文體中一篇不可多得的傳世佳作。
[賞析]:周敦頤,北宋人,其人一生澹泊名利,不求聞達。他的這種高潔的人品,誠如北宋文學大家黃庭堅所譽:「人品甚高,胸懷灑落,如光風霽月……」而他的傳世散文佳作《愛蓮說》恰恰正是他酒落胸懷所透射而出的精神折光。
蓮花,是古往今來文人筆下高歌詠嘆的對象,但大多數文人都是驚嘆於它的清姿素容,並將其形諸筆端;而這筆散文精品卻獨辟蹊徑,通過對蓮的形象和品質的描寫,歌頌了蓮花堅貞的品格,從而也表現了作者潔身自愛的高潔人格和灑落的胸襟。
從內容上看,這篇文章可明顯分為二部分:前一部分對蓮花高潔的形象極盡鋪排描繪之能事;第二部分則揭示了蓮花的比喻義,分評三花,並以蓮自況,抒發了作者內心深沉的概嘆。
文章的前一部分,寫出了蓮花之美就在於其一個「潔」字。首先,「出淤而不染,濯清蓮而不妖」寫出了蓮花身處污泥之中,卻纖塵不染,不隨世俗、潔身自愛和天真自然不顯媚態的可貴精神;其次,「中通外直,不蔓不枝」,寫出了它里外貫通、外表挺直、表裡如一、不牽扯攀附的高尚品質;再次「可遠觀而不可褻玩」,寫出了蓮如傲然不群的君子一樣,決不被俗人們輕慢玩弄。
前文所說的一切,事實上是作者人格的寫照,是作者心志的自明,關於這一點,我們可以從文章的第二部分得到明證。正如作者所說:「蓮之愛,同予者何人?」其間的潛台詞就是感慨於象他一樣具有蓮花之潔的人實在太少了。
在寫法上,《愛蓮說》具有「說」這一文體的共同特點,即托物言志。文章從「出淤泥而不染」起,以濃墨重彩描繪了蓮的氣度、蓮的風節,寄予了作者對理想人格的肯定和追求,也反射出作者鄙棄貪圖富貴、追名逐利的世態的心理和自己追求潔身自好的美好情操。同時,文章還運用了對比,反襯的手法,在文中幾次以菊、牡丹反襯蓮之美;還把菊花的隱逸,牡丹的富貴和蓮花的高潔相對比,使「愛蓮」之一主題得以加深,沒有空洞的說教,而是通過三種形象的對比,起到了突出中心,加深立意的作用,手法可謂高明之極。而且,文章以一個「愛」字貫通全文,使得文章結構謹嚴。 在文章結尾,作者一嘆真正隱逸的高士極少,二嘆品格高尚的君子罕見,三嘆貪慕富貴的俗人很多,耐人尋味,發人深省。
這首詩在語言上也同樣富有特色,那就是優美簡煉,的確是如蓮之美——「不枝不蔓」,沒有多餘的無用之語
蓮花的美麗別稱
(1)芙蓉:《爾雅》:「荷,芙蕖,別名芙蓉,亦作芙容。」
(2)芙蕖:《爾雅·釋草》:「荷、芙蕖。……其華菡萏,其實蓮,其根藕。」
(3)藕花: 唐張籍《送從弟之蘇州》詩:「夜月紅柑樹,秋風白藕花。」
(4)水芙蓉:《群芳譜》:「荷花亦稱作芙蕖、水芙蓉。」
(5)草芙蓉:杜詩注雲:產於陸者曰木芙蓉,產於水者曰草芙蓉。」
(6) 水花:李時珍《本草綱目》:「蓮花」釋名:「芙蓉、芙蕖、水華。」
(7)凈友又稱凈客。蓮花潔凈不染,因此人們稱其為凈友。
(8)水芝:普崔豹《古今注》下「草木」:「芙蓉一名荷華,一名水目,一名水芝,一名水花。」
(9)澤芝:《類聚》郭璞《爾雅圖贊 ·芙蓉贊 》雲:「芙蓉麗草,一曰澤芝,……」
(10) 靈草:吳閔鴻《芙蓉賦並序》:「乃有芙蓉靈草,栽育中川。」
(11)玉環:《本草經》載:「荷花又名玉芝。」
(12)君子花:北宋周敦頤著《愛蓮說》,謂蓮為花中君子,蓮又稱「君子花」。
(13) 水宮仙子:因蓮生水中,蓮花亭亭玉立於水面,好似仙女飄然而行,故名。
(14) 菡萏:《爾雅》:「荷,芙蕖……其華菡萏。」
蓮花與佛教
據 說 ,釋 迦 牟 尼 本 是 天 上 的 菩 薩 ,下 凡 降 生 到 迦 毗 羅 衛 國 凈 飯 王 處 。 凈 飯 王 的 王 妃 摩 耶 夫 人 , 長 得 象 天 仙 一 樣 美 麗 , 性 情 溫 和 賢 淑 , 與 國 王情 深 似 海 。摩 耶 夫 人 回 憶 新 婚 之 夜 , 她 朦 朧 中 看 到 遠 處 有 一 個 人 騎 著 一頭 白 象 向 她 走 來 並 且 逐 漸 變 小 , 從 她 的 右 肋 處 鑽 入 她 的腹 中 。 她 心 中 模 模 糊 糊 地 預 感 到 菩 薩 化 作 一 頭 白 象 入 胎。 日 後 , 身 懷 有 孕 的 摩 耶 夫 人 臉 上 , 微 微 泛 著 紅 暈 , 那 色 彩 鮮 艷 的 綠 色 領 口 花 邊 象 一 片 蓮 葉 , 她 的 臉 兒 象 一 朵 綻 開 的 蓮 花 。 後 來 摩 耶 夫 人 在 娑 羅 樹 下 降 生 佛 祖 時 , 百 鳥 群 集 歌 唱 , 天 樂 鳴 空 相 和 , 四 季 里 的 花 木 都 一 同 盛 開, 尤 其 是 沼 澤 內 突 然 開 放 出 大 得 象 車 蓋 一 樣 的 蓮 花 。 佛祖 一 出 世 , 便 站 在 蓮 花 上 , 一 手 指 天 , 一 手 指 地 , 並 說: 「 天 上 天 下 , 惟 我 獨 尊 」 。
不 僅 如 此 , 蓮 還 與 佛 教 醫 學 有 著 密 切 關 系 。 蓮 花 含 有 豐 富 的 營 養 , 既 可 食 用 又可 葯 用 。 古 代 女 子 常 采 清 晨 帶 露 的 蓮 花 敷 面 美 容 , 或 服 食 蓮 花 以 養 顏。 蓮 花 含 有 皮 素 和 木 樨 素 ,能 潤 澤 膚 色 。 初 放 鮮 嫩 的 蓮 花 用 開 水 泡 飲 , 其 汁 翠 綠 清 香 , 有 清 暑 解 熱 和 生 津 開 胃 之 功 效 。 蓮 的 地 下 根 莖 稱 為 蓮 藕 。 相 傳 佛 祖 的 十 大 弟 子之 一 舍 利 弗 患 有 肺 結 核 , 目 犍 連 來 探 望 他 , 並 得 知 舍 利 弗 喜 歡 吃 蓮 藕 , 就 帶 些 新 鮮 蓮 藕 讓 舍 利 弗 吃 , 舍 利 弗 吃 蓮 藕 後 果 然 病 愈 。 後 來 , 佛 祖 弟 子 經 常 用 蓮 藕 作 為 葯 用來 治 病 , 並 發 現 了 蓮 藕 的 許 多 葯 用 價 值 。
蓮花的美好品質
在千古第一詩人屈原的代表作 《離騷》中有這樣的詩句「制芰荷以為衣兮,集芙蓉以為裳。」詩人為了表達自己不與世俗同流合污的決心,要穿上用蓮花做成的香氣馥郁的衣服。在這里,蓮花這一形象,不僅象徵著詩人高潔的品質和美好的修養,而且表現了詩人濃烈的激情和奇幻的想像以及《離騷》這首不朽傑作的浪漫主義特色。
「江南可采蓮,蓮葉何田田。魚戲蓮葉間。魚戲蓮葉東,魚戲蓮葉西,魚戲蓮葉南,魚戲蓮葉北。」這是漢代樂府民歌中的一首極為清新優美的小詩。在這首小詩中,「蓮」既指實物花卉蓮花,又是愛憐的「憐」諧音,以魚戲蓮葉隱喻男女之間的愛情,極其生動形象。在秀美的江南水鄉的大背景中,采蓮的男女主人公搖著小舟,自由地歌唱著純潔美麗的愛情,該是一幅多麼清新的圖畫!
「荷葉羅裙一色裁,芙蓉向臉兩邊開。亂入池中看不見,聞歌始覺有人來。」在唐代七絕聖手王昌齡的這首《采蓮曲》中,采蓮少女的美麗雖不著一字,卻盡得風流,因為她們的身影已與風光秀麗、如詩如畫的荷塘、蓮花融為一體了。從這自然渾成、耐人尋味的意境中,我們不難感受到中國古典文學的魅力吧。
代表著南朝樂府民歌最高成就的《西洲曲》,更是對蓮花和采蓮有著細致入微的描寫:「開門郎不至,出門采紅蓮。采蓮南塘秋,蓮花過人頭。低頭弄蓮子,蓮子青如水。置蓮懷袖中,蓮心徹底紅。憶郎郎不至,仰首望飛鴻……」這首詩中采蓮的情形,不僅生動地展示了江南水鄉人民的生活,而且寫出了采蓮女主人公對遠行丈夫深深的思念之情,語言清新明麗,意境悠遠,情思纏綿。
以「誠齋體」聞名南宋詩壇的著名詩人楊萬里的詩《曉出凈慈寺送林子方》:「畢竟西湖六月中,風光不與四時同。接天蓮葉無窮碧,映日荷花別樣紅。」在這首詩中,詩人擷取了「接天蓮葉」和「映日荷花」兩個典型景物,以通俗明快、流轉圓活的風格,寫出了六月里西湖的美麗風光,一改宋詩瘦硬生澀的弊端,極具自然靈性。
宋朝理學的創導者、哲學家周敦頤的《愛蓮說》中有這樣的句子:「予獨愛蓮之出淤泥而不染,濯清漣而不妖,中通外直,不蔓不枝,香遠益清,亭亭靜植,可遠觀而不可褻玩焉……蓮,花之君子者也。」在這篇托物言志的散文中,作者從不同的角度、不同的方面寫盡了蓮花的高潔品質、優雅氣質、優美的姿態和莊重的儀表,表達了封建士大夫高潔的情操和志趣。自此,蓮花便有了靈性,步入花中君子之列。
明代的許仲琳,在其著名的神魔小說《封神演義》中,塑造了一個蓮花化身的少年英雄哪吒的形象,他純真勇敢而又法力高強,敢於蔑視神權、打抱不平,極具正義和反抗精神,是我國古典文學中為人民群眾所喜愛的人物形象之一。透過哪吒這一神話人物形象,我們看到蓮花又變成了正義和勇敢的化身。
一代散文大師朱自清的美文《荷塘月色》,通過高超的藝術手法和情景交融的意境營造,寫出了月下荷塘素淡朦朧的美:「曲曲折折的荷塘上面,彌望的是田田的葉子……,層層的葉子中間,零星地點綴著些白花,有婀娜的開著的,有羞澀的打著朵兒的,正如一粒粒的明珠,又如碧天里的星星,微風過處,送來縷縷清香,彷彿遠處高樓上渺茫的歌聲似的……」月下的荷葉、荷花和荷塘,在現代作家朱自清的筆下簡直就像一幅意境幽美的工筆畫
❺ 請教高手C++數據結構回溯演算法解,迷宮問題
//迷宮用棧做的
#include "stdio.h"
#include "stdlib.h"
#define INITSIZE 100
#define STACKINCRESMENT 10
#define WALL 9999
struct stack
{
int *base;
int *top;
int size;
};
struct mi
{
int val;
bool tag;
int di;
};
void init_stack(stack *);
void push(stack*,int);
int pop(stack*);
int getop(stack*);
int palace(stack*, mi p[10][10]);
int main()
{
int e;
int ch;
struct mi p[10][10];
for(int i=0;i<10;i++)
{
p[0][i].val = 0;
p[i][0].val = 0;
p[9][i].val = 0;
p[i][9].val = 0;
}
for(int j=1;j<9;j++)
{
for(int k=1;k<9;k++)
{
p[j][k].val = 1;
}
}
p[1][3].val = p[1][7].val =0;
p[2][3].val = p[2][7].val =0;
p[3][5].val = p[3][6].val =0;
p[4][2].val = p[4][3].val = p[4][4].val =0;
p[5][4].val = 0;
p[6][2].val = p[6][6].val =0;
p[7][2].val = p[7][3].val = p[7][4].val =0;
p[7][6].val = p[7][7].val =0;
p[8][1].val = 0;
for(int m=0;m<10;m++)
{
for(int n=0;n<10;n++)
{
printf(" %d ",p[m][n]);
p[m][n].tag =0;
p[m][n].di =0;
}
printf("\n");
}
struct stack *s = (stack*)malloc(sizeof(stack));
init_stack(s);
palace(s, p);
printf("\none path is: \n");
for(int a=0;*s->base<89;s->base++)
{
printf("-a");
printf("%d",*s->base);
}
return 0;
}
void init_stack(stack *s)
{
s->base = (int*)malloc(INITSIZE*sizeof(stack));
if(!s->base) printf("malloc error:");
*s->base++ = 0;//棧底為0
s->top = s->base;
s->size = INITSIZE;
}
void push(stack* s, int e)
{
if(s->top - s->base >= INITSIZE)
{
s->base = (int*)realloc(s->base,(s->size+STACKINCRESMENT)*sizeof(stack));
s->top = s->base + s->size;
s->size += STACKINCRESMENT;
}
*s->top++ = e;
}
int pop(stack* s)
{
if(s->top == s->base) printf("error\n");
int e = 0;
e = *--s->top;
*s->top = NULL;
return e;
}
int getop(stack* s)
{
if(s->top == s->base) printf("error\n");
int e = 0;
stack *p = s;
e = *(--p->top);
++p->top;
return e;
}
int palace(stack* s, mi p[10][10])
{
int i=1;
int j=1;
int k;
int r;
push(s,i*10+j);
j++;
do
{
r=getop(s);
if(r==88) return 0;
if(p[i][j].val>0 && p[i][j].di<1)
{
push(s,i*10+j);
p[i][j].tag = 1;
p[i][j].di = 1;
j++;
}
else
{
k = getop(s);
i = k/10;
j = k%10;
if(p[i][j].di==1 && (p[i][j].val>0))
{
p[i][j].di++;
i++;
}
if(p[i][j].di==2 && (p[i][j].val>0))
{
p[i][j].di++;
j--;
if(p[i][j].di>0) { k = pop(s);}
}
}
}while(1);
}
❻ 誰能解釋一下回溯演算法
回溯演算法也叫試探法,它是一種系統地搜索問題的解的方法。回溯演算法的基本思想是:從一條路往前走,能進則進,不能進則退回來,換一條路再試。
初識回溯演算法是在解決8皇後問題時候,第一步按照順序放一個皇後,然後第二步符合要求放第2個皇後,如果沒有符合位置符合要求,那麼就要改變第一個皇後的位置,重新放第2個皇後的位置,直到找到符合條件的位置就可以了
回溯在迷宮搜索中使用很常見,就是這條路走不通,然後返回前一個路口,繼續下一條路。
❼ c++迷宮回溯演算法問題 為什麼一地次執行if(ok!=1) mase[x][y]=0;這條語句後沒有返回main函數
你這個是遞歸演算法啊,當它第一次運行完後,肯定是返回上一次遞歸進來的地方啦
❽ 請問什麼是回溯演算法
回溯(backtracking)是一種系統地搜索問題解答的方法。為了實現回溯,首先需要為問題定義一個解空間(solution space),這個空間必須至少包含問題的一個解(可能是最優的)。
下一步是組織解空間以便它能被容易地搜索。典型的組織方法是圖(迷宮問題)或樹(N皇後問題)。
一旦定義了解空間的組織方法,這個空間即可按深度優先的方法從開始節點進行搜索。
回溯方法的步驟如下:
1) 定義一個解空間,它包含問題的解。
2) 用適於搜索的方式組織該空間。
3) 用深度優先法搜索該空間,利用限界函數避免移動到不可能產生解的子空間。
回溯演算法的一個有趣的特性是在搜索執行的同時產生解空間。在搜索期間的任何時刻,僅保留從開始節點到當前節點的路徑。因此,回溯演算法的空間需求為O(從開始節點起最長路徑的長度)。這個特性非常重要,因為解空間的大小通常是最長路徑長度的指數或階乘。所以如果要存儲全部解空間的話,再多的空間也不夠用。
❾ 求走迷宮問題的演算法,要求用非遞歸回溯的方法寫
public class MyMaze { private class Point { //自定義數組下標記錄類型 int x = 0;
int y = 0; public Point() {
this(0, 0);
} public Point(int x, int y) {
this.x = x;
this.y = y;
} public boolean equals(Point p) {
return (x == p.x) && (y == p.y);
} @Override
public String toString() {
return "(" + x + "," + y + ")";
}
} private int[][] maze = null; //迷宮圖
private java.util.Stack<Point> stack = new java.util.Stack<Point>();
//保存路徑的棧 public MyMaze(int[][] maze) {
this.maze = maze;
} public void go() {
Point out = new Point(maze.length-1, maze[0].length-1); //出口
Point in = new Point(0,0); //入口
Point curNode = in; //當前點為入口
Point nextNode = null; //下一個訪問點(目標點) while(!curNode.equals(out)) {
nextNode = new Point(curNode.x,curNode.y); //設置目標點為當前點,便於下面偏移
if((curNode.x+1)<maze.length&&maze[curNode.x+1][curNode.y]==0) { //如果下方是空的,則目標點向下偏移
nextNode.x++;
} else if((curNode.y+1)<maze[0].length&&maze[curNode.x][curNode.y+1]==0) { //如果右邊是空的,則目標點向右偏移
nextNode.y++;
} else if((curNode.x-1)>=0&&maze[curNode.x-1][curNode.y]==0) { //如果上方是空的,則目標點向上偏移
nextNode.x--;
} else if((curNode.y-1)>=0&&maze[curNode.x][curNode.y-1]==0) { //如果左邊是空的,則目標點向左偏移
nextNode.y--;
} else { //這里是沒有路的狀態
maze[curNode.x][curNode.y] = 3; //標記為死路
if(stack.isEmpty()) { //判斷棧是否為空
System.out.println("Non solution");
return;
}
curNode = stack.pop(); //彈出上一次的點
continue; //繼續循環
} //如果有路的話會執行到這里
stack.push(curNode); //當前點壓入棧中
maze[curNode.x][curNode.y] = 2; //標記為已走
curNode = nextNode; //移動當前點
} if(nextNode.equals(out)) {
stack.push(nextNode); //將出口點添加到當前路勁中
maze[nextNode.x][nextNode.y] = 2; //標記為已走
}
System.out.println("\n該迷宮的一條可行路勁為:");
System.out.println("\n"+stack);
} public static void main(String[] args) {
int[][] maze = {
{ 0, 0, 1, 0, 1, 0, 1, 0, 1, 0 },
{ 0, 0, 1, 1, 1, 0, 0, 0, 1, 0 },
{ 0, 1, 0, 0, 1, 0, 0, 0, 0, 1 },
{ 0, 0, 0, 0, 1, 0, 0, 0, 1, 1 },
{ 0, 0, 1, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 1, 0, 1, 0, 0, 1, 0, 0 },
{ 0, 1, 0, 0, 1, 0, 0, 1, 0, 1 },
{ 1, 0, 1, 0, 1, 1, 0, 1, 0, 0 }
};
new MyMaze(maze).go();
}
}
❿ 迷宮回溯
學c的路過,表示看不懂