用列表解决实际问题

很多朋友啃完了《算法》《算法導论》或其他算法书籍对各种排序、搜索、遍历等常用算法了如指掌,但是遇到实际的问题时还是束手无策这与智力无关,这其实就昰经验和方法集的问题很多啃过算法书的朋友都知道堆排序和最大最小堆,但是却不能有效地应用到实际问题中例如,某算法书介绍 Dijkstra 算法时提到当问题规模比较大时,每次查找 dist 数组中的最小值可能成为效率的瓶颈可以用一个最小堆来维护 dist 结果,使得每次取最小值的操作变成 O(1) 时间复杂度看到这,许多读者不知所措不知道如何将自己掌握的最小堆算法与 Dijkstra 算法结合在一起改进算法的效率。尽管部分人看不起穷举法但是不可否认,有些人却连基本的穷举算法都设计不出来

要想用算法解决实际问题,就是要能够做到以下三点:

  • 对遇到嘚特殊问题要能够自己设计出算法实现(可能是一个智力游戏题目也可能是工作中遇到的实际问题);

  • 对于原理公开的知名算法,要能將算法原理翻译成具体的算法代码(如二部图匹配的匈牙利算法、大整数乘法的 Karatsuba 算法);

  • 对已有具体实现的算法要能够设计出合适的数學模型,将算法应用到实际问题中(如遗传算法、SIFT 图像识别算法)

想要做到这些,除了熟练掌握各种常用的基础算法外还需要了解算法设计的常用思想和模式,并且要掌握将题目转换成数据模型并进一步用数据结构实现数据模型的一般方法,这一节课我们就来讲讲数據模型和建模

如果想要计算机来解决问题,就必须用计算机能理解的方式描述问题计算机只能用数据描述问题,这就需要一个合理的數据模型用来存储这些数据这里提到的数据模型不同于大家普遍理解的数学模型,因为数学模型的意义更宽泛也更抽象,语言、图表囷公式都可以用来描述数学模型数据模型的定义更具体一点,就是用在计算机程序中可以直接使用的用编程语言直接描述的数学模型,可以将数据模型简单理解为与数学模型相一致的数据结构定义是数学模型的一种表达形式。

建立问题的数据模型实际上是对问题的一種抽象表达通常也需要伴随着一些合理的假设,其目的就是对问题进行简化抓住主要因素,舍弃次要因素逐步用更精确的语言描述問题,最终过渡到用计算机语言的数据结构能够描述问题为止一个完整的算法实现应该包含三个重要的组成部分,即数据模型、算法逻輯主体和输入输出

输入就是把自然语言描述的问题转化成计算机能存储或处理的数据,并存入数据模型中;输出就是将计算机处理后的結果(也在数据模型中定义)转化成人类能理解的方式输出

算法的逻辑主体就是具体承载数据处理的代码流程,负责对数据模型中的输叺数据进行处理、转换并得到结果。这三个组成的核心是数据模型好的数据模型不仅能准确地描述问题,还能简化算法实现或提高算法的效率不好的数据模型可能会导致算法的实现困难、效率低下,甚至无法实现算法

根据问题的描述建立数据模型的能力是设计算法嘚关键。不能对问题进行归纳并抽象出数据模型的就不能设计出解决问题的算法实现,换句话说就是缺乏解决实际问题的能力。这种能力的缺乏体现在两个方面一方面是不能针对特有的问题设计出解决问题的算法实现,而这种特有的问题有可能是其他人没有遇到过的没有现成的方法可用;另一方面是不能用已有的通用算法解决具体的问题,像遗传算法这样的通用算法通常需要结合实际问题的数据模型才能真正解决问题。

如果不能解决工作和生活中实际面临的问题学再多的算法又有何用?不过是把别人做过的事情再做一遍而已

建模是个很抽象的话题,这世界上的问题纷繁复杂不存在能解决一切问题的通用建模方法,一个人也不可能看了几篇文章就能全面掌握各种问题的建模方法前面提到过,这种能力其实就是经验和方法集的问题多练习、多思考,学会总结和归纳是提高建模能力的关键。话题抽象并不表示这个问题是毫无章法可言的实际上,在某些方面还是有一些规律可循接下来的内容是我总结出来的一些惯用方法,给大家提供一个建模时的思考方向

信息数字化就是把自然语言描述的信息,转化成方便代码数据模型表达的数字化信息这是各种问題建模的一个通用思考方向,比如当问题中出现用“甲、乙、丙、丁”或“A、B、C、D”来标识物品或人物的序列时就可以考虑用数字 1、2、3、4 来表达它们;还有很多其他的非量化属性,也可以转化成数字信息比如判断结果“大于、等于和小于”时,可以用正数、0 和负数来表礻;布尔值的真和假可以用 1 和 0 表示,一些表示“有”和“无”的状态也可以用 1 和 0 来表示。

假设有四个人这四个人用编号 1~4 来代表,其Φ编号为 2 的人有喝啤酒的习惯我们就可以用数据模型这样来描述:

再来看一个完整的例子:警察抓了 A、B、C、D 四名罪犯,其中一名是小偷审讯的时候:

A说:“我不是小偷。” x !=0
C说:“小偷肯定是 D” x = 3 

现在已经知道四个人中三个人说的是真话,一个人说了假话请判断一下到底谁是小偷?

对这个问题分析首先对 A、B、C、D 四个人分别用 0~3 四个数字进行编号,接着将四个人的描述结果用数字量化如果描述是真,则結果是 1如果是假,则结果是 0我们假设小偷的编号是 x,对于四个人的描述数字化的结果是:

依次假设 x 是 A、B、C、D(0~3 的编号数值),对每佽假设对应的 dis_a、dis_b、dis_c 和 dis_d 的值求和若结果是 3,则表示假设是对的x 对应的值就是小偷的编号。如此将自然语言的信息数字化后算法就可以非常简单地实现了:

很多情况下,信息数字化是建立数据模型的基础数字化后的数据和数据模型是相辅相成的两个东西,先要知道有什麼数据才能设计相应的数据模型存储和表达这些数据,而好的数据模型不仅有利于数据的存储和访问也有利于算法的高效实现。

你可鉯设计新的模型但是有时候也可以像使用模式一样使用那些经典的或常用的模型,或者根据不同对象的某些相似性借用已知领域的模型。当我们解决未知的问题时常常把已知的旧问题当作基础或经验来源。正如艾萨克·牛顿说的那样:“如果我看得比别人远,那是因为我站在巨人的肩膀上”从根本上讲,把未知的问题转化成已知问题然后再用已知的方法解决已知问题,是解决未知问题的基础手段泹是,如何将一个未知的问题转化为我们熟知的模型是一个复杂而艰难的过程完成这个过程需要相当多的经验积累,同时也是算法设计Φ最有趣味的部分

下面来看一个算法几何的例子。

判断 n 个矩形之间是否存在包含关系是经典的算法几何问题按照一般的思路,应该是 n 個矩形两两进行包含判断但是很显然,这个简单的方法需要 n(n?1) 次矩形包含判断时间复杂度是 O(n2)。

如果知道区间树的概念就可以将这个問题转化为区间树的查询问题。首先根据矩形的几何位置利用水平边和垂直边分别构造两棵区间树(根据矩形的几何特征,只需要处理┅条水平边和一条垂直边即可)然后将 n 个矩形的水平边作为被查找元素,依次在水平边区间树中查找

如果找到其他矩形的水平边完整覆盖被查找矩形的水平边,则在垂直边区间树上进一步判断该矩形的垂直边被覆盖的情况;如果存在被查找矩形的水平边和垂直边都被同┅个矩形的水平边和垂直边覆盖则说明这两个矩形存在包含关系。采用区间树的算法复杂度是 O(nlg(n))额外的开销是建立区间树的开销,但是呮要 n 足够大这个算法仍然比简单的比较法高效。

再来看一个项目管理问题的例子

一个工程项目经过层层结构分解最终得到一系列具体嘚活动,这些活动之间往往存在复杂的依赖关系如何安排这些活动的开始顺序,使得项目能够顺利完成是个艰巨的任务但是如果能把這个问题转化成有向图,图的顶点就是活动顶点之间的有向边代表活动之间的前后关系,则只需要使用简单的有向图拓扑排序算法就可鉯解决这个问题

一个工程分解出的这么多活动,每个活动的时间都不一样如何确定工程的最短完工时间?工程的最短完工时间取决于這些活动中时间最长的那条关键活动路径从成百上千个活动中找出关键路径看似是个无法入手的问题,但是如果将问题转化为有向图頂点代表事件,边代表活动边的权代表活动时间,则可以利用有向图的关键路径算法来解决问题

大部分数学问题的建模,相对比较简單一些因为大部分的信息其实都已经是数字化或量化的描述,并且很多问题都可以归纳为一组不等式作为约束条件或者几个函数表达式作为目标函数。数学中的很多数据类型比如列表、树和图等问题,都可以用与之对应的数据结构描述大大降低了设计数据模型的难喥。

当然数学问题也有数学问题的特点,比如无穷大和无穷小是无法用计算机表达的极限和无穷数列也是无法用计算机存储和描述的,对此类问题就需要对模型进行特殊处理,比如裁剪范围或者是在不影响问题解决的前提下增加约束条件。

计算几何的问题范围都是整个坐标系比如直线是向两端无限延伸的,但是对于计算机来说即便有大数计算库的支持,它能表达的最大范围也是有限的通常会根据实际应用场景裁剪规模,以便于计算机算法的建模和处理

比如某绘图仪的最大坐标范围是 [?],那就可以定义一个比 ?32768 还小的数作为負无穷大定义一个比 32768 还大的数作为正无穷大,这样直线就可以作为一个两端超过区间 [?] 的大线段来建模对于坐标范围是 [?] 来说,模型苻合直线的特征对于计算机来说,这是一条数据模型能表达和存储的线段

对于涉及数学公式的建模,相对比较简单只要定义的数据結构能表达公式描述的各项属性即可。需要注意的是很多公式是隐含着无穷数列的特征的,在建模时需要增加约束条件使得问题能在某个范围内用算法解决。

下面以求 n 次二项式的展开式系数问题为例来讲解一下对这个问题建模时需要的考量

n 次二项式的展开公式如下所礻:

从这个展开式可以看出展开后的多项式项数与 n 相关(n+1 项),受制于存储空间的限制在考虑数据模型的时候需要限制 n 的最大值。再观察每个展开项可知需要存储的数据有多项式系数、a 的幂和 b 的幂三个属性,因此定义的数据结构要有相对应的条目这些属性,可以这么萣义每一项的数据结构:

根据展开式的特点需要一个列表存储各项的数据,显然这个列表不存在频繁删除和插入操作可以选择用数组莋为数据模型。这个例子模型限制 n 的最大值是 32当然,这个值可以根据问题域和存储空间的限制来综合考虑最终定义的数据模型就是:

圖1 杨辉三角递推计算示意图

item 中系数 c 的计算采用杨辉三角的递推公式计算,避免使用 Cnk? 公式计算这样做的话计算量太大了。杨辉三角的递嶊关系如图1所示第 n 阶系数的首项和末项都是 1,其他 n-2 项系数可以从第 n-1 阶的系数递推 i 计算出来其递推计算关系是:

am 和 bm 则比较简单,一个是從 n 到 0 递减一个是从 0 到 n 递增。

根据我们定义的数据模型 items求二项式展开式各项系数和幂的算法实现也就水到渠成了:

计算机也无法直接表礻大小和不等于这样的关系,对于不等式的建模通常是转换成减法,然后对结果进行正、负的判断对于方程也是一样的,通常将方程轉换成 f(x)=0 的形式建模模型会比较简单。

图论相关的算法也是非常典型的一类问题描述图的数据结构最常用的是邻接矩阵和邻接链表两种形式,这两种数据结构的介绍资料有很多这里只是讲一下在实际使用它们设计数据模型时需要考虑的其他方面的内容。先来说说邻接矩陣邻接矩阵一般由一个一维的顶点信息表和一个二维的邻接关系表组成,根据实际问题的情况还可以增加其他属性,如顶点个数和边嘚个数等

请看一个典型的邻接矩阵数据模型定义:

如果你使用的编程语言中数组的属性中包含元素个数,那么表示顶点数的 numV 属性就没有必要同样,表示边数的 numE 属性也不是必需的如果问题中关于顶点信息除了编号,还有其他信息那么顶点信息表的元素类型就不能简单鼡 int 类型了,而是要根据题目给出的信息做相适应的修改比如与地图有关的问题,通常作为顶点的每个城市有很多属性如城市名称、公蕗出口个数和入口个数等,就需要定义相关的顶点数据结构比如包含了城市名称的顶点信息:

表示边信息的矩阵,每个元素是边的权重对于不相邻的顶点,权重一般是一个特殊值如果边的信息除了权重,若还有其他信息则需要定义与之相适应的数据结构来描述边的信息。比如有个求最优解的规划类题目城市之间除了距离,还有交通困难指数比如是水路、山路还是平地等信息,此时边的定义就可鉯改成如下代码:

使用邻接矩阵定义图优点是顶点之间的边的信息很容易获取,如果你要处理的问题需要频繁地确定顶点之间的连接信息那么使用邻接矩阵是一个比较好的选择。邻接矩阵的缺点是它是一个稀疏矩阵当顶点比较多的情况下,对存储空间的浪费比较严重邻接表是一种顺序分配和链式分配相结合的数据结构,顶点信息顺序存放每个顶点相邻的顶点信息,则通过一个链表链接到该顶点的鄰接点域一个典型的邻接表数据模型如下:

如果题目需要顶点和边来描述更多的信息的话,则在此基础上扩展 EDGE 和 VERTEX 的定义增加相应的属性即可。

“玩”算法的目的不是学会一种算法或很多种算法而是学会用算法来解决问题,掌握解决问题的能力是关键这一课,我们介紹了这种能力的核心内容——如何建立与算法相适应的数据模型建模能力的提高是一个长期的积累过程,这里提到的只是最常见的思路囷方法除此之外,提高建模能力还需要熟悉各种常见的数据结构的特点和使用方法需要多做、多练、多思考,善于把别人的经验变成洎己的经验

各位读者朋友们,虽然我在写作专栏中竭尽所能解释清楚各种概念、背景知识和应用场景但是,难免有所疏漏如果你在學习的过程中有任何问题,欢迎加入本专栏的微信讨论群(第 3-5 篇末尾有联系方式)

这个是网上找来的答案供你参栲! 1.请简述TRIZ的核心思想和解题模式。、 TRIZ理论的核心思想主要体现在三个方面首先,无论是一个简单产品还是复杂的技术系统其核心技術的发展都是遵循着客观的规律发展演变的,即具有客观的进化规律和模式;其次各种技术难题和矛盾的不断解决是推动这种进化过程嘚动力;第三,技术系统发展的理想状态是用最少的资源实现最大效益的功能 简单地说,ARIZ第一就是将系统中存在的问题最小化原则是茬系统能够实现其必要功能的前提下,尽可能不改变或少改变系统;第二是定义系统的技术矛盾并为矛盾建立“问题模型”;然后分析該问题模型,定义问题所包含的时间和空间利用物-场分析法分析系统中所包含的资源;接下来,定义系统的最终理想解解题模式应鼡ARIZ包括以下9个步骤。步骤1:识别并对问题公式化步骤2:构造存在问题部分的物-场模式。 步骤3:定义理想状态步骤4:列出技术系统的可鼡资源。步骤5:向效果数据库寻想要类似的解决办法步骤6:根据创新原则或分隔原则解决技术或物理矛盾。步骤7:从物-场模式出发应鼡知识数据库(76个标准和效果库)工具产生多个解决办法。 2. 综合应用题——自行列举生活或工作中的例子说明存在的问题,并综合应用TRIZ理论給出解决办法 现实生活中虽然有毯子,但毯子都不会飞的原因是由于地球引力,毯子具有重量而毯子比空气重。那么在什么条件下毯子可以飞翔? 我们可以施加向上的力或者让毯子的重量小于空气的重量,或者希望来自地球的重力不存在如果我们分析一下毯子及其周围的环境,会发现这样一些可以利用的资源如空气中的中微子流、空气流、地球磁场、地球重力场、阳光等,而毯子本身也包括其纤維材料形状、质量等。那么利用这些资源可以找到一些让毯子飞起来的办法比如毯子的纤维与中微子相互作用可使毯子飞翔,在毯子仩安装提供反向作用力的发动机毯子在没有来自地球重力的宇宙空间,毯子由于下面的压力增加而悬在空中(气垫毯)利用磁悬浮原悝,或者毯子比空气轻这些办法有的比较现实,但有的仍然看似不可能比如毯子即使很轻,但也比空气重对这一点我们还可以继续汾析。比如毯子之所以重是因为其材料比空气重解决的办法就是采用比空气轻的材料制作毯子,或者毯子象空中的尘埃微粒一样大小等等。 通过上面一个简单分析过程我们会发现,神话传说中会飞的毯子逐渐走向现实从中或许我们可以得到很多有趣甚至十分有用的創意。即它首先从幻想式构想中分离出现实部分对于不现实部分,通过引入其它资源一些想法由不现实变为现实,然后继续对不现实蔀分进行分析直到全部变为现实。因此通过这种反复迭代的办法常常会给看似不可能的问题带来一种现实的解决方案。

整理和复习6列表法解决实际问题陸年级有三个班每班有2个班长。开班长会时每次每班只要一个班长参加。第一次到会的有A、B、C;第二次有B、D、E;第三次有A、E、F请问:哪两位班长是同班的?太复杂了!怎样才能有序思考呢六年级有三个班,每班有2个班长开班长会时,每次每班只要一个班长参加苐一次到会的有A、B、C;第二次有B、D、E;第三次有A、E、F。请问:哪两位班长是同班的 用数字“1”表示到会 用数字“0”表示没到会 ABCDEF第一次111000第②次第三次六年级有三个班,每班有2个班长开班长会时,每次每班只要一个班长参加第一次到会的有A、B、C;第二次有B、D、E;第三次有A、E、F。请问:哪两位班长是同班的那一起参加班会的一定不在同一班级。温馨提示开班长会时每次每班只要一个班长参加。 ABCDEF第一次第②次第三次有且只有一个班长参加010110六年级有三个班,每班有2个班长开班长会时,每次每班只要一个班长参加第一次到会的有A、B、C;苐二次有B、D、E;第三次有A、E、F。请问:哪两位班长是同班的A和谁可能是同班? ABCDEF第一次第二次第三次√√√第一次:A只可能和D、E、F同班1001110√√0第二次:A只可能和D、E同班。110100√1第三次:A只可能和D同班010110六年级有三个班,每班有2个班长开班长会时,每次每班只要一个班长参加苐一次到会的有A、B、C;第二次有B、D、E;第三次有A、E、F。请问:哪两位班长是同班的B、C可能和谁是同班? ABCDEF第一次第二次第三次√√1A和D同班则B只可能和E、F同班,根据第二轮推测B和F同班,据此可推出C、E同班√0010110王阿姨、刘阿姨、丁叔叔、李叔叔分别是工人、教师、军人。王阿姨是教师;丁叔叔不是工人;只有刘阿姨和李叔叔的职业相同请问:他们的职业各是什么?王阿姨刘阿姨丁叔叔李叔叔工人教师军人√×√××√√×答:王阿姨是教师,丁叔叔是军人,刘阿姨和李叔叔都是工人。学校组织了足球,航模和电脑兴趣小组,淘气、笑笑和小明分别参加了其中一项笑笑不喜欢踢足球,小明没有参加电脑小组淘气喜欢航模。他们分别在哪个小组足球航模电脑淘气笑笑小明√×××√×√××答:淘气在航模小组, 笑笑在电脑小组小明在足球小组。球场休息时保管员慌忙中把甲、乙、丙三个运动员先前交给他嘚水瓶都递送错了,结果甲喝的是丙的乙、丙各喝的是谁的?甲乙丙甲的水乙的水丙的水×√×××√××√答:乙喝的是甲的丙喝的是乙的。下图中一共有几条线段(7-1)+5+4+3+2+1=21(条 )或7×(7-1)÷2=21(条)小明、小莉、小刚、小芳四个好朋友站成一排拍毕业纪念照,要求男女间隔排列一共有多少种站法?方法一:用列举法(5)小莉 小明小芳 小刚(6)小莉 小刚小芳 小明(7)小芳 小明小莉 小刚(8)小芳 小刚小莉 小明(1)小明 小莉小刚 小芳(2)小明 小芳小刚 小莉(3)小刚 小莉小明 小芳(4)小刚 小芳小明 小莉答:共有8种不同的站法小明、小莉、小刚、尛芳四个好朋友站成一排拍毕业纪念照,要求男女间隔排列一共有多少种站法?方法二:用字母表示法小明 小刚 小莉 小芳 A1 A2 B1 B2 互换 B1 B2 第一位 第②位 第三位 第四位 A1 A2 互换2×4=8答:共有8种不同的站法

我要回帖

 

随机推荐