前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >学习算法的感想

学习算法的感想

作者头像
叶子陪你玩
发布2021-05-24 14:35:48
5790
发布2021-05-24 14:35:48
举报

算法是什么


很多人可能都听过算法,可能也实现过一些算法,如果问他什么是算法,可能也很难的准确的说出来。确实,给一个事物下定义是很难的,因为总会有没有覆盖的点。

当然了,百科已经有明确的说明了,想温习的可以自己去看。

不过我还是喜欢这个概念:解决问题的方法步骤,虽然不精准,但是容易理解。

比如让你求解1+2+3+4+...+99999999+100000000=?

最笨的方法从头加到尾,用我的破电脑计算,大概16秒后可以得出答案。

换个高效的数学方法:

(1+100000000)*100000000/2,一步到位,时间接近0。

这两个方法都能够计算出结果,都可以称为算法,因为它们都解决了问题。

那哪个算法更好呢?如果从计算时间来看,很明显第二种方法更好;如果从理解的角度来看,明显第一种更好理解。好坏的判断需要根据设定的维度来判断。

算法有什么用


初学编程是不是有这样一些想法,很多时候写的一些小程序,好像不需要用什么”高端“算法,程序也运行的很好。

首先是因为计算量小,再加上计算机的速度又非常快,所以基本上暴力循环算法可以搞定一切。

其次,很多底层核心的算法都已经被前人实现了,而我们只需要站在前人的基础上,根据需要,知道如何使用即可。

因此平常很少有对算法有比较强烈的需求。

算法的用处需根据应用场景来决定的,比如你做了一个游戏,要求结束后会立刻显示分数排名,这里就需要一个排序算法,从高到低排好序显示出来。如果你的暴力循环需要好几秒肯定不行,体验太差,这个时候你可能就需要一个排序非常快的算法了。

图书馆借书,图书馆很大,不知道自己要找的书在哪个位置,这个时候可以利用图书馆强大的检索系统,输入书名,就能够告诉你书在哪个具体位置了。

现在学习编程,相比之前已经简单很多了,因为绝大数人都是属于应用类型的。

游戏有创作者和玩家,机器有发明者和应用者。在玩游戏和使用机器的过程的时候,我们不需要知道它们是怎么来的,只需要按照它的说明就能够很好的玩起来,甚至比它的发明者玩的更好。

就好像你要做一个图像处理的程序,可能你并不知道怎么实现图片处理;如果你能够找到一个处理照片的方法,按照它的使用说明,对接到你的程序中,你只需要做一些基础的工作,提供照片,程序就会返回一个结果给你了。

所以学程序有时候就像拼积木一样,明确步骤,找到每一步的解决方法,最后拼到一起就是你想要的东西。

至于解决方法是你独自想出来的,还是参考其它人的,似乎并不是很重要,重要的是你已经解决了这个问题了。

因此未来很多人都将成为应用型人才,尽管如此,懂得事物背后的原理还是非常重要的。

应用型比较注重经验,步骤流程;而算法比较注重抽象,建模,找出问题和事物的本质。

怎么学习算法


先看几个策略问题:

渡河问题

一个农夫带着一头狼、一头羊、一颗白菜过河。他面前只有一条船,只能容纳他和一件物品,只有农夫会划船。如果农夫不在场,狼会吃羊、羊会吃白菜,农夫在场则不会。

求将所有物品运到对岸的方案。

传教士与吃人恶魔的问题

有三个传教士和三个吃人恶魔要渡过一条河,河中有一条船,只能装下两个人。在任何地方(无论是岸边还是船上),如果吃人恶魔数量多于传教士数量,吃人恶魔就会吃掉传教士。

问:怎么才能让这些都安全过河?

四人过桥问题

在一个漆黑的夜里,四位旅游者来到一座狭窄而没有护栏的桥边,如果不借助手电筒的话,大家是无论也不敢过去。不幸的是四个人中只有一只手电筒,而桥窄得只够两个人同时通过。如果各自单独过桥的话,四个人所需要的时间分别是1、2、5、10分钟,如果两个人同时过桥,所需要的时间是较慢的那个人单独行动时的时间。

问:如何设计一个方案,让四个人尽快过桥。


上面的问题,或多或少相信应该有见过一些,并且很多人应该很快的想出答案来了。

现在问题来了,能不能用计算机帮我们解决上面的问题呢?


通常情况下,我们比较擅长利用计算机解决纯数字类的计算问题,对于这种实际场景问题,好像不知道如何下手。


类似的还有汉诺塔问题

找零钱问题

N皇后问题

数独问题

迷宫问题


根据自己实践的经验,之所以会对这种问题束手无策,主要在于无法将场景数字化,其实也就是数学建模

比如让你测量一座山的高度,不可能真的拿尺子去测量,可以站在山顶上扔一个石头,计算石头下落的时间。根据自由落体运动,计算高度:H = 1/2gt2;

这个公式就是一个数学模型。当然实践还需要对模型进行修正,还得考虑阻力,人的反应时间等等。


按照数学方法对模型分类,又可以分为很多种类,比如有几何模型微分方程模型以及和图论模型等。(来源于数学建模书籍)

针对不同的问题,需要建立不同的数学模型。将实际问题用数字或者图形表示出来。

然后结合特定的算法与数据结构,解决特定的问题。除了常见的列表,字典,集合和排序和搜索算法外,还有队列,栈,树,图等数据结构,贪心算法,递归算法,递推算法,记忆化搜索,动态规划,回溯算法,广度,深度优先算法,它们各自有自己的应用场景。

太多了,写不完了,留到下次写吧。之后还是直接根据具体实例讲好理解。先放两个问题的效果和代码;


阶乘-递归算法过程图示

f(5) = 5*4*3*2*1

代码语言:javascript
复制
# 递归法
def f(n):
    if n==1 or n ==2:
        return 1
    else:
        return f(n-1)+f(n-2)


# 递推法
def f2(n):
    a = list(range(n+1))
    for i in range(n+1):
        if i<2:
            a[i]=i
        else:
            a[i]=a[i-1]+a[i-2]
        # print(a[i])
    return a[n]

N 皇后问题过程图示


数据变化过程

代码语言:javascript
复制
--开始选择--
[1, 0, 0, 0]
[0, 0, 0, 0]
[0, 0, 0, 0]
[0, 0, 0, 0]
--结束选择--
--开始选择--
[1, 0, 0, 0]
[0, 0, 1, 0]
[0, 0, 0, 0]
[0, 0, 0, 0]
--结束选择--
--开始回撤--
[1, 0, 0, 0]
[0, 0, 0, 0]
[0, 0, 0, 0]
[0, 0, 0, 0]
--结束回撤--
--开始选择--
[1, 0, 0, 0]
[0, 0, 0, 1]
[0, 0, 0, 0]
[0, 0, 0, 0]
--结束选择--
--开始选择--
[1, 0, 0, 0]
[0, 0, 0, 1]
[0, 1, 0, 0]
[0, 0, 0, 0]
--结束选择--
--开始回撤--
[1, 0, 0, 0]
[0, 0, 0, 1]
[0, 0, 0, 0]
[0, 0, 0, 0]
--结束回撤--
--开始回撤--
[1, 0, 0, 0]
[0, 0, 0, 0]
[0, 0, 0, 0]
[0, 0, 0, 0]
--结束回撤--
--开始回撤--
[0, 0, 0, 0]
[0, 0, 0, 0]
[0, 0, 0, 0]
[0, 0, 0, 0]
--结束回撤--
--开始选择--
[0, 1, 0, 0]
[0, 0, 0, 0]
[0, 0, 0, 0]
[0, 0, 0, 0]
--结束选择--
--开始选择--
[0, 1, 0, 0]
[0, 0, 0, 1]
[0, 0, 0, 0]
[0, 0, 0, 0]
--结束选择--
--开始选择--
[0, 1, 0, 0]
[0, 0, 0, 1]
[1, 0, 0, 0]
[0, 0, 0, 0]
--结束选择--
--开始选择--
[0, 1, 0, 0]
[0, 0, 0, 1]
[1, 0, 0, 0]
[0, 0, 1, 0]
--结束选择--
----方案----
[0, 1, 0, 0]
[0, 0, 0, 1]
[1, 0, 0, 0]
[0, 0, 1, 0]
------------
--开始回撤--
[0, 1, 0, 0]
[0, 0, 0, 1]
[1, 0, 0, 0]
[0, 0, 0, 0]
--结束回撤--
--开始回撤--
[0, 1, 0, 0]
[0, 0, 0, 1]
[0, 0, 0, 0]
[0, 0, 0, 0]
--结束回撤--
--开始回撤--
[0, 1, 0, 0]
[0, 0, 0, 0]
[0, 0, 0, 0]
[0, 0, 0, 0]
--结束回撤--
--开始回撤--
[0, 0, 0, 0]
[0, 0, 0, 0]
[0, 0, 0, 0]
[0, 0, 0, 0]
--结束回撤--
--开始选择--
[0, 0, 1, 0]
[0, 0, 0, 0]
[0, 0, 0, 0]
[0, 0, 0, 0]
--结束选择--
--开始选择--
[0, 0, 1, 0]
[1, 0, 0, 0]
[0, 0, 0, 0]
[0, 0, 0, 0]
--结束选择--
--开始选择--
[0, 0, 1, 0]
[1, 0, 0, 0]
[0, 0, 0, 1]
[0, 0, 0, 0]
--结束选择--
--开始选择--
[0, 0, 1, 0]
[1, 0, 0, 0]
[0, 0, 0, 1]
[0, 1, 0, 0]
--结束选择--
----方案----
[0, 0, 1, 0]
[1, 0, 0, 0]
[0, 0, 0, 1]
[0, 1, 0, 0]
------------
--开始回撤--
[0, 0, 1, 0]
[1, 0, 0, 0]
[0, 0, 0, 1]
[0, 0, 0, 0]
--结束回撤--
--开始回撤--
[0, 0, 1, 0]
[1, 0, 0, 0]
[0, 0, 0, 0]
[0, 0, 0, 0]
--结束回撤--
--开始回撤--
[0, 0, 1, 0]
[0, 0, 0, 0]
[0, 0, 0, 0]
[0, 0, 0, 0]
--结束回撤--
--开始回撤--
[0, 0, 0, 0]
[0, 0, 0, 0]
[0, 0, 0, 0]
[0, 0, 0, 0]
--结束回撤--
--开始选择--
[0, 0, 0, 1]
[0, 0, 0, 0]
[0, 0, 0, 0]
[0, 0, 0, 0]
--结束选择--
--开始选择--
[0, 0, 0, 1]
[1, 0, 0, 0]
[0, 0, 0, 0]
[0, 0, 0, 0]
--结束选择--
--开始选择--
[0, 0, 0, 1]
[1, 0, 0, 0]
[0, 0, 1, 0]
[0, 0, 0, 0]
--结束选择--
--开始回撤--
[0, 0, 0, 1]
[1, 0, 0, 0]
[0, 0, 0, 0]
[0, 0, 0, 0]
--结束回撤--
--开始回撤--
[0, 0, 0, 1]
[0, 0, 0, 0]
[0, 0, 0, 0]
[0, 0, 0, 0]
--结束回撤--
--开始选择--
[0, 0, 0, 1]
[0, 1, 0, 0]
[0, 0, 0, 0]
[0, 0, 0, 0]
--结束选择--
--开始回撤--
[0, 0, 0, 1]
[0, 0, 0, 0]
[0, 0, 0, 0]
[0, 0, 0, 0]
--结束回撤--
--开始回撤--
[0, 0, 0, 0]
[0, 0, 0, 0]
[0, 0, 0, 0]
[0, 0, 0, 0]
--结束回撤--

N皇后问题代码(4*4)

代码语言:javascript
复制
# 打印 board
def print_board(board):
    for row in board:
        print(row)

def is_valid(board, row, col):
    # 检查正上方
    for i in range(0, row):
        if board[i][col] == 1:
            return False

    # 检查左斜上方
    for i, j in zip(range(row-1, -1, -1), range(col-1, -1, -1)):
        if board[i][j] == 1:
            return False

    # 检查右斜上方
    for i, j in zip(range(row-1, -1, -1), range(col,cols)):
        if board[i][j] == 1:
            return False
    return True


def backtrack(board, row):
    if row == rows:
        print("----方案----")
        print_board(board)
        print("------------")
    else:
        for col in range(0, cols):
            #判断该位置是否有效
            if not is_valid(board, row, col):
                continue
            # 选择
            board[row][col] = 1
            print("--开始选择--")
            print_board(board)
            print("--结束选择--")
            backtrack(board, row+1)
            # 回撤
            board[row][col] = 0
            print("--开始回撤--")
            print_board(board)
            print("--结束回撤--")


row = 0
rows = 4
cols = 4
board = [[0 for i in range(rows)] for j in range(cols)]
backtrack(board, row)
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-05-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 叶子陪你玩编程 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 算法有什么用
  • 怎么学习算法
相关产品与服务
图片处理
图片处理(Image Processing,IP)是由腾讯云数据万象提供的丰富的图片处理服务,广泛应用于腾讯内部各产品。支持对腾讯云对象存储 COS 或第三方源的图片进行处理,提供基础处理能力(图片裁剪、转格式、缩放、打水印等)、图片瘦身能力(Guetzli 压缩、AVIF 转码压缩)、盲水印版权保护能力,同时支持先进的图像 AI 功能(图像增强、图像标签、图像评分、图像修复、商品抠图等),满足多种业务场景下的图片处理需求。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档