UVa 690 Pipeline Scheduling
An arithmetic pipeline is designed to process more than one task simultaneously in an overlap- ping manner. It includes function units and data paths among them. Tasks are processed by pipelining; at each clock, one or more units are dedicated to a task and the output produced for the task at the clock is cascading to the units that are responsible for the next stage; since each unit may work in parallel with the others at any clock, more than one task may be being processed at a time by a single pipeline.
In this problem, a pipeline may have a feedback structure, that is, data paths among function units may have directed loops as shown in the next figure.
Example of a feedback pipeline
Since an arithmetic pipeline in this problem is designed as special purpose dedicated hardware, we assume that it accepts just a single sort of task. Therefore, the timing information of a pipeline is fully described by a simple table called a reservation table
Example of ``reservation table''
clock | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
unit0 | X | . | . | . | X | X | . |
unit1 | . | X | . | . | . | . | . |
unit2 | . | . | X | . | . | . | . |
unit3 | . | . | . | X | . | . | . |
unit4 | . | . | . | . | . | . | X |
In reservation tables, `X' means ``the function unit is busy at that clock'' and `.' means ``the function unit is not busy at that clock.'' In this case, once a task enters the pipeline, it is processed by unit0 at the first clock, by unit1 at the second clock,
and so on. It takes seven clock cycles to perform a task.
Notice that no special hardware is provided to avoid simultaneous use of the same function unit.
Therefore, a task must not be started if it would conflict with any tasks being processed. For instance, with the above reservation table, if two tasks, say task 0 and task 1, were started at clock 0 and clock 1, respectively, a conflict would occur on unit0
at clock 5. This means that you should not start two tasks with single cycle interval. This invalid schedule is depicted in the following process table, which is obtained by overlapping two copies of the reservation table with one being shifted to the right
by 1 clock.
Example of ``conflict''
clock | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
unit0 | 0 | 1 | . | . | 0 | C | 1 | . |
unit1 | . | 0 | 1 | . | . | . | . | . |
unit2 | . | . | 0 | 1 | . | . | . | . |
unit3 | . | . | . | 0 | 1 | . | . | . |
unit4 | . | . | . | . | . | . | 0 | 1 |
(`0's and `1's in this table except those in the first row represent tasks 0 and 1, respectively, and `C' means the conflict.)
Your job is to write a program that reports the minimum number of clock cycles in which the given pipeline can process 10 tasks.
Input
The input consists of multiple data sets, each representing the reservation table of a pipeline. A data set is given in the following format.The integer n(< 20) in the first line is the width of the reservation table, or the number of clock cycles that is necessary to perform a single task. The second line represents the usage of unit0, the third line unit1, and so on. xi,j is either `X' or `.'. The former means reserved and the latter free. There are no spaces in any input line. For simplicity, we only consider those pipelines that consist of 5 function units. The end of the input is indicated by a data set with 0 as the value of n.
For each data set, your program should output a line containing an integer number that is the minimum number of clock cycles in which the given pipeline can process 10 tasks.7 X...XX. .X..... ..X.... ...X... ......X 0
34
Note: In this sample case, it takes 41 clock cycles to process 10 tasks if each task is started as early as possible under the condition that it never conflicts with any previous tasks being processed.
| 00000000001111111111222222222233333333334 clock | 01234567890123456789012345678901234567890 ------------------------------------------------- unit0 | 0.1.00112.3.22334.5.44556.7.66778.9.8899. unit1 | .0.1.....2.3.....4.5.....6.7.....8.9..... unit2 | ..0.1.....2.3.....4.5.....6.7.....8.9.... unit3 | ...0.1.....2.3.....4.5.....6.7.....8.9... unit4 | ......0.1.....2.3.....4.5.....6.7.....8.9(The digits in the table except those in the clock row represent the task number.)
However, it takes only 34 clock cycles if each task is started at every third clock.
| 0000000000111111111122222222223333 clock | 0123456789012345678901234567890123 ------------------------------------------ unit0 | 0..100211322433544655766877988.99. unit1 | .0..1..2..3..4..5..6..7..8..9..... unit2 | ..0..1..2..3..4..5..6..7..8..9.... unit3 | ...0..1..2..3..4..5..6..7..8..9... unit4 | ......0..1..2..3..4..5..6..7..8..9(The digits in the table except those in the clock row represent the task number.)
This is the best possible schedule and therefore your program should report 34 in this case.
1999-03-05
#include <cstdio>
#include <cstring>
// 總共的時鐘數目
int total_num;
// 每個unit所佔用情況的二進位制表示
// 如果unit0佔用情況為00000010,unit[0] = 2
int unit[5];
// able_place[i] = j 代表開始時鐘為j和開始時鐘為0可以並行
int able_place[30];
int able_count = 0;
// 記錄每個任務的開始時鐘
int start_clock[10];
// 記錄最小時間
int min_time;
bool check(int* p, int x);
void dfs_search(int* p, int x);
int main()
{
char str[30];
while(scanf("%d", &total_num) && total_num != 0)
{
memset(unit, 0, sizeof(unit));
memset(able_place, 0, sizeof(able_place));
memset(start_clock, 0, sizeof(start_clock));
able_count = 0;
min_time = 1000;
// 計算每個unit所佔用情況的二進位制表示
for(int i = 0; i < 5; i++)
{
memset(str, 0, sizeof(str));
scanf("%s", str);
int len = strlen(str);
for(int j = 0; j < len; j++)
{
if(str[j] == 'X')
unit[i] = unit[i]*2 + 1;
else
unit[i] = unit[i]*2;
}
}
// 計算與開始時鐘為0可以並行的位置
for(int i = 0; i <= total_num; i++)
{
if(check(unit, i))
{
able_place[able_count] = i;
able_count++;
}
}
/*
printf("it:%d\n", (unit[0]>>3)&unit[0]);
printf("unit: ");
for(int i = 0; i < 5; i++)
printf("%d ", unit[i]);
printf("\n");
printf("able: ");
for(int i = 0; i < able_count; i++)
printf("%d ", able_place[i]);
printf("\n");
*/
// 將第1個任務的位置確定,搜尋確定其他任務位置
start_clock[0] = 0;
dfs_search(unit, 1);
printf("%d\n", min_time);
}
return 0;
}
// 檢查開始時鐘為x能否與開始時鐘為0並行,開始時鐘為0的分佈為p
bool check(int* p, int x)
{
for(int i = 0; i < 5; i++)
{
if(((unit[i]>>x)& p[i]) != 0)
return false;
}
return true;
}
// 搜尋確定任務x的位置
// p為最後total_num個位置的佈局
void dfs_search(int* p, int x)
{
if(x == 10)
{
if(start_clock[x-1]+total_num < min_time)
{
min_time = start_clock[x-1]+total_num;
/* for(int i = 0; i < 10; i++)
{
printf("%d:%d ", i, start_clock[i]);
}
printf("\n");
*/ }
return;
}
// 在可行的時鐘位置中遍歷選擇
for(int i = 0; i < able_count; i++)
{
// 剪枝:如果現在選擇這個位置,以後的任務不考慮衝突全部選擇最小的位置還沒有現在的最優解好,就剪枝
if(start_clock[x-1]+able_place[i] + (9-x)*able_place[0] + total_num >= min_time)
continue;
// 否則,檢查該位置在當前佈局下是否可行
// 如果可行,就將任務放在該位置,並檢查下一任務
if(check(p, able_place[i]))
{
int next_p[5];
memset(next_p, 0, sizeof(next_p));
for(int k = 0; k < 5; k++)
{
next_p[k] = (p[k] << able_place[i]) ^ unit[k];
}
start_clock[x] = start_clock[x-1] + able_place[i];
dfs_search(next_p, x+1);
}
}
}
這是一道好題。
1.最主要的是將判斷unit是否衝突改為整數之間的位運算。
以後注意如果只存在0,1,並且在int整數範圍內(32位),可以用位運算來進行。
2.剪枝策略不一定能想到。下次做題應該考慮將能計算的東西儘量事先計算好,
比如下一個任務在前一個任務的影響下能放的位置。相關推薦
UVA 690 Pipeline Scheduling (搜尋+位運算+剪枝)
題意:10個任務,5個通道,要求每個通道都能放下10個任務且不衝突,然後每個通道的放的方式間隔都是一樣的,問最短需要時間。 思路:利用位運算儲存每個通道的放置方法,然後去深搜,要加剪枝。詳細見程式碼 程式碼: #include <stdio.h> #inc
UVa 690 Pipeline Scheduling
An arithmetic pipeline is designed to process more than one task simultaneously in an overlap- ping manner. It includes function units
UVA690-Pipeline Scheduling(dfs+二進制壓縮狀態)
cstring 沒有 pipe ... 方向 accep acc min sch Problem UVA690-Pipeline Scheduling Accept:142 Submit:1905 Time Limit: 3000 mSec Problem Descr
UVA690 Pipeline Scheduling 流水線排程
題意:給出5個工作單元,有10個完全相同的程式需要執行,工作單元要避免衝突,問所有程式執行完所需的時間最短是多少? 例: 7 X...XX. .X..... ..X.... ...X... ......X 7代表時間片,每個工作單元呼叫次數不固定,工作單元不能衝突,此資料最短時間為34。
UVa 452 - Project Scheduling
題目 有很多工,需要不同的時間,任務之間有先後關係,計算最晚結束的任務的結束時間。 分析 拓撲排序,計算關鍵路徑。資料較小,沒有回邊,這裡直接用dfs更新即可。 說明 又是好久刷題了。。。 #include <ios
UVa #1380 A Scheduling Problem (例題9-26)
居然一次就過了。。做了兩天,淚流滿面啊。不過程式碼跑得很慢。。有機會優化一下 這道題想清楚了還是很簡單的,但是一開始的思路不容易理順。下面文中我的f和g與Rujia書中的定義相反,請注意區分。 題目裡說,把所有的無向邊去掉之後,最終答案則一定是由剩下的有向邊組成的最長路
UVa Live 3683 A Scheduling Problem - 動態規劃
cto scanf -c bool 題目 inf namespace pro 指向 題目傳送門 傳送門 題目大意 給定一個樹,其中有一些邊已經定向,要求為剩下的邊定向使得最長路最短。 定理 答案不會超過定向前由已經定向的邊組成的最長路的長度加
UVa Live 3683 A Scheduling Problem
題目傳送門 傳送門 題目大意 給定一個樹,其中有一些邊已經定向,要求為剩下的邊定向使得最長路最短。 定理 答案不會超過定向前由已經定向的邊組成的最長路的長度加1。 我也不會證明qwq。 假設當前由已經定向的邊組成的最長路的長度為$L$,那麼只用判定答案是否能是$
UVa 11149 矩陣的冪(矩陣倍增法模板題)
ble 化簡 .cn target ans txt put std net https://vjudge.net/problem/UVA-11149 題意: 輸入一個n×n矩陣A,計算A+A^2+A^3+...A^k的值。 思路: 矩陣倍增法。
UVA - 434 Matty's Blocks
mes [0 () block += tty scan 一個 ems 題意:給你正視和側視圖,求最多多少個,最少多少個 思路:貪心的思想。求最少的時候:由於能夠想象著移動,盡量讓兩個視圖的重疊。所以我們統計每一個視圖不同高度的個數。然後計算。至於的話。就是每次拿正視圖的
UVA 11997 K Smallest Sums 優先隊列 多路合並
algorithm span 大白 while logs truct %d 算法 省賽 vjudge 上題目鏈接:UVA 11997 題意很簡單,就是從 k 個數組(每個數組均包含 k 個正整數)中各取出一個整數相加(所以可以得到 kk 個結果),輸出前 k 小的和
UVA 567 Risk【floyd】
art printf ios org std span app process iostream 題目鏈接: option=com_onlinejudge&Itemid=8&page=show_problem&problem=5
uva 1585
cout clu cnblogs push uva i++ namespace cin str #include <bits/stdc++.h> using namespace std; int main() { int k; cin>&
UVA 1584 環狀序列
-- 開頭 給定 字典 字典序 clu cout con sca 題意: 給定一個環狀字符串,輸出字典序最小的線裝字符串。 分析: 我一開始是將原字符串*2去模擬環,然後分別截取以字符串不同字母為首的子串,然後用sort去排序輸出最小的串,復雜度為O(n^2 + nlogn
Marvelous Mazes UVA - 445
累加 == return include printf str string iostream log #include<iostream> #include<stdio.h> #include<string> #include<
紫書第五章訓練 uva 10763 Foreign Exchange by crq
evo pan hang n) 情況 sed 是否 for ear Your non-profit organization (iCORE - international Confederation of Revolver Enthusiasts) coordinates
UVA 10129 Play on Words
bool seq lis rest ble u+ contains con sync Some of the secret doors contain a very interesting word puzzle. The team of archaeologists ha
【組合計數】UVA - 11538 - Chess Queen
bre cpp name using blog ios log return algorithm 考慮把皇後放在同一橫排或者統一縱列,答案為nm(m-1)和nm(n-1),顯然。 考慮同一對角線的情況不妨設,n<=m,對角線從左到右依次為1,2,3,...,n-1,n
UVA 12563(Jin Ge Jin Qu hao)
case class 利用 i++ its 價值 con == 節省空間 開始認真學DP。我對滾動數組的理解是:後一個狀態可以由前一個狀態求得,便可以使用一維數組重復利用節省空間復雜度。 這個題要註意題目要求的前提,求次數可以看作重量為v[i]價值為1放入w-1的背包,歌曲
POJ 3294 UVA 11107 Life Forms 後綴數組
ise -c orm pac str lap sizeof true n-1 相同的題目,輸出格式有區別。 給定n個字符串,求最長的子串,使得它同時出現在一半以上的串中。 不熟悉後綴數組的童鞋建議先去看一看如何用後綴數組計算兩個字符串的最長公共子串 Ural1517 這道題