国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

AStar尋路算法

這篇具有很好參考價值的文章主要介紹了AStar尋路算法。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

概述

AStar算法是一種圖形搜索算法,常用于尋路。他是以廣度優(yōu)先搜索為基礎(chǔ),集Dijkstra算法和最佳優(yōu)先(best fit)于一身的一種算法。

示例1:4向
astar算法,算法,算法

示例2:8向
astar算法,算法,算法

思路

astar算法,算法,算法
遞歸的通過估值函數(shù)找到最佳路徑,估值函數(shù)與距離相關(guān),也有可能與通過代價系數(shù)相關(guān)(例如平地系數(shù)為1,坡地系數(shù)為2),有三個參數(shù):文章來源地址http://www.zghlxwxcb.cn/news/detail-601263.html

  • G:起點點到當前點的代價
  • H: 當前點到終點的代價
  • F: F = G + H 與最佳路徑權(quán)重負相關(guān)的參數(shù)
    過程大概:
    astar算法,算法,算法

代碼示例

位置定義

public struct Vec2
{
    public int x;
    public int y;

    public Vec2(int x, int y)
    {
        this.x = x;
        this.y = y;
    }

    public static Vec2 Zero
    {
        get
        {
            return new Vec2(0, 0);
        }
    }

    public override bool Equals(object obj)
    {
        if (!(obj is Vec2))
            return false;

        var o = (Vec2)obj;
        return x == o.x && y == o.y;
    }

    public override int GetHashCode()
    {
        return x.GetHashCode() + y.GetHashCode();
    }

    public static Vec2 operator +(Vec2 a, Vec2 b)
    {
        return new Vec2(a.x + b.x, a.y + b.y);
    }

    public static Vec2 operator *(Vec2 a, int n)
    {
        return new Vec2(a.x * n, a.y * n);
    }

    public static Vec2 operator *(int n, Vec2 a)
    {
        return new Vec2(a.x * n, a.y * n);
    }

    public static bool operator ==(Vec2 a, Vec2 b)
    {
        return a.x == b.x && a.y == b.y;
    }

    public static bool operator !=(Vec2 a, Vec2 b)
    {
        return !(a.x == b.x && a.y == b.y);
    }
}

方向定義

public enum EDir
{
    Up = 0,
    Down = 1,
    Left = 2,
    Right = 3,
    UpLeft = 4,
    UpRight = 5,
    DownLeft = 6,
    DownRight = 7,
}

public abstract class CheckDirPol
{
    abstract public Dictionary<EDir, Vec2> GetDir();
}

public class CheckDir4Pol : CheckDirPol
{
    private Dictionary<EDir, Vec2> dirDict = new Dictionary<EDir, Vec2>
    {
        {EDir.Up, new Vec2(0, 1) },
        {EDir.Down, new Vec2(0, -1) },
        {EDir.Left, new Vec2(-1, 0) },
        {EDir.Right, new Vec2(1, 0) },
    };
    override public Dictionary<EDir, Vec2> GetDir()
    {
        return dirDict;
    }
}

public class CheckDir8Pol : CheckDirPol
{
    private Dictionary<EDir, Vec2> dirDict = new Dictionary<EDir, Vec2>
    {
        {EDir.Up, new Vec2(0, 1) },
        {EDir.Down, new Vec2(0, -1) },
        {EDir.Left, new Vec2(-1, 0) },
        {EDir.Right, new Vec2(1, 0) },
        {EDir.UpLeft, new Vec2(-1, 1) },
        {EDir.UpRight, new Vec2(1, 1) },
        {EDir.DownLeft, new Vec2(-1, -1) },
        {EDir.DownRight, new Vec2(1, -1) },

    };
    override public Dictionary<EDir, Vec2> GetDir()
    {
        return dirDict;
    }
}
  • 運用策略模式的技巧,以實現(xiàn)4向,8向搜索切換

估值函數(shù)

public abstract class EvaPol
{
	abstract public float Calc(Vec2 a, Vec2 b);
}

public class MANEvaPol : EvaPol
{
    override public float Calc(Vec2 a, Vec2 b)
    {
        return Mathf.Abs(a.x - b.x) + Mathf.Abs(a.y - b.y);
    }
}
  • 直接使用曼哈頓距離作為代價

節(jié)點定義

public class Node
{
    public int id;
    public Vec2 pos;
    public float g;
    public float h;
    public float f;
    public Vec2 prePos;
    public bool hasPrePos;

    public Node(Vec2 pos)
    {
        this.pos = pos;
    }

    public void SetPrePos(Vec2 pos)
    {
        prePos = pos;
        hasPrePos = true;
    }
}

算法上下文定義

Context context;
EvaPol disPol;
CheckDirPol checkDirPol;

public struct Context
{
    public Vec2 end;
    public Vec2 start;
    public Node[,] nodes;
    public List<Node> open;
    public List<Node> close;
    public int[,] map;
    public List<Vec2> result;
    public Vec2 size;
}

尋路算法

初始化

public void Init(Vec2 start, Vec2 end, int[,] map)
{
	var x = map.GetLength(0);
	var y = map.GetLength(1);
	context = new Context()
	{
		start = start,
		end = end,
		open = new List<Node>(),
		close = new List<Node>(),
		map = map,
		result = new List<Vec2>(),
		size = new Vec2(x, y),
	};

	context.nodes = new Node[x, y];
	for (int i = 0; i < x; i++)
		for (int j = 0; j < x; j++)
			context.nodes[i, j] = new Node(new Vec2(i, j));

	disPol = new MANEvaPol();
	//checkDirPol = new CheckDir4Pol();
	checkDirPol = new CheckDir8Pol();
}

獲取路徑

public List<Vec2> GetResult()
{
	return context.result;
}

尋路

尋路入口
public void FindPath()
{
	var s = context.start;
	var sn = context.nodes[s.x, s.y];
	sn.g = 0;
	sn.h = disPol.Calc(s, context.end);
	sn.f = sn.g + sn.h;
	context.open.Add(sn);

	FindArrangement(sn);
}
遞歸函數(shù)
void FindArrangement(Node node)
{
	context.close.Add(node);
	context.open.Remove(node);

	if (node.pos == context.end)
	{
		SetResult(node);
		return;
	}

	CheckRound(node);
	if (context.open.Count == 0)
		return;

	Node next = context.open[0];
	for (int i = 1; i < context.open.Count; i++)
		if (context.open[i].f < next.f)
			next = context.open[i];

	FindArrangement(next);
}
檢查周圍節(jié)點
void CheckRound(Node node)
{
	var dirDict = checkDirPol.GetDir();
	foreach (var pair in dirDict)
	{
		var dir = node.pos + pair.Value;

		if (IsBlock(dir))
			continue;
		var dn = context.nodes[dir.x, dir.y];

		if (context.close.Contains(dn))
			continue;

		if (context.open.Contains(dn))
			TryOverridePath(node, dn);
		else
		{
			dn.g = disPol.Calc(dn.pos, context.start);
			dn.h = disPol.Calc(dn.pos, context.end);
			dn.f = dn.g + dn.h;
			dn.SetPrePos(node.pos);
			context.open.Add(dn);
		}
	}
}

// 若是從鄰節(jié)點到該節(jié)點路徑更優(yōu),則替換更新
void TryOverridePath(Node a, Node b)
{
	var g = a.g + disPol.Calc(a.pos, b.pos);
	if (g < b.g)
	{
		b.g = g;
		b.SetPrePos(a.pos);
	}
}

bool IsBlock(Vec2 pos)
{
	return !InMap(pos) || context.map[pos.x, pos.y] == 1;
}

bool InMap(Vec2 pos)
{
	var x = pos.x;
	var y = pos.y;
	var size = context.size;
	return x >= 0 && x < size.x && y >= 0 && y < size.y;
}
生成路徑
void SetResult(Node node)
{
	Queue<Node> q = new Queue<Node>();
	while(node.hasPrePos)
	{
		q.Enqueue(node);
		node = context.nodes[node.prePos.x, node.prePos.y];
	}
	while(q.Count > 0)
	{
		context.result.Add(q.Dequeue().pos);
	}
}

完整代碼

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public struct Vec2
{
    public int x;
    public int y;

    public Vec2(int x, int y)
    {
        this.x = x;
        this.y = y;
    }

    public static Vec2 Zero
    {
        get
        {
            return new Vec2(0, 0);
        }
    }

    public override bool Equals(object obj)
    {
        if (!(obj is Vec2))
            return false;

        var o = (Vec2)obj;
        return x == o.x && y == o.y;
    }

    public override int GetHashCode()
    {
        return x.GetHashCode() + y.GetHashCode();
    }

    public static Vec2 operator +(Vec2 a, Vec2 b)
    {
        return new Vec2(a.x + b.x, a.y + b.y);
    }

    public static Vec2 operator *(Vec2 a, int n)
    {
        return new Vec2(a.x * n, a.y * n);
    }

    public static Vec2 operator *(int n, Vec2 a)
    {
        return new Vec2(a.x * n, a.y * n);
    }

    public static bool operator ==(Vec2 a, Vec2 b)
    {
        return a.x == b.x && a.y == b.y;
    }

    public static bool operator !=(Vec2 a, Vec2 b)
    {
        return !(a.x == b.x && a.y == b.y);
    }
}

public enum EDir
{
    Up = 0,
    Down = 1,
    Left = 2,
    Right = 3,
    UpLeft = 4,
    UpRight = 5,
    DownLeft = 6,
    DownRight = 7,
}

public class AstarFindPath
{
    public class Node
    {
        public int id;
        public Vec2 pos;
        public float g;
        public float h;
        public float f;
        public Vec2 prePos;
        public bool hasPrePos;

        public Node(Vec2 pos)
        {
            this.pos = pos;
        }

        public void SetPrePos(Vec2 pos)
        {
            prePos = pos;
            hasPrePos = true;
        }
    }

    public abstract class EvaPol
    {
        abstract public float Calc(Vec2 a, Vec2 b);
    }

    public class MANEvaPol : EvaPol
    {
        override public float Calc(Vec2 a, Vec2 b)
        {
            return Mathf.Abs(a.x - b.x) + Mathf.Abs(a.y - b.y);
        }
    }

    public abstract class CheckDirPol
    {
        abstract public Dictionary<EDir, Vec2> GetDir();
    }

    public class CheckDir4Pol : CheckDirPol
    {
        private Dictionary<EDir, Vec2> dirDict = new Dictionary<EDir, Vec2>
        {
            {EDir.Up, new Vec2(0, 1) },
            {EDir.Down, new Vec2(0, -1) },
            {EDir.Left, new Vec2(-1, 0) },
            {EDir.Right, new Vec2(1, 0) },
        };
        override public Dictionary<EDir, Vec2> GetDir()
        {
            return dirDict;
        }
    }

    public class CheckDir8Pol : CheckDirPol
    {
        private Dictionary<EDir, Vec2> dirDict = new Dictionary<EDir, Vec2>
        {
            {EDir.Up, new Vec2(0, 1) },
            {EDir.Down, new Vec2(0, -1) },
            {EDir.Left, new Vec2(-1, 0) },
            {EDir.Right, new Vec2(1, 0) },
            {EDir.UpLeft, new Vec2(-1, 1) },
            {EDir.UpRight, new Vec2(1, 1) },
            {EDir.DownLeft, new Vec2(-1, -1) },
            {EDir.DownRight, new Vec2(1, -1) },

        };
        override public Dictionary<EDir, Vec2> GetDir()
        {
            return dirDict;
        }
    }

    public struct Context
    {
        public Vec2 end;
        public Vec2 start;
        public Node[,] nodes;
        public List<Node> open;
        public List<Node> close;
        public int[,] map;
        public List<Vec2> result;
        public Vec2 size;
    }

    Context context;
    EvaPol disPol;
    CheckDirPol checkDirPol;

    public void Init(Vec2 start, Vec2 end, int[,] map)
    {
        var x = map.GetLength(0);
        var y = map.GetLength(1);
        context = new Context()
        {
            start = start,
            end = end,
            open = new List<Node>(),
            close = new List<Node>(),
            map = map,
            result = new List<Vec2>(),
            size = new Vec2(x, y),
        };
        
        context.nodes = new Node[x, y];
        for (int i = 0; i < x; i++)
            for (int j = 0; j < x; j++)
                context.nodes[i, j] = new Node(new Vec2(i, j));

        disPol = new MANEvaPol();
        //checkDirPol = new CheckDir4Pol();
        checkDirPol = new CheckDir8Pol();
    }

    public void FindPath()
    {
        var s = context.start;
        var sn = context.nodes[s.x, s.y];
        sn.g = 0;
        sn.h = disPol.Calc(s, context.end);
        sn.f = sn.g + sn.h;
        context.open.Add(sn);
        
        FindArrangement(sn);
    }

    public List<Vec2> GetResult()
    {
        return context.result;
    }

    void FindArrangement(Node node)
    {
        context.close.Add(node);
        context.open.Remove(node);

        if (node.pos == context.end)
        {
            SetResult(node);
            return;
        }

        CheckRound(node);
        if (context.open.Count == 0)
            return;

        Node next = context.open[0];
        for (int i = 1; i < context.open.Count; i++)
            if (context.open[i].f < next.f)
                next = context.open[i];
        
        FindArrangement(next);
    }

    void SetResult(Node node)
    {
        Queue<Node> q = new Queue<Node>();
        while(node.hasPrePos)
        {
            q.Enqueue(node);
            node = context.nodes[node.prePos.x, node.prePos.y];
        }
        while(q.Count > 0)
        {
            context.result.Add(q.Dequeue().pos);
        }
    }

    void CheckRound(Node node)
    {
        var dirDict = checkDirPol.GetDir();
        foreach (var pair in dirDict)
        {
            var dir = node.pos + pair.Value;

            if (IsBlock(dir))
                continue;
            var dn = context.nodes[dir.x, dir.y];

            if (context.close.Contains(dn))
                continue;

            if (context.open.Contains(dn))
                TryOverridePath(node, dn);
            else
            {
                dn.g = disPol.Calc(dn.pos, context.start);
                dn.h = disPol.Calc(dn.pos, context.end);
                dn.f = dn.g + dn.h;
                dn.SetPrePos(node.pos);
                context.open.Add(dn);
            }
        }
    }

    void TryOverridePath(Node a, Node b)
    {
        var g = a.g + disPol.Calc(a.pos, b.pos);
        if (g < b.g)
        {
            b.g = g;
            b.SetPrePos(a.pos);
        }
    }

    bool IsBlock(Vec2 pos)
    {
        return !InMap(pos) || context.map[pos.x, pos.y] == 1;
    }

    bool InMap(Vec2 pos)
    {
        var x = pos.x;
        var y = pos.y;
        var size = context.size;
        return x >= 0 && x < size.x && y >= 0 && y < size.y;
    }
}

到了這里,關(guān)于AStar尋路算法的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務器費用

相關(guān)文章

  • Unity 中 A*尋路(AStar,A星)的優(yōu)化,二叉堆,雙向隊列,哈希表

    前篇:A星尋路的簡單實現(xiàn) A星尋路,在2D地圖下使用頻率較高 本篇基于上一篇文章實現(xiàn)的A星尋路進一步優(yōu)化。利用二叉堆代替了原先openList的數(shù)據(jù)結(jié)構(gòu), 改進了path返回時的操作,以及在搜索時的性能開銷。 c#中的Sort函數(shù),在實現(xiàn)方面采用的是快速排序。 在日常的使用上,好

    2024年02月03日
    瀏覽(19)
  • 自動駕駛路徑規(guī)劃——A*(Astar)算法

    自動駕駛路徑規(guī)劃——A*(Astar)算法

    ???? 最佳優(yōu)先搜索(BFS) ,又稱A算法,是一種啟發(fā)式搜索算法(Heuristic Algorithm)。[不是廣度優(yōu)先搜索算法( Breadth First Search , BFS )] ????BFS算法在廣度優(yōu)先搜索的基礎(chǔ)上, 用啟發(fā)估價函數(shù)對將要被遍歷到的點進行估價 ,然后選擇代價小的進行遍歷,直到找到目標節(jié)點

    2024年02月01日
    瀏覽(65)
  • 【ROS-Navigation】—— Astar路徑規(guī)劃算法解析

    【ROS-Navigation】—— Astar路徑規(guī)劃算法解析

    ????最近在學習ROS的navigation部分,寫些東西作為筆記,方便理解與日后查看。本文從Astar算法入手,對navigation源碼進行解析。 PS:ros navigation源碼版本https://gitcode.net/mirrors/ros-planning/navigation/-/tree/noetic-devel ????對于Astar算法,想必大家都非常熟悉了。具體算法原理就不

    2024年01月18日
    瀏覽(56)
  • 【Unity】一篇文章搞定AStar(A*)算法

    【Unity】一篇文章搞定AStar(A*)算法

    AStar(A*)算法,是一種在靜態(tài)網(wǎng)格中求解最短路徑直接有效的搜索方法。在游戲開發(fā)中,A*算法常應用于部分RPG游戲和策略戰(zhàn)棋類游戲。對于Unity開發(fā)者來說,掌握A*算法也是十分有必要的。不過在了解A*算法之前,有必要先回顧一下深度優(yōu)先算法(DFS)、廣度優(yōu)先算法(BFS)

    2024年02月02日
    瀏覽(20)
  • C#,人工智能,機器人,路徑規(guī)劃,A*(AStar Algorithm)算法、源代碼及計算數(shù)據(jù)可視化

    C#,人工智能,機器人,路徑規(guī)劃,A*(AStar Algorithm)算法、源代碼及計算數(shù)據(jù)可視化

    Peter Hart? Nils Nilsson? Bertram Raphael? 參考: C#,人工智能(AI)機器人路徑規(guī)劃(Path Planning)的ARA*(Anytime Replanning A* Algorithm)算法與源程序 https://blog.csdn.net/beijinghorn/article/details/125464754 A*算法最初由斯坦福研究院(Stanford Institute)的? Peter Hart,Nils Nilsson,Bertram Raphael? 發(fā)表于

    2024年01月18日
    瀏覽(35)
  • 算法修養(yǎng)--A*尋路算法

    算法修養(yǎng)--A*尋路算法

    廣度優(yōu)先算法搜索以廣度做為優(yōu)先級進行搜索。 從起點開始,首先遍歷起點周圍鄰近的點,然后再遍歷已經(jīng)遍歷過的點鄰近的點,逐步的向外擴散,直到找到終點。 這種算法就像洪水(Flood fill)一樣向外擴張。直至洪水將整張地圖都漫延。在訪問節(jié)點時候,每個點需要記錄

    2024年02月08日
    瀏覽(16)
  • A*尋路算法

    A*尋路算法

    深度優(yōu)先算法(BFS)在所有方向上平等的探索,是最好寫的尋路算法 Dijkstra算法優(yōu)先考慮低成本的路徑,在游戲中可以規(guī)定遠離敵人、避開森林需要更高的成本,所以當移動成本發(fā)生變化的時候我們使用該算法而不是BFS A*尋路是對Dijkstra算法的修改,針對單個目標時進行了優(yōu)

    2023年04月26日
    瀏覽(15)
  • Unity尋路A星算法

    Unity尋路A星算法

    在Unity中實現(xiàn)A星(A*,A-Star)算法是一種用于尋找兩點之間最短路徑的廣泛應用的技術(shù)。該算法結(jié)合了啟發(fā)式搜索與圖論中的Dijkstra算法,通過評估每個節(jié)點到起點和終點的成本來確定最優(yōu)路徑。 以下是Unity中使用A*尋路算法的一個簡要步驟和實例: 實現(xiàn)步驟概覽: 構(gòu)建網(wǎng)格

    2024年01月17日
    瀏覽(14)
  • 探索迷局:解密廣度尋路算法

    探索迷局:解密廣度尋路算法

    ================================ 專欄文章,自下而上 數(shù)據(jù)結(jié)構(gòu)與算法——二叉搜索樹 數(shù)據(jù)結(jié)構(gòu)與算法——深度尋路算法 數(shù)據(jù)結(jié)構(gòu)與算法——二叉樹+實現(xiàn)表達式樹 數(shù)據(jù)結(jié)構(gòu)與算法——樹(三指針描述一棵樹) 數(shù)據(jù)結(jié)構(gòu)與算法——棧和隊列<也不過如此> 數(shù)據(jù)結(jié)構(gòu)與算法——八大經(jīng)

    2024年02月06日
    瀏覽(17)
  • “ 探索迷局:解密廣度尋路算法 “

    “ 探索迷局:解密廣度尋路算法 “

    ================================ 專欄文章,自下而上 數(shù)據(jù)結(jié)構(gòu)與算法——二叉搜索樹 數(shù)據(jù)結(jié)構(gòu)與算法——深度尋路算法 數(shù)據(jù)結(jié)構(gòu)與算法——二叉樹+實現(xiàn)表達式樹 數(shù)據(jù)結(jié)構(gòu)與算法——樹(三指針描述一棵樹) 數(shù)據(jù)結(jié)構(gòu)與算法——棧和隊列<也不過如此> 數(shù)據(jù)結(jié)構(gòu)與算法——八大經(jīng)

    2024年02月04日
    瀏覽(14)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包