Greedy Algorithm贪心算法

Greedy Algorithms Greedy Algorithms

Dr. Zhenyu He

Autumn 2008

1

16

Greedy Algorithms z 16 Greedy Algorithms

Similar to dynamic programming. Used for optimization problems.

2z

z

Optimization problems typically go through a sequence of steps, with a set of

choices at each step.

For many optimization problems, using dynamic programming to determine

z

y p p ,g y p g g the best choices is overkill (过度的杀伤威力).

Greedy Algorithm: Simpler, more efficient

16

Greedy Algorithms z

16 Greedy Algorithms

Greedy algorithms (GA) do not always yield 3

y g ()y y

optimal solutions, but for many problems they do.

161the activity selection problem

16.1, the activity-selection problem (活动安排)16.2, basic elements of the GA; knapsack prob.

(贪婪算法的基本特征;背包问题)

16.3, an important application: the design of data compression (Huffman) codes. (哈夫曼编码)16.5, unit-time tasks scheduling

6.5,u t t e tas s sc edu g (有限期作业调度)

16

Greedy Algorithms z

16 Greedy Algorithms

The greedy method is quite powerful and works 4

g y q p

well for a wide range of problems:

minimum-spanning-tree algorithms (Chap 23)

minimum-spanning-tree algorithms (Chap 23)

(最小生成图)

h t t th f i l (Ch 24)

shortest paths from a single source (Chap 24)(最短路径)

set-covering heuristic (Chap 35).

(集合覆盖)

First example:Activity Selection First example: Activity Selection

Horseback Riding (骑马)

5

Canoeing (独木舟)

Surfing (冲浪)

Driving

Swimming Rock Climbing (攀岩)

z

9

1011121314151617

How to make an arrangement to have the more activities?

S1Sh i i fi 短优原

S1. Shortest activity first (最短活动优先原则)Swimming , Driving

S2First starting activity first

S2. First starting activity first

(最早开始活动优先原则)Horseback Riding , Driving

S3. First finishing activity first (最早结束活动优先原则)

Swimming , Rock Climbing , Surfing

161An activity selection problem 16.1 An activity-selection problem

6

i i i i

z

n activities require exclusive use of a common resource.Example, scheduling the use of a classroom.playground

p e,sc edu g e use o c ss oo

(n 个活动,1 项资源,任一活动进行时需唯一占用该资源)

Set of activities S = {a 1, a 2, . . . , a n }.

a i needs resource during period [s i , f i ), which is a half-open interval, where s i is start time and f i is finish time.

Goal:Select the largest possible set of nonoverlapping (mutually

Goal: Select the largest possible set of nonoverlapping (mutually compatible) activities. (安排一个活动计划,使得相容的活动数目最多)Other objectives: Maximize income rental fees , …j ,

161

An activity selection problem

z

16.1 An activity-selection problem

n activities require exclusive use of a common resource.

7

Set of activities S = {a1, a2, . . . , a n}

a i needs resource during period [s i , f i )

l S fi i i

z Example: S sorted by finish time:

Maximum-size mutually

Maximum size mutually

compatible set:

{a1 , a3 , a6 , a

,a3,a6,a8}.

Not unique: also

{a2 , a5 , a7 , a9}.

16.1.1 Optimal substructure of activity selection

Space of subproblems 8

z S ij = {a k ∈S : f i ≤ s k < f k ≤ s j }

= activities that start after a i finishes & finish before a j starts z

Activities in S ij are compatible with

all activities that finish by f i (完成时间早于f i 的活动), and ll ti iti th t t t li th z

all activities that start no earlier than s j .

To represent the entire problem, add fictitious activities:a 0=[0);1=[“

z

0 = [﹣∞, 0); a n+1 = [∞, “∞+1”)We don’t care about ﹣∞ in a 0 or “∞+1” in a n+1.

Then S = S 0,n+1

. Range for S ij is 0 i, j n + 1.,g j ≤,j ≤

16.1.1 Optimal substructure of activity selection Space of subproblems 9

z z

p p

S ij = {a k ∈S : f i ≤ s k < f k ≤ s j }

Assume that activities are sorted by monotonically increasing finish time

Assume that activities are sorted by monotonically increasing finish time (以结束时间单调增的方式对活动进行排序)

f 0 ≤ f 1 ≤ f 2 ≤ · · · ≤ f n < f n+1 (if i ≤ j, then f i ≤ f j )

(16.1)11

10

98

7

6

5

4

3

2

1

123456

7891011121314

16.1.1 Optimal substructure of activity selection

if 012···n

Then i ≥ j S ij =

i k

if f 0 ≤ f 1 ≤ f 2 ≤ ≤ f n < f n+1 (if i ≤ j, then f i ≤ f j ) (16.1)Proof If there exists a k ∈S ij , then

f i ≤ s k < f k ≤ s j < f j f i < f j .

z

But i ≥ j f i ≥ f j . Contradiction.

So only need to worry about with 0 ≤i

are ij S ij

16.1.1 Optimal substructure of activity selection

11

S th t l ti t i l d H 2b b z

Suppose that a solution to S ij includes a k . Have 2 sub-prob S ik (start after a i finishes, finish before a k starts)S kj (start after a k finishes, finish before a j starts)z

Solution to S ij = (solution to S ik )∪{a k }∪(solution to S kj )

Since a k is in neither of the subproblems, and the subproblems are disjoint |solution to S |=|solution to ik |+1+|solution to kj |z

disjoint, | solution to S | = | solution to S ik | + 1 + | solution to S kj | .Optimal substructure: If an optimal solution to S ij includes a k , then the solutions to S ik and S kj used within this solution must be optimal ll (l t d t t)z

as well. (use usual cut-and-paste argument).Let A ij = optimal solution to S ij ,

so A ij = A ik ∪{a k ∪A kj (16.2)so j {}j ,

assuming: S ij is nonempty; and we know a k .

()

A i

l i

z

16.1.2 A recursive solution Let c[i, j ] = size of maximum-size subset of mutually compatible activities in

ij c[i j]ij 12

i ≥ j S ij = c[i, j ] = 0.

z S ij .(c[i,j] 表示S ij 相容的最大活动数)If S ij ≠ , suppose that a k is used in a maximum-size subsets of mutually S ij .Then c[i j]=c[i k]+1+c[k j ]z

Then c[i, j] = c[i, k] + 1 + c[k, j ] .

But of course we don’t know which k to use, and so

0if Sij = (16.3)

0 , if Sij ,

c [i , j ] =

max{c [i , k ] + c [k , j ] + 1} , if Sij ? .

 

i

k ij

a S ∈

16.1.3 Converting a DP solution to a greedy solution

 0 , if S ij = ,

] 13

 i < k < j c [i , j ]

= max{c [i , k ] + c [k , j ] + 1} , if S ij ? .

(16.3)

z

 a k S ij

It may be easy to design an algorithm to the problem based on recurrence

(16.3).

Di t i l ith (l it ?)

z

Direct recursion algorithm (complexity?)Dynamic programming algorithm (complexity?)Can we simplify our solution?

16.1.3 Converting a DP solution to a greedy solution

Theorem 16.1L t d l t b th ti it i ith th li t fi i h ti 14

Let S ij ≠ , and let a m be the activity in S ij with the earliest finish time: f m =min {f k : a k ∈S ij }. Then

1. a m is used in some maximum-size subset of mutually compatible activities of S i j .(a m 包含在某个最大相容活动子集中)

2. S im = , so that choosing a m leaves S mj as the only nonempty

subproblem.

(仅剩下一个非空子问题S mj )p j 11

10

98

7

6

5

4

3

2

1

123456

7891011121314

16.1.3 Converting a DP solution to a greedy solution

Theorem 16.1L t d l t b th ti it i ith th li t fi i h ti 15

Let S ij ≠ , and let a m be the activity in S ij with the earliest finish time: f m =min {f k : a k ∈S ij }. Then

1. a m is used in some maximum-size subset of mutually

compatible activities of S i j .(a m 包含在某个最大相容活动子集中)2. S im = , so that choosing a m leaves S mj as the only

nonempty subproblem. (仅剩下一个非空子问题S mj )

Proof

2. Suppose there is some .Then Then a S ∈i l l m m l m f s f s f f f <<≤

and it has an earlier finish time than , which contradicts our choice of

l im

m f l

im

im

a S S ∈?=?

16.1.3 Converting a DP solution to a greedy solution

Theorem 16.1 Let S ij ≠ , and let a m be the activity in S ij with the li t fi i h ti i {f }Th

16

earliest finish time: f m = min {f k : a k ∈S ij }. Then 1. a m is used in some maximum-size subset of mutually

compatible activities of S i j .(a m 包含在某个最大相容活动子集中)p j Proof 1. Let A ij be a maximum-size subset of mutually Compatible

activities in ij Order activities in ij in monotonically increasing activities in S ij . Order activities in A ij in monotonically increasing order of finish time. Let a k be the first activity in A ij .If a k = a m , done (a m is used in a maximum-size subset).

a k a m

Otherwise construct =A ij }(replace k by )

first activity in A ij to finish. f m ≤f k a m doesn’t overlap anything Otherwise, construct B ij A ij -{a k }∪{a m } (replace a k by a m ).Activities in B ij are disjoint. (Activities in A ij are disjoint, a k is the else in ij ).Since |B ij |=ij |and ij is a maximum-size subset,else in B ij ). Since |B ij | |A ij | and A ij is a maximum size subset,so is B ij .

16.1.3 Converting a DP solution to a greedy solution

 0 , if S ij = ,

,j ]= 17

 i k k S

c [i , j ]

max{c [i , k ] + c [k , j ] + 1} , if S ij ? .

 a < < ij

(16.3)

Th 161L t d l t b th ti it i

Theorem 16.1 Let S ij ≠ , and let a m be the activity in S ij with the earliest finish time: f m = min {f k : a k ∈S ij }. Then 1. a m is used in some maximum-size subset of mutually y

compatible activities of S i j .(a m 包含在某个最大相容活动子集中)2. S im = , so that choosing a m leaves S mj as the only nonempty b bl 仅剩下个非空子问题z

subproblem. (仅剩下一个非空子问题S mj )This theorem is great:

before theorem

after theorem # of sub-prob in optimal solution #of choices to consider 2O (j i 1)

11

# of choices to consider

O (j –i –1)

16.1.3 Converting a DP solution to a greedy solution

Theorem 16.1 Let S ij ≠ , and let a m be the activity in S ij with the earliest finish time:=min {f k :k ij }Then

18

earliest finish time: f m = min {f k : a k ∈S ij }. Then 1. a m is used in some maximum-size subset of mutually compatible activities

of S i j .(a m 包含在某个最大相容活动子集中)

2i = so that choosing leaves j as the only nonempty subproblem

z

2. S im = , so that choosing a m leaves S mj as the only nonempty subproblem.(仅剩下一个非空子问题S mj )

Now we can solve a problem ij in a top-down fashion Now we can solve a problem S ij in a top down fashion Choose a m ∈S ij with earliest finish time: the greedy choice. ( it leaves as

much opportunity as possible for the remaining activities to be scheduled )

(留下尽可能的时间来安排活动,贪心选择)

Then solve S mj .

z

16.1.3 Converting a DP solution to a greedy solution

What are the subproblems?

19

Original problem is S 0,n+1 〔a 0 = [﹣∞, 0); a n+1 = [∞, “∞+1”) 〕Suppose our first choice is a m1 (in fact, it is a 1)Then ne t s bproblem is Then next subproblem is

S m1,n+1Suppose next choice is a m2 (it must be a 2?)

Next subproblem is

S m2,n+1p ,

And so on

11

10

7

8

93

5

4

6

1

2

123456

7891011121314

z

16.1.3 Converting a DP solution to a greedy solution

What are the subproblems?

20

Original problem is S 0,n+1

Suppose our first choice is a m1Then next subproblem is m1n+1 Then next subproblem is S m1,n+1Suppose next choice is a m2Next subproblem is S m2,n+1z

And so on

Each subproblem is S mi ,n+1.

And the subproblems chosen have finish times that increase z

z

And the subproblems chosen have finish times that increase. (所选的子问题,其完成时间是增序排列)

Therefore, we can consider each activity just once, in monotonically increasing order of finish time increasing order of finish time.

贪心算法构造哈夫曼树

软件02 1311611006 张松彬利用贪心算法构造哈夫曼树及输出对应的哈夫曼编码 问题简述: 两路合并最佳模式的贪心算法主要思想如下: (1)设w={w0,w1,......wn-1}是一组权值,以每个权值作为根结点值,构造n棵只有根的二叉树 (2)选择两根结点权值最小的树,作为左右子树构造一棵新二叉树,新树根的权值是两棵子树根权值之和 (3)重复(2),直到合并成一颗二叉树为 一、实验目的 (1)了解贪心算法和哈夫曼树的定义(2)掌握贪心法的设计思想并能熟练运用(3)设计贪心算法求解哈夫曼树(4)设计测试数据,写出程序文档 二、实验内容 (1)设计二叉树结点数据结构,编程实现对用户输入的一组权值构造哈夫曼树(2)设计函数,先序遍历输出哈夫曼树各结点3)设计函数,按树形输出哈夫曼树 代码: #include #include #include #include typedef struct Node{ //定义树结构 int data; struct Node *leftchild; struct Node *rightchild; }Tree; typedef struct Data{ //定义字符及其对应的频率的结构 int data;//字符对应的频率是随机产生的 char c; }; void Initiate(Tree **root);//初始化节点函数 int getMin(struct Data a[],int n);//得到a中数值(频率)最小的数 void toLength(char s[],int k);//设置有k个空格的串s void set(struct Data a[],struct Data b[]);//初始化a,且将a备份至b char getC(int x,struct Data a[]);//得到a中频率为x对应的字符 void prin(struct Data a[]);//输出初始化后的字符及对应的频率 int n; void main() { //srand((unsigned)time(NULL));

贪心算法经典例题

贪心算法经典例题 发布日期:2009-1-8 浏览次数:1180 本资料需要注册并登录后才能下载! ·用户名密码验证码找回密码·您还未注册?请注册 您的账户余额为元,余额已不足,请充值。 您的账户余额为元。此购买将从您的账户中扣除费用0.0元。 内容介绍>> 贪心算法经典例题 在求最优解问题的过程中,依据某种贪心标准,从问题的初始状态出发,直接去求每一步的最优解,通过若干次的贪心选择,最终得出整个问题的最优解,这种求解方法就是贪心算法。 从贪心算法的定义可以看出,贪心法并不是从整体上考虑问题,它所做出的选择只是在某种意义上的局部最优解,而由问题自身的特性决定了该题运用贪心算法可以得到最优解。 我们看看下面的例子 例1 均分纸牌(NOIP2002tg) [问题描述] 有 N 堆纸牌,编号分别为 1,2,…, N。每堆上有若干张,但纸牌总数必为 N 的倍数。可以在任一堆上取若干张纸牌,然后移动。移牌规则为:在编号为 1 堆上取的纸牌,只能移到编号为 2 的堆上;在编号为 N 的堆上取的纸牌,只能移到编号为 N-1 的堆上;其他堆上取的纸牌,可以移到相邻左边或右边的堆上。现在要求找出一种移动方法,用最少的移动次数使每堆上纸牌数都一样多。例如 N=4,4 堆纸牌数分别为: ①9 ②8 ③17 ④ 6 移动3次可达到目的: 从③取 4 张牌放到④(9 8 13 10) -> 从③取 3 张牌放到②(9 11 10 10)-> 从②取 1 张牌放到①(10 10 10 10)。 [输入]:键盘输入文件名。 文件格式:N(N 堆纸牌,1 <= N <= 100) A1 A2 … An (N 堆纸牌,每堆纸牌初始数,l<= Ai <=10000) [输出]:输出至屏幕。格式为:所有堆均达到相等时的最少移动次数。 [输入输出样例] a.in: 4 9 8 17 6 屏慕显示:3 算法分析:设a[i]为第i堆纸牌的张数(0<=i<=n),v为均分后每堆纸牌的张数,s为最小移到次数。 我们用贪心法,按照从左到右的顺序移动纸牌。如第i堆(0

实验三.哈夫曼编码的贪心算法设计

实验四 哈夫曼编码的贪心算法设计(4学时) [实验目的] 1. 根据算法设计需要,掌握哈夫曼编码的二叉树结构表示方法; 2. 编程实现哈夫曼编译码器; 3. 掌握贪心算法的一般设计方法。 实验目的和要求 (1)了解前缀编码的概念,理解数据压缩的基本方法; (2)掌握最优子结构性质的证明方法; (3)掌握贪心法的设计思想并能熟练运用 (4)证明哈夫曼树满足最优子结构性质; (5)设计贪心算法求解哈夫曼编码方案; (6)设计测试数据,写出程序文档。 实验内容 设需要编码的字符集为{d 1, d 2, …, dn },它们出现的频率为 {w 1, w 2, …, wn },应用哈夫曼树构造最短的不等长编码方案。 核心源代码 #include #include #include typedef struct { unsigned int weight; //用来存放各个结点的权值 unsigned int parent,LChild,RChild; //指向双亲、孩子结点的指针 } HTNode, *HuffmanTree; //动态分配数组,存储哈夫曼树 typedef char *HuffmanCode; //动态分配数组,存储哈夫曼编码 ∑=j i k k a

//选择两个parent为0,且weight最小的结点s1和s2 void Select(HuffmanTree *ht,int n,int *s1,int *s2) { int i,min; for(i=1; i<=n; i++) { if((*ht)[i].parent==0) { min=i; break; } } for(i=1; i<=n; i++) { if((*ht)[i].parent==0) { if((*ht)[i].weight<(*ht)[min].weight) min=i; } } *s1=min; for(i=1; i<=n; i++)

算法习题

算法设计与分析试卷 一、填空题(20分,每空2分) 1、算法的性质包括输入、输出、确定性、有限性。 2、动态规划算法的基本思想就将待求问题分解成若干个子问题、先求解子问题,然后 从这些子问题的解得到原问题的解。 3、设计动态规划算法的4个步骤: (1)找出最优解的性质,并刻画其结构特征。 (2)递归地定义最优值。 (3)以自底向上的方式计算出最优值。 (4)根据计算最优值得到的信息,构造最优解。 4、流水作业调度问题的johnson算法: (1)令N1={i|ai=bj}; (2)将N1中作业依ai的ai的非减序排序;将N2中作业依bi的非增序排序。 5、对于流水作业高度问题,必存在一个最优调度π,使得作业π(i)和π(i+1)满足Johnson不等式min{bπ(i),aπ(i+1)}≥min{bπ(i+1),aπ(i)}。 6、最优二叉搜索树即是最小平均查找长度的二叉搜索树。 二、综合题(50分) 1、当(a1,a2,a3,a4,a5,a6)=(-2,11,-4,13,-5,-2)时,最大子段和为∑ak(2<=k<=4)=20(5分) 2、由流水作业调度问题的最优子结构性质可知,T(N,0)=min{ai+T(N-{i},bi)}(1=sum){ sum=thissum; besti=i; bestj=j;} } return sum; } 4、设计最优二叉搜索树问题的动态规划算法OptimalBinarysearchTree? (15分) Void OptimalBinarysearchTree(int a,int n,int * * m, int * * w) { for(int i=0;i<=n;i++) {w[i+1][i]=a[i]; m[i+1][i]= 0;} for(int r=0;r

0023算法笔记——【贪心算法】哈夫曼编码问题

0023算法笔记——【贪心算法】哈夫曼编码问题 1、问题描述 哈夫曼编码是广泛地用于数据文件压缩的十分有效的编码方法。其压缩率通常在20%~90%之间。哈夫曼编码算法用字符在文件中出现的频率表来建立一个用0,1串表示各字符的最优表示方式。一个包含100,000个字符的文件,各字符出现频率不同,如下表所示。 有多种方式表示文件中的信息,若用0,1码表示字符的方法,即每个字符用唯一的一个0,1串表示。若采用定长编码表示,则需要3位表示一个字符,整个文件编码需要300,000位;若采用变长编码表示,给频率高的字符较短的编码;频率低的字符较长的编码,达到整体编码减少的目的,则整个文件编码需要(45×1+13×3+12×3+16×3+9×4+5×4)×1000=224,000位,由此可见,变长码比定长码方案好,总码长减小约25%。 前缀码:对每一个字符规定一个0,1串作为其代码,并要求任一字符的代码都不是其他字符代码的前缀。这种编码称为前缀码。编码的前缀性质可以使译码方法非常简单;例如001011101可以唯一的分解为0,0,101,1101,因而其译码为aabe。

译码过程需要方便的取出编码的前缀,因此需要表示前缀码的合适的数据结构。为此,可以用二叉树作为前缀码的数据结构:树叶表示给定字符;从树根到树叶的路径当作该字符的前缀码;代码中每一位的0或1分别作为指示某节点到左儿子或右儿子的“路标”。 从上图可以看出,表示最优前缀码的二叉树总是一棵完全二叉树,即树中任意节点都有2个儿子。图a表示定长编码方案不是最优的,其编码的二叉树不是一棵完全二叉树。在一般情况下,若C是编码字符集,表示其最优前缀码的二叉树中恰有|C|个叶子。每个叶子对应于字符集中的一个字符,该二叉树有|C|-1个内部节点。 给定编码字符集C及频率分布f,即C中任一字符c以频率f(c)在数据文件中出现。C的一个前缀码编码方案对应于一棵二叉树T。字符c在树T中的深度记为d T(c)。d T(c)也是字符c的前缀码长。则平均码长定义为:

贪心算法概论

贪心算法概论 贪心算法一般来说是解决“最优问题”,具有编程简单、运行效率高、空间 复杂度低等特点。是信息学竞赛中的一个有为武器,受到广大同学们的青睐。本 讲就贪心算法的特点作些概念上的总结。 一、贪心算法与简单枚举和动态规划的运行方式比较 贪心算法一般是求“最优解”这类问题的。最优解问题可描述为:有n个输入,它的解是由这n 个输入的某个子集组成,并且这个子集必须满足事先给定的条 件。这个条件称为约束条件。而把满足约束条件的子集称为该问题的可行解。这 些可行解可能有多个。为了衡量可行解的优劣,事先给了一个关于可行解的函数,称为目标函数。目标函数最大(或最小)的可行解,称为最优解。 a)求“最优解”最原始的方法为搜索枚举方案法(一般为回溯法)。 除了极简单的问题,一般用深度优先搜索或宽度优先搜索。通常优化方法为利用约束条件进行可行性判断剪枝;或利用目标函数下界(或上界),根据当前最 优解进行分枝定界。 b)其次现今竞赛中用的比较普遍的动态规划(需要满足阶段无后效性原则)。 动态规划主要是利用最最优子问题的确定性,从后向前(即从小规模向大规模)得到当前最优策略,从而避免了重复的搜索。 举例说明:求多段图的最短路径。

在图(1)中,我们省略了各线段的长度。 如果用回溯法,搜索树大致如下: 显然,上面的搜索有大量重复性工作。比如节点8、9、10到11的最短路分别被调用了9次,从节点5、6、7到节点11也分别搜索了3次。 如果先算出节点8、9、10到11的最短路,由于它与前面的点无关,因此最优值确定下来,再用它们求定节点5、6、7 到节点11 的最短路径。同理,再用节 点5、6、7 的最优值,来求节点2、3、4 优值。最后从节点2、3、4 推出1 到 11的最优值。显然复杂度大为降低。 当然,如果本题把简单搜索改为搜索+记忆化的方法,则就是得能动态规划的原理,本质上就是动态规划,只是实现的方法不同与传统的表格操作法。搜索+记忆化算法有其特有的特点,以后再讨论。 c)贪心算法则不同,它不是建立在枚举方案的基础上的。它从前向后,根据当前情况,“贪心地”决定出下一步,从而一步一步直接走下去,最终得到解。 假如上面的例子中,我们定下这样的贪心策略:节点号k%3= =1。则有图3:

哈夫曼编码_贪心算法

淮海工学院计算机工程学院实验报告书 课程名:《算法分析与设计》 题目:实验3 贪心算法 哈夫曼编码 班级:软件102班 学号:11003215 姓名:鹿迅

实验3 贪心算法 实验目的和要求 (1)了解前缀编码的概念,理解数据压缩的基本方法; (2)掌握最优子结构性质的证明方法; (3)掌握贪心法的设计思想并能熟练运用 (4)证明哈夫曼树满足最优子结构性质; (5)设计贪心算法求解哈夫曼编码方案; (6)设计测试数据,写出程序文档。 实验内容 设需要编码的字符集为{d 1, d 2, …, dn },它们出现的频率为 {w 1, w 2, …, wn },应用哈夫曼树构造最短的不等长编码方案。 实验环境 Turbo C 或VC++ 实验学时 2学时,必做实验 数据结构与算法 struct huffman { double weight; //用来存放各个结点的权值 int lchild,rchild,parent; //指向双亲、孩子结点的指针 }; 核心源代码 #include #include using namespace std; struct huffman { double weight; int lchild,rchild,parent; }; static int i1=0,i2=0; int Select(huffman huff[],int i) { ∑=j i k k a

int min=11000; int min1; for(int k=0;k

算法分析与设计期末模拟试题

安徽大学2010-2011学年第1学期《算法分析与设计》 期末试题 押宝 (内部交流,非考试试题,学生自发交流创作,版权归作者testfudan@https://www.360docs.net/doc/938820492.html, 所有) 一、选择题(单选)(10*2’=20’) 1. 选择正确的组合对于 2112n +=( ) ①2()o n ② 2()O n ③2()n θ ④2()n Ω ⑤ 2()n ω A. ①③④ B. ②③④ C.③④⑤ D. ①⑤ 2. ①21()()n i i O n O n ==∑ ②2()()n O n O n = ③(log )()O n O n ? ④ 2.99993 ()n O n = ⑤2/lo g ()n n n ω=其中正确的有( ) A .5组 B.4组 C.3组 D.没有正确的 3. 2/102n n +=( ) A. 2()O n B.(2)n O C.2(2)n n O + D.2 ()o n 4. 211/n += ( )(我认为是比较不错的一道题,考试可能会出现相同的方法,用极限定义来做,最后一节课老师也讲过类似的方法) A. ()O n B.()o n C.()n Ω D.(1)O 5. 310lo g n = ( ) A.(log )O n n B. (log )O n C. 3()O n D. lo g ()n O n 6. 认真完成课后习题P5面的算法分析题1-6,里面也有我不会做的,可是有谁愿意讨论? 如果能够把以上的题目都能做对,应该就是掌握了。给自己一个奖励吧!答案(如有问题,联系我吧):1-5:BBBDB 6.做出来对对答案吧。 二、填空题 1.()2(/2)T n T n n =+????的一个渐进上界为 (答案:(log )O n n ,用迭代法) 2.()(/3)(2/3)()T n T n T n O n =++的一个渐进上界为 (答案:(log )O n n ,用递归树求解,不会的赶快看) 3.()9(/3)T n T n n =+的一个渐进紧致界为 (答案:2 ()n θ,采用迭代法或者采用主方法,不会的赶快看)

4+四+贪心算法+习题参考答案

第四章作业 部分参考答案 1. 设有n 个顾客同时等待一项服务。顾客i 需要的服务时间为n i t i ≤≤1,。应该如何安排n 个顾客的服务次序才能使总的等待时间达到最小?总的等待时间是各顾客等待服务的时间的总和。试给出你的做法的理由(证明)。 策略: 对 1i t i n ≤≤进行排序,,21n i i i t t t ≤≤≤ 然后按照递增顺序依次服务12,,...,n i i i 即可。 解析:设得到服务的顾客的顺序为12,,...,n j j j ,则总等待时间为 ,2)2()1(1221--+++-+-=n n j j j j t t t n t n T 则在总等待时间T 中1j t 的权重最大,jn t 的权重最小。故让所需时间少的顾客先得到服务可以减少总等待时间。 证明:设,21n i i i t t t ≤≤≤ ,下证明当按照不减顺序依次服务时,为最优策略。 记按照n i i i 21次序服务时,等待时间为T ,下证明任意互换两者的次序,T 都不减。即假设互换j i ,)(j i <两位顾客的次序,互换后等待总时间为T ~ ,则有.~ T T ≥ 由于 ,2)2()1(1221--+++-+-=n n i i i i t t t n t n T ,2)()()2()1(1221--+++-++-++-+-=n n j i i i i i i i t t t j n t i n t n t n T ,2)()()2()1(~ 1221--+++-++-++-+-=n n i j i i i i i i t t t j n t i n t n t n T 则有 .0))((~ ≥--=-i j i i t t i j T T 同理可证其它次序,都可以由n i i i 21经过有限次两两调换顺序后得到,而每次交换,总时间不减,从而n i i i 21为最优策略。

贪心算法的应用

从贪心算法的定义可以看出,贪心法并不是从整体上考虑问题,它所做出的选择只是在某种意义上的局部最优解,而由问题自身的特性决定了该题运用贪心算法可以得到最优解。 我们看看下面的例子 例1 均分纸牌(NOIP2002tg) [问题描述] 有 N 堆纸牌,编号分别为 1,2,…, N。每堆上有若干张,但纸牌总数必为 N 的倍数。可以在任一堆上取若干张纸牌,然后移动。移牌规则为:在编号为 1 堆上取的纸牌,只能移到编号为 2 的堆上;在编号为 N 的堆上取的纸牌,只能移到编号为 N-1 的堆上;其他堆上取的纸牌,可以移到相邻左边或右边的堆上。现在要求找出一种移动方法,用最少的移动次数使每堆上纸牌数都一样多。例如 N=4,4 堆纸牌数分别为: ①9 ②8 ③17 ④6 移动3次可达到目的: 从③取 4 张牌放到④(9 8 13 10) -> 从③取 3 张牌放到②(9 11 10 10)-> 从②取 1 张牌放到①(10 10 10 10)。 [输入]:键盘输入文件名。 文件格式:N(N 堆纸牌,1 <= N <= 100) A1 A2 … An (N 堆纸牌,每堆纸牌初始数,l<= Ai <=10000) [输出]:输出至屏幕。格式为:所有堆均达到相等时的最少移动次数。 [输入输出样例] : 4 9 8 17 6 屏慕显示:3 算法分析:设a[i]为第i堆纸牌的张数(0<=i<=n),v为均分后每堆纸牌的张数,s为最小移到次数。 我们用贪心法,按照从左到右的顺序移动纸牌。如第i堆(0v,则将a[i]-v张纸牌从第I堆移动到第I+1堆; (2)若a[i]

贪心算法经典问题:活动安排,背包问题,最优装载,单源最短路径 Dijiksra,找零钱问题,多机调度

活动安排 public static int greedySelector(int [] s, int [] f, boolean a[]) { //s[]开始时间f[]结束时间 int n=s.length-1; a[1]=true; int j=1; int count=1; for (int i=2;i<=n;i++) { if (s[i]>=f[j]) { a[i]=true; j=i; count++; } else a[i]=false; } return count; } 背包问题 void Knapsack(int n,float M,float v[],float w[],float x[]) { Sort(n,v,w); //以每种物品单位重量的价值Vi/Wi从大到小排序 int i; for (i=1;i<=n;i++) x[i]=0; float c=M; for (i=1;i<=n;i++) { if (w[i]>c) break; x[i]=1; c-=w[i]; } if (i<=n) x[i]=c/w[i]; //允许放入一个物品的一部分 } 最优装载 void Loading(int x[], T ype w[], T ype c, int n) { int *t = new int [n+1]; //t[i]要存的是w[j]中重量从小到大的数组下标Sort(w, t, n); //按货箱重量排序 for (int i = 1; i <= n; i++) x[i] = 0; //O(n) for (int i = 1; i <= n && w[t[i]] <= c; i++) {x[t[i]] = 1; c -= w[t[i]];} //调整剩余空间 } 单源最短路径Dijiksra template void Dijikstra(int n, int v, Type dist[], int prev[], Type **c) { //c[i][j]表示边(i,j)的权,dist[i]表示当前从源到顶点i的最短特殊路径bool s[maxint]; for(int i= 1;i<=n; i++) { dist[i]=c[v][i]; s[i]=false;

算法分析与设计选修课-贪心算法应用研究

武汉理工大学 算法设计与分析论文题目:贪心算法应用研究 姓名:吴兵 学院:信息工程 专业班级:电子133 学号: 1409721303131 任课教师:张小梅

目录 摘要 (1) 1.绪论 (2) 2贪心算法的基本知识概述 (3) 2.1 贪心算法定义 (3) 2.2 贪心算法的基本思路及实现过程 (3) 2.3贪心算法的核心 (3) 2.4贪心算法的基本要素 (4) 2.5 贪心算法的理论基础 (6) 2.6 贪心算法存在的问题 (7) 3贪心算法经典应用举例 (8) 3.1删数问题 (8) 3.2 汽车加油问题 (10) 3.3会场安排问题 (12) 4.总结 (16) 5.参考文献 (17)

摘要 在求最优解问题的过程中,依据某种贪心标准,从问题的初始状态出发,直接去求每一步的最优解,通过若干次的贪心选择,最终得出整个问题的最优解,这种求解方法就是贪心算法。从贪心算法的定义可以看出,贪心法并不是从整体上考虑问题,它所做出的选择只是在某种意义上的局部最优解,而由问题自身的特性决定了该题运用贪心算法可以得到最优解。贪心算法所作的选择可以依赖于以往所作过的选择,但决不依赖于将来的选择,也不依赖于子问题的解,因此贪心算法与其它算法相比具有一定的速度优势。如果一个问题可以同时用几种方法解决,贪心算法应该是最好的选择之一。本文讲述了贪心算法的含义、基本思路及实现过程,贪心算法的核心、基本性质、特点及其存在的问题。并通过贪心算法的特点举例列出了以往研究过的几个经典问题,对于实际应用中的问题,也希望通过贪心算法的特点来解决。 关键词:贪心算法最小生成树多处最优服务次序问题删数问题

五大常用算法

五大常用算法之一:分治算法 分治算法 一、基本概念 在计算机科学中,分治法是一种很重要的算法。字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。这个技巧是很多高效算法的基础,如排序算法(快速排序,归并排序),傅立叶变换(快速傅立叶变换)…… 任何一个可以用计算机求解的问题所需的计算时间都与其规模有关。问题的规模越小,越容易直接求解,解题所需的计算时间也越少。例如,对于n个元素的排序问题,当n=1时,不需任何计算。n=2时,只要作一次比较即可排好序。n=3时只要作3次比较即可,…。而当n较大时,问题就不那么容易处理了。要想直接解决一个规模较大的问题,有时是相当困难的。 二、基本思想及策略 分治法的设计思想是:将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。 分治策略是:对于一个规模为n的问题,若该问题可以容易地解决(比如说规模n较小)则直接解决,否则将其分解为k个规模较小的子问题,这些子问题互相独立且与原问题形式相同,递归地解这些子问题,然后将各子问题的解合并得到原问题的解。这种算法设计策略叫做分治法。 如果原问题可分割成k个子问题,1

五大经典算法介绍

1分治法 1.1基本概念 在计算机科学中,分治法是一种很重要的算法。字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。这个技巧是很多高效算法的基础,如排序算法(快速排序,归并排序),傅立叶变换(快速傅立叶变换)…… 任何一个可以用计算机求解的问题所需的计算时间都与其规模有关。问题的规模越小,越容易直接求解,解题所需的计算时间也越少。例如,对于n个元素的排序问题,当n=1时,不需任何计算。n=2时,只要作一次比较即可排好序。n=3时只要作3次比较即可,…。而当n较大时,问题就不那么容易处理了。要想直接解决一个规模较大的问题,有时是相当困难的。 1.2基本思想及策略 分治法的设计思想是:将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。 分治策略是:对于一个规模为n的问题,若该问题可以容易地解决(比如说规模n较小)则直接解决,否则将其分解为k个规模较小的子问题,这些子问题互相独立且与原问题形式相同,递归地解这些子问题,然后将各子问题的解合并得到原问题的解。这种算法设计策略叫做分治法。 如果原问题可分割成k个子问题,1

贪心法构造哈夫曼树

实验报告 ( 2013 / 2014 学年第二学期) 学院贝尔学院 学生姓名任晓强 班级学号 Q12010218 指导教师季一木 指导单位计算机软件教学中心 日期 2014年3月12日

实验一:贪心算法构造哈夫曼树 问题简述: 两路合并最佳模式的贪心算法主要思想如下: (1)设w={w0,w1,......w }是一组权值,以每个权值作为根结点值,构造n棵只有根的 n-1 二叉树 (2)选择两根结点权值最小的树,作为左右子树构造一棵新二叉树,新树根的权值是两棵子树根权值之和 (3)重复(2),直到合并成一颗二叉树为止 一、实验目的 (1)了解贪心算法和哈夫曼树的定义 (2)掌握贪心法的设计思想并能熟练运用 (3)设计贪心算法求解哈夫曼树 (4)设计测试数据,写出程序文档 二、实验内容 (1)设计二叉树结点数据结构,编程实现对用户输入的一组权值构造哈夫曼树 (2)设计函数,先序遍历输出哈夫曼树各结点 (3)设计函数,按树形输出哈夫曼树 三、程序源代码 #include #include #include #include typedef struct Node{ //定义树结构 int data; struct Node *leftchild; struct Node *rightchild;

}Tree; typedef struct Data{ //定义字符及其对应的频率的结构int data;//字符对应的频率是随机产生的 char c; }; void Initiate(Tree **root);//初始化节点函数 int getMin(struct Data a[],int n);//得到a中数值(频率)最小的数void toLength(char s[],int k);//设置有k个空格的串s void set(struct Data a[],struct Data b[]);//初始化a,且将a备份至b char getC(int x,struct Data a[]);//得到a中频率为x对应的字符void prin(struct Data a[]);//输出初始化后的字符及对应的频率 int n; void main() { //srand((unsigned)time(NULL)); Tree *root=NULL,*left=NULL,*right=NULL,*p=NULL; int min,num; int k=30,j,m; struct Data a[100]; struct Data b[100]; int i;

贪心法-C语言-霍夫曼编码

贪心算法 霍夫曼编码 学院计算机科学与软件姓名XXX 班级XXXXXX 学号XXXX 课程名称计算机算法设计与分析教师韩其睿 日期: 2015 年 4 月 22 日

【实验题目】 设需要编码的字符集为{ d 1,d 2,…,d n }它们出现的频率为{ p 1,p 2,…,p n },应用霍夫曼树构造最短的非等长编码。 【实验要求】 证明霍夫曼编码问题具有最优子结构性质和贪心选择性质,设计贪心算法求解霍夫曼编码问题,编写实验程序,给出测试数据和测试结果。 【实验目的】 1)掌握贪心选择性质的证明方法。 2)掌握贪心法的设计思想并能熟练运用。 【实验思路】 设需要编码的字符集为{ d 1,d 2,…,d n }它们出现的频率为{ p 1,p 2,…,p n }, 以d 1,d 2,…,d n 作为叶子结点,p 1,p 2,…,p n 作为叶子结点的权值,构造一棵霍夫曼树,规定霍夫曼树的左子树代表0,右子树代表1,由根结点到叶子结点经过的路径组成的0和1的序列是该叶子结点对应字符的编码,即霍夫曼编码。 霍夫曼树共有2n-1个结点,设置一个数组ht[2n-1]保存霍夫曼树中各结点的信息。数组元素结构为 weight :结点的权值 lchild :结点的左孩子结点在数组中的下标. rchild :结点的右孩子结点在数组中的下标 parent :结点的双亲结点在数组中的下标 【算法源码】 #include #include #include typedef struct { unsigned int weight; //存放权值 unsigned int parent,LChild,RChild; } HTNode, *HuffmanTree; typedef char *HuffmanCode; //选择两个双亲为0,且权重最小的结点s1和s2

C语言经典四种算法详解

一分而治之算法 分而治之方法与软件设计的模块化方法非常相似。为了解决一个大的问题,可以: 1)把它分成两个或多个更小的问题; 2)分别解决每个小问题; 3)把各小问题的解答组合起来,即可得到原问题的解答。小问题通常与原问题相似,可以递归地使用分而治之策略来解决。下列通过实例加以说明。 例:利用分而治之算法求一个整数数组中的最大值。

练习:[找出伪币]给你一个装有16个硬币的袋子。16个硬币中有一个是伪造的,并且那个伪造的硬币比真的硬币要轻一些。你的任务是找出这个伪造的硬币。 二贪心算法 贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的仅是在某种意义上的局部最优解。贪心算法不是对所有问题都能得到整体最优解,但对范围相当广泛的许多问题他能产生整体最优解或者是整体最优解的近似解。 贪心算法(Greedy algorithm)是一种对某些求最优解问题的更简单、更迅速的设计技术。用贪婪法设计算法的特点是一步一步地进行,常以当前情况为基础根据某个优化测度作最优选择,而不考虑各种可能的整体情况,它省去了为找最优解要穷尽所有可能而必须耗费的大量时间,它采用自顶向下,以迭代的方法做出相继的贪心选择,每做一次贪心选择就将所求问题简化为一个规模更小的子问题,通过每一步贪心选择,可得到问题的一个最优解,虽然每一步上都要保证能获得局部最优解,但由此产生的全局解有时不一定是最优的,所以贪婪法不要回溯。 贪心算法是一种改进了的分级处理方法。其核心是根据题意选取一种量度标准。然后将这多个输入排成这种量度标准所要求的顺序,按这种顺序一次输入一个量。如果这个输入和当前已构成在这种量度意义下的部分最佳解加在一起不能产生一个可行解,则不把此输入加到这部分解中。这种能够得到某种量度意义下最优解的分级处理方法称为贪婪算法。 对于一个给定的问题,往往可能有好几种量度标准。初看起来,这些量度标准似乎都是可取的,但实际上,用其中的大多数量度标准作贪婪处理所得到该量度意义下的最优解并不是问题的最优解,而是次优解。因此,选择能产生问题最优解的最优量度标准是使用贪婪算法的核心。 一般情况下,要选出最优量度标准并不是一件容易的事,但对某问题能选择出最优量度标准后,用贪婪算法求解则特别有效。最优解可以通过一系列局部最优的选择即贪婪选择来达到,根据当前状态做出在当前看来是最好的选择,即局部最优解选择,然后再去解做出这个选择后产生的相应的子问题。每做一次贪婪选择就将所求问题简化为一个规模更小的子问题,最终可得到问题的一个整体最优解。 贪心算法特性 贪心算法可解决的问题通常大部分都有如下的特性: (1)有一个以最优方式来解决的问题。为了构造问题的解决方案,有一个候选的对象的集合:比如不同面值的硬币。 (2)随着算法的进行,将积累起其它两个集合:一个包含已经被考虑过并被选出的候选对象,另一个包含已经被考虑过但被丢弃的候选对象。 (3)有一个函数来检查一个候选对象的集合是否提供了问题的解答。该函数不考虑此时的解决方法是否最优。 (4)还有一个函数检查是否一个候选对象的集合是可行的,也即是否可能往该集合上添加更多的候选对象以获得一个解。和上一个函数一样,此时不考虑解决方法的最优性。 (5)选择函数可以指出哪一个剩余的候选对象最有希望构成问题的解。 (6)最后,目标函数给出解的值。 为了解决问题,需要寻找一个构成解的候选对象集合,它可以优化目标函数,贪婪算法一

贪心算法经典例题

贪心算法经典例题 所谓贪心算法指的是为了解决在不回溯的前提之下,找出整体最优或者接近最优解的这样一种类型的问题而设计出来的算法。贪心算法的基本思想是找出整体当中每个小的局部的最优解,并且将所有的这些局部最优解合起来形成整体上的一个最优解。因此能够使用贪心算法的问题必须满足下面的两个性质:1.整体的最优解可以通过局部的最优解来求出;2.一个整体能够被分为多个局部,并且这些局部都能够求出最优解。使用贪心算法当中的两个典型问题是活动安排问题和背包问题。 利用贪心算法解题,需要解决两个问题: 一是问题是否适合用贪心法求解。我们看一个找币的例子,如果一个货币系统有3种币值,面值分别为一角、五分和一分,求最小找币数时,可以用贪心法求解;如果将这三种币值改为一角一分、五分和一分,就不能使用贪心法求解。用贪心法解题很方便,但它的适用范围很小,判断一个问题是否适合用贪心法求解,目前还没有一个通用的方法,在信息学竞赛中,需要凭个人的经验来判断何时该使用贪心算法。 二是确定了可以用贪心算法之后,如何选择一个贪心标准,才能保证得到问题的最优解。在选择贪心标准时,我们要对所选的贪心标准进行验证才能使用,不要被表面上看似正确的贪心标准所迷惑,如下面的例子。

例2 (NOIP1998tg)设有n个正整数,将他们连接成一排,组成一个最大的多位整数。例如:n=3时,3个整数13,312,343,连成的最大整数为:34331213 又如:n=4时,4个整数7,13,4,246连接成的最大整数为7424613 输入:N N个数 输出:连接成的多位数 算法分析:此题很容易想到使用贪心法,在考试时有很多同学把整数按从大到小的顺序连接起来,测试题目的例子也都符合,但最后测试的结果却不全对。按这种贪心标准,我们很容易找到反例:12,121 应该组成12121而非12112,那么是不是相互包含的时候就从小到大呢?也不一定,如:12,123 就是12312而非12112,这样情况就有很多种了。是不是此题不能用贪心法呢? 其实此题是可以用贪心法来求解,只是刚才的贪心标准不对,正确的贪心标准是:先把整数化成字符串,然后再比较a+b和b+a,如果a+b>b+a,就把a排在b的前面,反之则把a排在b的后面。 源程序: var s:array[1..20] of string; t:string;i,j,k,n:longint; begin

相关文档
最新文档