欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

UVA690 Pipeline Scheduling 流水线调度

发布时间:2024/4/11 编程问答 46 豆豆
生活随笔 收集整理的这篇文章主要介绍了 UVA690 Pipeline Scheduling 流水线调度 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

题意:给出5个工作单元,有10个完全相同的程序需要执行,工作单元要避免冲突,问所有程序执行完所需的时间最短是多少?

例:

7
X...XX.
.X.....
..X....
...X...
......X

7代表时间片,每个工作单元调用次数不固定,工作单元不能冲突,此数据最短时间为34。

分析:

这个只能是暴力求解,但是容易超时,我的想法就是每次枚举它的偏移量,判断是否冲突,加上剪枝。但是超时,就算是初始化所有可能偏移量加上预期剪枝还是超时,测试数据是真的强。

超时代码如下:

#include<iostream> #include<string> #include<string.h> #include<queue> #include<vector> #include<list> #include<set> #include<sstream> #include<algorithm> #include<iomanip> using namespace std; const int maxn = 200 + 10; int mp[maxn],n,maxt=20000; int tp[maxn][20+5]; int ttemp[20 + 5]; int a[maxn]; int cnt = 0, diffarray[maxn]; bool isok(int k) {for (int i = 0; i < 5; i++) {if (a[i] & (a[i] >> k))return false;}return true; } void dfs(int layer, int diff) {if (layer == 10) {maxt = min(diff + n, maxt);return;}if (diff+(10-layer)*diffarray[0] >= maxt)return;//预期判断for (int k = 0 ;k<cnt; k++) {//枚举所有偏移量memset(ttemp, 0, sizeof(ttemp));int j = diff + diffarray[k];int ok = 1;for (int z = j; z < j + n; z++) {if (tp[z][mp[z - j]] == 1) {ok = 0;break;}}if (ok) {for (int z = j; z < j + n; z++) {tp[z][mp[z - j]] = 1;ttemp[z - j] = mp[z - j];}//memcpy(ttemp, mp, sizeof(mp));dfs(layer+1, j + 1);for (int i = 0; i < n; i++) {tp[j + i][ttemp[i]] = 0;}}} } int main() {char x;while (cin >> n && n) {int k = 1; maxt = 200000;memset(mp, 0, sizeof(mp));memset(tp, 0, sizeof(tp));memset(diffarray, 0, sizeof(diffarray));cnt = 0;for (int i = 0; i < 5; i++) {for (int j = 0; j < n; j++) {cin >> x;if (x == 'X') {mp[j] = i;tp[j][i] = 1;a[i] = 1 << j;//用二进制模拟}}}for (int i = 1; i <= n; i++) {if (isok(i))diffarray[cnt++] = i;//保存所有可能的偏移量}dfs(1, 1);cout << maxt-1<< endl;}return 0; }

看了大佬的二进制模拟,真是巧妙,想不到,我用数组一个一个判断工作单元是否冲突,人家用二进制直接判断程序之间的所有工作单元是否冲突。

二进制模拟:

#include <cstdio> #include <cstring> #include<iostream> #include <algorithm> using namespace std;const int maxn = 25; int n, a[5], dt[maxn], ans, cnt;bool ok(int *p, int k) {for (int i = 0; i < 5; ++i)if (a[i] & (p[i] >> k)) return false;return true; }void dfs(int *p, int d, int sum) {if (sum + dt[0] * (10 - d) >= ans) return;if (d == 10) { ans = min(ans, sum); return; }for (int i = 0; i < cnt; ++i) {if (ok(p, dt[i])) {//直接判断当前程序的所有工作单元和已经被占用的工作单元是否冲突int p2[5];for (int j = 0; j < 5; ++j)p2[j] = (p[j] >> dt[i]) | a[j];//时间片前进,所有单元后移,没有冲突,加上新单元dfs(p2, d + 1, sum + dt[i]);}}return; }int main() {while (cin>>n&&n) {memset(a, 0, sizeof(a));memset(dt, 0, sizeof(dt));char x;for (int i = 0; i < 5; i++) {for (int j = 0; j < n; j++) {cin >> x;if (x == 'X')a[i] |= (1 << j);//存入位置量}}cnt = 0;for (int i = 1; i <= n; ++i)if (ok(a, i)) dt[cnt++] = i;//找到所有可能偏移量ans = 10 * n;dfs(a, 1, n);cout << ans << endl;}return 0; }

 

总结

以上是生活随笔为你收集整理的UVA690 Pipeline Scheduling 流水线调度的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。