• 递归探测算法的实现


    迷茫童鞋的阅读指南

    该项目的详细描述和算法的具体说明

    请参见前一篇 Project2 Percolation in Grids 网格渗透

    本人给出了percolation_provided.py的函数说明

    目前已完成水波探测算法的实现

     

    该算法的关键是实现explore函数中递归,及percolation_recursiveexplore的初始调用

    Step1:
      
      国际惯例导入提供的函数:from percolation_provided import *

      先考虑percolation_recursive函数,参数和前面的水波算法函数一样,定义为:percolation_recursive(input_grid, trace=True, short=False)

    Step2:
      老样子,还是生成一个flow_grid网格。
        size = len(input_grid)
        flow_grid 
    = grid(size, -1)

     

    Step3:

      为explore函数提供一个初始的开始状态,从第一行开始,遍历每个位置。
        #start exploration from each space in top (zeroth) row
        for col in range(size):
            
    if explore(input_grid, flow_grid, 0, col, trace, short):
                
    return flow_grid, True
    Step4:

      设计这个explore函数,还是比较头疼的。关键是要考虑到如何在这里面实现递归,我们从项目中的描述来分解这个问题:

    假设一个单元与[i][j]相邻,流能够到达(i也可以为第一行),input_grid[i][j]=0flow_grid[i][j]=-1。这意味着没有流到达过[i][j]位置,该位置不阻塞,且流能够从相邻的位置到达它。我们通过设置flow_grid[i][j]=*来记录流能够到达位置[i][j]。然后,函数explore考虑流能够到达的[i][j]的相邻位置,每个位置探测一次。对于每个这样的相邻位置,explore将其相邻位置看作行列索引,并使用一次递归调用。在递归调用结束后,上面的explore的初始状态保持不变。

       那么就是:

        1.对于位置[i][j]的相邻位置,如果是开放且未被访问,使用递归调用

        2.对于每次探索到的位置设置flow_grid[i][j]=*来标记,保证只探测一次

          3.由percolation_recursive传来的值,需要判断该位置是否是开放的,是的话标记为'*'

        4.算法是全部执行完才退出的,返回值为None,为了快速结束算法并确定是否渗透,我们使用传入的short布尔值变量作为判断,只要当前处理的位置处于最后一行,就退出返回True


      具体实现如下:
    Look Code
    def explore(input_grid, flow_grid, row, col, trace, short):
        
    """Explore the grid, marking unblocked cells as full as they are explored"""
        size 
    = len(input_grid)
        
    if input_grid[row][col] == 0:
            flow_grid[row][col] 
    = '*'
            
            
    if trace:
                visualize(flow_grid, input_grid)
                rate(
    2)

            
    #explore neighboring cells

            
    if short:
                
    if row + 1 == size:
                    
    return True

            
    # Look down
            if row + 1 < size:
                
    if input_grid[row+1][col] == 0 and flow_grid[row+1][col] == -1:
                    percolation_recursive_explore(input_grid, flow_grid,
                                                  row
    +1, col, trace, short)
            
    # Look right
            if col + 1 < size:
                
    if input_grid[row][col+1== 0 and flow_grid[row][col+1== -1:
                    percolation_recursive_explore(input_grid, flow_grid,
                                                  row, col
    +1, trace, short)

            
    # Look left
            if col - 1 >= 0:
                
    if input_grid[row][col-1== 0 and flow_grid[row][col-1== -1:
                    percolation_recursive_explore(input_grid, flow_grid,
                                                  row, col
    -1, trace, short)

            
    # Look up
            if row - 1 >= 0:
                
    if input_grid[row-1][col] == 0 and flow_grid[row-1][col] == -1:
                    percolation_recursive_explore(input_grid, flow_grid,
                                                  row
    -1, col, trace, short)
    Step5:

      回到前面的函数,如果short被定义为False。那么无论最后是否发生渗透,explore函数表面上看是void类型的,其实会返回一个值None。那么就需要在函数体加上一段渗透判断。判断依据就是flow_grid的最后一行是否有元素的值为*

        for col in range(size):
            
    if flow_grid[size-1][col] == '*':
                
    return flow_grid, True

    最后这里是完整的代码:

    I’m Code
     1 #! /usr/bin/env python
     2 from visual import rate
     3 from percolation_provided import *
     4 
     5 def percolation_recursive(input_grid, trace=True, short=False):
     6     """
     7     Determine whether or not a grid percolates, and which cells are filled.
     8     Like before, short is True if you want the algorithm to stop immediately
     9     when it percolates, rather than exploring the entire grid.
    10     """
    11     size = len(input_grid)
    12     flow_grid = grid(size, -1)
    13 
    14     #start exploration from each space in top (zeroth) row
    15     for col in range(size):
    16         if explore(input_grid, flow_grid, 0, col, trace, short):
    17             return flow_grid, True
    18 
    19     #check last (size-1'th) row for full spaces
    20     for col in range(size):
    21         if flow_grid[size-1][col] == '*':
    22             return flow_grid, True
    23 
    24     #no full spaces in bottom row; doesn't percolate
    25     return flow_grid, False
    26 
    27 def explore(input_grid, flow_grid, row, col, trace, short):
    28     """Explore the grid, marking unblocked cells as full as they are explored"""
    29     size = len(input_grid)
    30     if input_grid[row][col] == 0:
    31         flow_grid[row][col] = '*'
    32         
    33         if trace:
    34             visualize(flow_grid, input_grid)
    35             rate(2)
    36 
    37         #explore neighboring cells
    38 
    39         if short:
    40             if row + 1 == size:
    41                 return True
    42 
    43         # Look down
    44         if row + 1 < size:
    45             if input_grid[row+1][col] == 0 and flow_grid[row+1][col] == -1:
    46                 percolation_recursive_explore(input_grid, flow_grid,
    47                                               row+1, col, trace, short)
    48         # Look right
    49         if col + 1 < size:
    50             if input_grid[row][col+1== 0 and flow_grid[row][col+1== -1:
    51                 percolation_recursive_explore(input_grid, flow_grid,
    52                                               row, col+1, trace, short)
    53 
    54         # Look left
    55         if col - 1 >= 0:
    56             if input_grid[row][col-1== 0 and flow_grid[row][col-1== -1:
    57                 percolation_recursive_explore(input_grid, flow_grid,
    58                                               row, col-1, trace, short)
    59 
    60         # Look up
    61         if row - 1 >= 0:
    62             if input_grid[row-1][col] == 0 and flow_grid[row-1][col] == -1:
    63                 percolation_recursive_explore(input_grid, flow_grid,
    64                                               row-1, col, trace, short)

      

  • 相关阅读:
    mysql 定时器
    mysql 存储过程记录
    mysql 常用sql
    mysql 取最后一条数据 分组
    Java8 Stream使用flatMap合并List 交 并 合 差集
    微服务技术栈
    spring boot 拦截 以及Filter和interceptor 、Aspect区别
    在springMVC的controller中获取request,response对象的一个方法
    spring boot 用@CONFIGURATIONPROPERTIES 和 @Configuration两种方法读取配置文件
    SSRS 2016 Forms Authentication
  • 原文地址:https://www.cnblogs.com/yuxc/p/2133047.html
Copyright © 2020-2023  润新知