• 浅谈深度优先和广度优先(scrapy-redis)


    首先先谈谈深度优先和广度优先的定义

    深度优先搜索算法英语:Depth-First-Search,DFS)是一种用于遍历或搜索算法。沿着树的深度遍历树的节点,尽可能深的搜索树的分支。当节点v的所在边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点。这一过程一直进行到已发现从源节点可达的所有节点为止。如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访问为止。属于盲目搜索。

     

    深度优先搜索
    节点搜索的顺序
    节点进行深度优先搜索的顺序
    概况
    类别: 搜索算法
    数据结构:
    时间复杂度: {displaystyle O(b^{m})}O(b^m)
    空间复杂度: {displaystyle O(bm)}O(bm)
    最佳解:
    完全性:
    其他: b - 分支系数
    m - 图的最大深度

    广度优先搜索算法英语:Breadth-First-Search,缩写为BFS),又译作宽度优先搜索,或横向优先搜索,是一种图形搜索算法。简单的说,BFS是从根节点开始,沿着树的宽度遍历树的节点。如果所有节点均被访问,则算法中止。广度优先搜索的实现一般采用open-closed表。

    广度优先搜索
    节点搜索的顺序
    节点进行广度优先搜索的顺序
    概况
    类别: 搜索算法
    数据结构:
    时间复杂度: {displaystyle O(|V|+|E|)=O(b^{d})}O(|V|+|E|) = O(b^d)
    空间复杂度: {displaystyle O(|V|+|E|)=O(b^{d})}O(|V|+|E|) = O(b^d)
    最佳解:
    完全性:

    通俗的讲:

    深度优先:一个一个节点往下找,不找兄弟节点,每一个深度一个节点,先进去的后出来

    广度优先:横向取值,一个节点有关联其他的节点,一同被取出来,一个深度多个节点,先进去的先出来

    在settings里面的配置:

    from   scrapy_redis.queue import PriorityQueue,FifoQueue,LifoQueue
    先进先出:广度优先
    SCHEDULER_QUEUE_CLASS='scrapy_redis.queue.FifoQueue'
    后进先出:深度优先
    SCHEDULER_QUEUE_CLASS='scrapy_redis.queue.LifoQueue'
    优先级队列:
    SCHEDULER_QUEUE_CLASS='scrapy_redis.queue.PriorityQueue'
    优先级队列里面也有深度优先和广度优先:

    requets.priority=1   广度优先
    requets.priority=1   深度优先

    实现原理:

    from scrapy_redis import queue

    prio=1

    depth = response.meta['depth'] + 1

    requets.priority-=depth*self.prio

    每一次循环,depth加1
    同一个深度可以找到很多url(兄弟节点)

    如果是1的话,广度优先

    广度优先:
    depth 优先级
    1 -1
    1 -1
    1 -1
    2 -2

    从深度为1的开始往下找,优先级也越大
    重点:深度越小,优先级越小

    def push(self, request):
    """Push a request"""
    data = self._encode_request(request)
    score = -request.priority##取反,注意

    ......

    优先级队列:
    放进队列里面:
    反一下
    1 1
    1 1
    1 1
    2 2
    ......

    print('这里优先级是',score)
    print(request.meta.get('depth'))
    # We don't use zadd method as the order of arguments change depending on
    # whether the class is Redis or StrictRedis, and the option of using
    # kwargs only accepts strings, not bytes.
    self.server.execute_command('ZADD', self.key, score, data)
    #按照分值来看


    def pop(self, timeout=0):
    """
    Pop a request
    timeout not support in this queue class
    """
    # use atomic range/remove using multi/exec
    ##开启事物
    pipe = self.server.pipeline()
    pipe.multi()
    ##取第一个值出来,拿出一个删除一个
    pipe.zrange(self.key, 0, 0).zremrangebyrank(self.key, 0, 0)
    results, count = pipe.execute()
    if results:
    return self._decode_request(results[0])

    最终pop是按照这个优先级来取值的,优先级越小的越先被取出来,优先级从小多大取值
    总结:就是深度越小,优先级越小,越先被取出来>>广度优先(先进先出,横向取值)

     

    深度优先:
    先进后出:一个一个节点的往下面执行

    深度越大,优先级越小,越先被pop出来

    深度优先类似,就不多说了

    ....................

  • 相关阅读:
    图片编辑网站
    mysql导出表的字段及相关属性
    SpringBoot使用注解实现事务管理
    Linux命令
    linux上部署SpringBoot项目及遇到的问题
    使用配置文件产生随机数
    UUID生成随机字符串
    第二十二节 web服务器里集成了解析动态请求的功能
    第二十节 多进程面对对象web服务器
    第二十节 tcp_ip协议
  • 原文地址:https://www.cnblogs.com/yunxintryyoubest/p/9955867.html
Copyright © 2020-2023  润新知