转: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)边形的问题)。
使用前
使用后
其本思路:
- 使用A*得出基本路径
- 删除路径中方向相同的节点 比如 [0,1],[0,2],[0,3],[1,2] 可表现为 [0,1][0,3][1,2]
- 把余下的节点做为转角,代入flody算法进行计算,最后得出最简洁的方法。
在用flody计算两两转角是否连通时,需要获得一直线上经过的格子。可参考:http://25swf.blogbus.com/logs/82350359.html
flody算法:参考 http://www.itweb2.com/article/system/317.htm
A*参考:http://eidiot.net/2007/04/17/a-star-pathfinding/
package {
/**
* ...
* @author sliz http://game-develop.net/blog/
*/
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.text.TextField;
import flash.utils.getTimer;
import sliz.miniui.Button;
import sliz.miniui.Checkbox;
import sliz.miniui.Label;
import sliz.miniui.LabelInput;
import sliz.miniui.layouts.BoxLayout;
import sliz.miniui.Window;
public class Game2 extends Sprite {
private var _cellSize:int = 5;
private var _grid:Grid;
private var _player:Sprite;
private var _index:int;
private var _path:Array;
private var tf:Label;
private var astar:AStar;
private var path:Sprite = new Sprite();
private var image:Bitmap = new Bitmap(new BitmapData(1, 1));
private var imageWrapper:Sprite = new Sprite();
public function Game2(){
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
addChild(imageWrapper);
imageWrapper.addChild(image);
makePlayer();
var w:Window = new Window(this, 20, 20, "tool");
numCols = new LabelInput("numCols ", "numCols");
numCols.setValue("50");
w.add(numCols);
numRows = new LabelInput("numRows ", "numRows");
w.add(numRows);
numRows.setValue("50");
cellSize = new LabelInput("cellSize", "cellSize");
cellSize.setValue("10");
w.add(cellSize);
density = new LabelInput("density ", "density");
density.setValue("0.1");
w.add(density);
isEight = new Checkbox("是否8方向");
isEight.setToggle(true);
w.add(isEight);
tf = new Label("info");
w.add(tf);
w.add(new sliz.miniui.Link("author sliz"));
w.add(new sliz.miniui.Link("source", "http://code.google.com/p/actionscriptiui/"));
var btn:Button = new Button("新建", 0, 0, null, newMap);
w.add(btn, null, 0.8);
w.setLayout(new BoxLayout(w, 1, 5));
w.doLayout();
imageWrapper.addEventListener(MouseEvent.CLICK, on