最佳路径搜索算法1

算法,就是(结合各种数学知识)解决问题的有限步骤,可以表现为程序、流程图。

 

假设要寻找一条路径,从起点S,终点G。

有几个关键原则:

1. 路径的下一个节点,不能和以往节点相同,否则会造成死循环。

2. 所有“待选”,“待算”路径,放在一个列表中;

OK,现在可以假设,有基础数据,各个点的坐标:

struct Point {

  char ID;

  double x;

  double y;

}

各个可走路径的长度

struct distance

{

  char Id1;

  char id2;

  double lenght;

}

那么,我们想要的结果,是:

struct Path {

  List<int> Ids; //一个有序的节点集合


 

british museum算法

这个算法,说白了就是构造一颗树,没什么目的的构造,造到死胡同为止,最后看看那条包含S和G

要实现这个算法,需要两个列表,一个存放所有走到死胡同的路径R,一个存放还没走到死胡同的路径T。

被划去的路径,例如:在上一步演变到下一步中划去的。

算法开始:

1.  T:(S)   R:空

2.  T:(S,A),(S,B)  R:空

3.  T:(S,A,B),(S,A,D),(S,B)  R:空

4.  T:(S,A,B,C),(S,A,D),(S,B)  R:空

5.  T:(S,A,B,C,E)(S,A,D),(S,B)  R:空

6.  T:(S,A,D,G)(S,B)  R:(S,A,B,C,E)

7.  T:(S,B,A),(S,B,C)  R:(S,A,B,C,E),(S,A,D,G)

8.  T:(S,B,A,D),(S,B,C)  R:(S,A,B,C,E),(S,A,D,G)

9.  T:(S,B,A,D,G)(S,B,C)  R:(S,A,B,C,E),(S,A,D,G)

10.  T:(S,B,C,E)  R:(S,A,B,C,E),(S,A,D,G),(S,B,A,D,G)

11.  T:空  R:(S,A,B,C,E),(S,A,D,G),(S,B,A,D,G),(S,B,C,E)

12. 看看R中那条路径含有S和G,S到G的距离那条最短即可。

伪代码:

while(T.Count > 0)

{

  if ( T[0]的最后一个节点不是G && 能T[0]的下一个节点 的数目n > 0  )

    复制n个T[0],然后分别往后边添加可添加的节点; 

    移除T的第0个元素;

    将新的n个队列插入到T的前面;

  else

    将T的第0个元素放进R;

    移除T的第0个元素;

}


 

deepth first(深度优先)算法

和british museum算法不同的地方是:1. 不需要结果列表;2. 发现目标马上停下来;3. 有回溯

缺点:不能总是发现最优路径

1.  T:(S)   

2.  T:(S,A),(S,B)   

3.  T:(S,A,B),(S,A,D),(S,B)   

4.  T:(S,A,B,C),(S,A,D),(S,B)   

5.  T:(S,A,B,C,E)(S,A,D),(S,B)   

6.  T:(S,A,D,G),(S,B) 

伪代码:

while(T.Count>0)

{

    if ( 能T[0]的下一个节点 的数目n > 0  )

        if (能加在T[0]后的节点有G)

          返回T[0] + G的路径

        else

          复制n个T[0],然后分别往后边添加可添加的节点;

          移除T的第0个元素

          将新的n个队列插入到T的前面(这个是算法最要特点)

    else

      移除T的第0个元素

}

 


 breadth first(广度优先)算法

和british museum算法不同的地方是:1. 实现上将扩展后的路径,放到列表后边;2. 没回溯

比深度优先的优点是,更早发现路径的路线,虽然本例子是同一个,但难保“右”边出现G比较快。

缺点:较“浅”的不一定是路径最短的。

1.  T:(S)   

2.  T:(S,A),(S,B)   

3.  T:(S,B),(S,A,B),(S,A,D)   

4.  T:(S,A,B),(S,A,D),(S,B,A), (S,B,C)

5.  T:(S,A,D),(S,B,A), (S,B,C),(S,A,B,C)

6.  T:(S,B,A), (S,B,C),(S,A,B,C),(S,A,D,G)

 


breadth first(广度优先)算法的优化

以上,无论哪个算法,都会对同一节点考虑多次,例如:

那么,优化的地方是,考虑过的节点不再考虑,变为:

1.  T:(S)   

2.  T:(S,A),(S,B)   

3.  T:(S,B),(S,A,D)   

4.  T:(S,A,D), (S,B,C)

5.  T:(S,B,C),(S,A,D,G) 

在实现上,对比广度算法,只需要在添加到列表后边前,去除部分不再考虑的节点。


hill climing算法:在深度优先的基础上改进

有不断扩展节点,回溯,使用启发信息的特点

特点:在深度优先的基础上,只考虑离目标直线距离最近的节点。

区别: 在将新的路线插入队列前,先根据离目标的距离,按升序排列。

缺点:这种是一种比较“短视”的算法。

优点:如果路网太复杂的话,效果可能更好

 

 

1.  T:(S)   

2.  T:(S,B),(S,A)          (这里发生了排序)

3.  T:(S,B,C),(S,B,A),(S,A)  (这里发生了排序)

4.  T:(S,B,C,E)(S,B,A),(S,A)   

5.  T:(S,B,A,D),(S,A)  

6.  T:(S,B,A,D,G),(S,A) 

 


 

束搜索:广度优先的改良,使用“知情启发信息”

区别:1. 在广度优先中,限制每一层中考虑的路径数量w;2.  节点重复的不考虑;3. 将距离教小的值放到队列前面

关键:设置好w值

 

1.  T:(S)   

2.  T:(S,B) ,(S,A)  //B点比A点近

3.  T:(S,A),(S,B,C)   

4.  T:(S,B,C),(S,A,D)

5.  T:(S,A,D)(S,B,C,E)

6.  T:(S,A,D,G) 

 

伪代码:

while(T.Count>0)

{

    if ( 能T[0]的下一个节点 的数目n > 0  )

        if (能加在T[0]后的节点有G)

          返回T[0] + G的路径;

        else

          移除n个节点中,在路径已经出现过节点          

          复制 ≤ n个T[0],然后分别往后边添加可添加的节点;

          移除T的第0个元素;

          对 ≤ n个T[0]延伸路径,根据最后一个节点对G点的距离,按升序排列,并取前w个T[0]的延伸路径;(这个是算法主要特点)

          将新w个T[0]的延伸路径插入到T的后面(这个是算法主要特点)

    else

      移除T的第0个元素

}


搜索办法回溯         节点扩展   使用启发式信息扩展路径插入方式
british museumfalsefalsefalse 
深度优先(deepth first)truetruefalse
广度优先(breath first)falsetruefalse
爬山算法(hill climing)truetruetrue
束搜素falsefalsetrue

 

*节点扩展,在实现上,将新的扩展路径加入到队列的前面;思想上,是否对新的扩展路径“一路走到黑”

*回溯,在实现上,将新的扩展路径加入到队列的前面;新的路径走到死胡同后,及时丢弃;

*启发式信息,是否使用坐标值来优化

转载于:https://www.cnblogs.com/pylblog/p/10287740.html

最佳路径优先搜索算法,也称为Dijkstra算法,是一种用于在加权图中找到最短路径的算法。它通过计算从起始节点到所有其他节点的最短路径来工作。 以下是最佳路径优先搜索算法的Java实现: ```java import java.util.*; public class DijkstraAlgorithm { private static final int INF = Integer.MAX_VALUE; public static void dijkstra(int[][] graph, int start) { int n = graph.length; int[] dist = new int[n]; boolean[] visited = new boolean[n]; Arrays.fill(dist, INF); dist[start] = 0; for (int i = 0; i < n - 1; i++) { int minDist = INF; int minIndex = -1; for (int j = 0; j < n; j++) { if (!visited[j] && dist[j] < minDist) { minDist = dist[j]; minIndex = j; } } visited[minIndex] = true; for (int j = 0; j < n; j++) { if (!visited[j] && graph[minIndex][j] != 0 && dist[minIndex] != INF && dist[minIndex] + graph[minIndex][j] < dist[j]) { dist[j] = dist[minIndex] + graph[minIndex][j]; } } } // 打印最短路径 System.out.println("节点\t最短距离"); for (int i = 0; i < n; i++) { System.out.println(i + "\t\t" + dist[i]); } } public static void main(String[] args) { int[][] graph = { {0, 4, 0, 0, 0, 0, 0, 8, 0}, {4, 0, 8, 0, 0, 0, 0, 11, 0}, {0, 8, 0, 7, 0, 4, 0, 0, 2}, {0, 0, 7, 0, 9, 14, 0, 0, 0}, {0, 0, 0, 9, 0, 10, 0, 0, 0}, {0, 0, 4, 14, 10, 0, 2, 0, 0}, {0, 0, 0, 0, 0, 2, 0, 1, 6}, {8, 11, 0, 0, 0, 0, 1, 0, 7}, {0, 0, 2, 0, 0, 0, 6, 7, 0} }; dijkstra(graph, 0); } } ``` 这段代码实现了Dijkstra算法,通过传入一个加权图和起始节点,计算出从起始节点到其他节点的最短路径,并打印出最短距离。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值