1. 程式人生 > >A*尋路 -- 弗洛伊德(Floyd)演算法

A*尋路 -- 弗洛伊德(Floyd)演算法

轉:http://www.itweb2.com/article/system/317.htm

弗洛伊德(Floyd)演算法過程:
1、用D[v][w]記錄每一對頂點的最短距離。
2、依次掃描每一個點,並以其為基點再遍歷所有每一對頂點D[][]的值,看看是否可用過該基點讓這對頂點間的距離更小。
演算法理解:
最短距離有三種情況:
1、兩點的直達距離最短。(如下圖<v,x>)
2、兩點間只通過一箇中間點而距離最短。(圖<v,u>)
3、兩點間用通過兩各以上的頂點而距離最短。(圖<v,w>)

對於第一種情況:在初始化的時候就已經找出來了且以後也不會更改到。
對於第二種情況:弗洛伊德演算法的基本操作就是對於每一對頂點,遍歷所有其它頂點,看看可否通過這一個頂點讓這對頂點距離更短,也就是遍歷了圖中所有的三角形(演算法中對同一個三角形掃描了九次,原則上只用掃描三次即可,但要加入判斷,效率更低)。
對 於第三種情況:如下圖的五邊形,可先找一點(比如x,使<v,u>=2),就變成了四邊形問題,再找一點(比如y,使<u,w>=2),可變成三角形問題了(v,u,w),也就變成第二種情況了,由此對於n邊形也可以一步步轉化成四邊形三角形問題。(這裡面不用擔心哪個點要 先找哪個點要後找,因為找了任一個點都可以使其變成(n-1)邊形的問題)。


使用前

使用後

其本思路:

  1. 使用A*得出基本路徑
  2. 刪除路徑中方向相同的節點 比如 [0,1],[0,2],[0,3],[1,2] 可表現為 [0,1][0,3][1,2]
  3. 把餘下的節點做為轉角,代入flody演算法進行計算,最後得出最簡潔的方法。
Java程式碼  收藏程式碼
  1. package {  
  2.     /** 
  3.      * ... 
  4.      * @author sliz http://game-develop.net/blog/ 
  5.      */  
  6.     import flash.display.Bitmap;  
  7.     import flash.display.BitmapData;  
  8.     import flash.display.Sprite;  
  9.     import flash.display.StageAlign;  
  10.     import flash.display.StageScaleMode;  
  11.     import flash.events.Event;  
  12.     import flash.events.MouseEvent;  
  13.     import flash.geom.Point;  
  14.     import flash.geom.Rectangle;  
  15.     import flash.text.TextField;  
  16.     import flash.utils.getTimer;  
  17.     import sliz.miniui.Button;  
  18.     import sliz.miniui.Checkbox;  
  19.     import sliz.miniui.Label;  
  20.     import sliz.miniui.LabelInput;  
  21.     import sliz.miniui.layouts.BoxLayout;  
  22.     import sliz.miniui.Window;  
  23.     public class Game2 extends Sprite {  
  24.         private var _cellSize:int = 5;  
  25.         private var _grid:Grid;  
  26.         private var _player:Sprite;  
  27.         private var _index:int;  
  28.         private var _path:Array;  
  29.         private var tf:Label;  
  30.         private var astar:AStar;  
  31.         private var path:Sprite = new Sprite();  
  32.         private var image:Bitmap = new Bitmap(new BitmapData(11));  
  33.         private var imageWrapper:Sprite = new Sprite();  
  34.         public function Game2(){  
  35.             stage.align = StageAlign.TOP_LEFT;  
  36.             stage.scaleMode = StageScaleMode.NO_SCALE;  
  37.             addChild(imageWrapper);  
  38.             imageWrapper.addChild(image);  
  39.             makePlayer();  
  40.             var w:Window = new Window(this2020"tool");  
  41.             numCols = new LabelInput("numCols ""numCols");  
  42.             numCols.setValue("50");  
  43.             w.add(numCols);  
  44.             numRows = new LabelInput("numRows ""numRows");  
  45.             w.add(numRows);  
  46.             numRows.setValue("50");  
  47.             cellSize = new LabelInput("cellSize""cellSize");  
  48.             cellSize.setValue("10");  
  49.             w.add(cellSize);  
  50.             density = new LabelInput("density ""density");  
  51.             density.setValue("0.1");  
  52.             w.add(density);  
  53.             isEight = new Checkbox("是否8方向");  
  54.             isEight.setToggle(true);  
  55.             w.add(isEight);  
  56.             tf = new Label("info");  
  57.             w.add(tf);  
  58.             w.add(new sliz.miniui.Link("author sliz"));  
  59.             w.add(new sliz.miniui.Link("source""http://code.google.com/p/actionscriptiui/"));  
  60.             var btn:Button = new Button("新建"00null, newMap);  
  61.             w.add(btn, null0.8);  
  62.             w.setLayout(new BoxLayout(w, 15));  
  63.             w.doLayout();  
  64.             imageWrapper.addEventListener(MouseEvent.CLICK, onGridClick);  
  65.             addEventListener(Event.ENTER_FRAME, onEnterFrame);  
  66.             imageWrapper.addChild(path);  
  67.             makeGrid();  
  68.         }  
  69.         private function newMap(e:Event):void {  
  70.             makeGrid();  
  71.         }  
  72.         private function changeMode(e:Event):void {  
  73.         /*if (_grid.getType()==1) { 
  74.            _grid.calculateLinks(0); 
  75.            (e.currentTarget as Button).text = "  四方向  "; 
  76.            }else { 
  77.            _grid.calculateLinks(1); 
  78.            (e.currentTarget as Button).text = "  八方向  "; 
  79.          }*/  
  80.         }  
  81.         private function makePlayer():void {  
  82.             _player = new Sprite();  
  83.             _player.graphics.beginFill(0xff00ff);  
  84.             _player.graphics.drawCircle(002);  
  85.             _player.graphics.endFill();  
  86.             imageWrapper.addChild(_player);  
  87.         }  
  88.         private function makeGrid():void {  
  89.             var rows:int = int(numRows.getValue());  
  90.             var cols:int = int(numCols.getValue());  
  91.             _cellSize = int(cellSize.getValue());  
  92.             _grid = new Grid(cols, rows);  
  93.             for (var i:int = 0; i < rows * cols * Number(density.getValue()); i++){  
  94.                 _grid.setWalkable(Math.floor(Math.random() * cols), Math.floor(Math.random() * rows), false);  
  95.             }  
  96.             _grid.setWalkable(00true);  
  97.             _grid.setWalkable(cols / 2, rows / 2false);  
  98.             if (isEight.getToggle())  
  99.                 _grid.calculateLinks();  
  100.             else  
  101.                 _grid.calculateLinks(1);  
  102.             astar = new AStar(_grid);  
  103.             drawGrid();  
  104.             isClick = false;  
  105.             _player.x = 0;  
  106.             _player.y = 0;  
  107.             path.graphics.clear();  
  108.         }  
  109.         private function drawGrid():void {  
  110.             image.bitmapData = new BitmapData(_grid.numCols * _cellSize, _grid.numRows * _cellSize, false0xffffff);  
  111.             for (var i:int = 0; i < _grid.numCols; i++){  
  112.                 for (var j:int = 0; j < _grid.numRows; j++){  
  113.                     var node:Node = _grid.getNode(i, j);  
  114.                     if (!node.walkable){  
  115.                         image.bitmapData.fillRect(new Rectangle(i * _cellSize, j * _cellSize, _cellSize, _cellSize), getColor(node));  
  116.                     }  
  117.                 }  
  118.             }  
  119.         }  
  120.         private function getColor(node:Node):uint {  
  121.             if (!node.walkable)  
  122.                 return 0;  
  123.             if (node == _grid.startNode)  
  124.                 return 0xcccccc;  
  125.             if (node == _grid.endNode)  
  126.                 return 0xcccccc;  
  127.             return 0xffffff;  
  128.         }  
  129.         private function onGridClick(event:MouseEvent):void {  
  130.             var xpos:int = Math.floor(mouseX / _cellSize);  
  131.             var ypos:int = Math.floor(mouseY / _cellSize);  
  132.             xpos = Math.min(xpos, _grid.numCols - 1);  
  133.             ypos = Math.min(ypos, _grid.numRows - 1);  
  134.             _grid.setEndNode(xpos, ypos);  
  135.             xpos = Math.floor(_player.x / _cellSize);  
  136.             ypos = Math.floor(_player.y / _cellSize);  
  137.             _grid.setStartNode(xpos, ypos);  
  138.             findPath();  
  139.             //path.graphics.clear();  
  140.             //path.graphics.lineStyle(0, 0xff0000,0.5);  
  141.             //path.graphics.moveTo(_player.x, _player.y);  
  142.         }  
  143.         private function findPath():void {  
  144.             var time:int = getTimer();  
  145.             if (astar.findPath()){  
  146.                 _index = 0;  
  147.                 isClick = true;  
  148.                 astar.floyd();  
  149.                 _path = astar.floydPath;  
  150.                 time = getTimer() - time;  
  151.                 tf.text = time + "ms   length:" + astar.path.length;  
  152.                 trace(astar.floydPath);  
  153.                 path.graphics.clear();  
  154.                 for (var i:int = 0; i < astar.floydPath.length; i++){  
  155.                     var p:Node = astar.floydPath[i];  
  156.                     path.graphics.lineStyle(00xff0000);  
  157.                     path.graphics.drawCircle((p.x + 0.5) * _cellSize, (p.y + 0.5) * _cellSize, 2);  
  158.                     path.graphics.lineStyle(00xff00000.5);  
  159.                     path.graphics.moveTo(_player.x, _player.y);  
  160.                 }  
  161.             } else {  
  162.                 time = getTimer() - time;  
  163.                 tf.text = time + "ms 找不到";  
  164.             }  
  165.         }  
  166.         private var isClick:Boolean = false;  
  167.         private var numCols:LabelInput;  
  168.         private var numRows:LabelInput;  
  169.         private var cellSize:LabelInput;  
  170.         private var density:LabelInput;  
  171.         private var isEight:Checkbox;  
  172.         private function onEnterFrame(event:Event):void {  
  173.             if (!isClick){  
  174.                 return;  
  175.             }  
  176.             var targetX:Number = _path[_index].x * _cellSize + _cellSize / 2;  
  177.             var targetY:Number = _path[_index].y * _cellSize + _cellSize / 2;  
  178.             var dx:Number = targetX - _player.x;  
  179.             var dy:Number = targetY - _player.y;  
  180.             var dist:Number = Math.sqrt(dx * dx + dy * dy);  
  181.             if (dist < 1){  
  182. 相關推薦

    A* -- Floyd演算法

    轉:http://www.itweb2.com/article/system/317.htm弗洛伊德(Floyd)演算法過程:1、用D[v][w]記錄每一對頂點的最短距離。2、依次掃描每一個點,並以其為基點再遍歷所有每一對頂點D[][]的值,看看是否可用過該基點讓這對頂點間的距離更小。演算法理解:最短距離有三

    Floyd演算法求圖的最短路徑

    https://blog.csdn.net/jeffleo/article/details/53349825 弗洛伊德基本思想 弗洛伊德演算法作為求最短路徑的經典演算法,其演算法實現相比迪傑斯特拉等演算法是非常優雅的,可讀性和理解都非常好。 基本思想: 弗洛伊德演算法定義了兩個二維

    演算法:最短路徑之Floyd演算法

    #include<iostream>using namespace std;#define MAXEDGE 20#define MAXVEX 20#define INFINITY 65535typedef struct {     int vexs[MAXVEX];     int arc[MAX

    最短路徑算法

    creat github lib tab auth logs sca for maxsize 假設條件同上。。 整個算法最核心的,個人覺得就是一個公式: weight[a][b] = min{weight[a][b], weight[a][c]+weight[c][b]}

    數據結構圖---最短路徑算法

    直接 char getchar 更新 none typedef article truct 使用 一:定義 弗洛伊德算法是用來求所有頂點到所有頂點的時間復雜度。 雖然我們可以直接對每個頂點通過迪傑斯特拉算法求得所有的頂點到所有頂點的時間復雜度,時間復雜度為O(n*3)

    演算法7-16:最短路徑演算法模板

    題目描述 在帶權有向圖G中,求G中的任意一對頂點間的最短路徑問題,也是十分常見的一種問題。 解決這個問題的一個方法是執行n次迪傑斯特拉演算法,這樣就可以求出每一對頂點間的最短路徑,執行的時間複雜度為O(n3)。 而另一種演算法是由弗洛伊德提出的,時間複雜度同樣是O(n3),但

    一本通之信使算法

    ffffff () col include %d sin 情況 esp namespace 問題為信使到達所有點用的最小時間。 一個點的所有信使同時出發,這會使一個點產生n種情況,所以我們不能把每一個點拆開看。那我們從整體上看這個題,問的就是從①點到每個點的最小時間中最

    Codeup 問題 B: 演算法7-16:最短路徑演算法

    題目描述 在帶權有向圖G中,求G中的任意一對頂點間的最短路徑問題,也是十分常見的一種問題。 解決這個問題的一個方法是執行n次迪傑斯特拉演算法,這樣就可以求出每一對頂點間的最短路徑,執行的時間複雜度為O(n3)。 而另一種演算法是由弗洛伊德提出的,時間複雜度同樣是O(n3

    演算法7-16:最短路徑演算法

    題目描述 在帶權有向圖G中,求G中的任意一對頂點間的最短路徑問題,也是十分常見的一種問題。 解決這個問題的一個方法是執行n次迪傑斯特拉演算法,這樣就可以求出每一對頂點間的最短路徑,執行的時間複雜度為O(n3)。 而另一種演算法是由弗洛伊德提出的,時間複雜度同樣是O(n3

    codeup 問題 B: 演算法7-16:最短路徑演算法

                                     問題 B: 演算法7-16:弗洛伊德最短路徑演算法                                                                時間限制: 1 Sec  記憶

    A* -- 更加真實 的路徑

    轉自:http://bbs.9ria.com/thread-95620-1-1.html對於A*傳統尋路的結果不平滑的問題,我們討論了一種判斷兩點間是否存在障礙物的演算法,並在使用者點選滑鼠選擇了目的地後先判斷起終點間是否存在障礙物,若不存在,則路徑陣列中將只具有一個終點節點;否則進行A*尋路運算。大致過程可

    算法Floyd算法

    開始 如果 ++ lin 引入 true 斯坦福大學 ora 狀態 原博來自http://www.cnblogs.com/skywang12345/ 弗洛伊德算法介紹 和Dijkstra算法一樣,弗洛伊德(Floyd)算法也是一種用於尋找給定的加權圖中頂點間最短路徑的算法。

    算法Floyd-Warshall

    找不到 main 三個點 () div 轉會 init 就是 int 文章非原創,轉載的~~ 暑假,小哼準備去一些城市旅遊。有些城市之間有公路,有些城市之間則沒有,如下圖。為了節省經費以及方便計劃旅程,小哼希望在出發之前知道任意兩個城市之前的最短路程。

    Floyd-傻子也能看懂的算法

    五行 ont 繼續 floyd 如果 甚至有 16px main courier 暑假,小哼準備去一些城市旅遊。有些城市之間有公路,有些城市之間則沒有,如下圖。為了節省經費以及方便計劃旅程,小哼希望在出發之前知道任意兩個城市之前的最短路程。

    拓撲排序以及迪傑斯特拉演算法演算法的一些例子天勤資料結構

    拓撲排序核心演算法     在一個有向圖中找到一個拓撲排序的過程如下:     1)從一個有向圖中選擇一個沒有前驅(入度為0)的頂點輸出;     2)刪除1)中的頂點,並刪除從該頂點出發的全部邊;  

    最短路徑鄰接矩陣演算法

    #include<bits/stdc++.h> #define MaxInt 1e8 #define MVNum 100 #define OK 1 #define ERROR 0 using namespace std; typedef int VerTexType; typedef i

    關於需要記錄路徑的最短路

    弗洛伊德用來求單、多源最短路都很常見,然而有些題一定要記錄路徑,很煩,不會的又重新用暴力,爆零也很常見。 真是氣skr人。 其實,時間複雜的確實會比較高,但是也比暴力好,是O(n^3+ n^4)。 首先,還是要走一遍弗洛伊德,記錄最優解。這裡O(n^3);

    最短路徑 單源最短路徑Dijkstra迪傑斯特拉演算法 Floyd演算法

    兩個演算法的主要思想都是鬆弛,就是兩點間的距離通過第三點來變短 比如   1->3=10     1->2=2   2->3=5    這樣你就可以通過2號點把1,3兩點的距離縮短為7 Dijkstra演算法被稱為單源最短路,意思就是隻能計算某個點到

    資料結構篇:校園最短路徑導航二:演算法理解與應用

    求最短路徑最常用的有迪傑斯特拉(Dijkstra)和弗洛伊德(Floyd)演算法兩種。本著簡潔為王道的信條,我選擇了Floyd演算法。 Floyd演算法 首先來看一個簡單圖,紅色標記代表在陣列的下標,橙色標記代表距離(邊權值) 我們用D[6][6]這個矩陣儲存兩點之間最短路徑,

    位元組跳動冬令營網路賽H-Accel World(最短路+圖DP)

    題目連結https://ac.nowcoder.com/acm/contest/296/H 題目描述 Chiaki was trapped in a strange place which can be regarded as a connected undirected graph with n ver