请求处理问题 收藏

任务调度算法
介绍一种解决在有限存储空间中,如何合理安排多个计算任务的顺序,确保每个任务既能顺利执行又能存储其结果的任务调度算法。

问题描述:

说有一台机器,上面有m个储存空间。然后有n个请求,第i个请求计算时需要占R[i]个空间,储存计算结果则需要占据O[i]个空间(其中 O[i]<R[i])。问怎么安排这n个请求的顺序,使得所有请求都能完成。你的算法也应该能够判断出无论如何都不能处理完的情况。

题解:

假设可以满足所有请求,并且处理请求的顺序是:r1,r2,……r(n-1),r(n),那么存储完所有的请求结果后,剩余的存储空间为L= m-∑O[i]。

如果假设成立,必须满足:针对请求r(n),一定有L+O[r(n)]>=R[r(n)]。同理,针对r(n-1),一定有

L+O[r(n)] + O[r(n-1)] >= R[r(n-1)],依次类推。于是,证明假设成立就转化为:针对假设中的每一个请求r(i),都有L+∑O[r(n-j)]>=R[r(i)],其中i>=j>=0。相应的,原问题也就转化成从寻找这样的r(i)。

既然如此,从寻找r(n)开始,这时候有n个选择(R[1]~R[n]),那么选择哪一个呢?如上所说,我们选择的原则是满足L+O[r(n)]>=R[r(n)],即L>=R[r(n)]-O[r(n)]。所以将所有的选择按照R[r(n)]-O[r(n)]从小到大排序,每次选择时试探R[r(n)]-O[r(n)]最小的值,如果最小值都不能满足,那么已经证明假设不成立,否则继续探测n-1,n-2……1,直到出现不能满足的情况,或者证明假设成立。

时间复杂度:nlogn(事先的排序)+n

view plaincopy to clipboardprint?
public class Schedule {
static final int R[]={10,15,23,20,6,9,7,16};
static final int O[]={2,7,8,4,5,8,6,8};
static final int N = 8;
static final int M = 50;
static int index[];
public Schedule()
{
index = new int[N];
}
/**
* part step of qusort
*/
int part(int s,int e)
{
int p = R[e]-O[e];
int l = s;
int h = e;
int tmp = 0;
while(l<h)
{
while(l<h&&(R[l]-O[l])<=p)
l++;
/* save the sorted sequence if necessary
tmp = index[l];
index[l]=index[h];
index[h]=tmp;
*/
tmp =R[l];
R[l]=R[h];
R[h]=tmp;
tmp = O[l];
O[l]=O[h];
O[h]=tmp;
while(l<h&&(R[h]-O[h])>=p)
h--;
/* save the sorted sequence if necessary
tmp = index[l];
index[l]=index[h];
index[h]=tmp;
*/
tmp =R[l];
R[l]=R[h];
R[h]=tmp;
tmp = O[l];
O[l]=O[h];
O[h]=tmp;

}
return l;
}
/**
* quick-sort
*/
void qsort(int s,int e)
{
if(s<e)
{
int pos = part(s,e);
qsort(s,pos-1);
qsort(pos+1,e);
}
}
/**
* output schedule sequence
*/
void display()
{
int i =0;
for(i=N-1;i>=0;i--)
{
System.out.println(R[i]+" "+O[i]);
}
}
/**
* sum O[0~N-1]
*/
int sum()
{
int sum = 0;
int i = 0;
for(i = 0;i<N;i++)
sum += O[i];
return sum;
}
/**
* main fun
*/
public static void main(String[] args) {

Schedule t = new Schedule();
int i = 0;
for(i = 0;i<N;i++)
index[i]=i;
t.qsort(0,N-1);
int sum = t.sum();
int left = M - sum;
i = 0;
int min = R[i]-O[i];
while(left >= min )//left >= min(R[i]-O[i])
{
left += O[index[i]];
i ++;
if(i>=N)
break;
min = R[i]-O[i];
}
if(i == N)
t.display();
else
System.out.println("cant be scheduled");
}
}
public class Schedule {
static final int R[]={10,15,23,20,6,9,7,16};
static final int O[]={2,7,8,4,5,8,6,8};
static final int N = 8;
static final int M = 50;
static int index[];
public Schedule()
{
index = new int[N];
}
/**
* part step of qusort
*/
int part(int s,int e)
{
int p = R[e]-O[e];
int l = s;
int h = e;
int tmp = 0;
while(l<h)
{
while(l<h&&(R[l]-O[l])<=p)
l++;
/* save the sorted sequence if necessary
tmp = index[l];
index[l]=index[h];
index[h]=tmp;
*/
tmp =R[l];
R[l]=R[h];
R[h]=tmp;
tmp = O[l];
O[l]=O[h];
O[h]=tmp;
while(l<h&&(R[h]-O[h])>=p)
h--;
/* save the sorted sequence if necessary
tmp = index[l];
index[l]=index[h];
index[h]=tmp;
*/
tmp =R[l];
R[l]=R[h];
R[h]=tmp;
tmp = O[l];
O[l]=O[h];
O[h]=tmp;

}
return l;
}
/**
* quick-sort
*/
void qsort(int s,int e)
{
if(s<e)
{
int pos = part(s,e);
qsort(s,pos-1);
qsort(pos+1,e);
}
}
/**
* output schedule sequence
*/
void display()
{
int i =0;
for(i=N-1;i>=0;i--)
{
System.out.println(R[i]+" "+O[i]);
}
}
/**
* sum O[0~N-1]
*/
int sum()
{
int sum = 0;
int i = 0;
for(i = 0;i<N;i++)
sum += O[i];
return sum;
}
/**
* main fun
*/
public static void main(String[] args) {

Schedule t = new Schedule();
int i = 0;
for(i = 0;i<N;i++)
index[i]=i;
t.qsort(0,N-1);
int sum = t.sum();
int left = M - sum;
i = 0;
int min = R[i]-O[i];
while(left >= min )//left >= min(R[i]-O[i])
{
left += O[index[i]];
i ++;
if(i>=N)
break;
min = R[i]-O[i];
}
if(i == N)
t.display();
else
System.out.println("cant be scheduled");
}
}


本文来自优快云博客,转载请标明出处:http://blog.youkuaiyun.com/clearriver/archive/2009/07/24/4377060.aspx

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值