貪心算法訓練(七)——加工生產調度(流水作業調度問題)


1. 問題描述

  某工廠收到了 n 個產品的訂單,這 n 個產品分別在 A、B 兩個車間加工,並且必須先在 A 車間加工后才可以送到 B 車間。某個產品 i 在 A、B 兩車間加工的時間分別為 $A_i$、$B_i$。怎樣安排這 n 個產品的加工順序,才能使總的加工時間最短?這里所說的加工時間是指:從開始加工第一個產品到所有產品都加工完畢的時間。

2. 輸入格式

  第一行僅一個數據 n(0 < n< 1000),表示產品的數量

  接下來 n 個數據是表示這 n 個產品在 A 車間加工,各自所需要的時間(都是整數)

  最后的 n 個數據是表示這 n 個產品在 B 車間加工,各自所需要的時間(都是整數)

3. 輸出格式

  第一行一個數據,表示最短的加工時間

  第二行是一種用時最短的產品加工率

4. 樣例輸入

5
3 5 8 7 10
6 2 1 4 9

5. 樣例輸出

34 
1 5 4 2 3

6. 思路分析

  直觀上,最優調度一定讓 $M_1$ 沒有空閑,$M_2$ 的空閑時間盡量短

  Johnson 算法:設 $N_1$ 為 a < b 的作業集合,$N_2$ 為 a >= b 的作業集合,將 $N_1$ 的作業按 a 非減序排序,$N_2$ 中的作業按照 b 非增序排序,則 $N_1$ 作業接 $N_2$ 構成最優順序

7. 代碼

#include <iostream>

using namespace std;

int num;
int a[1001],b[1001],c[1001],d[1001];

typedef struct DATA Data;

struct DATA
{
    int m[1001];
    bool mark[1001];
};

Data data;

void insertion_sort(int a[],int arr[],int len);

int main()
{
    ios::sync_with_stdio(false);
    cin>>num;
    int i = 1,sum = 0;
    for(;i <= num;i++)
        cin>>a[i];
    for(i = 1;i <= num;i++)
    {
        cin>>b[i];
        data.m[i] = min(a[i],b[i]);
        d[i] = i;
        if(data.m[i] == a[i])
            data.mark[i] = false;
        else
            data.mark[i] = true;
    }
    insertion_sort(d,data.m,num);
    int j = num,k = 1;
    for(i = 1;i <= num;i++)
    {
        if(data.mark[d[i]] == true)
            c[j--] = d[i];
        else
            c[k++] = d[i];
    }
    for(i = 1;i <= num;i++)
        sum += a[c[i]];
    sum += b[c[i-1]];
    cout<<sum<<endl;
    for(i = 1;i <= num;i++)
        cout<<c[i]<<"  ";
    return 0;
}
void insertion_sort(int a[],int arr[],int len)
{
    for(int i=2; i<=len; i++)
    {
        int key=arr[i];
        int key1 = a[i];
        int j;
        for(j=i-1; j>=0 && key<arr[j]; j--)
        {
            arr[j+1] = arr[j];
            a[j+1] = a[j];
        }
        arr[j+1]=key;
        a[j+1] = key1;
    }
}

 

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM