[迷宫中的算法实践]迷宫生成算法——Prim算法
?????? 普里姆算法(Prim算法),圖論中的一種算法,可在加權連通圖里搜索最小生成樹。意即由此算法搜索到的邊子集所構成的樹中,不但包括了連通圖里的所有頂點(英語:Vertex (graph theory)),且其所有邊的權值之和亦為最小。該算法于1930年由捷克數學家沃伊捷赫·亞爾尼克(英語:Vojtěch Jarník)發現;并在1957年由美國計算機科學家羅伯特·普里姆(英語:Robert C. Prim)獨立發現;1959年,艾茲格·迪科斯徹再次發現了該算法。因此,在某些場合,普里姆算法又被稱為DJP算法、亞爾尼克算法或普里姆-亞爾尼克算法。
——來自百度百科
當我們將Prim算法用于迷宮生成時,情況有些不同,維基百科中給出了隨機Prim迷宮生成算法的解釋及實現過程:
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.
我們將算法實現部分翻譯成中文
?
?????? 簡單研究算法實現過程我們可以發現,Prim算法就是不斷地從所有可以是通路的位置中隨意選一個挖洞,直到沒有可能為通路的位置。
?????? 整個實現過程還是相當于隨意為路線附權值的Prim算法。
?
下面我們來做C#下的代碼實現:
/// <summary> /// 普利姆迷宮生成法 /// </summary> /// <param name="startX">起始點X坐標</param> /// <param name="startY">起始點Y坐標</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;//迷宮起點合法化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;//迷宮起點換算成帶墻起點startX *= 2;startY *= 2;if (haveBorder){startX++;startY++;}//產生空白迷宮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>();//將起點作為目標格int targetX = startX, targetY = startY;//將起點標記為通路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){//隨機選一堵墻var blockIndex = r.Next(0, blockPos.Count / 3) * 3;//找到墻對面的墻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];}//如果目標格未連通if (mazeMap[targetX, targetY] == block){//聯通目標格mazeMap[blockPos[blockIndex], blockPos[blockIndex + 1]] = unBlock;mazeMap[targetX, targetY] = unBlock;//添加目標格相鄰格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; }轉載于:https://www.cnblogs.com/WayneShao/p/5890379.html
總結
以上是生活随笔為你收集整理的[迷宫中的算法实践]迷宫生成算法——Prim算法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: react- native 入门
- 下一篇: MyBatis关联查询,表字段相同,re