雙機流水作業調度問題——Johnson算法

概述

流水作業是並行處理技術領域的一項關鍵技術,它是以專業化爲基礎,將不同處理對象的同一施工工序交給專業處理部件執行,各處理部件在統一計劃安排下,依次在各個作業面上完成指定的操作。
流水作業調度問題是一個非常重要的問題,其直接關係到計算機處理器的工作效率。然而由於牽扯到數據相關、資源相關、控制相關等許多問題,最優流水作業調度問題處理起來非常複雜。已經證明,當機器數(或稱工序數)大於等於3時, 流水作業調度問題是一個NP-hard問題(e.g分佈式任務調度)。粗糙地說,即該問題至少在目前基本上沒有可能找到多項式時間的算法。只有當機器數爲2時,該問題可有多項式時間的算法(機器數爲1時該問題是平凡的)。

我們先給出流水作業調度的定義:

設有nn個作業,每一個作業ii均被分解爲mm項任務: Ti1,Ti2,,Tim\mathrm{T}_{\mathrm{i} 1}, \mathrm{T}_{\mathrm{i} 2}, \ldots, \mathrm{T}_{\mathrm{im}}(1in1 \leq i \leq n,故共有mnm * n個任務), 要把這些任務安排到m臺機器上進行加工。 如果任務的安排滿足下列3個條件, 則稱該安排爲流水作業調度:

  1. 每個作業 i 的第 j 項任務Tij (1in,1jm)(1 \leqslant \mathrm{i} \leqslant \mathrm{n}, 1 \leqslant \mathrm{j} \leqslant \mathrm{m}) 只能安排在機器 Pj\mathrm{P}_{\mathrm{j}} 上進行加工
  2. 作業 i 的第 j 項任務 Tij(1in,2jm)\mathrm{T}_{\mathrm{ij}}(1 \leq \mathrm{i} \leq \mathrm{n}, 2 \leq \mathrm{j} \leq \mathrm{m}) 的開始加工時間均安排在第 j1\mathrm{j}-1 項任務Tij1\mathrm{T}_{\mathrm{ij}-1} 加工完畢之後,任何一個作業的任務必須依次完成,前一項任務完成之後才能開 始着手下一項任務:
  3. 任何一臺機器在任何一個時刻最多隻能承擔一項任務。

最優流水作業調度是指:

設任務τij\tau_{i j}在機器PjP_{j}上進行加工需要的時間爲tijt_{i j}。 如果所有的tij(1in,1jm)\mathrm{t}_{\mathrm{ij}}(1 \leqslant \mathrm{i} \leqslant \mathrm{n}, 1 \leqslant \mathrm{j} \leqslant \mathrm{m})均已給出, 要找出一種安排任務的方法, 使得完成這 nn個作業的加工時間爲最少。 這個安排稱之爲最優流水作業調度。

前面已經說過,當m3\mathrm{m} \geq 3時該問題是NP問題,這裏我們只給出m=2m = 2時時間複雜度在多項式以內的Johnson算法。

求解流水作業調度問題的Johnson算法具體描述如下:

1、設 a[i]和 b[i] (0i<n)(0 \leq i<n)分別爲作業 i 在兩臺設備上的處理時間。建立由三元組 (作業
號,處理時間,設備號)組成的三元組表 d。其中,處理時間是指每個作業所包含的兩 個任務中時間較少的處理時間。

 設 n=4,(a0,a1,a2,a3)=(3,4,8,10) 和 (b0,b1,b2,b3)=(6,2,9,15) 的作業 0 的三元組爲 (0,3,0), 作業 1 的三元組爲 (1,2,1) 。  如圖 (a) 所示。 \begin{array}{l} \text { 設 } \mathrm{n}=4,\left(\mathrm{a}_{0}, \mathrm{a}_{1}, \mathrm{a}_{2}, \mathrm{a}_{3}\right)=(3,4,8,10) \text { 和 }\left(\mathrm{b}_{0}, \mathrm{b}_{1}, \mathrm{b}_{2}, \mathrm{b}_{3}\right)=(6,2,9,15) \text { 的作業 } 0 \text { 的三元組爲 } \\ (0,3,0), \text { 作業 } 1 \text { 的三元組爲 }(1,2,1) \text { 。 } \text { 如圖 }(\mathrm{a}) \text { 所示。 } \end{array}

(a)三元組表
 作業號  處理時間  設備號 0301212803100\begin{array}{|c|c|c|} \hline \text { 作業號 } & \text { 處理時間 } & \text { 設備號 } \\ \hline 0 & 3 & 0 \\ \hline 1 & 2 & 1 \\ \hline 2 & 8 & 0 \\ \hline 3 & 10 & 0 \\ \hline \end{array}

2、對三元組表按處理時間排序,得到排序後的三元組表 d。如圖(b)所示。

(b)按處理時間排序
 作業號  處理時間  設備號 1210302803100\begin{array}{|c|c|c|} \hline \text { 作業號 } & \text { 處理時間 } & \text { 設備號 } \\ \hline 1 & 2 & 1 \\ \hline 0 & 3 & 0 \\ \hline 2 & 8 & 0 \\ \hline 3 & 10 & 0 \\ \hline \end{array}

3、對三元組表的每一項 d[i](0i<n),\mathrm{d}[\mathrm{i}](0 \leq \mathrm{i}<n), 從左右兩端生成最優作業排列 c[j](0j<n),c[j]\mathrm{c}[\mathrm{j}](0 \leq \mathrm{j}<n), \mathrm{c}[\mathrm{j}]是作業號。如果 d[i]設備號爲 1,則將作業 i 置於 c 的左端末尾,否則置於 c 的右端 末尾。如圖©所示,由兩端向中間存放。

(c)最優作業排列
(0,2,3,1)

(d)最優調度方案

p138104p269152\begin{array}{|l|l|l|l|l|} \hline \mathrm{p} 1 & 3 & 8 & 10 & 4 \\ \hline \mathrm{p} 2 & 6 & 9 & 15 & 2 \\ \hline \end{array}

例題:

下面是北大PKU POJ 第2751題Saving Endeavour

有2臺機器,n件任務,必須先在S1上做,再在S2上做。任務之間先做後做任意。求最早的完工時間。

雙機調度問題Johnson算法簡析:
(1)把作業按工序加工時間分成兩個子集,第一個集合中在S1上做的時間比在S2上少,其它的作業放到第二個集合。先完成第一個集合裏面的作業,再完成第二個集合裏的作業。

(2)對於第一個集合,其中的作業順序是按在S1上的時間的不減排列;對於第二個集合,其中的作業順序是按在S2上的時間的不增排列。

Johnson算法的時間取決於對作業集合的排序,因此,在最懷情況下算法的時間複雜度爲0( nlogn )0(\text { nlogn }),所需的空間複雜度爲0( n )0(\text { n })

c語言代碼如下:

#include <stdio.h>
#include <memory.h>
#include <algorithm>
using namespace std;

const int MAXN=10005;

struct TNode
{
	int s1,s2;
}ws[MAXN];

int topf,tops;
int n;

bool operator<(TNode x,TNode y)
{
	if (x.s1<x.s2&&y.s1>=y.s2) return true;
	if (x.s1<x.s2&&y.s1<y.s2) return x.s1<y.s1;
	if (x.s1>=x.s2&&y.s1>=y.s2) return x.s2>y.s2;
	return false;
}

int max(int x,int y)
{
	return x>y?x:y;
}

void Work()
{
	sort(ws,ws+n);
	int i,t1=0,t2=0;
	for (i=0;i<n;i++)
	{
		t1+=ws.s1;
		t2=max(t1,t2)+ws.s2;
	}
	printf("%dn",t2);
}

void Read()
{
	int i;
	while (scanf("%d",&n)&&n)
	{
		for (i=0;i<n;i++)
			scanf("%d%d",&ws.s1,&ws.s2);
		Work();
	}
}

int main()
{
	Read();
	return 1;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章