[迷宫中的算法实践]迷宫生成算法——Prim算法
?????? 普里姆算法(Prim算法),圖論中的一種算法,可在加權(quán)連通圖里搜索最小生成樹(shù)。意即由此算法搜索到的邊子集所構(gòu)成的樹(shù)中,不但包括了連通圖里的所有頂點(diǎn)(英語(yǔ):Vertex (graph theory)),且其所有邊的權(quán)值之和亦為最小。該算法于1930年由捷克數(shù)學(xué)家沃伊捷赫·亞爾尼克(英語(yǔ):Vojtěch Jarník)發(fā)現(xiàn);并在1957年由美國(guó)計(jì)算機(jī)科學(xué)家羅伯特·普里姆(英語(yǔ):Robert C. Prim)獨(dú)立發(fā)現(xiàn);1959年,艾茲格·迪科斯徹再次發(fā)現(xiàn)了該算法。因此,在某些場(chǎng)合,普里姆算法又被稱(chēng)為DJP算法、亞爾尼克算法或普里姆-亞爾尼克算法。
——來(lái)自百度百科
當(dāng)我們將Prim算法用于迷宮生成時(shí),情況有些不同,維基百科中給出了隨機(jī)Prim迷宮生成算法的解釋及實(shí)現(xiàn)過(guò)程:
Randomized Prim's algorithm
This algorithm is a randomized version of Prim's algorithm.
It will usually be relatively easy to find the way to the starting cell, but hard to find the way anywhere else.
Note that simply running classical Prim's on a graph with random edge weights would create mazes stylistically identical to Kruskal's, because they are both minimal spanning tree algorithms. Instead, this algorithm introduces stylistic variation because the edges closer to the starting point have a lower effective weight.
我們將算法實(shí)現(xiàn)部分翻譯成中文
?
?????? 簡(jiǎn)單研究算法實(shí)現(xiàn)過(guò)程我們可以發(fā)現(xiàn),Prim算法就是不斷地從所有可以是通路的位置中隨意選一個(gè)挖洞,直到?jīng)]有可能為通路的位置。
?????? 整個(gè)實(shí)現(xiàn)過(guò)程還是相當(dāng)于隨意為路線附權(quán)值的Prim算法。
?
下面我們來(lái)做C#下的代碼實(shí)現(xiàn):
/// <summary> /// 普利姆迷宮生成法 /// </summary> /// <param name="startX">起始點(diǎn)X坐標(biāo)</param> /// <param name="startY">起始點(diǎn)Y坐標(biāo)</param> /// <param name="widthLimit">迷宮寬度</param> /// <param name="heightLimit">迷宮高度</param> /// <param name="haveBorder">迷宮是否含有墻</param> private int[,] Prim(int startX, int startY, int widthLimit, int heightLimit,bool haveBorder) {//block:不可通行 unBlock:可通行const int block = 0,unBlock = 1;var r=new Random();//迷宮尺寸合法化if (widthLimit < 1)widthLimit = 1;if (heightLimit < 1)heightLimit = 1;//迷宮起點(diǎn)合法化if (startX < 0 || startX >= widthLimit)startX = r.Next(0, widthLimit);if (startY < 0 || startY >= heightLimit)startY = r.Next(0, heightLimit);//減去邊框所占的格子if (!haveBorder){widthLimit--;heightLimit--;}//迷宮尺寸換算成帶墻尺寸widthLimit *= 2;heightLimit *= 2;//迷宮起點(diǎn)換算成帶墻起點(diǎn)startX *= 2;startY *= 2;if (haveBorder){startX++;startY++;}//產(chǎn)生空白迷宮var mazeMap = new int[widthLimit + 1, heightLimit + 1];for (int x = 0; x <= widthLimit; x++){//mazeMap.Add(new BitArray(heightLimit + 1));for (int y = 0; y <= heightLimit; y++){mazeMap[x, y] = block;}}//鄰墻列表var blockPos = new List<int>();//將起點(diǎn)作為目標(biāo)格int targetX = startX, targetY = startY;//將起點(diǎn)標(biāo)記為通路mazeMap[targetX, targetY] = unBlock;//記錄鄰墻if (targetY > 1){blockPos.AddRange(new int[] { targetX, targetY - 1, 0 });}if (targetX < widthLimit){blockPos.AddRange(new int[] { targetX + 1, targetY, 1 });}if (targetY < heightLimit){blockPos.AddRange(new int[] { targetX, targetY + 1, 2 });}if (targetX > 1){blockPos.AddRange(new int[] { targetX - 1, targetY, 3 });}while (blockPos.Count > 0){//隨機(jī)選一堵墻var blockIndex = r.Next(0, blockPos.Count / 3) * 3;//找到墻對(duì)面的墻if (blockPos[blockIndex + 2] == 0){targetX = blockPos[blockIndex];targetY = blockPos[blockIndex + 1] - 1;}else if (blockPos[blockIndex + 2] == 1){targetX = blockPos[blockIndex] + 1;targetY = blockPos[blockIndex + 1];}else if (blockPos[blockIndex + 2] == 2){targetX = blockPos[blockIndex];targetY = blockPos[blockIndex + 1] + 1;}else if (blockPos[blockIndex + 2] == 3){targetX = blockPos[blockIndex] - 1;targetY = blockPos[blockIndex + 1];}//如果目標(biāo)格未連通if (mazeMap[targetX, targetY] == block){//聯(lián)通目標(biāo)格mazeMap[blockPos[blockIndex], blockPos[blockIndex + 1]] = unBlock;mazeMap[targetX, targetY] = unBlock;//添加目標(biāo)格相鄰格if (targetY > 1 && mazeMap[targetX, targetY - 1] == block && mazeMap[targetX, targetY - 2] == block){blockPos.AddRange(new int[] { targetX, targetY - 1, 0 });}if (targetX < widthLimit && mazeMap[targetX + 1, targetY] == block && mazeMap[targetX + 2, targetY] == block){blockPos.AddRange(new int[] { targetX + 1, targetY, 1 });}if (targetY < heightLimit && mazeMap[targetX, targetY + 1] == block && mazeMap[targetX, targetY + 2] == block){blockPos.AddRange(new int[] { targetX, targetY + 1, 2 });}if (targetX > 1 && mazeMap[targetX - 1, targetY] == block && mazeMap[targetX - 1, targetY] == block){blockPos.AddRange(new int[] { targetX - 1, targetY, 3 });}}blockPos.RemoveRange(blockIndex, 3);}return mazeMap; }轉(zhuǎn)載于:https://www.cnblogs.com/WayneShao/p/5890379.html
總結(jié)
以上是生活随笔為你收集整理的[迷宫中的算法实践]迷宫生成算法——Prim算法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: react- native 入门
- 下一篇: 使用jedis实现Redis消息队列(M