贪心算法 --- 例题5.多机调度问题

一.问题描述

N个独立的作业{1,2,…,n},m台相同的机器。每个作业需要在机器上加工ti时间。每个作业不能拆分成更小的作业,只能在一台机器上完成,而且处理过程不能中断.如何调度,使得全部作业在最短时间内完成?
当n ≤ m时,很简单。
当n > m时,属于NP完全难题,迄今未有效解决。

二.解题思路

我们可以采取最长处理时间作业优先的贪心选择策略,可以设计出解多机调度问题的较好的近似算法.

  • 当n<=m(作业数小于机器数)时,只要将机器 i 的 时间区间分配给作业 i 即可;
  • 当n>m时,首先将n个作业从大到小排序,然后依此顺序将作业分配给空闲的处理机。也就是说从剩下的作业中,选择需要处理时间最长的,然后依次选择处理时间次长的,直到所有的作业全部处理完毕,或者机器不能再处理其他作业为止。如果我们每次是将需要处理时间最短的作业分配给空闲的机器,那么可能就会出现其它所有作业都处理完了只剩所需时间最长的作业在处理的情况,这样势必效率较低。

代码如下:

// 多级作业调度问题贪心算法
#include<bits/stdc++.h>
using namespace std;
bool cmp(pair<int, int> A, pair<int, int> B)
{
    return A.second > B.second;  //降序排列
}
int JobSort(vector<pair<int, int>> &Job, int n)
{
    int m = Job.size();
    sort(Job.begin(), Job.end(), cmp);
    for(const auto x:Job)
    {
        cout<<"("<<x.first<<","<<x.second<<")"<<endl;
    }
    int timeTotal = 0;
    vector<int> timeOfMachine(n, 0);
    int pos = 0;  //表示Job数组的下标
    while(m--)
    {
        int minPosition = min_element(timeOfMachine.begin(), timeOfMachine.end()) - timeOfMachine.begin();
        timeOfMachine[minPosition] += Job[pos].second;
        cout<<"将作业"<<Job[pos].first<<"分配给机器"<<minPosition+1<<",用时"<<Job[pos].second;
        cout<<"机器"<<minPosition+1<<"目前总用时为"<<timeOfMachine[minPosition]<<endl;
        pos++;
    }
    return *max_element(timeOfMachine.begin(), timeOfMachine.end());
}
int main()
{
    cout<<"一共m个作业,请输入m: ";
    int m;
    cin>>m;
    cout<<"请输入每个作业的时间: "<<endl;
    vector<pair<int, int>> Job;
    int time;
    for(int i=0; i<m; i++)
    {
        cin>>time;
        Job.push_back(pair<int, int>(i+1, time));
    }
    cout<<"指定n台机器,请输入n: "<<endl;
    int n;
    cin>>n;
    int timeTotal = JobSort(Job, n);
    cout<<"总用时为: "<<timeTotal<<endl;
    system("pause");
    return 0;
}
参考毕方明老师《算法设计与分析》课件.

欢迎大家访问个人博客网站---乔治的编程小屋,和我一起加油吧!

posted @ 2021-12-21 15:34  PGokc  阅读(571)  评论(0编辑  收藏  举报