黑客调度算法

时间:2017-08-28 04:41:49

标签: c++ algorithm

https://www.hackerrank.com/challenges/minimum-average-waiting-time/problem 这是一个黑客问题的链接。我正在努力。 它传递了一些测试用例并且失败了一些。我在STL中使用了内置的优先级队列模板。 代码如下,

#include<iostream>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
struct customer
{
    long long arrTime;
    long long cookTime;
    long long index;
};
void swap(customer& a,customer& b)
{
    customer &temp=a;
    a=b;
    b=temp;
}
bool compare( customer& a, customer& b)
{
    return a.arrTime<b.arrTime;
}
struct Compare1
{
    bool operator()(customer a,customer b)
    {
        return a.cookTime>b.cookTime;
    }
};
struct Compare2
{
    bool operator()(customer a,customer b)
    {
        return a.arrTime>b.arrTime;
    }
};
int main()
{
    vector<customer>c;
    vector<bool>done;
    long long n;
    cin>>n;
    for(long long i=0;i<n;i++)
    {
        customer cust;
        cin>>cust.arrTime;
        cin>>cust.cookTime;
        cust.index=i;
        c.push_back(cust);
        done.push_back(false);
    }
    sort(c.begin(),c.end(),compare);
    for(long long i=0;i<n-1;i++)
    {
        if(c[i].arrTime==c[i+1].arrTime && c[i].cookTime>c[i].cookTime)
        {
            swap(c[i],c[i+1]);
        }
    }
    priority_queue<customer,vector<customer>,Compare1> waitList;
    vector<long long>tat(n);
    vector<long long>ct(n);

    //next step- priority queue work starts
    long long count=0;
    long long totalTime=0;

    long long i=0;
    while(count!=n)
    {
        while(i<n && c[i].arrTime<=totalTime)
        {
            waitList.push(c[i]);
            i++;
        }
        customer next;
        if(!waitList.empty())
        {
            next=waitList.top();
            //cout<<"Job "<<next.index<<endl;
            waitList.pop();
            totalTime+=next.cookTime;
            ct[next.index]=totalTime;
            done[next.index]=true;  
            count++;

        }
        else if(i<n)
        {
            next=c[i];
            //cout<<"Job "<<next.index<<endl;
            i++;
            totalTime+=next.cookTime;
            ct[next.index]=totalTime;
            done[next.index]=true;  
            count++;
        }

    }
    long long sum=0;
    for(long long i=0;i<n;i++)
    {
        tat[i]=ct[i]-c[i].arrTime;
        sum+=tat[i];
    }
    cout<<sum/n;
    return 0;
}

我为这个问题查找了一个名为非抢先优先级调度的算法并实现了它。我怀疑: 这种调度算法是否适用于该问题?我想知道我的调度算法的实现是否有任何错误。 或者任何其他算法来实现它。 以下是变量名称的描述,

tat数组代表作业的总周转时间

ct数组代表完成时间。

我考虑过周转时间=非抢占式优先级调度的等待时间。

done只是一个标志数组,用于指示标记为已完成的进程。

arrTime代表到达时间。

cookTime代表烹饪时间(而不是实际算法中过程的突发时间)

2 个答案:

答案 0 :(得分:0)

我猜你错过了那些同时开始有多个工作的案例 并且所有这些都可以在下一个工作开始之前完成,这非常小。

例如,

5
0 3
0 2
0 4
10 2
10 1
在接受其他2项之前,

应该包含前3项并处理所有这些项目。这种情况在你的情况下会失败。

其他观察:

不需要并且错误地编码用于在烹饪时间内布置矢量的for循环。

for(long long i=0;i<n-1;i++)
{
    if(c[i].arrTime==c[i+1].arrTime && c[i].cookTime>c[i].cookTime)
    {
        swap(c[i],c[i+1]);
    }
}

必须是'c [i] .cookTime&gt; c [i + 1] .cookTime' 优先级队列确保您从给定的集合中获得最少的烹饪时间

下面给出了传递用python编写的所有案例的工作解决方案,以供参考。

import heapq

def getAvgWaitTime(n, cust):
    heap = []
    curTime = 0
    waitTime = 0
    cust = sorted(cust)
    i = 0

    while i < n:
        if curTime < cust[i][0]:
            curTime = cust[i][0]
        while i < n and (curTime >= cust[i][0]):
            heapq.heappush(heap, (cust[i][1], cust[i][0]))
            i += 1

        while (i < n) and curTime < cust[i][0] and len(heap) > 0:
            time, wait = calculateWaiting(heap, curTime)
            curTime += time
            waitTime += wait

    # Clear all the jobs
    while len(heap) > 0:
        time, wait = calculateWaiting(heap, curTime)
        curTime += time
        waitTime += wait

    return waitTime / n


def calculateWaiting(heap, curTime):
    wait = 0
    cur = heapq.heappop(heap)
    wait = curTime - cur[1] + cur[0] 
    return (cur[0], wait)


n = int(raw_input().strip())
cust = []
for i in range(n):
    ar = map(int, raw_input().strip().split(' '))
    cust.append((ar[0], ar[1]))


result = getAvgWaitTime(n, cust)
print result

希望它有所帮助!

答案 1 :(得分:0)

说明

首先,简要说明问题的重要方面。

  1. 订单的顺序可能不正确,这意味着它们可能未按到达时间排序。因此,请务必先按到达时间对它们进行排序。
  2. 重要的是要意识到,在等待订单中,厨师必须选择烹饪时间最短的订单。这样一来,所产生的等待时间将始终最短。
  3. 此外,如果厨师没有要处理的订单,“当前”时间可以播放到下一个到达的订单。

代码

除了已接受的答案外,C++ 解决方案(因为问题标有 C++ 标记)可能如下所示。

#include <bits/stdc++.h>

using namespace std;

struct customer {
    uint64_t arrivalTime;
    uint64_t cookingTime;    
};

/*
 * Complete the minimumAverage function below.
 */
uint64_t minimumAverage(std::deque<customer> clients, uint32_t numberOfClients) {
    auto compareByArrivalTime = [](customer const &client1, customer const &client2)
            {
                return client1.arrivalTime < client2.arrivalTime;
            };
    
    auto compareByCookingTime = [](const customer &client1, const customer &client2)
            {
                return client1.cookingTime > client2.cookingTime;
            };
    
    std::sort(clients.begin(), clients.end(), compareByArrivalTime);
    
    std::priority_queue<customer, std::vector<customer>, decltype(compareByCookingTime)> clientPriorityQueue(compareByCookingTime);
    
    uint64_t minWaitingTime = 0;
    uint64_t currentTime = clients.front().arrivalTime;
    for (auto servedClient = 1; servedClient <= numberOfClients; servedClient++) {
        while (!clients.empty() && currentTime >= clients.front().arrivalTime) {
            clientPriorityQueue.push(clients.front());
            clients.pop_front();
        } 
        
        customer bestClient = clientPriorityQueue.top();
        clientPriorityQueue.pop();
        
        uint64_t arrivalTime = bestClient.arrivalTime;
        uint64_t cookingTime = bestClient.cookingTime;
        minWaitingTime += (currentTime - arrivalTime + cookingTime);
        currentTime += cookingTime;
        
        if (!clients.empty()) {
            currentTime = std::max(currentTime, clients.front().arrivalTime);    
        }
    }
    
    return minWaitingTime / numberOfClients;
}

int main()
{
    uint32_t n;
    std::cin >> n;

    std::deque<customer> clients;
    for (auto i = 0; i < n; i++) {
        customer client;
        std::cin >> client.arrivalTime >> client.cookingTime;
        clients.push_back(client);
    }

    uint64_t result = minimumAverage(clients, n);

    std::cout << result << "\n";

    return 0;
}