算法导论学习笔记5 随机算法

栏目: 编程工具 · 发布时间: 5年前

内容简介:我觉得Marceau教授说的挺有道理. 我的想法是把i=2的时候做为初始状态, 只要证明交换过A[1]之后, 每种可能的子数组A[1..1]的概率是1/n. 这个结论应该是”明显”的.按我的理解应该是不可以的. 如果初始的时候, 第一个数字是X的概率小, 那么程序跑完之后, 第一个数字不是X的概率就会变大, 而不 1/n 了.我们来写程序来验证一下 5.3-1 和 5.3-2 的结果吧.

5.3-1

我觉得Marceau教授说的挺有道理. 我的想法是把i=2的时候做为初始状态, 只要证明交换过A[1]之后, 每种可能的子数组A[1..1]的概率是1/n. 这个结论应该是”明显”的.

5.3-2

按我的理解应该是不可以的. 如果初始的时候, 第一个数字是X的概率小, 那么程序跑完之后, 第一个数字不是X的概率就会变大, 而不 1/n 了.

我们来写程序来验证一下 5.3-1 和 5.3-2 的结果吧.

package main

import (
	"fmt"
	"math/rand"
	"time"
)

func shuffle(array []int) {
	rand.Seed(time.Now().UnixNano())

	var (
		tmp   int
		index int
		n     = len(array)
	)

	for i := 0; i < n; i++ {
		index = rand.Intn(n-i) + i
		tmp = array[index]
		array[index] = array[i]
		array[i] = tmp
	}
}

func generate_array(n int) []int {
	array := make([]int, n)
	for i := 0; i < n; i++ {
		array[i] = i
	}
	return array
}

func main() {
	var (
		loop = 6000
		N    = 3
	)

	for i := 0; i < loop; i++ {
		array := generate_array(N)
		shuffle(array)
		fmt.Printf("%v\n", array)
	}
}

看5.3-1的结果, 还是很平均的.

% go run 5.3.1.go | sort | uniq -c
 990 [0 1 2]
1038 [0 2 1]
 965 [1 0 2]
 991 [1 2 0]
1002 [2 0 1]
1014 [2 1 0]

5.3-2的结果, 第一位永远不是0

package main

import (
	"fmt"
	"math/rand"
	"time"
)

func shuffle(array []int) {
	rand.Seed(time.Now().UnixNano())

	var (
		tmp   int
		index int
		n     = len(array)
	)

	for i := 0; i < n-1; i++ {
		index = rand.Intn(n-i-1) + i + 1
		tmp = array[index]
		array[index] = array[i]
		array[i] = tmp
	}
}

func generate_array(n int) []int {
	array := make([]int, n)
	for i := 0; i < n; i++ {
		array[i] = i
	}
	return array
}

func main() {
	var (
		loop = 6000
		N    = 3
	)

	for i := 0; i < loop; i++ {
		array := generate_array(N)
		shuffle(array)
		fmt.Printf("%v\n", array)
	}
}
% go run 5.3.2.go | sort | uniq -c
2951 [1 2 0]
3049 [2 0 1]

5.3-3

这些题目.. 都是谁想来杀我脑细胞的..

完全用教材中的示例去套已经不行了, 得到的结果貌似是”不能证明”. 但是直觉感觉是可以的. 先放下, 来写个程序验证下吧.

package main

import (
	"fmt"
	"math/rand"
	"time"
)

func shuffle(array []int) {
	rand.Seed(time.Now().UnixNano())

	var (
		tmp   int
		index int
		n     = len(array)
	)

	for i := 0; i < n-1; i++ {
		index = rand.Intn(n)
		tmp = array[index]
		array[index] = array[i]
		array[i] = tmp
	}
}

func generate_array(n int) []int {
	array := make([]int, n)
	for i := 0; i < n; i++ {
		array[i] = i
	}
	return array
}

func main() {
	var (
		loop = 6000
		N    = 3
	)

	for i := 0; i < loop; i++ {
		array := generate_array(N)
		shuffle(array)
		fmt.Printf("%v\n", array)
	}
}

运行结果

% go run 5.3.3.go | sort | uniq -c
1316 [0 1 2]
 689 [0 2 1]
1331 [1 0 2]
1309 [1 2 0]
 682 [2 0 1]
 673 [2 1 0]

果然不行.. 想了一会, 用一个反例来说明吧.

比如 0 1 2 这三个排列好的数字, 用5.3.3的程序来跑, 我们来算一下跑完之后2出现在第一位的概率, 是 4/27 . 这样应该能证明这个算法是错误的了. 和我最开始的直觉是反过来的.


以上所述就是小编给大家介绍的《算法导论学习笔记5 随机算法》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

C++程序设计

C++程序设计

谭浩强 / 清华大学出版社 / 2004-6-1 / 36.00元

《C++程序设计》作者深入调查了我国大学的程序设计课程的现状和发展趋势,参阅了国内外数十种有关C++的教材,认真分析了学习者在学习过程中遇到的困难,研究了初学者的认识规律。在本书中做到准确定位,合理取舍内容,设计了读者易于学习的教材体系,并且以通俗易懂的语言化解了许多复杂的概念,大大减少了初学者学习C++的困难。C++是近年来国内外广泛使用的现代计算机语言,它既支持面向过程的程序设计,也支持基于对......一起来看看 《C++程序设计》 这本书的介绍吧!

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

MD5 加密
MD5 加密

MD5 加密工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具