算法设计与分析——分治DC算法

1、Algorithm Introduction

image.png

#include <stdio.h>
#define N 100

//子函数实现二分搜索算法,查找给定元素 x 的位置
int Binary_Search(int a[],int low,int high,int x)
{
	int mid;
	mid=(low+high)/2;
	if(low>high)
		return -1; /*查找失败*/
	else if(x==a[mid])
		return mid; /*找到元素的位置并返回*/
	else if(x>a[mid])
		return Binary_Search(a,mid+1,high,x);
	else
		return Binary_Search(a,low,mid-1,x);
}

void main()
{
	int a[N];
	int i,t,x,n;
	printf("请输入已排序数组中元素的个数 n:");
	scanf("%d",&n);
	printf("请输入已排序数组中的元素(共%d 个数):\n",n);
	for(i=0;i<n;i++)
	{
		scanf("%d",&a[i]); /*从键盘输入一组数*/
	}
	printf("请输入要查找的元素 x 为:");
	scanf("%d",&x);
	t=Binary_Search(a,0,n-1,x); /*调用子函数,查找元素 x 在数组 a[n]中的位置*/
	if (t==-1)
		printf("\n 查找失败!");
	else
		printf("元素 x 是数组中第%d 个元素。\n",t+1);  /*因为数组的下标从 0 开始,实际的位置应为其坐标位置加 1*/
}

(2)、Merge_Sort

image.png

#include <stdio.h>
#include <stdlib.h>
#define N 8

//将两个有序的数组 R[low...m]和 R[m+1...high]归并成一个有序的数组 R[low..high]
void Merge(int R[],int b[],int low,int m,int high)
{
	int i=low,j=m+1,p=0;
	while(i<=m&&j<=high) /*两子数组非空时取其小者输出到 R1[p]上*/
		b[p++]=(R[i]<=R[j])?R[i++]:R[j++];
	while(i<=m) /*若第 1 个子文件非空,则复制剩余记录到 R1 中*/
		b[p++]=R[i++];
	while(j<=high) /*若第 2 个子文件非空,则复制剩余记录到 R1 中*/
		b[p++]=R[j++];
	for(p=0,i=low;i<=high;p++,i++)
		R[i]=b[p]; /*归并完成后将结果复制回 R[low..high]*/
}
//用分治法对 R[low..high]进行二路归并排序
void MergeSort(int R[],int low,int high)
{
	int mid;
	int b[N];
	if(low<high) /*区间长度大于 1*/
	{
		mid=(low+high)/2; /*分解*/
		MergeSort(R,low,mid); /*递归地对 R[low..mid]排序*/
		MergeSort(R,mid+1,high); /*递归地对 R[mid+1..high]排序*/
		Merge(R,b,low,mid,high); /*组合,将两个有序区归并为一个有序区*/
	}
}

void main()
{
	int a[N];
	int i,j;
	for(j=0;j<N;j++)
		a[j]=rand()%100; /*系统随机生成 8 个数*/
	//scanf("%d",&array[j]); //取消此注释语句可以手动输入无序数组
	printf("随机生成数组为:\n");
	for(i=0;i<N;i++)
		printf("%d ",a[i]);
	MergeSort(a,0,N-1);
	printf("\n 已排序数组为:\n");
	for(i=0;i<N-1;i++)
		printf("%d ",a[i]);
	printf("\n\n");
}

2、Maximum Contiguous Subarray Problem

(1)、Overview

  • Clean way to illustrate basic algorithm design
    • A Θ(n 3) brute force algorithm
    • A Θ(n 2) algorithm that reuses data
    • A Θ(n log n) divide-and-conquer algorithm
  • Cost of algorithm will be number of primitive operations, e.g., comparisons and arithmetic operations, that it uses.

(2)、MCS Example

image.png

Between years 5 and 8 ACME earned 5 + 2 − 1 + 3 = 9 Million Dollars

This is the MAXIMUM amount that ACME earned in any contiguous span of years.

Examples: Between years 1 and 9 ACME earned −3 + 2 + 1 − 4 + 5 + 2 − 1 + 3 − 1 = 4 and between years 2 and 6 2 + 1 − 4 + 5 + 2 = 6

The Maximum Contiguous Subarray Problem is to find the span of years in which ACME earned the most, e.g., (5, 8).

(3)、Formal Definition

image.png

(4)、Θ(n 3) Solution: Brute Force

Idea: Calculate the value of V (i, j) for each pair i ≤ j and return the maximum value.

VMAX=A[1];
for (i=1 to N) 
{
	for (j=i to N) 
    {
		// calculate V(i, j)
		V=0;
		for (x= i to j)
			V=V+A[x];
		if (V > VMAX)
			VMAX=V;
	}
}
return VMAX;

(5)、Θ(n 2) Solution: Reuse data

Idea: We don’t need to calculate each V (i, j) from “scratch” but can exploit the fact that

image.png

VMAX=A[1];
for (i=1 to N)
{
	V=0;
	for (j=i to N) 
    {
		// calculate V(i, j)
		V=V+A[j];
		if (V > VMAX)
		VMAX=V;
	}
}
return VMAX;

(6)、Θ(n log n) Solution: Divide-and-Conquer

Idea: Set M = [(N + 1)/2] , [] indicates rounding down temporarily.

Let A1 and A2 be the MCS that must contain A[M] and A[M + 1] respectively. Note that the MCS must be one of

  • S1 : The MCS in A[1 . . . M]
  • S2 : The MCS in A[M + 1 . . . N]
  • A : Where A = A1 ∪ A2

image.png

(7)、Example

image.png

(8)、Finding A : The conquer stage

image.png

MAX=A[M];
SUM=A[M];
for (k=M-1 down to i)
{
	SUM+=A[k];
	if (SUM > MAX) 
        MAX=SUM;
}
A_1=MAX;

image.png

(9)、The Full Divide-and-Conquer Algorithm

// Input : A[i . . . j] with i ≤ j

// Output : the MCS of A[i . . . j]

image.png

(10)、A full example

image.png

(11)、Analysis of the DC Algorithm

Let T(m) (where m is the problem size) be time needed to run

​ MCS(A, i, j), (j − i + 1 = m)

Step (1) requires O(1) time.

Steps (3) and (4) each require T(m/2) time.

Step (5) requires O(m) time.

Step (6) requires O(1) time

Then T(1) = O(1) and for n > 1, T(n) = 2 T(n/2) + O(n)

To simplify the analysis, we assume that n is a power of 2.

T(n) ≤ 2 T( n 2 ) + c n.

Repeating this recurrence gives

image.png

Set h = log2 n, so that 2 h = n.

With this substitution, we have

image.png

(12)、Review

In this lecture we saw 3 different algorithms for solving the maximum contiguous subarray problem. They were

  • A Θ(n 3) brute force algorithm
  • A Θ(n 2) algorithm that reuses data
  • A Θ(n log n) divide-and-conquer algorithm
posted @ 2021-11-18 16:29  我在吃大西瓜呢  阅读(173)  评论(0编辑  收藏  举报