【分支限界法】批处理作业调度问题
给定n个作业的集合{J1,J2,…,Jn}。每个作业必须先由机器1处理,然后由机器2处理。作业Ji需要机器j的处理时间为tji。对于一个确定的作业调度,设Fji是作业i在机器j上完成处理的时间。所有作业在机器2上完成处理的时间和称为该作业调度的完成时间和。
批处理作业调度问题要求对于给定的n个作业,制定最佳作业调度方案,使其完成时间和达到最小。
例:设n=3,考虑以下实例:
这3个作业的6种可能的调度方案是1,2,3;1,3,2;2,1,3;2,3,1;3,1,2;3,2,1;它们所相应的完成时间和分别是19,18,20,21,19,19。易见,最佳调度方案是1,3,2,其完成时间和为18。
// FlowshopHeap.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include<queue>
using namespace std;
template<class Type>
class MinHeapNode
{
template<class Type>
friend class Flowshop;
public:
operator Type ()const { return bb; }
private:
void init(int);
void NewNode(MinHeapNode<Type>, int, int, int, int);
Type s,//已经安排的作业数
f1,//机器1上的最后完成时间
f2,//机器2上的最后完成时间
sf2,//当前机器2上的完成时间
bb,//当前完成时间的下界
* x;//当前作业调度
};
template<class Type>
void MinHeapNode<Type>::init(int n)
{
x = new Type[n];
for (int i = 0; i < n; i++)
x[i] = i;
s = 0;
f1 = 0;
f2 = 0;
sf2 = 0;
bb = 0;
}
template<class Type>
void MinHeapNode<Type>::NewNode(MinHeapNode<Type> E, int Ef1, int Ef2, int Ebb, int n)
{
x = new Type[n];
for (int i = 0; i < n; i++)
x[i] = E.x[i];
f1 = Ef1;
f2 = Ef2;
sf2 = E.sf2 + f2;
bb = Ebb;
s = E.s + 1;
}
template<class Type>
class Flowshop
{
friend int main(void);
public:
Type BBFlow(void);
void Sort();
Type Bound(MinHeapNode<Type>, Type&, Type&, bool**);
private:
int n;
Type** M,//各作业所需的处理时间数组
** b,//各作业所需的处理时间排序数组
** a,//b和M对应的关系
* bestx,//最优解
bestc;//当前时间和
bool** y;
};
template<class Type>
void Swap(Type& a, Type& b)
{
Type temp = a;
a = b;
b = temp;
}
template<class Type>
Type Flowshop<Type>::Bound(MinHeapNode<Type> E, Type& f1, Type& f2, bool** y)
{
for (int i = 0; i < 2; i++)
for (int j = 0; j < 3; j++)
y[i][j] = false;
for (int i = 0; i < 2; i++)
for (int j = 0; j < E.s; j++)
y[i][a[i][E.x[j]]] = true;
f1 = E.f1 + M[0][E.x[E.s]];
f2 = (f1 > E.f2 ? f1 : E.f2) + M[1][E.x[E.s]];
int sf2 = E.sf2 + f2;
int s1 = 0, s2 = 0, k1 = n - E.s, k2 = n - E.s, f3 = f2;
for (int i = 0; i < n; i++)
{
if (!y[0][i])
{
k1--;
if (k1 = n - E.s - 1)
f3 = f2 > f1 + b[0][i] ? f2 : f1 + b[0][i];
s1 += f1 + k1 * b[0][i];
}
}
for (int i = 0; i < n; i++)
{
if (!y[1][i])
{
k2--;
s1 += b[1][i];
s2 += f3 + k2 * b[1][i];
}
}
return sf2 + (s1 > s2 ? s1 : s2);
}
template<class Type>
Type Flowshop<Type>::BBFlow(void)
{
Sort();
priority_queue<MinHeapNode<Type>, vector<MinHeapNode<Type>>, greater<MinHeapNode<Type>>> priority;
MinHeapNode<Type> E;
E.init(n);
while (E.s<=n)
{
if (E.s == n)
{
if (bestc > E.sf2)
{
bestc = E.sf2;
for (int i = 0; i < n; i++)
bestx[i] = E.x[i];
}
delete[]E.x;
}
else
{
for (int i = E.s; i < n; i++)
{
Swap(E.x[E.s], E.x[i]);
int f1, f2;
int bb = Bound(E, f1, f2, y);
if (bb < bestc)
{
MinHeapNode<Type> N;
N.NewNode(E, f1, f2, bb, n);
priority.push(N);
}
Swap(E.x[E.s], E.x[i]);
}
delete[]E.x;
}
if (priority.empty())
break;
else
{
E = priority.top();
priority.pop();
}
}
return bestc;
}
template<class Type>
void Flowshop<Type>::Sort()
{
Type* c = new Type[n];
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
b[i][j] = M[i][j];
c[j] = j;
}
for (int j = 0; j < 3-1; j++)
{
for (int k = 3 -1; k >j; k--)
{
if (b[i][k] < b[i][k - 1])
{
Swap<Type>(b[i][k], b[i][k - 1]);
Swap<Type>(c[k], c[k - 1]);
}
}
}
for (int j = 0; j < 3; j++)
a[i][c[j]] = j;
}
/*for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
cout << M[i][j] << "\t";
}
cout << endl;
}
cout << "__________________" << endl;
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
cout << b[i][j] << "\t";
}
cout << endl;
}
cout << "__________________" << endl;
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
cout << a[i][j] << "\t";
}
cout << endl;
}
cout << "__________________" << endl;*/
delete[] c;
}
int main()
{
int** M;
M = new int* [2];
for (int i = 0; i < 2; i++)
M[i] = new int[3];
M[0][0] = 2, M[0][1] = 3, M[0][2] = 2;
M[1][0] = 1, M[1][1] = 1, M[1][2] = 3;
Flowshop<int> flow;
int** b, ** a;
b = new int* [2];
for (int i = 0; i < 2; i++)
b[i] = new int[3];
a = new int* [2];
for (int i = 0; i < 2; i++)
a[i] = new int[3];
bool** y;
y = new bool* [2];
for (int i = 0; i < 2; i++)
y[i] = new bool[3];
flow.M = M;
flow.a = a;
flow.b = b;
flow.n = 3;
flow.y = y;
flow.bestc = 10000;
flow.bestx = new int[flow.n];
cout << flow.BBFlow() << endl;
return 0;
}