UVa 690 Pipeline Scheduling Pipeline scheduling binary representation status DFS pruning

Topic link: Pipeline Scheduling
topic description:

Given a 5 × n ( 1 ≤ n ≤ 20 ) 5\times n(1\le n\le20)5×n(1n20 ) Resource Requirements Schedule, SectioniiLine i , jjThe value of column j is 'X' indicating that the process is injjResources need to be used at j moment iii , if it is '.', it means no need to use it. Your task is to schedule the startup time of ten identical processes so that all processes finish as early as possible. When scheduling the start time of each process you need to pay attention to:

  • Once a process is started, it must be executed and cannot be stopped;
  • Any resource must be used mutually exclusive, that is, at any time jjj needs to ensure that for1 ≤ i ≤ 5 1\le i\le51i5 i i i resources are used by at most one process.

You need to output the earliest completion time.
For example, the input is:
Insert image description here
the corresponding output should be 34 3434 , the corresponding execution of each process is as follows (the numbers in the figure represent the process numbers):
Insert image description here

answer:

A brute force method that is easy to think of for this question is to enumerate the start times of ten processes. Since there are ten processes in total, the start time range of each process is: [0, n] [0, n][0,n ] , so the time complexity isO ( n 10 ) O(n^{10})O ( n10 ).
There are too many states that need to be enumerated. How to reduce the states? When we know the time demand of each resource, we can actually know that it is not[0, n] [0, n][0,n ] All start times are feasible, and we can determine a limited number of feasible start times. We assume that the current process starts delay Time later than the previous process. delayTimed e l a y Time , then it is possible to determine which resources the current process will occupy at those times, and only when there is no conflict between the resources occupied by the current process and the resources occupied by the previous process, delay Time delayTimed e l a y Time is only feasible if alldelay Time delayTime can be calculated in advanced e l a y T im e , then the complexity will be greatly reduced when enumerating at the end.
How to quickly determine adelay Time delayTimeIs d e l a y T im e feasible? We can use binary to save the relationship between each resource and time. For example, the input of the sample can be expressed in binary as:
status [ 0 ] = 0110001 status [ 1 ] = 0000010 status [ 2 ] = 0000100 status [ 3 ] = 0001000 status [ 4 ] = 1000000 status[0] = 0110001\\ status[1] = 0000010\\ status[2] = 0000100\\ status[3] = 0001000\\ status[4] = 1000000status[0]=0110001status[1]=0000010status[2]=0000100status[3]=0001000status[4]=1000000
and the current process is delayed compared to the previous process delayTime delayTimed e l a y Time starts after __status[i]>>d e l a y T im e (note that the binary representation used here is inverted from the picture, so right shift is needed here to represent the passage of time, and if it is not inverted, it will be troublesome to make a specific number of digits judgment), The resource usage of the current process isstatus [ i ] status[i]s t a t u s [ i ] , so as long asKaTeX parse error: Expected 'EOF', got '&' at position 11: status[i] &̲ (status[i] >>d..., itrepresents resourceiii will not conflict, onlythe delay Time delayTimed e l a y T im e is feasible.
Is there any way to prune? In fact, this should be able to pass most of the data, but we also have a relatively simple pruning, but this pruning can remove a lot of states. We need to record amin Delay Time minDelayTimemin De l a y Time represents all delay Time delayTimedelayTime中的最小值,如果 n o w S t a r t T i m e + r e s t P r o c e s s N u m × m i n D e l a y T i m e + n ≥ n o w A n s nowStartTime + restProcessNum \times minDelayTime + n \ge nowAns n o wSt a r tT im e+res tP rocess N u m×minDelayTime+nn o w A n s , then we can directly prune (that is, assuming that all subsequent processes can start at the earliest but still cannot be devalued earlier than the currently recorded answer).

Code:

#include <bits/stdc++.h>

const int INF = 0x3f3f3f3f;
const int UNIT_NUM = 5;
const int PROCESS_NUM = 10;

using namespace std;

int ans, n, minDelayTime;
int status[UNIT_NUM];
string reservationTable;
vector<int> nextStep;

void init()
{
    
    
    nextStep.resize(0);
    ans = INF;
    minDelayTime = -1;
    for (int delayTime = 1; delayTime <= n; delayTime++) {
    
    
        bool canStart = true;
        for (int unitID = 0; unitID < UNIT_NUM; unitID++) {
    
    
            if ((status[unitID] >> delayTime) & status[unitID]) {
    
    
                canStart = false;
                break;
            }
        }
        if (canStart) {
    
    
            if (minDelayTime == -1) {
    
     minDelayTime = delayTime; }
            nextStep.push_back(delayTime);
        }
    }
}

void dfs(int nowDepth, int nowStartTime, int s0, int s1, int s2, int s3, int s4) {
    
    
    if (nowDepth == PROCESS_NUM - 1) {
    
     // 这里等于PROCESS_NUM - 1是因为0号进程已经安排到0时刻开始,后续安排的是1-9号进程
        ans = min(ans, nowStartTime + n);
        return ;
    }
    if (nowStartTime + (9 - nowDepth) * minDelayTime + n >= ans) {
    
     return; }
    for (int delayTime : nextStep) {
    
    
        int ns0 = s0 >> delayTime, ns1 = s1 >> delayTime, ns2 = s2 >> delayTime, ns3 = s3 >> delayTime, ns4 = s4 >> delayTime;
        if ((ns0 & status[0]) || (ns1 & status[1]) || (ns2 & status[2]) || (ns3 & status[3]) || (ns4 & status[4])) {
    
    continue; }
        dfs(nowDepth + 1, nowStartTime + delayTime, ns0 | status[0], ns1 | status[1], ns2 | status[2], ns3 | status[3], ns4 | status[4]);
    }
}

int main()
{
    
    
    ios::sync_with_stdio(false);
    while (cin >> n && n != 0) {
    
    
        for (int i = 0; i < UNIT_NUM; i++) {
    
    
            cin >> reservationTable;
            status[i] = 0;
            for (int j = 0; j < n; j++) {
    
    
                if (reservationTable[j] == 'X') {
    
    
                    status[i] |= 1 << j;
                }
            }
        }
        init();
        dfs(0, 0, status[0], status[1], status[2], status[3], status[4]);
        cout << ans << endl;
    }
    return 0;
}

Guess you like

Origin blog.csdn.net/qq_45523675/article/details/129133184