問題描述:假設要用很多個教室對一組活動進行調度。我們希望使用盡可能少的教室來調度所有活動。請給出一個算法,來確定哪一個活動使用哪一間教室。這個問題也被稱為區間圖着色問題,即相容的活動着同色,不相容的着不同顏色,使得所用顏色數最少。
解法思想:
其實我們知道,對於單個教室我們可以用貪心算法進行求解,但是對於這個區間圖的問題,我們采用的方法是多次的貪心。其實你想想看,你無非就是要使那些活動
全部被安排完吧,當然這樣安排的方法很多,如何使得安排后的教室最小呢????
這明顯也是個貪心的問題。聰明的人很快地想到,是不是可以多次的貪心呢?也就是說我對這些活動作一個標記,開始全部標記為”未安排“,第一次的時候就采用貪心算
法盡可能地用一間教室安排盡可能多的活動進去,然后將安排過的活動標記為”己安排“。然后對剩下的活動再進行用同樣的貪心算法進行安排。
#ifndef INTERVAL_GRAPH_COLORING_H
#define INTERVAL_GRAPH_COLORING_H
struct Activity{
int startTime;
int endTime;
bool isArranged; //標記是否己被安排過
};
int greedyCore(Activity *activityArr,int Length);
int intervalGraphColoringRoomNumber(int *startTime,int *endTime,int Length){
Activity *activityArr=new Activity[Length-1];
for(int i=0;i<Length; i++){//初使化活動
activityArr[i].startTime=startTime[i];
activityArr[i].endTime=endTime[i];
activityArr[i].isArranged=false;
}
int usedActivity=0; //己安排過的活動
int roomArrangedCount=0; //教室的計數
while(usedActivity<Length-1){//不停地貪心選擇活動,直到所有的活動己安排完。
usedActivity+=greedyCore(activityArr,Length);
roomArrangedCount++;
}
return roomArrangedCount;
}
//貪心算法的核心,返回本次貪心算法所安排的活動數。
int greedyCore(Activity *activityArr,int Length){
int firstunusedActivity=0;
for(int i=0;i<Length-1; i++){
if(!activityArr[i].isArranged){
firstunusedActivity=i;
break;
}
}
int lastArrangedActivity=firstunusedActivity;
int arrangedActiveityCount=1;
for(int i=firstunusedActivity+1;i<Length;i++){
if(!activityArr[i].isArranged){
if(activityArr[i].startTime>=activityArr[lastArrangedActivity].endTime){
activityArr[i].isArranged=true;
arrangedActiveityCount++;
lastArrangedActivity=i;
}
}
}
return arrangedActiveityCount;
}
#endif
#include"intervalGraphColoring.h"
int main(){
int start_time[11]={1,3,0,5,3,5,6,8,8,2,12};
int end_time[11]={4,5,6,7,9,9,10,11,12,14,16};
std::cout<<intervalGraphColoringRoomNumber(start_time,end_time,11);
}