
算法
文章平均质量分 81
天降风云
这个作者很懒,什么都没留下…
展开
-
算法导论随笔(十六):线性规划与单纯形算法(下篇:算法细节和实现(附Python源码))
在算法导论随笔(十五):线性规划与单纯形算法(上篇:基本概念)中,我介绍了解决线性规划问题的单纯性算法所用到的一些概念。在这篇文章中我们来看看算法的一些实现的细节。单纯形算法的Python实现已经上传到我的GitHub仓库https://github.com/tjfy1992/Simplex中。下载后在PyCharm中打开工程即可。1. 松弛型的转动(Pivot)上篇文章中提到过,单纯形算法的目的是将一个标准型的线性规划问题转化为松弛型,并且对松弛型进行一系列转化,使得该松弛型的目标函数中,所有变量的系原创 2020-11-15 10:28:59 · 1027 阅读 · 2 评论 -
算法导论随笔(十五):线性规划与单纯形算法(上篇:基本概念)
线性规划(Linear Programming)问题指的是在给定有限资源的前提下,最大化或最小化某个目标的问题。这里我将分上下两篇来谈谈线性规划和单纯形算法。前言线性规划问题有很多例子,比如在算法导论随笔(六):贪心算法Greedy algorithm与分数背包问题中,我曾经提到过一个分数背包问题。当时是使用贪心策略来解决。其实,这个问题也可以使用线性规划来解决。先来回顾一下分数背包问题:如下图,图中有5瓶液体,分别标号为1,2,3,4,5。编号为1的液体有4毫升,每毫升价值3美元。所以该液体的总价值原创 2020-11-12 12:52:01 · 1025 阅读 · 1 评论 -
算法导论随笔(十四):NP完全性之P问题、NP问题、NPC问题和NP难问题
这篇文章中我来简单谈谈NP完全性。不同于前面所有文章中的各个具体的问题和算法,NP完全性是一个很抽象的大概念,其包括但不仅限于标题中提到的P问题、NP问题、NPC问题和NP难问题。这里我简单谈谈我对书上的内容和一些例子的理解。P问题首先来谈谈P问题。算法导论随笔系列写到现在,已经介绍了很多问题及它们的算法。其中大部分的问题,都是P问题。那么什么是P问题呢?P问题指的是能在多项式时间内解决的问题。这里的P是Polynomial(即多项式)的缩写。初中数学告诉我们,一个多项式有如下的形式:其中a0,a1原创 2020-11-10 12:12:46 · 4261 阅读 · 2 评论 -
算法导论随笔(十三):动态规划与最长公共子序列(LCS)
前言动态规划(Dynamic programming)与前文算法导论随笔(二): 归并排序与分治策略中提到的分治策略类似,都是通过组合子问题的解来求解原问题。与分治策略不同的是,在分治策略中,每一个子问题是独立的,而动态规划中每一个子问题之间则有重叠的情况。举例来说,归并排序使用的是分治策略,因为它的每一个子问题都是将一个子数组中的数进行排序,而每个子问题中排序的子数组与其他子问题中的子数组并没有任何关系,即互相独立。因此,对于每一个子数组,归并排序算法都要对其进行重新排序。例如有两组长度为2的子数组,原创 2020-11-09 06:14:36 · 529 阅读 · 1 评论 -
算法导论随笔(十二):摊还分析(Amortized Analysis)之聚合分析、核算法和势能法
在算法导论随笔(一): 操作计数与复杂度Big(O)中,我简单介绍了计算一个算法的时间复杂度的方法。该方法结算结果虽然都是正确的,但有时不一定特别准确地代表复杂度函数的渐进上界。因此,人们创建了一个分析方式,可以更精确地表示一个复杂度函数的渐进上界。这个分析方式就是我今天要介绍的摊还分析。1.为什么要引入摊还分析前文说到,使用分析操作计数的方法来计算时间复杂度时,有的时候求出的渐进上限并不准确,也就是说,由于我们一直是在考虑程序消耗时间的最坏情况,而程序并不是一直处于最坏情况。因此我们求出的复杂度经常高原创 2020-09-02 06:28:12 · 3014 阅读 · 0 评论 -
算法导论随笔(十一):最大流(Max-Flow)与Ford-Fulkerson算法(附Python实现源码)
前面的几篇文章中我们讨论了一些图的算法。其中大部分都是关于无向图的算法。这篇文章里我来说说有向图的算法。先说一说有向图的一个应用,也就是流网络(Flow Network)。1. 流网络先来看流网络的定义。对于流网络,《算法导论》第26章是这样定义的:流网络 G = (V, E)是一个有向图,图中每一条边(u, v) ∈ E有一个非负的容量值c(u, v) >=0。而且,如果边集合E包含一条边(u, v),则图中不存在反方向的边(v, u)。如果(u, v) ∉ E,则为方便起见,定义c(u,原创 2020-09-01 06:32:36 · 6408 阅读 · 3 评论 -
算法导论随笔(十):最小生成树(MST)与Kruskal算法、Prim算法
这篇文章中我来写写图的最小生成树,以及计算一个图的最小生成树的算法,即Kruskal算法和Prim算法。两个算法均使用了贪婪策略。1. 最小生成树先来谈谈 最小生成树(Minimum Spanning Tree,MST) 的概念。这个概念分为三个部分:最小,生成,和树。因此,这里分别对这三个概念作出解释。首先,树的定义在算法导论随笔(四):树形结构与二叉树已经有完整介绍。这里,介绍生成树(Spanning tree)的概念。首先,当我们以 “生成” 作为前缀来修饰一个图或一棵树时,表示的是该树和该图是原创 2020-08-31 02:57:57 · 716 阅读 · 0 评论 -
算法导论随笔(九):图(Graph)的进阶与图的遍历方式(DFS, BFS)
在这篇文章中,我将介绍一些跟图有关的进阶术语,以及图的两种遍历方式,即DFS(深度优先搜索)和BFS(广度优先搜索)。对于文中使用的一些图的术语,可以读算法导论随笔(七):图(Graph)的表示(附Python实现源码)复习一下。首先让我们来看看连通图的概念。1. 图的连通性在一个无向图G中,对于两个顶点u和v,若u和v之间有路径,则称u与v是连通的。如果图中任意两点都是连通的,那么图被称作连通图。如果G是有向图,那么连接u和v的路径中所有的边都必须同向。这种任意两个点都相同的特性叫做连通性。连通图原创 2020-08-30 12:52:05 · 700 阅读 · 0 评论 -
算法导论随笔(八):图的最短路径问题与Dijkstra算法
在上一篇文章中,我介绍了图(Graph)的概念。这篇文章和未来几篇文章中,我主要讨论关于图的一些经典问题和解决这些问题的经典算法。首先是图的最短路径问题。1. 图的最短路径(Shortest Path)问题首先来讨论图的最短路径问题。举一个例子,我们可以把中国的地图看做一个图,把每一个城市看做图中的一个顶点,把相邻城市的高速公路当做一条边。那么,如果我想从北京出发去上海,要经过哪些城市才能使得走过的距离最短呢?这就是图的最短路径问题。给定一个图,图中每一条边都有一个权重(weight)。比如上面的例子原创 2020-08-30 06:25:43 · 975 阅读 · 1 评论 -
算法导论随笔(七):图(Graph)的表示(附Python实现源码)
与树类似,图也是计算机算法领域的一个重要的数据结构。很多经典问题的算法都是基于图实现的,例如最大流(Max-Flow)、最小生成树(MST)等等。这些经典问题在今后的文章中都会提到。今天这篇文章,主要介绍图的定义、有关图的一些术语和图的特性。1. 图(Graph)的定义在计算机理论中,图可以表示为G=(V,E)G = (V, E)G=(V,E)其中V是一组节点的集合,称作顶点(vertices),E是一个集合,集合中每一个元素是一对顶点(pair of vertices),称作边(edge)。以原创 2020-08-29 05:57:15 · 1281 阅读 · 0 评论 -
算法导论随笔(六):贪心算法Greedy algorithm与分数背包问题(附Python实现源码)
上一篇文章中我介绍了霍夫曼编码,并提到了它是贪心算法的一个应用。这篇文章我继续来谈谈贪心算法和它解决的一个经典问题,分数背包问题。1.贪心算法在《算法导论》中,对贪心算法是这样描述的:求解最优化问题的算法通常需要经过一系列的步骤,在每个步骤都面临多种选择。贪心算法就是这样的算法,它在每一步都作出当时看起来是最佳的选择。也就是说,它总是作出局部最优的选择,寄希望这样的选择能导致全局最优解。我们可以看出,贪心算法在每一步中只作出当时看起来是最佳的选择。也就是说,贪心算法并不能保证对于每一个问题都能得原创 2020-08-29 03:33:33 · 3634 阅读 · 0 评论 -
算法导论随笔(五):二叉搜索树和霍夫曼编码
上一篇文章中讨论了树这种数据结构,以及其衍生的二叉树。这篇文章中,主要讨论二叉树的衍生树以及基于二叉树的算法。1.二叉搜索树二叉搜索树是由二叉树衍生出的一个高级数据结构,具备了二叉树的所有特性。二叉搜索树的每一个内部节点(internal node)都存储了一个键(或一对键值对)。二叉搜索树的叶子节点不存储任何东西。在此基础上,设x是二叉搜索树中的任意一个节点,x有如下性质:若y是x左子树中的一个节点,则有y.key≤x.keyy.key \le x.keyy.key≤x.key若y是x右子树原创 2020-08-28 06:20:47 · 456 阅读 · 0 评论 -
算法导论随笔(四):树形结构与二叉树
算法的设计与实现都必须依赖于数据结构。在这篇文章中,我来介绍计算机理论中的最常见的数据结构之一:树。其实,树这种结构,并不只是存在于算法理论中,在计算机的其他领域也有着重要的作用。例如,我们所熟知的C,Java,C++等编程语言的编译器,都离不开树这个结构,因为树在词法分析中起到至关重要的作用。1.树的定义在计算机科学中,树是一个用来表示层级结构的抽象模型。一棵树中包含了一些节点(Node),这些节点具有父子关系(Parent-Child relation)。下图中就是一棵树。树形结构的应用除了前文原创 2020-08-28 01:45:07 · 779 阅读 · 0 评论 -
算法导论随笔(三): 分治策略与主方法Master Method
上一篇文章中介绍了分治策略和归并排序算法。这一篇中主要谈谈分治策略的复杂度计算公式,也就是主方法。我们知道,递归函数的表达式可以分为两部分,即递归部分和带有终止条件的结束部分。例如下面的公式,描述了归并排序复杂度的递归表达式。注意:此篇文章较偏向于理论和数学计算,不过基本原理非常简单。不要被主方法中看似复杂的公式吓到,其本质只是初中数学。看到最后就会知道完全是自己吓自己。上一篇文章中提到,分治策略的核心就是递归,因此,每一个使用分治策略的算法都应该有一个类似上图中的表达式来描述它的复杂度。这也是我接下原创 2020-08-26 07:34:16 · 1510 阅读 · 1 评论 -
算法导论随笔(二): 归并排序与分治策略
在上一篇文章中,我提到了两个排序算法,冒泡排序和归并排序。对于冒泡排序,上一篇文章中已经介绍了它的复杂度为什么是O(n2)。在这一篇文章中,我来写写归并排序的原理以及如何计算它的复杂度。归并排序(Merge Sort)首先介绍一下归并排序。归并排序(Merge Sort)是一种经典的排序算法,它的复杂度是O(nlogn)。 对于刚接触算法的同学来说,这个表达式可能比较奇怪。在后文中会介绍它的复杂度为什么是O(nlogn)。注意: 在算法领域,logn是log2n的缩写,即以2为底n的对数,一定不要混淆原创 2020-08-26 03:20:22 · 573 阅读 · 0 评论 -
算法导论随笔(一): 操作计数与复杂度Big(O)
算法导论随笔(一): 操作计数与复杂度Big(O)最近有点空闲时间,准备开一个新坑来纪录自己读《算法导论》的一些读书笔记,有时间的话也讨论一些有趣的算法。首先来谈谈程序的操作计数与算法的复杂度计算,也就是我们常听说的大O。对于新手程序员来说,“算法”这个概念可能看上去比较高深,尤其是“复杂度”这个概念,有时会让人一头雾水。不过看了这篇文章后,相信大家对算法和复杂度的概念会有一个更直观的了解, 即使是只会初中数学,也完全可以看懂。1. 复杂度的概念对算法有一定了解的朋友们都知道,判断一个算法好坏的方法是原创 2020-08-25 03:37:31 · 1223 阅读 · 3 评论 -
人工智能: 自动寻路算法实现(二、深度优先搜索)
本篇文章是机器人自动寻路算法实现的第二章。我们要讨论的是一个在一个M×N的格子的房间中,有若干格子里有灰尘,有若干格子里有障碍物,而我们的扫地机器人则是要在不经过障碍物格子的前提下清理掉房间内的灰尘。原创 2017-07-12 09:39:25 · 6180 阅读 · 0 评论 -
面试题:八皇后问题(N皇后问题)
八皇后问题是一个以国际象棋为背景的问题:如何能够在 8×8 的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?这道题目也可以稍微延伸一下,变为 N×N的棋盘上放置N个皇后,其他条件相同。原创 2017-07-07 09:52:00 · 9417 阅读 · 0 评论 -
人工智能: 自动寻路算法实现(一、广度优先搜索)
前言随着人工智能技术的日益发达,我们的生活中也出现了越来越多的智能产品。我们今天要关注的是智能家居中的一员:扫地机器人。智能扫地机器人可以在主人不在家的情况下自动检测到地面上的灰尘,并且进行清扫。有些更为对路线进行规划,找到可以清理灰尘的最短路径,达到省电的效果。当然,绕过障碍物也是必须拥有的技能。我们今天就来看一下扫地机器人自动寻路的算法的简单实现。这里我们不对机器人如何识别出灰尘进行讨论,我们只原创 2017-07-11 16:01:19 · 16649 阅读 · 1 评论 -
人工智能: 自动寻路算法实现(三、A*算法)
前言本篇文章是机器人自动寻路算法实现的第三章。我们要讨论的是一个在一个M×N的格子的房间中,有若干格子里有灰尘,有若干格子里有障碍物,而我们的扫地机器人则是要在不经过障碍物格子的前提下清理掉房间内的灰尘。具体的问题情景请查看人工智能: 自动寻路算法实现(一、广度优先搜索)这篇文章,即我们这个系列的第一篇文章。在前两篇文章里,我们介绍了通过广度优先搜索算法和深度优先算法来实现扫地机器人自动寻路的功能。原创 2017-09-20 10:18:01 · 9657 阅读 · 0 评论 -
面试题:从1, 2, 3, 4, 5五个数字中能找出多少个每位数字都不同的三位数?
前言前几天看到了一道简单的面试题,从5个数字中找出所有每位数字都不同的三位数的数量并且一一输出。从数学上来讲,算出数量比较简单,只是一个排列的计算。比如这道题的计算方法就是P(5,3) = 60。输出的过程也比较简单,这里提出两种方法:正文方法一:一种通俗易懂的方法。用三个for循环,第一个for循环遍历所有的数字,第二个循环遍历除了第一个数字之外的所有数字,第三个循环遍历除了前两个数字之外的所有数原创 2017-07-05 14:35:50 · 7008 阅读 · 0 评论