日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[迷宫中的算法实践]迷宫生成算法——Prim算法

發布時間:2024/4/15 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [迷宫中的算法实践]迷宫生成算法——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.

  • Start with a grid full of walls.
  • Pick a cell, mark it as part of the maze. Add the walls of the cell to the wall list.
  • While there are walls in the list:
  • Pick a random wall from the list. If the cell on the opposite side isn't in the maze yet:
  • Make the wall a passage and mark the cell on the opposite side as part of the maze.
  • Add the neighboring walls of the cell to the wall list.
  • Remove the wall from the list.
  • 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算法的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。