4.6 独立作业最优调度问题

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

4.6 独立作业最优调度问题

算法设计思想:

(1) 动态规划法

用数组*A 和*B 分别存放作业由处理机A 和B 处理需要的时间,预处理得到所有作业均由机器A 处理所需的时间A_total 和均由B 处理的时间B_total 。

构造布尔型三维数组***p ,p[i][j][k]=true 表示前k 个作业能够在机器A 用时不超过i 时间、机器B 不超过j 时间内完成。这样,对于任意一个状态p[i][j][k]=true ,第k 个任务可能由机器A 或机器B 完成,对应的前一状态分别为p[i-A[k-1]][j][k-1]和p[i][j-B[k-1]][k-1]。显然,对任意的i 、j ,有p[i][j][0]。

初始令p[i][j][k]=false ,可以得到动态规划的状态转移方程:

[][][][[1]][][1]|[][[1]][1],0_,0_,1[][][0],0_,0_p i j k p i A k j k p i j B k k i A total j B total k n p i j true i A total j B total

=------≤≤≤≤≤≤⎧⎨

=≤≤≤≤⎩ 计算出所有的状态后,得到最优解(最短处理时间)为:

0_,0_,[][][]=

min {max(,)}i A total j B total p i j n true

minimum i j ≤≤≤≤=

另外,构造整型三维数组***c ,表示p[i][j][k]=true 时第k 个作业的调度情况。初始c[i][j][k]均为0,c[i][j][k]=1表示由机器A 处理,c[i][j][k]=2表示由机器B 处理,c[i][j][k]=3表示机器A 、B 都能处理。在计算状态时,如果p[i-A[k-1]][j][k-1]=true ,则c[i][j][k]=1;如果p[i][j-B[k-1]][k-1]=true ,则c[i][j][k]=2;如果都都满足,则c[i][j][k]=3。从每一个p[i][j][n]=true 且max(i,j)=minimun 的c[i][j][n]反推,即可构造所有可能的最优调度方案。

(2) 二叉树思想输出

二叉树思想输出所有最优解:如果不存在c[i][j][k]=3的情况,则反推c[i][j][n]即可得到所有可能的最优调度方案。但是,解空间中c[i][j][k]=3实际上是二叉树中含有两个儿子的情况,因此必须采用二叉树的遍历算法,才能不漏掉所有的最优方案。想到上学期的数据结构这门课中学到的二叉树结构,通过二叉树的后序遍历算法,即可输出所需叶子节点的路径。

采用动态数组,注意了三维动态数组的申请和释放,这样做节省了内存,使程序变得灵活,可以处理大规模数据。

除此之外,程序对鲁棒性做了增强,对非法输入和文件错误进行了检测。

程序设计代码:

/*头文件 作业调度问题.h*/

#ifndef KNAP_H #define KNAP_H

#include

#include

using namespace std;

struct state //记录状态地址

{

int i, j; //AB处理时间

int k; //处理的任务

int c; //1代表A处理,2代表B处理};

class Schedule //作业调度

{

public:

Schedule(char *in, char *out); //构造函数

~Schedule(); //析构函数

void Solve(); //输出结果到文件protected:

void Plan(); //动态规划最优方案

int Max(int x, int y); //返回二者最大值

void Print(); //打印最优解

void PrintBinaryTree(int i, int j); //用二叉树思想后序遍历打印所有最优方案private:

int task_num; //作业数

int *A, *B; //处理时间数组

int A_total, B_total; //作业均有A/B处理需要时间bool ***p; //p[i][j][k]=true表示前k个作业在A用时不超过i,B不超过j内完成int ***c; //c[i][j][k]表示p[i][j][k]=true时第k个作业的调度情况

int minimum; //最短处理时间

ofstream fout; //输出结果文件

};

#endif

/*函数实现文件作业调度问题.cpp*/

#include "作业调度问题.h"

Schedule::Schedule(char *in, char *out) : fout(out)

{

ifstream fin(in);

if( !fin )

{

fout << "文件" << in << "无法打开!" << endl;

exit(1);

}

fin >> task_num; //初始化作业数

A = new int[task_num];

B = new int[task_num];

for(int i = 0; i < task_num; i++)

fin >> A[i]; //初始化A处理器时间表for(int i = 0; i < task_num; i++)

fin >> B[i]; //初始化B处理器时间表minimum = INT_MAX; //初始化最短处理时间A_total = B_total = 0;

for(int i = 0; i < task_num; i++) //全部由A/B处理的时间{

A_total += A[i];

B_total += B[i];

}

p = new bool**[A_total+1];

c = new int**[A_total+1];

for(int i = 0; i <= A_total; i++)

{

p[i] = new bool*[B_total+1];

c[i] = new int*[B_total+1];

}

for(int i = 0; i <= A_total; i++)

for(int j = 0; j <= B_total; j++)

{

p[i][j] = new bool[task_num+1];

c[i][j] = new int[task_num+1];

for(int k = 0; k <= task_num; k++)

{

p[i][j][k] = false;

c[i][j][k] = 0;

}

}

fin.close();

if( !fout )

{

fout << "文件" << out << "无法打开!" << endl;

exit(1);

}

}

Schedule::~Schedule()

相关文档
最新文档