美文网首页算法编程算法Go语言
基础-5:人人都应该懂点的随机算法

基础-5:人人都应该懂点的随机算法

作者: CodingTech | 来源:发表于2017-03-14 09:41 被阅读257次

概述

随机算法是当前工业界和学术界都比较热的一个话题,从机器学习、数据挖掘到现在热得发烫的深度学习,无一没有随机算法的影子。随机算法起源于人类天性:赌博,最初用来解决一些不确定问题,现在已逐渐发展为一门独立的学科,深入到工程领域各学科。本文以一个简单的例子对基本的随机算法作简单介绍,深入了解请研读随机算法

寻宝问题

寻宝问题描述如下:

假设有10个山头,其中3个山头里面分别有价值10个金币宝藏,每个山头都有1个精灵守护,要进山寻宝,必须给精灵3个金币,当在一个山头找到宝藏后,精灵不允许继续再寻宝,哪个山头有宝藏未知,是否应该寻宝,采用何种策略寻宝?

因为每个山里面是否有宝藏是未知的,不妨对这10个山里面是否有宝藏进行编号,设为{0, 0, 0, 1, 0, 0, 1, 0, 0, 1},其中的0表示没有宝藏,1表示有宝藏。

因为宝藏未知,按照什么样的顺序访问山头也是未知的。在这种情况下,有两种方案:

  • 情况1: 给山头排个序,然后依次访问;
  • 情况2: 随机访问;

对于情况1,假设排序为p=<0, 0, 0, 1, 0, 0, 1, 0, 0, 1>,则挖到宝藏会亏本2个金币。也就是说,一旦确定了访问山头的次序,并且这个次序是一个亏本的次序,则必然亏本。

对于情况2,随机访问有是什么样子呢?在这里不作具体的数学分析(分析也比较简单,利用离散均匀分布,计算期望)。随机访问一般有两种算法,一种是lasvegas算法,一种是monter carlo算法,随机算法的本质是算法的某一步骤中引入随机函数确定的某个值,从而导致不同相同的输入可能得到不同的结果。

lasvegas算法针对寻宝问题的代码为:

func LasVegas(input []int, key int) int {
    retCount := 0
    r := rand.New(rand.NewSource(time.Now().UnixNano()))

    idxs := make([]int, 0)
    for i, _ := range input {
        idxs = append(idxs, i)
    }

    for count := 0; count < len(input); count++ {
        // 从未选择的山头中选择一个
        i := r.Intn(len(idxs))
        retCount++
        if input[idxs[i]] == key {
            fmt.Println("===========")
            return 10 - 3*retCount
        }
        idxs = lefts(idxs, idxs[i])
    }
    return 0 - 3*retCount
}

分析上面的代码,lasvegas算法的本质是只要存在解(在本例的寻宝中),会一直尝试,直到得到正确解。也就是:只要存在解,lasvegas算法最终一定会得到解。

如果寻宝问题中,山头数量足够多,而宝藏山头特别少,则按照lasvegas算法可能会亏损特别严重,得不偿失,因此,monter carlo算法对尝试的次数作了限制,这本质上就是一种尝试-止损原则,即先确定一个止损位,按照在止损范围内尝试获利。其代码为:

func MC(input []int, upperTryNum int, key int) int {
    retCount := 0
    r := rand.New(rand.NewSource(time.Now().UnixNano()))

    idxs := make([]int, 0)
    for i, _ := range input {
        idxs = append(idxs, i)
    }

    for count := 0; count < len(input); count++ {
        if retCount <= upperTryNum {
            retCount++
            i := r.Intn(len(idxs))
            if input[i] == key {
                return 10 - 3*retCount
            }

            idxs = lefts(idxs, idxs[i])
        }
    }

    return 0 - upperTryNum
}

其中的upperTryNum就是尝试的次数。

通常情况下,Monte Carlo不一定会得到解,但是其损失是可以预见。针对寻宝这个例子,在本人机器上分别运行10次,其获益金币数结果为(每次运行结果都不同):
lvs(lasvegas): [4 1 -2 4 -8 7 7 7 4 1] , mcs(monter carlo): [4 7 7 7 7 7 7 1 7 7]

大家可以在自己的机器上观测运行结果( https://github.com/bjutJohnson/Algorithms/tree/master/src/probabilistic ) ,可以把尝试次数设置得更多一些,然后结合数学期望进行分析。

小结

随机算法虽然起源于不确定性问题,但是对于规模庞大的确定性问题如围棋、解密度空间稀疏等,都有与之相应的解决方案,特别是求解次优解的情况。

相关文章

  • 基础-5:人人都应该懂点的随机算法

    概述 随机算法是当前工业界和学术界都比较热的一个话题,从机器学习、数据挖掘到现在热得发烫的深度学习,无一没有随机算...

  • 人人都应该懂点算法

    今年跨年我觉得比较有意义的一件事就是听了“时间的朋友2017”跨年演讲。 看这个也是在机缘巧合的情况下,为了追《虎...

  • 人人都应该懂点设计

    为什么人人都应该懂一点设计呢,我们看到你刚从学校毕业找工作,那么你首先需要一份简历,回想你当年是怎么写简历的?去网...

  • 总结那些常用的优化方法

    知识点 基础的损失函数优化算法为梯度下降算法SGD(根据每次参与计算的样本数又分为了普通梯度下降算法,随机梯度下降...

  • 人人都应该懂点逆向思维

    逆向思维说来简单,凡是上过学的肯定都有接触。那就是数学中经常用的一个解题方法——反证法。它的步骤很简单:一、假设命...

  • 算法导论:概率分析和随机算法

    参考资料:概率分析和随机算法雇佣问题在讲述概率分析和随机算法之前,需要先简单介绍一下,概率论的基础知识 基础知识 ...

  • 操作系统基础 内存换页算法

    操作系统基础 内存换页算法 换页算法的分类 公平算法: 随机算法 先来先出(FIFO)算法 第二次机会算法 时钟算...

  • 人人都应该懂点经济学

    字数统计:3600 建议阅读:10分钟 文章关键词:经济学思维 微观经济学 全局性思维 经济学教会我们如何...

  • 人人都应该懂点项目进度管理

    1、日常生活中的进度管理 进度管理并非在工作中才会有,包括我们日常生活里所做的每一件事情都有进度管理。例如正在写的...

  • 人人都应该懂点营养学

    我是番茄01 最近读到有关营养学方面的知识,顿时感觉到原来吃也是有很大学问的,怎么吃才健康合理,需要讲究一定的科学...

网友评论

    本文标题:基础-5:人人都应该懂点的随机算法

    本文链接:https://www.haomeiwen.com/subject/mudfnttx.html