随笔 - 48  文章 - 16 评论 - 1175 trackbacks - 23

.net asp web c# vb VS2005 VS2008 VS2003

    姓名 景春雷
    网名 1-2-3
    生日 1980.2.29
    城市 沈阳
《一升的眼泪》看完了。少有的几部看完了还有些舍不得的好剧。也开始意思到执着于那一丁点名利和私欲的自己是多么渺小。 11-29 19:59

与我联系

搜索

 

常用链接

我参与的团队

我的标签

随笔分类(47)

随笔档案(45)

文章分类(15)

相册

收藏夹(2)

积分与排名

  • 积分 - 155821
  • 排名 - 262

最新评论

阅读排行榜

评论排行榜

声明 本文并不是从教科书上抄下来的,而是笔者自己瞎想的,很可能有错误,请不吝批评指正。不要在答卷的时候使用本文内容,否则得0分之后果自负。另,本文的示例代码的语法使用的是《算法导论》的伪代码语法。

分治法简介

分治法是一种递归求解问题的方法,分为三个步骤:
    - 分解:将问题分为若干个子问题。
    - 解决:递归地求解每个子问题,直到子问题小到可以直接求解。
    - 合并:将每个子问题的解合并成为整个问题的解。

例如我们想实现一个求和算法 SUM(A, p, r)。算法的输入是一个长度为 n 的数组A,以及需要进行求和的起始下标 p 和结束下标 r,算法返回。伪代码如下

SUM(A, p, r)
1  if p ≥ r
2    then return A[p]
3    else return SUM(A, p, r-1) + A[r]

如果 A = [1,2,3,4],则 SUM(A,1,4) 将返回 10。

看下面的图示会对算法的运行情况有一个更直观的了解。

分解过程
          [1,2,3,4]
            /        \
      [1,2,3]      4
        /    \
   [1,2]    3
    /   \
 [1]   2
 /
1

合并过程
1      2
   \   /
     3      3
        \   /
         6      4
             \   /
              10


证明分治算法的正确性

循环不变式同样可以用来证明分治算法的正确性。只不过具体操作上稍有不同——我们不是从第一次递归之前开始证明,而是从第一次直接求解(即最后一次递归调用)时开始证明。一般过程为
初始化:在函数直接求解后,循环不变式成立。
保持:先假设函数内部的所有递归调用均满足循环不变式,再证明函数本身返回后,循环不变式仍然成立。
终止:“最外层”的函数调用返回后,算法结果一定是正确的。

证明 SUM(A, p, r) 是正确的

作为一个实例,证明 SUM() 函数的正确性。
首先,给出循环不变式:对于给定的长度为 n (n ≥ 1) 的数组A,对于任意满足 1 ≤ p ≤ r ≤ n 的整数 p 和 r,SUM(A, p, r) 的返回值为
初始化:当 p = r 时,SUM() 函数会直接返回 A[p]。另, r = p 时,=A[p]。循环不变式成立。
保持:假设 SUM(A, p, r) 内部执行的递归调用 SUM(A, p, r-1) 满足循环不变式,即 SUM(A, p, r-1) 的返回值是。由于在第3行执行了 return SUM(A, p, r-1) + A[r],所以SUM(A, p, r) 返回值满足循环不变式。
终止:当“最外层”的 SUM() 函数返回时,返回值一定是,算法是正确的。

一个更为复杂的例子

这是《算法导论》的思考题7-3,STOOGE 排序。

STOOGE-SORT(A, i, j)
1  if A[i] > A[j]
2    then exchange A[i] « A[j]
3  if i+1 ≥ j
4    then return
5  k ¬ ë(j-i+1)/3û    # 下取整
6  STOOGE-SORT(A, i, j-k)    # 前 2/3
7  STOOGE-SORT(A, i+k, j)   # 后 2/3
8  STOOGE-SORT(A, i, j-k)    # 再次前 2/3

这是一个号称很厉害的排序算法。说它厉害并不是因为它有多么的快,事实上它比插入排序还要慢。它的厉害之处在于,用一般的掰手指头的方法绝对无法证明它的正确性。让我们用循环不变式来证明它的正确性。

循环不变式:在每次 STOOGE-SORT(A, i, j) 返回时,数组 A[i..j] 是有序的。

初始化:当 i+1 ≥ j 时,不再进行递归,函数会立即返回。由于执行了第1、2行,可保证 A[i] ≤ A[j]。因为 i+1=j,所以数组A[i..j]有序。循环不变式成立。

保持:假设 STOOGE-SORT(A, i, j) 内部对STOOGE-SORT() 的所有递归调用都满足循环不变式,即STOOGE-SORT(A, i, j-k) 可使 A[i..j-k] 有序,STOOGE-SORT(A, i+k, j) 可使 A[i+k..j] 有序。
∵ k = ë(j-i+1)/3û
∴ j-i+1 ≥ 3k
∴ (j-i+1)-2k ≥ k

∵ A[i..j-k] 与 A[i+k..j] 重叠的部分为 A[i+k..j-k],共(j-k)-(i+k)+1 = (j-k+1) - 2k ≥ k 个元素
     而 A[i..j-k] 与 A[i+k..j] 不重叠的部分为 A[j-k+1..j] 共 j-(j-k+1)+1 = k 个元素。即,A[i..j-k] 与 A[i+k..j] 重叠部分的元素个数大于等于不重叠部分的元素个数。
∴ 在执行了第 6、7 行的STOOGE-SORT(A, i, j-k) 和 STOOGE-SORT(A, i+k, j),分别使A[i..j-k] 和 A[i+k..j]有序后,可保证 A[j-k+1..j] 中的元素是 A[i..j] 中最大的 k 个元素,且是有序的。
∵ 在执行了第8行的STOOGE-SORT(A, i, j-k)后,可保证 A[i..j-k] 有序。
∴ 综上,可保证在 STOOGE-SORT(A, i, j) 返回后,A[i..j] 是有序的。循环不变式成立。
 
终止:在最外层的 STOOGE-SORT(A, 1, n) 返回后,可使数组 A 有序,算法是正确的。

证毕

posted on 2007-09-10 09:30 1-2-3 阅读(722) 评论(12)  编辑 收藏 网摘 所属分类: 算法学习

FeedBack:
@证明 SUM(A, p, r) 是正确的
循环不变量顾名思义应该用在证明循环中(不是我naive)

如果为了证明递归Sum,其实只要做类似数学归纳法的工作.
首先SUM(A,p,p)正确
假设Sum(A,p,r-1)正确
由于Sum(A,p,r)=Sum(A,p,r-1)+r也正确
得证.

循环不变量的使用是:
1.初始状态正确
2.每次循环后正确
3.程序会结束

所以循环不变量一般用于证明像插入排序这种一步一步接近问题N的算法.
证明递归最好用数学归纳法.
  回复  引用    
#2楼 [楼主] 2007-12-20 11:33 1-2-3      
@liangliangzai
您说得很对。其实循环不变式也是用了数学归纳法的思想,不过用在递归证明上是有些别扭。
  回复  引用  查看    
#3楼 [楼主] 2007-12-20 11:35 1-2-3      
@liangliangzai
使用归纳法也应该有“程序可以正确结束递归”这样的证明吧?
  回复  引用  查看    
@STOOGE-SORT
也应该采用递归式证明而不是循环不变量.其实循环不变量证明是一种特殊的递归式证明(尾递归)

当N=2成立,既交换排序.

假设STOOGE-SORT正确
为描述方便将数组分为p1,p2,p3

STOOGE-SORT(A, i, j-k)
=>p1 和 p2 有序
=>for each element: p1 < p2

STOOGE-SORT(A, i+k, j)
=>p2 和 p3 有序
=>p2 < p3
=>p1 < p3

STOOGE-SORT(A, i, j-k)
=>p1 和 p2 和 p3 有序
=>p1 < p2 <p3
=>A有序 #

简单分析复杂度:

T(1) = 1
T(n) = 3(T/(3/2)) + 1

利用master method
a = 3
b = 3/2
T(n) = O(n^2.7)
  回复  引用    
#5楼 [楼主] 2007-12-20 12:10 1-2-3      
@liangliangzai
非常感谢您的指导。我的《算法导论》看到100页就扔下了,不过俺不会半途而废的,等俺看完《领域驱动开发》一定要把它看完。您的邮箱俺记下了,要是俺碰到想一个星期仍想不明白的问题,一定会向您请教的,千万别嫌俺笨啊,先行谢过!
  回复  引用  查看    
博主太客气. 我还是个学生,所以这方面比较熟. 过些年估计都忘的差不多了.
最近发现你的博客, 天天都看, 因为发现我们研究的东西很相近, 非常喜欢你轻松诙谐的风格, 能把这么多难懂枯燥的概念讲得如此引人入神, 实在佩服, 希望有空多交流, 和高手过招才能进步, 呵呵.
  回复  引用    
#7楼 [楼主] 2007-12-20 13:18 1-2-3      
@liangliangzai
还是个学生?不会吧,现在的大学生不是整天翘课玩游戏的么?居然还有您这么厉害的,能不能问问您是哪个学校的呀?
  回复  引用  查看    
老大怎么好久不更新了. 期待你的大作呢.
最近在帮别人公司做asp.net方面的开发, 有什么问题咨询你啊, 不吝请教俄
msn: mikezhuyuan@hotmail.com
  回复  引用    
#9楼 [楼主] 2008-01-14 08:20 1-2-3      
@liangliangzai
最近觉得自己的基础知识不是很扎实,正在温习基础知识,边看书边总结,会总结几篇基础知识的文章,其实也就是抄书啦。我这就在MSN里边加你。
  回复  引用  查看    
您好,我正在看这个循环不变式,不过看不明白。你的这篇文章我也没能看明白。你能给我说说么? 谢谢
  回复  引用    
@1-2-3
不是所有人都跷课玩游戏的,比如我,就很努力!!哇哈哈

  回复  引用    
#12楼 [楼主] 2008-09-01 08:34 1-2-3      
@bendanshiwo
加油啊,书到用时方恨少,偶前一阵刚刚恶补了一下微积分,呵呵。
  回复  引用  查看    

标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2007-10-08 14:30 编辑过
Google站内搜索

China-pub 计算机图书网上专卖店!6.5万品种 2-8折!
近千种 9-95 新二手计算图书火热销售中!
开发者征途系统新作:《设计模式——基于C#的工程化实现及扩展》



相关文章:

相关链接: