多机最佳调度

来源:互联网 发布:阿里云企业邮箱条件 编辑:程序博客网 时间:2024/05/16 16:23

11089 多机最佳调度

时间限制:13000MS  内存限制:65535K
提交次数:0 通过次数:0

题型: 编程题   语言: 无限制

Description

假设有n个任务(n<=100),m台机器(m<=50),任务可以由任何一个机器完成,完成任务i需要的时间为ti,请设计两种算法(一种采用贪心算法,另一种采用回溯算法),找出完成这n个任务的最佳调度,使得最早时间完成全部任务。这里采用两种算法来求解:1)贪心算法可以得到近似的最早完成时间,算法思想在书上4.7节。2)回溯算法搜索m叉树(除叶节点外每个节点m个儿子),寻找最早的完成时间。



输入格式

输入两行,第一行为n和m,中间空格相连(其中n表示任务的数量,m表示机器的数量),(n<=100, m<=50)。第二行的n个数是任务i的处理时间ti。


输出格式

输出两行,第一行为采用贪心算法算出的最早完成时间,第二行为采用回溯算法搜索出的最早完成时间。


输入样例

7 32 14 4 16 6 5 3另一个输入示例:14 3 10 10 10 10 10 7 7 7 7 7 5 5 5 5


输出样例

1717另一个输出示例:3735


提示

第(1)个贪心算法按书上思想去实现。第(2)个就是在m叉树上深度优先搜寻最优解的过程。//t数组为初始的任务处理时间;//len2数组为第二种回溯算法在搜索过程中已探察过任务的完成时间和;//x数组用来保存探察过的任务编号。void backtrack (int dep){    if (dep == n) //叶子,或者if (dep>n),看首次调用backtrack参数是0还是1    {        ……        return;    }    for(int i = 0; i < m; i++)    {        len2[i] += t[dep];        x[dep] = i+1;        if(len2[i] < best)        {            backtrack(dep+1);        }        len2[i] -= t[dep];    }}


贪心算法:

#include <stdio.h>
#define SIZE 100 + 10
void Swap(int &a,int &b)
{
int temp = a ;
a = b ;
b = temp ;
}
void Sort(int t[],int n) //对任务的处理时间进行递减排序
{
int i,j ;  
for(i = 0;i<n;i++){
for(j = 0;j<n-1;j++){
if(t[i]>t[j])
Swap(t[i],t[j]) ;
}
}
}
int solve(int t[],int n,int m)
{
int b[SIZE] = {0} ;
if(n<=m)
return t[0] ;
int i = 0,k = 0,min,max ;
while(k<n){
min = 0 ;
for(i = 1;i<m;i++){
if(b[i]<b[min])
min = i ; //取得机器中时间最小的一个的位置
}
b[min] += t[k] ;
k++ ;
}
max = b[0] ;
for(i = 1;i<m;i++){
if(b[i]>max)
max = b[i] ;
}
return max ;
}
int main()
{
int n,m,i,t[SIZE],b[SIZE] ;
scanf("%d %d",&n,&m) ;
for(i = 0;i<n;i++)
scanf("%d",&t[i]) ;
Sort(t,n) ;
printf("%d\n",solve(t,n,m)) ;
return 0 ;


}


回溯(dfs)+贪心:

#include <stdio.h>
#include<stdlib.h>
#define SIZE 100 + 10
void Swap(int &a,int &b)
{
int temp = a ;
a = b ;
b = temp ;
}
void Sort(int t[],int n) //对任务的处理时间进行递减排序
{
int i,j ;  
for(i = 0;i<n;i++){
for(j = 0;j<n-1;j++){
if(t[i]>t[j])
Swap(t[i],t[j]) ;
}
}
}
int greedy(int t[],int n,int m)
{
int b[SIZE] = {0} ;
if(n<=m)
return t[0] ;
int i = 0,k = 0,min,max ;
while(k<n){
min = 0 ;
for(i = 1;i<m;i++){
if(b[i]<b[min])
min = i ; //取得机器中时间最小的一个的位置
}
b[min] += t[k] ;
k++ ;
}
max = b[0] ;
for(i = 1;i<m;i++){
if(b[i]>max)
max = b[i] ;
}
return max ;
}
int ans;
int b[100];
int dfs(int t[],int k,int l,int n,int m){
    int i,j;
    if(k==n){
int ansn=0;
for(i=0;i<n;i++){
if(ansn<b[i])
ansn = b[i] ;
}
if(ansn<ans)
ans=ansn;
return 0;
    }


for(j=0;j<=l;j++){
   bool flag=false;
   for(int jj=0;jj<j;jj++){
if(b[jj]==b[j]){
flag=true;
break;
}
   }
   if(flag==false){
b[j]+=t[k];
if(b[j]>ans){
b[j]-=t[k];
continue;
}
if(l+1<m)
dfs(t,k+1,l+1,n,m);
else
dfs(t,k+1,l,n,m);
b[j]-=t[k];
   }
}


    return ans;
}


int main()
{
int n,m,i,t[SIZE],b[SIZE] ;
scanf("%d %d",&n,&m) ;
for(i = 0;i<n;i++)
scanf("%d",&t[i]) ;
Sort(t,n) ;
printf("%d\n",greedy(t,n,m)) ;
ans=1000000;
    for(i=0;i<m;i++)
b[i]=0;
    printf("%d\n",dfs(t,0,0,n,m));
return 0 ;


}


























































































/*
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
bool cmp(int a,int b)
{    
return a>b;
}
int main()
{    
int n,m,t[101],a[101],i;        
memset(a,0,sizeof(a));        
scanf("%d %d",&n,&m);        
for(i=0;i<n;i++)            
scanf("%d",&t[i]);        
sort(t,t+n,cmp);        
for(i=0;i<n;i++)        
{            
*min_element(a,a+m)+=t[i];        
}        
printf("%d\n",*max_element(a,a+m));   

*/ 























































































/*
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
bool cmp(int a,int b)
{    
return a>b;
}
int main()
{    
int n,m,t[101],a[101],i;        
memset(a,0,sizeof(a));        
scanf("%d %d",&n,&m);        
for(i=0;i<n;i++)            
scanf("%d",&t[i]);        
sort(t,t+n,cmp);        
for(i=0;i<n;i++)        
{            
*min_element(a,a+m)+=t[i];        
}        
printf("%d\n",*max_element(a,a+m));   

*/ 

原创粉丝点击