版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xp1994816/article/details/49390335
//DP算法--流水作业调度
#include <iostream>
using namespace std;
class Jobtype {
public:
int operator <= (Jobtype a) const {
return (key <= a.key);
}
int key , index;
bool job;
};
//冒泡排序
void Sort(Jobtype *d , int n)
{
int i , j ,flag;
Jobtype temp;
for (i = 0 ; i < n ; i++){
flag = 0;
for (j = n-1 ; j > i ; j--) {
//如果前一个数大于后一个数,则交换
if (d[j] <= d[j-1]) {
temp = d[j];
d[j] = d[j-1];
d[j-1] = temp;
flag = 1;
}
}
//如果本次排序没有进行一次交换(已排好序),则break,减少了执行时间。
if (flag == 0) {
break;
}
}
}
//调用流水作业算法
int FlowShop(int n , int a[] , int b[] , int c[])
{
Jobtype* d = new Jobtype[n];
for (int i = 0 ; i<n ; i++) {
d[i].key = a[i] > b[i] ? b[i] : a[i]; //按Johnson法则分别取第i个作业的a[i]或b[i]值作为关键值
d[i].job = a[i] <= b[i]; //给符合条件a[i]<b[i]的放入到N1子集标记为true
d[i].index = i;
}
//排序
Sort(d,n); //按关键字排序
int j = 0 , k = n-1 ;
for (i = 0 ; i < n ; i++)
{
if ( d[i].job)
c[j++] = d[i].index; //将排过序的数组d,取其中作业序号属于N1的从前面进入
else
c[k--] = d[i].index; //属于N2的从后面进入,从而实现N1的非减序排序,N2的非增序排序
}
j = a[c[0]];
k = j + b[c[0]];
for (i = 1 ; i < n ; i++)
{
j += a[c[i]]; //M1在执行c[i]作业的同时,M2在执行c[i-1]号作业,最短执行时间
//取决于M1与M2谁后执行完
k = j < k ? k+b[c[i]] : j+b[c[i]]; //计算最优加工时间
}
delete d;
return k;
}
int main()
{
int n;
int *a , *b , *c;
cout << "输入作业数: \n";
cin >> n;
a = new int[n];
b = new int[n];
c = new int[n];
cout << "输入M1上加工时间a[]: \n";
for (int i = 0 ; i< n ; i++) {
c[i] = 0;
cin >> a[i] ;
}
cout << "输入M2上加工时间b[]: \n";
for (i = 0 ; i< n ; i++) {
cin >> b[i];
}
//调用流水作业调度算法
cout << "完成作业所需最短时间为: " << FlowShop(n , a , b , c) << endl;
cout << "编号从0开始,作业调度的顺序为: \n";
for (i = 0 ; i < n ; i++) {
cout << c[i] << " ";
}
cout << endl;
return 0;
}