赞
踩
广度优先搜索是—种依照“由近及远,按层展开”的策略进行的枚举算法,也意味着它需要遍历整个状态空间图,导致算法效率不高。给定一个问题的状态间表示,设计搜索算法时需要考虑以下两个事实
◆并不是所有的分支都包含可行解
◆并不是所有的分支都包含最优解
分支限界算法=广度优先搜索+剪枝策略
分支限界算法需要设计合适的剪枝策略,限制某些分支的扩展,尽量避免不必要的搜索。常用的剪枝策略包括两大类
1.约束函数剪枝:根据约束条件,状态空间图中的部分状态可能是不合法的。因此,在状态空间图中以不合法状态为根的分支不包含可行解,故其分支可以剪枝。
2.限界函数剪枝:这种策略一般应用于最优化问题。假设搜索算法当前访问的状态为S,且存在一个判定函数:它能判定以S为根的分支不包含最优解,因此该分支可以剪除而无需搜索
约束函数剪枝可以剪除状态空间图中的不可行解
限界函数剪枝用于剪除状态空间图中的可行但是非最优的解
借鉴:https://blog.csdn.net/qq_35649945/article/details/93056866
问题描述:
旅行家要旅行n个城市,已知各城市之间的路程。要求选定一条从驻地出发经过每个城市一次,最后回到驻地的路线,使总的路程最小。例如:从如图中的无向带权图G=(V,E)中的1号点出发,经过图中的每个点,并且不能重复,然后回到1号点,要求经过的路径长度是最短的(即求图中 路径 )。
算法思想:
定义解空间树后,对解空间进行搜索,需要先找到限界条件和约束条件
(1)约束条件:如果带权邻接矩阵maps[i][j]不为无穷,即<i,j>能走通,否则继续寻找能走通的路。队列不为空。
(2)限界条件:cl<bestw,cl初始值为0,bestw初始值为无穷。
cl表示当前已走过的路径长度。
搜索过程:
将满足条件(即上一层节点的路径长度+上层节点到扩展节点的长度<bestw)的节点加入队列,为了加快搜索速度,使用优先队列,优先队列中的优先级为已走过的路径长度cl,cl值越小,越优先。
- import java.util.Arrays;
- import java.util.Comparator;
- import java.util.PriorityQueue;
- import java.util.Scanner;
- class Node1{
- int cl; //已经走过的路径长度
- int id;//表示所在解空间树的第几层
- int x[]=new int[105];//存储路径
- public Node1(int cl,int id){
- this.cl=cl;
- this.id=id;
- }
- }
- public class Main {
- static final int MAX=105;
- static final int INF=(int)1e9;
- //优先队列存储,每次自动排序,cl小的优先处理
- static PriorityQueue<Node1> q=new PriorityQueue<Node1>(new Comparator<Node1>() {
- public int compare(Node1 o1, Node1 o2) {
- if(o1.cl>o2.cl) return 1;
- else return -1;
- }
- });
- static int g[][]=new int[MAX][MAX];
- static int bestw;//最短路径长度
- static int best[]=new int[MAX];//最短路径
- static int n,m;//n个点,m条边
- static void bfs(){
- Node1 node=new Node1(0,2);//初始经过的路径为0,起点1位于第树的第二层
- for(int i=1;i<=n;i++)
- node.x[i]=i;
- q.add(node);
- while(!q.isEmpty()){
- Node1 newnode=q.poll();
- int t=newnode.id;
- if(t==n){
- if(g[newnode.x[t-1]][newnode.x[n]]!=INF && g[newnode.x[n]][newnode.x[1]]!=INF){
- if(newnode.cl+g[newnode.x[t-1]][newnode.x[n]]+g[newnode.x[n]][newnode.x[1]]<bestw){
- bestw=newnode.cl+g[newnode.x[t-1]][newnode.x[n]]+g[newnode.x[n]][newnode.x[1]];
- for(int i=1;i<=n;i++){
- best[i]=newnode.x[i];
- }
- }
- }
- }
- if(newnode.cl>=bestw) continue;//约束条件 两点不可达
- //对当前节点进行扩展子节点
- for(int j=t;j<=n;j++){
- if(newnode.cl+g[newnode.x[t-1]][newnode.x[j]]<bestw){ //限界条件
- int c=newnode.cl+g[newnode.x[t-1]][newnode.x[j]];
- node=new Node1(c,t+1);
- for(int i=1;i<=n;i++){
- node.x[i]=newnode.x[i];
- }
- //通过交换实现路径节点更新
- int tmp=node.x[t];
- node.x[t]=node.x[j];
- node.x[j]=tmp;
- q.add(node);
- }
- }
- }
- }
- public static void main(String[] args) {
- Scanner scan=new Scanner(System.in);
- n=scan.nextInt();
- m=scan.nextInt();
- for(int i=0;i<n;i++){
- Arrays.fill(g[i], INF);
- }
- for(int i=0;i<m;i++){
- int a=scan.nextInt();
- int b=scan.nextInt();
- int c=scan.nextInt();
- g[a][b]=g[b][a]=c;
- }
- bestw=INF;//最短路径初始为0
- bfs();
- System.out.println("最短路径长度:"+bestw);
- for(int i=1;i<=n;i++){
- System.out.println(best[i]);
- }
- System.out.println(best[1]);
- }
- }
- //4 6
- //1 2 15
- //1 3 30
- //1 4 5
- //2 3 6
- //2 4 12
- //3 4 3
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。