双机调度问题

大家好,我是一只学弱狗,记录学习的点点滴滴!

优质文章

优质专栏


题目描述

   有n项任务,任务i的加工时间为ti,ti为正整数,i=1,2,…n,用两台相同的机器加工,从0时刻开始计时,完成时间是后停止加工机器的停机时间,问如何把这些任务分配到两台机器上,使得完成时间达到做小?

分析

   这个题呢,不知道大家看完什么感受,我觉的是挺不好搞的,但是呢,通过老师的指点,我猛然间就会做了,现在我也讲给你听:首先我们可以设解是取值只能是0或1的向量<x1,x2,…,xn>,当为0时,表示任务i分配到第一台机器,当为1时,表示任务i分配给第二台机器,设机器1的加工时间<=机器2的加工时间,令T=t1+t2+…+tn,D=T/2下取整,机器1的加工时间不超过D,且达到最大,这样就能保证机器2的加工时间达到最小,从而使得总时间达到最小。所以我们只需分析当时间D内,使得任务的总时间达到最大,类比背包问题,D可以看做是背包的容量,每个任务的加工时间可看做是商品的价值和重量,就可以求出机器1加工时间的最大值。


#include <iostream>
using namespace std;
int main(){
	int n,T=0; 
	freopen("双机调度问题.txt","r",stdin);
	cin>>n;
	int *data = new int[n];
	for(int i=0;i<n;i++) {
		cin>>data[i];
		T+=data[i];	
	}
	
	int D = T/2;
	//背包问题:背包容量是D,各个任务看做商品,加工时间看做质量和重量
	//用滚动数组来求解
	int **map = new int*[2];
	for(int i=0;i<2;i++){
		map[i] = new int[D+1];
	}
	for(int i=0;i<2;i++)
		for(int j=0;j<=D;j++)
			map[i][j]=0;
	
	for(int i=1;i<=n;i++){
		for(int j=0;j<=D;j++){
			if(data[i-1]<=j){
				map[i%2][j]=max(map[(i+1)%2][j],map[(i+1)%2][j-data[i-1]]+data[i-1]);
			}else{
				map[i%2][j]=map[(i+1)%2][j];
			}
		}
	}
	cout<<max(map[n%2][D],T-map[n%2][D])<<endl;
	return 0;
}

具体方案


#include <iostream>
using namespace std;
int main(){
	int n,T=0; 
	freopen("双机调度问题.txt","r",stdin);
	cin>>n;
	int *data = new int[n];
	for(int i=0;i<n;i++) {
		cin>>data[i];
		T+=data[i];	
	}
	
	int D = T/2;
	//背包问题:背包容量是D,各个任务看做商品,加工时间看做质量和重量
	//用滚动数组来求解
	int **map = new int*[n+1];
	for(int i=0;i<n+1;i++){
		map[i] = new int[D+1];
	}
	for(int i=0;i<n+1;i++)
		for(int j=0;j<=D;j++)
			map[i][j]=0;
			
	int **rect = new int*[n+1];//追踪数组 
	for(int i=0;i<n+1;i++){
		rect[i] = new int[D+1];
	}
	for(int i=0;i<n+1;i++)
		for(int j=0;j<=D;j++)
			rect[i][j]=0;
			
	for(int i=1;i<=n;i++){
		for(int j=0;j<=D;j++){
			if(data[i-1]<=j){
				int temp1 = map[i-1][j];
				int temp2 = map[i-1][j-data[i-1]]+data[i-1];
				if(temp2>=temp1){
					rect[i][j]=1;
					map[i][j] = temp2;
				}else{
					rect[i][j]=0;
					map[i][j] = temp1;
				}
			}else{
				rect[i][j]=0;
				map[i][j]=map[i-1][j];
			}
		}
	}
	
	for(int i=0;i<n+1;i++){
		for(int j=0;j<=D;j++)
			cout<<rect[i][j]<<" ";
		cout<<endl;
	}

	cout<<"-----------------------"<<endl;
	for(int i=0;i<n+1;i++){
		for(int j=0;j<=D;j++)
			cout<<map[i][j]<<" ";
		cout<<endl;
	}
	
	int *recode = new int[n];
	for(int i=0;i<n;i++)
		recode[i] = 1;
	//求解具体方案 
	int x=n,y=D;
	while(x>=0 && y>=0){
		if(rect[x][y]==1){
			recode[x-1]=0;
			y-=data[x-1];
		}
		x--;
	}
	for(int i=0;i<n;i++){
		if(recode[i]==0){
			cout<<"机器1:"<<i+1<<endl; 
		}else{
			cout<<"机器2:"<<i+1<<endl;
		}
	}
	
	for(int i=0;i<n+1;i++){
		delete[] map[i];
		delete[] rect[i];
	}
	delete[] map;
	delete[] rect;
	return 0;
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一只学弱狗!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值