1.求N个作业的最优加工顺序,采用非优先调度。 POJ 2751
采用回溯法求解(效率较低)
对应的解空间是一个排列树,也就是求1-N的全排列使完成时间最少。
选择不同的作业对应的方案也就不一样。
f2是执行的总时间。
#include<stdio.h>
#include<string.h>
#define INF 0x3f3f3f3f
#define MAX 1001
#define max(x,y) ((x)>(y)?(x):(y))
int n=4;
int a[MAX]={0,5,12,4,8};
int b[MAX]={0,6,2,14,7};
int bestf;
int f1;
int f2[MAX];
int x[MAX];
int bestx[MAX];
void swap(int &x,int &y){
int tmp=x;
x=y;y=tmp;
}
void dfs(int i){
if(i>n){
if(f2[n]<bestf) {
bestf=f2[n];
for(int j=1;j<=n;j++){
bestx[j]=x[j];
}
}
}
else {
for(int j=i;j<=n;j++){
swap(x[i],x[j]);
f1+=a[x[i]];
f2[i]=max(f1,f2[i-1])+b[x[i]];
if(f2[i]<bestf)
dfs(i+1);
f1-=a[x[i]];
swap(x[i],x[j]);
}
}
}
int main(){
f1=0;
bestf=INF;
memset(f2,0,sizeof(f2));
for(int k=1;k<=n;k++){
x[k]=k;
}
dfs(1);
printf("最少时间: %d , 最优调度方案 : ",bestf);
for(int j=1;j<=n;j++){
printf("%d ",bestx[j]);
}
printf("\n");
}
采用下界函数进行剪枝,仍然超时,时间复杂度O(n!) .
int bound(int i){
int sum=0;
for(int j=1;j<=i;j++){
sum+=b[x[j]];
}
return f2[i]+tot-sum;
}
void dfs(int i){
if(i>n){
if(f2[n]<bestf) {
bestf=f2[n];
for(int j=1;j<=n;j++){
bestx[j]=x[j];
}
}
}
else {
for(int j=i;j<=n;j++){
swap(x[i],x[j]);
f1+=a[x[i]];
f2[i]=max(f1,f2[i-1])+b[x[i]];
if(bound(i)<bestf) dfs(i+1);
f1-=a[x[i]];
swap(x[i],x[j]);
}
}
}
2.活动安排问题仍为排列树
#include<stdio.h>
#define MAX 51
struct Action {
int b;
int e;
};
int n=4;
Action A[]={{0,0},{1,3},{2,5},{4,8},{6,10}};
int x[MAX];
int bestx[MAX];
int laste=0;
int sum=0;
int maxsum=0;
void swap(int &x,int &y){
int tmp=x;
x=y;y=tmp;
}
void dispasolution(){
printf("最优调度方案:\n");
int laste=0;
for(int j=1;j<=n;j++){
if(A[bestx[j]].b>=laste){
printf("选取活动%d: [%d,%d)\n",bestx[j],A[bestx[j]].b,A[bestx[j]].e);
laste=A[bestx[j]].e;
}
}
printf("安排活动的个数= %d\n",maxsum);
}
void dfs(int i){
if(i>n){
if(sum>maxsum){
maxsum=sum;
for(int k=1;k<=n;k++){
bestx[k]=x[k];
}
}
}
else {
for(int j=i;j<=n;j++){
swap(x[i],x[j]);
int sum1=sum;
int laste1=laste;
if(A[x[j]].b>=laste){
sum++;
laste=A[x[j]].e;
}
dfs(i+1);
swap(x[i],x[j]);
sum=sum1;
laste=laste1;
}
}
}
int main(){
for(int i=1;i<=n;i++){
x[i]=i;
}
dfs(1);
dispasolution();
}
3,采用优先队列式分支限界法求解