———————————————————————————

First priority is to make you code ** CLEAR and CORRECT, but ** PERFORMANCE is also an essential, Keep Asking: How long will my program take, as a function of Input Size?

程序首先要简洁正确,性能也不可忽视

总是记得问自己:不同的输入情况下,我的程序的性能会如何?

———————————————————————————

算法分析,枯燥抽象,我的粗浅了解只停留在复杂度(big-Oh)、运行时间、占用内存上,很零散。《算法4》的讲解思路很有一套模式,感觉我也尝试做了一时刻的科学研究。

基本思路

开篇作者提出两个大家非常关心的两个问题:

这个程序多长时间跑完?

为什么报错“内存不足”了?

解决此类关于算法/程序分析的问题,作者建议的思路抽象、烧脑,但是系统、普世智慧:

Base on the ** Scientific Method,

Apply the ** Mathematical Analysis
to develop concise cost models

Do the ** Experimental Studies** to validate these models

基于科学研究的方法,

使用数学分析产生算法成本模型,

通过各种试验验证这些模型。

这是算法分析的大方向,其实我们也可以拿来用在很多方面,以后再研究。

科学方法 (OHPVV)

科学方法是科学家们用来研究理解现实世界的,我们进行算法分析的时候也可以套用这一方法,我简称为 OHPVV:

观察(Observe)

假设(Hyperthesize)

预测(Predict)

验证(Verify)

确认(Validate)

科学家这样做:

观察现实世界的问题现象,清楚的进行表述,通常进行具体的量化,比如牛顿发现苹果从树上往地上掉,当时他已经知道是由于重力的吸引,他想:如果苹果树长得更高,像月球那么高是不是还会掉呢?为什么月球没有掉下来呢?

对前面观察到的现象可能的答案进行猜想和假设,他设想月球受到一个向心力的作用,在做圆周运动,所以不会掉。

之后根据假设和设想,进行预测,验证自己的预测,并最终确认万有引力的假说。

将科学方法应用于算法分析中

那我们进行算法分析的时候如何借鉴这种科学方法呢?

  1. 观察程序在给定的不同输入情况下,运行多久?

    可以在程序的关键代码段执行前后加入计时代码,计算duration。
long start = System.currentTimeMillis()
.......<code>
long end = System.currentTimeMillis()
long duration = (start - end ) /1000.0;

这里容易忽视的一点是,程序的输入(Input Size)很关键。大文件和小文件的处理时间肯定不一样,算法分析的一个重点就是,如何保证程序在大量输入的情况下,依然可以在合理的时间内运行完。

  1. 建立一套数学模型,模拟计算程序运行时间
  • Develop an input model, including a definition of the problem size
  • Identify the inner loop
  • Define a cost model that includes operations in the inner loop
  • Determine the frequency of execution of those operations of the given input.

简单的说就是,界定程序的输入模型,找出程序的核心耗时代码块(通常循环语句比较占时),给出核心循环代码块中操作代码的成本模型(耗时),确定对于不同的输入模型(比如最坏情况下),这些操作代码的执行频率。

套用二八原则,就是大多数程序的运行时间取决于一小部分核心代码块的算法实现。

举例分析:Binary Search

public static int rank(int key, int[] a){
int lo=0;
int hi = a.length -1;
while (lo <=hi){
int mid = lo + (hi - lo) / 2;
if (key < a[mid]) hi = mid - 1;
else if (key > a[mid]) lo = mid + 1;
else return mid;
}
return -1;
}

输入模型:array a[N], size of N

核心循环块: while loop

成本模型:数组值之间的比较操作

运行频次分析:最坏情况下是 lgN+1

3 . 应用算法并进行试验、校正算法

这是算法分析的基本套路,掌握起来。至于具体的成本分析和频次分析这里不具体展开,后面会单独再写。

那现在做好算法分析了,接下来就是改进算法,测试,改进再测试了。

总结

当程序员解决一个新问题的时候,建议以下的策略:

Always keep asking "How long will it take, as a function of the input size?"

1。参考经典,简洁正确的实施代码

2。进行算法分析,分析:

  • 输入(input model)
  • 核心代码块(inner loop)
  • 成本模型(cost model)
  • 运行频次分析(analysis)

分析最坏情况很重要。

3。改进算法

4。测试新算法,重复2,3,4

算法分析很烧脑、费时,一般需要比较专业的人士做,但任何普通的程序员在日常工作中学会一些算法分析,对改进程序的性能,以及提升自己早日成为更专业人士,功不可没。

另外还有一点,数学真的很重要,很重要,很重要,后悔当初没有好好学习数学了。学生时代家长老师们挂在嘴边的话,“学好数理化,走遍天下都不怕”,现在想想,很有道理。

《算法4》读书笔记 1.4 - 算法分析(Analysis of Algorithm)的更多相关文章

  1. 数据结构与算法JavaScript 读书笔记

    由于自己在对数组操作这块比较薄弱,然后经高人指点,需要好好的攻读一下这本书籍,原本想这个书名就比较高深,这下不好玩了.不过看着看着突然觉得讲的东西都比较基础.不过很多东西,平时还是没有注意到,故写出读 ...

  2. 《java数据结构和算法》读书笔记

    大学时并不是读计算机专业的, 之前并没有看过数据结构和算法,这是我第一次看.         从数据结构方面来说:                数组:最简单,遍历.查找很快:但是大小固定,不利于扩展 ...

  3. 程序语言的奥妙:算法解读 ——读书笔记

    算法(Algorithm) 是利用计算机解决问题的处理步骤. 算法是古老的智慧.如<孙子兵法>,是打胜仗的算法. 算法是古老智慧的结晶,是程序的范本. 学习算法才能编写出高质量的程序. 懂 ...

  4. KMP算法_读书笔记

    下面是KMP算法的实现伪代码: KMP_MATCHER ( T, P ) . n = T.length . m = P.length . next = COMPUTE_PREFIX_FUNCTION ...

  5. 【FSFA 读书笔记】Ch4 Volume Analysis & Cr 5 PC-based Partitions

    Volume Analysis 1. “卷”可以理解为从逻辑上对物理存储设备的重新编制,便于操作系统管理. (A volume is a collection of addressable secto ...

  6. <算法图解>读书笔记:第4章 快速排序

    第4章 快速排序 4.1 分而治之 "分而治之"( Divide and conquer)方法(又称"分治术") ,是有效算法设计中普遍采用的一种技术. 所谓& ...

  7. <算法图解>读书笔记:第3章 递归

    第3章 递归 3.1 递归 程序调用自身的编程技巧称为递归( recursion).递归做为一种算法在程序设计语言中广泛应用. 一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一 ...

  8. <算法图解>读书笔记:第2章 选择排序

    第2章 选择排序 2.1 内存的工作原理 需要将数据存储到内存时,请求计算机提供存储空间,计算机会给一个存储地址.需要存储多项数据时,有两种基本方式-数组和链表 2.2 数组和链表 2.2.1 链表 ...

  9. <算法图解>读书笔记:第1章 算法简介

    阅读书籍:[美]Aditya Bhargava◎著 袁国忠◎译.人民邮电出版社.<算法图解> 第1章 算法简介 1.2 二分查找 一般而言,对于包含n个元素的列表,用二分查找最多需要\(l ...

随机推荐

  1. 【Spring】使用Spring和AMQP发送接收消息(上)

    讲AMQP之前,先讲下传统的JMS的消息模型,JMS中主要有三个参与者:消息的生产者.消费者.传递消息的通道(队列或者主题),两种消息模型如下:通道是队列: 通道是队列: 通道是主题: 在JMS中,虽 ...

  2. canvas的beginPath和closePath分析总结,包括多段弧的情况

    参考博文: Html5 canvas画图教程17:论beginPath的重要性 先看两个例子 例1: <canvas id="myCanvas" width="30 ...

  3. linux 私房菜 CH5 笔记

    知识点 linux 大小写敏感 接口的切换 [Ctrl] + [Alt] + [F1] ~ [F6] :文字接口登入 tty1 ~ tty6 终端机: [Ctrl] + [Alt] + [F7] :图 ...

  4. SSH登录与增删改查demo详解+源代码

    点击下载,测试绝对可用SSH整合框架登录加增删改查demo 下载地址:http://download.csdn.net/detail/qq_33599520/9784679   一.框架概述 spri ...

  5. resin远程调试配置,connection refused问题解决

    http://john521.iteye.com/blog/1879805 这篇博客中讲的很好. 我在配置的过程中遇到了几个问题,记录一下: 1. 调试服务器监听的端口号,百度的开发机都限制了端口在某 ...

  6. SQL基本编程,分支语句,循环语句,存储过程,触发器

    基本编程: 定义变量 declare @变量名 数据类型 赋值 set @变量名 = 值 select @变量名 = 值 取值打印 select @变量名 print @变量名 映射到结果集 打印到消 ...

  7. php文件基本操作与文件管理功能

    文件的基本操作 先来看一下PHP文件基础操作,请看强大注释 <body> <?php var_dump(filetype("./img/11.png")); // ...

  8. JavaScript当页面关闭时向后台发送请求

    今天做项目时遇上一个需求,当浏览器或页面关闭时将数据存储到数据库内.实现思想是采用js监测onunload然后发送请求.结果失败,刷新可以发送但是关闭并不能,整了一整天并没有解决,最后找到了解决办法. ...

  9. 如何在container中编译dotnet的eShopOnContainers

    准备的软件   问题 Image下载问题 以下就是为啥要有最后一个软件(我是使用版): SQLSever for Linux 内存需求 需要编译Image   成功搞定 参考 Welcome to t ...

  10. Java语言定义的线程状态分析

    说到线程,一定要谈到线程状态,不同的状态说明线程正处于不同的工作机制下,不同的工作机制下某些动作可能对线程产生不同的影响. Java语言定义了6中状态,而同一时刻,线程有且仅有其中的一种状态.要获取J ...