`
128kj
  • 浏览: 600207 次
  • 来自: ...
社区版块
存档分类
最新评论

广度优先搜索学习五例之三

阅读更多
   广度优先搜索是以某一节点为出发点,先拜访所有相邻的节点。 再依序拜访与刚才被拜访过的节点相邻但未曾被拜访过的节点,直到所有相邻的节点都已被拜访过。 因此,进行广搜 时,需要使用queue ,以便记录拜访的顺序。一般有下面的模板:
public  void bfs(int v) {
  //队列用来保存被访问节点的分支节点
  Queye< Integer> que = new LinkedList< Integer>();
  que.offer(v);//起点入队列
  while (!que.isEmpty()) {
    v = que.poll();//弹出当前顶点
    if(!visited[v]){//如果当前顶顶点没有被访问过
       System.out.print(v+"  ");//访问当前顶点
       visited[v] = true;//标记为已访问过
    }
     //将当前节点的分支节(邻接)点加入到队列中
      for (int i = 0; i < k; i++) {
       if (G[v][i] == 1 && !visited[i]) {
	que.add(i);
       }
      }
    }
 }


对照这个模板,很容易解答下面两题.

例一:
   国际象棋,又称欧洲象棋或西洋棋,是一种二人对弈的战略棋盘游戏。国际象棋的棋盘由64个黑白相间的格子组成。黑白棋子各16个,多用木或塑胶制成,也有用石块制作;较为精美的石头、玻璃(水晶)或金属制棋子常用作装饰摆设。国际象棋是世界上最受欢迎的游戏之一,数以亿计的人们以各种方式下国际象棋。
    其中有一棋子,称为knight,和中国象棋里的马的走法一样,每次走都是一个 “日” 型。给定起始位置和目标位置,计算knight从起始位置走到目标位置所需的最少步数。
To get from xx to yy takes n knight moves.
从一点xx到另一点yy需要多少步,至少需要多少步 ??


Sample Input

e2 e4
a1 b2
b2 c3
a1 h8
a1 h7
h8 a1
b1 c3
f6 f6

Sample Output

To get from e2 to e4 takes 2 knight moves.
To get from a1 to b2 takes 4 knight moves.
To get from b2 to c3 takes 2 knight moves.
To get from a1 to h8 takes 6 knight moves.
To get from a1 to h7 takes 5 knight moves.
To get from h8 to a1 takes 6 knight moves.
To get from b1 to c3 takes 1 knight moves.
To get from f6 to f6 takes 0 knight moves.


import java.util.*;
public class Main {
 //初始化马可以走的方向
 private int dis[][]={{1,2},{2,1},{2,-1},{1,-2}, {-1,-2},{-2,-1},{-2,1},{-1,2}};

 private int[][] chessboard ;//棋盘

 public Main() {
     chessboard = new int[8][8];
     for(int i=0;i<8;i++)
       Arrays.fill(chessboard[i],0);
 }


 private  int[] getRC(String s) {//用来处理输入,字符坐标转化为数字坐标
  int[] rc = new int[2];
  rc[0] = Integer.valueOf(String.valueOf(s.charAt(1))) - 1;
  rc[1] = s.charAt(0) - 'a';
  return rc;
 }

 /**
  * 广度搜索算法
  * 
  * @param s1
  * @param s2
  */
 public  void bsf(String s1, String s2) {//输出从s1到s2至少需要多少步
  int[] rc = getRC(s1);
  int formR = rc[0];
  int formC = rc[1];
   //System.out.println(formR + " ," + formC);
  rc = getRC(s2);
  int toR = rc[0];
  int toC = rc[1];
   //System.out.println(toR + " ," + toC);
  Queue< Point> queue = new LinkedList<Point>();

  Point p = new Point();
  p.r = formR;
  p.c = formC;
  p.steps = 0;
  queue.offer(p);//起点入队列
  chessboard[p.r][p.c] = 1;//标记为已访问
  p = null;

  while (!queue.isEmpty()) {//队列非空时
   p = queue.poll();//当前顶点
   if (p.r == toR && p.c == toC) {//如果搜索到目标,输入
    System.out.println("To get from " + s1 + " to " + s2
      + " takes " + p.steps + " knight moves.");
    break;
   }
   for (int i = 0; i < 8; ++i) {//从八个方向依次访问当前顶点的八个可能的邻接点
    Point pp = new Point();
    pp.r = p.r + dis[i][0];
    pp.c = p.c + dis[i][1];
    pp.steps = p.steps + 1;
    if (pp.r >= 0 && pp.c >= 0 && pp.r <= 7 && pp.c <= 7
      && chessboard[pp.r][pp.c] == 0) {//如果是当前顶点的邻接点
     queue.offer(pp);//邻接点入队列
     chessboard[pp.r][pp.c] = 1;//标记为已访问
    }
    pp = null;
   }
   p = null;
  }
 }

 public static void main(String[] args) {
  Scanner sc = new Scanner(System.in);
   while (sc.hasNext()) {
   String s1 = sc.next();
   String s2 = sc.next();
    new Main().bsf(s1, s2);
  }
 }

}

class Point {
 int r;
 int c;
 int steps;
}



例二:农夫找牛(POJ 3278)
  一个农场主为了找到自己走失的牛,要走最短的路径,只有三种走法:
x->x+1;
x->x-1;
x->2x;
    解释成数学问题: 给出2个数N和K(0 ≤ N ≤ 100,000,0 ≤ K ≤ 100,000),问从N经过+1或者-1或者*2能到达K的最小步数。

[分析]
   分3个方向BFS,找到后树的深度就是最小步数了。注意n可以比k大,这时只有-1一种办法可以从n到达k,直接减就行了.
import java.util.*;   

public class Main {   
  
    public static final int MAX = 200000;   
  
    public static void main(String[] args) {   
  
        Scanner scan = new Scanner(System.in);   
        if (scan.hasNext()) {   
            int n = scan.nextInt();   
            int k = scan.nextInt();   
            System.out.println(catchTheCow(n, k));   
        }   
    }   
  
    public static int catchTheCow(int n, int k) {   
        //找到   
        if (n == k) {   
            return 0;   
        }   
        Queue< Integer> queue = new LinkedList<Integer>();   
        boolean[] visited = new boolean[MAX + 5];   
        int[] minutes = new int[MAX + 5];   
        visited[n] = true;  //标记起点已访问 
        queue.add(n);   
        while (!queue.isEmpty()) {   
            int current = queue.poll();  //从队列中弹出当前点 
            for (int i = 0; i < 3; i++) {//依次访问当前点的邻接点 
                int next = current;   
                //遍历3个方向   
                if (i == 0) {   
                    next++;   
                } else if (i == 1) {   
                    next--;   
                } else if (i == 2) {   
                    next<<=1;
                }   
                if (next < 0 || next > MAX) {   
                    continue;   
                }   
                //剪枝  保证每个数只进链表一次。
                if (!visited[next]) {   
                    queue.add(next);   //当前点的邻接点入队
                    visited[next] = true; //标记为已访问  
                    minutes[next] = minutes[current] + 1;   
                }   
                //找到   
                if (next == k) {   
                    return minutes[k];   
                }   
            }   
        }   
  
        return 0;   
    }   
}  
程序运行:
D:\tutu>java  Main
5 17
4
*/


下载源码:
  • 大小: 27.8 KB
分享到:
评论

相关推荐

    广度优先搜索学习五例之四

    【标题】:“广度优先搜索学习五例之四” 在计算机科学中,广度优先搜索(Breadth-First Search,简称BFS)是一种用于遍历或搜索树或图的算法。它按照从根节点开始,逐层进行探索的方式进行。在本案例中,我们可能...

    广度优先搜索学习五例之二(JAVA)

    【标题】:“广度优先搜索学习五例之二(JAVA)” 在计算机科学中,图算法是解决问题的关键工具之一,而广度优先搜索(Breadth-First Search, BFS)是一种用于遍历或搜索树或图的算法。本篇文章将重点讲解如何在...

    广度优先搜索学习五例之一

    **广度优先搜索(Breadth-First Search, BFS)**是一种在图或树中进行搜索的算法,常用于寻找最短路径或者遍历结构。它遵循“先探索节点的所有邻居,再探索邻居的邻居”的策略,从起点开始,逐层向外扩展。BFS的关键...

    广度优先搜索学习五例之五

    在给定的"广度优先搜索学习五例之五"中,我们可能探讨的是一个具体的应用场景或者变体,但描述中并未提供详细信息。通常,BFS 的实现涉及以下几个关键元素: 1. **队列(Queue)**:BFS 使用队列作为主要的数据结构...

    深度优先搜索学习五例之四(JAVA)

    在这个“深度优先搜索学习五例之四”的主题中,我们将重点关注使用Java实现DFS解决具体问题的情况。这篇博客文章可能通过一个具体的实例,如迷宫求解,来演示如何利用DFS进行递归或栈操作。 首先,我们来看"MazeDsf...

    深度优先搜索学习五例之一(JAVA)

    在这个主题"深度优先搜索学习五例之一(JAVA)"中,我们可以期待看到至少五个不同的应用实例,这些实例将用Java语言实现,可能包括但不限于以下场景: 1. **图的遍历**:DFS可以用于遍历无向图或有向图,通过访问每...

    图的广度优先搜索的应用

    通过深入学习和实践这些案例,我们可以掌握如何运用广度优先搜索解决实际问题,并且在遇到类似问题时能够快速找到合适的算法和方法。此外,对于同一问题的深入探讨可以帮助我们探索更优的解决方案,比如通过剪枝技术...

    python深度,广度,三种启发式搜索解决八数码问题

    三、宽度优先搜索(BFS) BFS是一种按层次搜索的策略,每次扩展最近添加到队列的节点。对于八数码问题,BFS能保证找到最短的解决方案,因为它总是先检查离起点近的节点。然而,BFS在处理大规模问题时可能会消耗大量...

    广度优先搜索例程:迷宫最短路径-易语言

    广度优先搜索(BFS)是一种用于遍历或搜索树或图的算法,其基本思想是从根节点开始,沿着树的宽度优先遍历,直到找到目标节点或者遍历完所有节点。在本例中,我们将关注如何运用广度优先搜索(BFS)来寻找迷宫中的...

    广度优先算法算例,可直接运行

    **广度优先搜索(BFS)算法是一种在图或树中搜索节点的遍历方法,其基本思想是从起点开始,先访问所有距离起点最近的节点,然后再依次访问更远的节点。这种算法常用于查找最短路径、解决迷宫问题等。在本程序包中,...

    浅谈网络爬虫中广度优先算法和代码实现.pdf

    在爬虫技术中,两种常见的遍历策略是深度优先搜索(DFS, Depth-First Search)和广度优先搜索(BFS, Breadth-First Search)。本篇将重点探讨广度优先算法及其在网络爬虫中的应用。 首先,广度优先算法的核心思想是...

    八数码C代码

    该程序可能包含了实现八数码问题的各种算法,如深度优先搜索(DFS)、广度优先搜索(BFS)或A*搜索等。 描述中的"可以直接运行的程序,是八数码的C的源代码,直接运行即可"表明这个压缩包里的1.cpp文件是一个可执行的C...

    人工智能原理学习教案.pptx

    盲目搜索如宽度优先搜索(BFS)和深度优先搜索(DFS),在未知环境中探索所有可能的解决方案路径,虽然简单但效率较低。启发式搜索则依据某种评估函数来指导搜索方向,如A*搜索,通过结合路径代价和预计到达目标的...

    C++语言经典、实用、趣味编程百例精解\C++经典程序200例、c语言经典算法100例

    这些例子可能包含经典的排序算法(如插入排序、选择排序)、查找算法(如二分查找)、图算法(如深度优先搜索、广度优先搜索)以及其他实用的算法如动态规划和回溯法。通过实践这些算法,学习者将能提高问题解决能力...

    高效算法128例配套代码

    1. **算法基础**:书中涵盖的基础算法包括排序(快速排序、归并排序、堆排序等)、搜索(深度优先搜索、广度优先搜索)以及动态规划。这些是任何程序员都需要掌握的核心技能,对于解决实际问题至关重要。 2. **数据...

    《人工智能导论-》- 03 搜索.ppt

    总结来说,搜索是人工智能问题求解的关键技术之一,包括但不限于盲目搜索(如宽度优先搜索)和启发式搜索。这些方法在游戏策略、知识表示、规划等领域有广泛应用。理解并掌握搜索策略对于深入学习人工智能至关重要。

    C语言经典算法100例

    此外,C语言也常用于实现图的遍历算法,如深度优先搜索(DFS)和广度优先搜索(BFS)。这些算法在解决网络路由、社交网络分析等问题时有着广泛的应用。还有动态规划、贪心算法、回溯法等高级算法,它们在解决复杂...

Global site tag (gtag.js) - Google Analytics