zoukankan      html  css  js  c++  java
  • 算法之A星算法(寻路)

    1.启发式搜索:启发式搜索就是在状态空间中的搜索对每一个搜索的位置进行评估,得到最好的位置,再从这个位置进行搜索直到目标。这样可以省略大量无谓的搜索路径,提高了效率。在启发式搜索中,对位置的估价是十分重要的。采用了不同的估价可以有不同的效果。

      启发算法有: 蚁群算法遗传算法模拟退火算法等。

    2.估价算法:从当前节点移动到目标节点的预估损耗。

      预估算法有:曼哈顿(manhattan)等。

    3.算法特点:理论上时间是最优的,但空间增长是指数型的。

    4.java实现:上下左右移动

      1 package cn.liushaofeng.algorithm;
      2 
      3 import java.util.ArrayList;
      4 import java.util.List;
      5 
      6 /**
      7  * A Star Algorithm
      8  * @author liushaofeng
      9  * @date 2015-8-24 下午11:05:48
     10  * @version 1.0.0
     11  */
     12 public class AstarAlgorithm
     13 {
     14     private List<Node> openList = null;
     15     private List<Node> closeList = null;
     16     private int[][] map;
     17 
     18     /**
     19      * default constructor
     20      * @param map data map
     21      */
     22     public AstarAlgorithm(int[][] map)
     23     {
     24         this.map = map;
     25         this.openList = new ArrayList<Node>();
     26         this.closeList = new ArrayList<Node>();
     27     }
     28 
     29     /**
     30      * find path
     31      * @param srcNode source node
     32      * @param desNode destination node
     33      * @return node path
     34      */
     35     public Node findPath(Node srcNode, Node desNode)
     36     {
     37         init(srcNode);
     38         do
     39         {
     40             if (openList.isEmpty())
     41             {
     42                 break;
     43             }
     44 
     45             Node node = openList.get(0);
     46             List<Node> aroundPoint = getAroundPoint(srcNode, node, desNode);
     47             openList.addAll(aroundPoint);
     48             closeList.add(node);
     49             openList.remove(node);
     50 
     51         } while (!findDes(desNode));
     52 
     53         return findNodePath(desNode);
     54     }
     55 
     56     private Node findNodePath(Node desNode)
     57     {
     58         for (Node node : openList)
     59         {
     60             if (node.getX() == desNode.getX() && node.getY() == desNode.getY())
     61             {
     62                 return node;
     63             }
     64         }
     65         return null;
     66     }
     67 
     68     private boolean findDes(Node desNode)
     69     {
     70         for (Node node : openList)
     71         {
     72             if (node.getX() == desNode.getX() && node.getY() == desNode.getY())
     73             {
     74                 return true;
     75             }
     76         }
     77         return false;
     78     }
     79 
     80     private void init(Node srcNode)
     81     {
     82         openList.add(srcNode);
     83     }
     84 
     85     // top bottom left and right, four points
     86     private List<Node> getAroundPoint(Node srcNode, Node nextNode, Node desNode)
     87     {
     88         int x = srcNode.getX();
     89         int y = srcNode.getY();
     90 
     91         int[] xData = new int[2];
     92         int[] yData = new int[2];
     93         if (x - 1 >= 0)
     94         {
     95             xData[0] = x - 1;
     96         }
     97         if (x + 1 < map.length)
     98         {
     99             xData[1] = x + 1;
    100         }
    101 
    102         if (y - 1 >= 0)
    103         {
    104             yData[0] = y - 1;
    105         }
    106         if (y + 1 < map[0].length)
    107         {
    108             yData[1] = y + 1;
    109         }
    110 
    111         List<Node> tmpList = new ArrayList<Node>();
    112 
    113         for (int i : xData)
    114         {
    115             Node node = new Node(i, y, srcNode);
    116             if (!isObstacle(node) && !inClosetList(node))
    117             {
    118                 calcWeight(srcNode, node, desNode);
    119                 tmpList.add(node);
    120             }
    121         }
    122 
    123         for (int i : yData)
    124         {
    125             Node node = new Node(x, i, srcNode);
    126             if (!isObstacle(node) && !inClosetList(node))
    127             {
    128                 calcWeight(srcNode, node, desNode);
    129                 tmpList.add(node);
    130             }
    131         }
    132 
    133         return tmpList;
    134     }
    135 
    136     private void calcWeight(Node parentNode, Node node, Node desNode)
    137     {
    138         node.setG(parentNode.getG() + 10);
    139         int h = Math.abs(node.getX() - desNode.getX()) + Math.abs(node.getY() - desNode.getY());
    140         node.setWeight(node.getG() + h * 10);
    141     }
    142 
    143     private boolean inClosetList(Node nextNode)
    144     {
    145         for (Node node : closeList)
    146         {
    147             if (node.getX() == nextNode.getX() && node.getY() == nextNode.getY())
    148             {
    149                 return true;
    150             }
    151         }
    152         return false;
    153     }
    154 
    155     private boolean isObstacle(Node nextNode)
    156     {
    157         return map[nextNode.getX()][nextNode.getY()] == 1;
    158     }
    159 
    160     public static void main(String[] args)
    161     {
    162         int[][] map =
    163         {
    164         { 0, 0, 0, 0, 0, 0, 0 },
    165         { 0, 0, 0, 0, 0, 0, 0 },
    166         { 0, 0, 0, 1, 0, 0, 0 },
    167         { 0, 0, 0, 1, 0, 0, 0 },
    168         { 0, 0, 0, 1, 0, 0, 0 },
    169         { 0, 0, 0, 0, 0, 0, 0 },
    170         { 0, 0, 0, 0, 0, 0, 0 } };
    171 
    172         AstarAlgorithm astar = new AstarAlgorithm(map);
    173         Node pathNode = astar.findPath(new Node(3, 1, null), new Node(3, 5, null));
    174         System.out.println(pathNode == null ? "Can not find path!" : pathNode.toString());
    175     }
    176 }
    查看代码

    数据模型

      1 package cn.liushaofeng.algorithm;
      2 
      3 import java.util.ArrayList;
      4 import java.util.List;
      5 
      6 /**
      7  * Node
      8  * @author liushaofeng
      9  * @date 2015-8-24 下午09:48:53
     10  * @version 1.0.0
     11  */
     12 public class Node
     13 {
     14     private Node parentNode;
     15     private int x;
     16     private int y;
     17 
     18     private int weight;
     19     private int g;
     20 
     21     /**
     22      * default constructor
     23      * @param x x point
     24      * @param y y point
     25      * @param parentNode parent node
     26      */
     27     public Node(int x, int y, Node parentNode)
     28     {
     29         this.x = x;
     30         this.y = y;
     31         this.parentNode = parentNode;
     32     }
     33 
     34     public int getG()
     35     {
     36         return g;
     37     }
     38 
     39     public void setG(int g)
     40     {
     41         this.g = g;
     42     }
     43 
     44     public Node getParentNode()
     45     {
     46         return parentNode;
     47     }
     48 
     49     public void setParentNode(Node parentNode)
     50     {
     51         this.parentNode = parentNode;
     52     }
     53 
     54     public int getX()
     55     {
     56         return x;
     57     }
     58 
     59     public void setX(int x)
     60     {
     61         this.x = x;
     62     }
     63 
     64     public int getY()
     65     {
     66         return y;
     67     }
     68 
     69     public void setY(int y)
     70     {
     71         this.y = y;
     72     }
     73 
     74     public int getWeight()
     75     {
     76         return weight;
     77     }
     78 
     79     public void setWeight(int weight)
     80     {
     81         this.weight = weight;
     82     }
     83 
     84     @Override
     85     public String toString()
     86     {
     87         return getPath();
     88     }
     89 
     90     private String getPath()
     91     {
     92         List<Node> dataList = new ArrayList<Node>();
     93         Node node = this;
     94         while (node != null)
     95         {
     96             dataList.add(node);
     97             node = node.getParentNode();
     98         }
     99 
    100         StringBuffer sb = new StringBuffer();
    101         for (int i = dataList.size() - 1; i >= 0; i--)
    102         {
    103             if (i == 0)
    104             {
    105                 sb.append("(" + dataList.get(i).getX() + "," + dataList.get(i).getY() + ")");
    106             } else
    107             {
    108                 sb.append("(" + dataList.get(i).getX() + "," + dataList.get(i).getY() + ")->");
    109             }
    110         }
    111         return sb.toString();
    112     }
    113 }
    查看代码

     代码待调试。

  • 相关阅读:
    Java实现 蓝桥杯VIP 算法提高 排队打水问题
    Java实现 蓝桥杯VIP 算法提高 排队打水问题
    Java实现 蓝桥杯VIP 算法提高 排队打水问题
    Java实现 蓝桥杯VIP 算法提高 特殊的质数肋骨
    Java实现 蓝桥杯VIP 算法提高 特殊的质数肋骨
    Java实现 蓝桥杯VIP 算法提高 特殊的质数肋骨
    Java实现 蓝桥杯VIP 算法提高 特殊的质数肋骨
    现在使用控件, 更喜欢继承(覆盖控件已有的函数,很奇怪的一种使用方式)
    Controls 属性与继承 TShape 类的小练习(使用TShape可以解决很多图形问题)
    QT创建窗口程序、消息循环和WinMain函数(为主线程建立了一个QEventLoop,并执行exec函数)
  • 原文地址:https://www.cnblogs.com/liushaofeng89/p/4759115.html
Copyright © 2011-2022 走看看