问题描述:假如要用很多个教室对一组课程进行调度,每节课程都有其开始时间和结束时间,我们希望使用尽量少的时间来调度所有的课程,请给出调度算法?
分析:
1、利用贪心算法来解决这个问题。
1)将课程按照其结束时间的先后顺序排序。
2)设课程集合为C,我们可以利用贪心算法先求出初始课程集合C的一个最大兼容课程子集C1(C包含C1),为集合C1的课程安排一个教室。
3)将课程集合{C-C1}作为一个新的集合,进行第1)步操作直到将所有的课程都安排完。
此算法的时间复杂度是O(n平方)
2、不利用贪心算法,而是直接根据课程开始的先后顺序和兼容情况来安排课程。(直接法)
1)将课程按照其开始时间的先后顺序排序。
2)将排好序的课程依次加入教室。对每一个即将加入的课程的规则如下:
a、从第一个教室开始检查。
b、若未被占用,就使用;若占用了,比较该教室中的最后一门课程的结束时间与将要加入的课程的开始时间,若后者大于等于前者,则将其加入该教室,并更新该教室的最后结束时间。
c、若上一个教室不能使用,就按照a中的方式检查下一个教室
d、按上述方式将所有的课程安排完毕。
此算法由于只需将课程遍历一遍,遍历的时间复杂度为O(n),排序的时间负责度为O(nlogn),故其时间复杂度为O(nlogn)。
C语言实现如下:
文件“h1.h”
#ifndef H1_H
#define H1_H
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
#include<process.h>
#include<math.h>
#define MAXSIZE 100
struct Class{
int startTime;
int finishTime;
int flag; //a value to check whether the class is distributed, 1 denotes the class has been distributed,
}; //0 the other way.
void finishTimeQuickSort(Class c[], int n, int flag);
void qSort(Class c[], int low, int high, int flag);
int partition(Class c[], int low, int high, int flag);
void classroomDistributionGreedy(Class c[], int n, int classroom[][MAXSIZE]);
void printCourseDistributed(int classroom[][MAXSIZE]);
void classroomDistribution(Class c[], int n, int classroom[][MAXSIZE]);
#endif
文件:"ClassroomDistribution.cpp"
#include "h1.h"
void timeQuickSort(Class c[], int n, int flag){ //Quick sort,when flag==1,order according to finishTime; when flag==0,order according to startTime.
qSort(c, 1, n, flag);
}
void qSort(Class c[], int low, int high, int flag){
if(low < high){
int pivotKey = partition(c, low, high, flag);
qSort(c, low, pivotKey-1, flag);
qSort(c, pivotKey+1, high, flag);
}
}
int partition(Class c[], int low, int high, int flag){
Class pivot = c[low];
while(low < high){
if(flag == 1){
while(low<high && c[high].finishTime>=pivot.finishTime){
high--;
}
}
else{
while(low<high && c[high].startTime>=pivot.startTime){
high--;
}
}
c[low] = c[high];
if(flag == 1){
while(low<high && c[low].finishTime<=pivot.finishTime){
low++;
}
}
else{
while(low<high && c[low].startTime<=pivot.startTime){
low++;
}
}
c[high] = c[low];
}
c[low] = pivot;
return low;
}
void classroomDistributionGreedy(Class c[], int n, int classroom[][MAXSIZE]){
int i, j, k, flag; //i denotes the i'th classroom, j denotes the j'th class.
flag = 1; //A flag to check whether a new classroom is needed.
k = 1; //The k'th class of a very classroom, initial value is 1.
for(i=1; i<=n; i++){
k=1;
if( flag ){
flag = 0;
for(j=1; j<=n; j++){
if( !c[j].flag && classroom[i][1]==0 ){ //Find the first class of a new classroom.
classroom[i][k] = j;
c[j].flag = 1; //The j'th class is distributed.
k++;
flag = 1;
}
else if(!c[j].flag && (c[classroom[i][k-1]].finishTime<=c[j].startTime)){
classroom[i][k] = j;
c[j].flag = 1;
k++;
flag = 1;
}
}
}
else{
break;
}
}
}
void printCourseDistributed(int classroom[][MAXSIZE]){
int i, j, flag;
flag = 1;
for(i=1; i<=6; i++){
if( flag ){
flag = 0;
printf("The courses of the %d 'th classroom:\n", i);
for(j=1; j<=6; j++){
if(classroom[i][j] == 0){
break;
}
else{
printf("%d ", classroom[i][j]);
flag = 1;
}
}
printf("\n");
}
else{
break;
}
}
}
void classroomDistribution(Class c[], int n, int classroom[][MAXSIZE]){
int i, k; //i denotes the i'th course. k denotes the k's classroom.
int position[MAXSIZE] = {0}; //The flag to record the last course's position added to each classroom.
for(i=1; i<=n; i++){
k = 1;
while(c[classroom[k][position[k]]].finishTime>c[i].startTime){
k++;
}
flag[k]++;
classroom[k][position[k]] = i;
}
}
int main(){
int i;
Class c[7];
int classroom[MAXSIZE][MAXSIZE] = {0};
for(i=0; i<=6; i++){
c[i].flag = 0;
}
c[6].startTime=1; c[6].finishTime=3;
c[5].startTime=2; c[5].finishTime=4;
c[4].startTime=3; c[4].finishTime=5;
c[3].startTime=4; c[3].finishTime=6;
c[2].startTime=5; c[2].finishTime=7;
c[1].startTime=6; c[1].finishTime=8; //Test values.
c[0].startTime=0; c[0].finishTime=0;//Initiate class values.
//timeQuickSort(c, 6, 0); //Sort according to starting time of each course.
//classroomDistribution(c, 6, classroom);//Direct strategy.
timeQuickSort(c, 6, 1);//Sort according to finishing time of each course.
classroomDistributionGreedy(c, 6, classroom);//Greedy strategy
printCourseDistributed(classroom);
return 0;
}