13.活動選擇問題
1.問題解釋
假定有n個活動要求只能在同一間教室裡面舉辦,要求怎麼安排才能使給定的任務數內做最多的活動。
輸入:按每個活動完成時間排序(升序),開始時間陣列S,完成時間陣列F
輸出:表示最大活動數的陣列{X1,X2,...Xn},其中Xi=0(沒選擇)或者1(選擇)
2.貪心選擇
如上圖所示,一開始先由排序結果確定第一個要做的活動,然後遍歷剩下的活動,如果發現有下一個活動的舉辦時間發生在現有活動結束時間之後的,就記錄下來,然後再遍歷剩下的活動開始時間在第二個活動結束時間之後的,重複記錄,多次比較後,當遍歷所有活動結束後就能得到最優解。
演算法虛擬碼:
RECURSIVE-ACTIVITY-SELECTOR(S,F,i,j)
1. m<-i+1
2. while m<j 且 Sm<Fi //一開始比較的是第一個
3. do Xm<-0
4. m<-m+1
5. if m<j
6. then Xm<-1
7. RECURSIVE-ACTIVITY-SELECTOR(S,F,m,j)
C:
actsel.h
#define _actsel_h #include<stdio.h> int *x; void recurciveactivityselector(int *s,int *f,int i,int j){ int m=i+1; while(m<j&&s[m]<f[i]) x[m++]=0; if(m<j){ x[m]=1; recurciveactivityselector(s,f,m,j); } }
main.cpp
#include<stdlib.h> #include"actsel.h" #include<limits.h> int main(){ x=(int*)malloc(12*sizeof(int)); int s[]={0,1,3,0,5,3,5,6,8,8,2,12,INT_MAX}, f[]={0,4,5,6,7,8,9,10,11,12,13,14,INT_MAX},i; recurciveactivityselector(s,f,0,12); for(i=1;i<12;i++) printf("%d",x[i]); printf("\n"); free(x); }
輸出結果:
C++:
Actselcpp.h
#define _Actselcpp_h int* recurciveactivityselector(int *s,int *f,int i,int j){ static int*x=new int(j); int m=i+1; while(m<j&&s[m]<f[i]) x[m++]=0; if(m<j){ x[m]=1; recurciveactivityselector(s,f,m,j); } return x; }
main.cpp
#include<iostream> #include"Actselcpp.h" #include<limits> using namespace std; int main(){ int *x; int s[]={0,1,3,0,5,3,5,6,8,8,2,12,numeric_limits<int>::max()}, f[]={0,4,5,6,7,8,9,10,11,12,13,14,numeric_limits<int>::max()}; x=recurciveactivityselector(s,f,0,12); for(int i=1;i<12;i++) cout<<x[i]<<" "; cout<<endl; delete []x; }
JAVA:
Activityselector.java
package Jamin;
public class Activityselector { public static int[] x; public static void recurciveactivityselector(int[] s,int[] f,int i,int j) { int m=i+1; while(m<j&&s[m]<f[i]) x[m++]=0; if(m<j) { x[m]=1; recurciveactivityselector(s,f,m,j); } } }
Test.java
package Jamin;
public class Test {
public static void main(String[] args) { // TODO Auto-generated method stub Activityselector.x=new int[12]; int s[]= {0,1,3,0,5,3,5,6,8,8,2,12,Integer.MAX_VALUE}, f[]= {0,4,5,6,7,8,9,10,11,12,13,14,Integer.MAX_VALUE}; Activityselector.recurciveactivityselector(s, f, 0, 12); for(int i=1;i<12;i++) { System.out.print(Activityselector.x[i]+" ");} System.out.println(); } } 輸出結果:
1 0 0 1 0 0 0 1 0 0 1