@songpfei
2016-02-20T02:00:59.000000Z
字数 2418
阅读 2232
算法导论
活动选择问题具有最优子结构,另表示在结束之后开始,球在开始之前结束的那些活动子集。
c[i,j]为集合的最优解大小,则递归式为:
参考:http://www.cnblogs.com/Anker/archive/2013/03/16/2963625.html
为了方便讨论和后面的计算,添加两个虚构活动a0和an+1,其中f0=0,sn+1=∞。
动态规划c代码实现:
#include<stdlib.h>#include<stdio.h>#include<limits.h>#define N 11/*根据递归公式,采用自底向下的策略进行计算c[i][j],trace[n][n]保存中间划分的k值*/void DynamicActivitySelector(int*s, int*f, int c[N + 2][N + 2], int trace[N + 2][N + 2]){//1. i>=j时,c[i,j]=0 c[i,j]已初始化为0//2. i<j时,需要寻找子问题的最优解,即找到一个合适的k划分为两个子问题int temp;int imax = 0;for (int j = 1;j <N + 2;j++)for (int i = 0; i < j; i++){//寻找k,将问题分成两个子问题c[i][k]、c[k][j]for (int k = i + 1; k < j; k++){if (f[i] <= s[k] && f[k] <= s[j])// 判断活动k的兼容性{temp = c[i][k] + c[k][j] + 1;if (temp > c[i][j]) //找到一个最优的分界k{c[i][j] = temp;trace[i][j] = k;if (k > imax){imax = k;printf("a%d ", imax);}}}}}}int main(){int s[N + 2] = {0,1,3,0,5,3,5,6,8,8,2,12,100};int f[N + 2] = {0,4,5,6,7,9,9,10,11,12,14,16,101};int c[N + 2][N + 2] = { 0 };int trace[N + 2][N + 2] = { 0 };DynamicActivitySelector(s, f, c, trace);printf("\nc[i][j]为:\n");for (int i = 0; i < 13; i++){for (int j = 0; j < 13; j++)printf("%d ", c[i][j]);printf("\n");}printf("trace[i][j]为:\n");for (int i = 0; i < 13; i++){for (int j = 0; j < 13; j++)printf("%d ", trace[i][j]);printf("\n");}system("pause");return 0;}
ACTIVITY-SELECTOR(s,f,0,n)
RECURSIVE-ACTIVITY-SELECTOR(s,f,k,n)m=k+1while m<=n and s[m]<f[k]m=m+1if m<=nrerurn {am}URECURSIVE-ACTIVITY-SELECTOR(s,f,m,n)elsereturn ∅
#### 2.2 迭代贪心算法
GREEDY-ACTIVITY-SELECTOR(s,f)n=s.lengthA={a1}k=1 //子集中最早结束的活动akfor m=2 to nif(s[m]>=f[k])A=A U {am}k=mreturn A
C算法实现
//返回兼容活动的个数int GreedyAcitivitySelector(int* start, int* final,int *solution_set,int n){if (start == NULL || final == NULL || solution_set==NULL)return -1;int solution_count = 0;if (n >= 1){int k = 1;solution_set[0] = k;solution_count++;for (int m = 2; m <= n; m++){if (start[m] >= final[k]){k = m;solution_set[solution_count] = k;solution_count++;}}}return solution_count;}int main(){int solution_count;int s[12] = {0,1,3,0,5,3,5,6,8,8,2,12 };int f[12] = {0,4,5,6,7,9,9,10,11,12,14,16};int solution_set[12];solution_count = GreedyAcitivitySelector(s, f, solution_set, 12);printf("活动的最优解为:\n");for (int i = 0; i < solution_count; i++)printf("%d ", solution_set[i]);system("pause");return 0;}