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

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. 关于TCP/IP协议栈

    1. TCP/IP协议栈 与OSI参考模型不同,TCP/IP协议栈共有4层,其中网络接口层对应OSI中的物理层和数据链路层,应用层对应OSI中的应用层.表示层和会话层. 在网络接口层的主要协议有:AR ...

  2. WebGIS前端瓦片地图显示原理及实现

    目前,有很多WebGIS开发包,ArcGIS API for JS.OpenLayers.LeafLetjs等为我们从事WebGIS开发的人封装了很多强大的功能.我们很方便的使用这些库的时候,也让我们 ...

  3. 一个小时学会MySQL数据库

    随着移动互联网的结束与人工智能的到来大数据变成越来越重要,下一个成功者应该是拥有海量数据的,数据与数据库你应该知道. 一.数据库概要 数据库(Database)是存储与管理数据的软件系统,就像一个存入 ...

  4. vue入门 vue与react和Angular的关系和区别

    一.为什么学习vue.js vue.js兼具angular.js和react的优点,并且剔除了他们的缺点 官网:http://cn.vuejs.org/ 手册:http://cn.vuejs.org/ ...

  5. 1639: [Usaco2007 Mar]Monthly Expense 月度开支

    1639: [Usaco2007 Mar]Monthly Expense 月度开支 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 593  Solved: ...

  6. java关于map用来筛选的用法

    我有一个实体 PropTemplateItem{id,名称,父节点,模版id},父节点为root是定义为根节点. 例如数据: 001,颜色,root,123 002,白色,001,123 003,红色 ...

  7. IE浏览器下使用AJAX登陆接口请求缓存与登陆不了的问题解决

    问题: 在IE浏览器下面,登陆的时候老是登陆不上,但是打开控制台的时候再登陆却能登陆上. 分析: 通过抓包,发现,在不打开控制台的时候,少了一个接口的请求,却返回了改接口的返回信息,但是返回信息并不是 ...

  8. canvas的使用

      1.概念 canvas一般就是用来绘制图像的     2.基本知识 上下文对象   var canvas = doucment.getElementById("canvas") ...

  9. 页面异步发送json数据封装controller方法形参 pojo中,使用@requestBody和不使用它页面的异步方式不同之处

    方式一: 使用@requestBody 方式二 : 直接封装到pojo的方式

  10. iOSiOS开发之数据存储之NSKeyedArchiver

    1.概述 NSKeyedArchiver归档和plist文件存储不同的是NSKeyedArchiver可以直接保存对象.如果对象是NSString.NSDictionary.NSArray.NSDat ...