• uva 1006 1006


    A technique used in early multiprogramming operating systems involved partitioning the available primary memory into a number of regions with each region having a fixed size, different regions potentially having different sizes. The sum of the sizes of all regions equals the size of the primary memory.

    Given a set of programs, it was the task of the operating system to assign the programs to different memory regions, so that they could be executed concurrently. This was made difficult due to the fact that the execution time of a program might depend on the amount of memory available to it. Every program has a minimum space requirement, but if it is assigned to a larger memory region its execution time might increase or decrease.

    In this program, you have to determine optimal assignments of programs to memory regions. Your program is given the sizes of the memory regions available for the execution of programs, and for each program a description of how its running time depends on the amount of memory available to it. Your program has to find the execution schedule of the programs that minimizes the average turnaround time for the programs. An execution schedule is an assignment of programs to memory regions and times, such that no two programs use the same memory region at the same time, and no program is assigned to a memory region of size less than its minimum memory requirement. The turnaround time of the program is the difference between the time when the program was submitted for execution (which is time zero for all programs in this problem), and the time that the program completes execution.

    Input 

    The input data will contain multiple test cases. Each test case begins with a line containing a pair of integers m and n. The number m specifies the number of regions into which primary memory has been partitioned (1 ≤ m ≤ 10), and n specifies the number of programs to be executed (1 ≤ n ≤ 50).

    The next line contains m positive integers giving the sizes of the m memory regions. Following this are n lines, describing the time-space tradeoffs for each of the n programs. Each line starts with a positive integer k (k ≤ 10), followed by k pairs of positive integers s1,t1,s2,t2,�,sk,tk, that satisfy si < si+1 for 1 ≤ i < k. The minimum space requirement of the program is s1, i.e. it cannot run in a partition of size less than this number. If the program runs in a memory partition of size s, where si ≤ s < si+1 for some i, then its execution time will be ti. Finally, if the programs runs in a memory partition of size sk or more, then its execution time will be tk.

    A pair of zeroes will follow the input for the last test case.

    You may assume that each program will execute in exactly the time specified for the given region size, regardless of the number of other programs in the system. No program will have a memory requirement larger than that of the largest memory region.

    Output 

    For each test case, first display the case number (starting with 1 and increasing sequentially). Then print the minimum average turnaround time for the set of programs with two digits to the right of the decimal point. Follow this by the description of an execution schedule that achieves this average turnaround time. Display one line for each program, in the order they were given in the input, that identifies the program number, the region in which it was executed (numbered in the order given in the input), the time when the program started execution, and the time when the program completed execution. Follow the format shown in the sample output, and print a blank line after each test case.

    If there are multiple program orderings or assignments to memory regions that yield the same minimum average turnaround time, give one of the schedules with the minimum average turnaround time.

    Sample Input 

    2 4
    40 60
    1 35 4
    1 20 3
    1 40 10
    1 60 7
    3 5
    10 20 30
    2 10 50 12 30
    2 10 100 20 25
    1 25 19
    1 19 41
    2 10 18 30 42
    0 0
    

    Sample Output 

    Case 1
    Average turnaround time = 7.75
    Program 1 runs in region 1 from 0 to 4
    Program 2 runs in region 2 from 0 to 3
    Program 3 runs in region 1 from 4 to 14
    Program 4 runs in region 2 from 3 to 10
    
    Case 2
    Average turnaround time = 35.40
    Program 1 runs in region 2 from 25 to 55
    Program 2 runs in region 2 from 0 to 25
    Program 3 runs in region 3 from 0 to 19
    Program 4 runs in region 3 from 19 to 60
    Program 5 runs in region 1 from 0 to 18

    左边点为各个程序,右边为状态(j, region),表示在分区region中第j个执行程序的状态。
    有个问题没搞懂,但AC了,记下先:
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<vector>
    #include<cstdlib>
    #include<algorithm>
    
    using namespace std;
    
    #define LL long long
    #define ULL unsigned long long
    #define UINT unsigned int
    #define MAX_INT 0x7fffffff
    #define MAX_LL 0x7fffffffffffffff
    #define MAX(X,Y) ((X) > (Y) ? (X) : (Y))
    #define MIN(X,Y) ((X) < (Y) ? (X) : (Y))
    
    #define MAXR 11
    #define MAXP 55
    #define MAXN MAXR*MAXP
    #define INF 10000000
    
    int rt[MAXP][MAXR];
    int n,m;
    int w[MAXP*MAXR][MAXP*MAXR];
    int ytox[MAXP*MAXR];
    
    vector<int> g[MAXR*MAXP];
    
    inline void add(int u, int v, int _w){
        g[u].push_back(v);
        w[u][v]=_w;
    }
    
    int lx[MAXN], ly[MAXN], slack[MAXN];
    bool s[MAXN], t[MAXN];
    
    bool dfs(int u){
        s[u]=true;
        for(int i=0; i<g[u].size(); i++){
            int v=g[u][i];
            if(t[v]) continue;
            int d=lx[u]+ly[v]-w[u][v];
            if(!d){
                t[v]=true;
                if(-1==ytox[v] || dfs(ytox[v])){
                    ytox[v]=u;
                    return true;
                }
            }
            else slack[v]=MIN(slack[v], d);
        }
        return false;
    }
    
    void km(){
        int i,j, k=n*m;
        memset(ly, 0, sizeof(ly));
        memset(ytox, -1, sizeof(ytox));
        for(i=0; i<k; i++)
            for(lx[i]=-INF, j=0; j<k; j++)
                lx[i]=MAX(w[i][j], lx[i]);
    
        for(i=0; i<k; i++){
            for(j=0; j<k; j++)  slack[j]=INF;
            while(1){
                memset(s, 0, sizeof(s));
                memset(t, 0, sizeof(t));
                if(dfs(i)) break;
                int d=INF;
                for(j=0; j<k; j++) if(!t[j])
                    d=MIN(d, slack[j]);
                for(j=0; j<k; j++){
                    if(s[j]) lx[j]-=d;
                    if(t[j]) ly[j]+=d;
    //                else slack[j]-=d;
                }
            }
        }
    }
    
    void print(){
        int start[MAXP], tot=0, rnum[MAXP];
        for(int r=0; r<m; r++){
    //        vector<int> pros;
            int time=0;
            for(int pos=0; pos<n; pos++){
                int rit=pos+r*n;
                int lft=ytox[rit];
                if(lft>=n) break;
    //            pros.push_back(lft);
                rnum[lft]=r;
                start[lft]=time;
                time+=rt[lft][r];
                tot-=w[lft][rit];
            }
        }
    
        printf("Average execution turnaround time = %.2f
    ", (double)tot/n);
        for(int pro=0; pro<n; pro++){
            printf("Program %d runs in region %d from %d to %d
    ", pro+1, rnum[pro]+1, start[pro], start[pro]+rt[pro][rnum[pro]]);
        }
        printf("
    ");
    }
    
    
    // 打印具体方案
    void print_solution() {
      int start[MAXP], region_number[MAXP], total = 0; // 起始时刻、分配到得区域编号、总回转时间
      for(int region = 0; region < m; region++) {
        vector<int> programs; // 本region执行的所有程序,按照逆序排列(因为是指“倒数”第pos个程序)
        for(int pos = 0; pos < n; pos++) {
          int right = region * n + pos;
          int left = ytox[right];
          if(left >= n) break; // 匹配到虚拟结点,说明本region已经没有更多程序了
          programs.push_back(left);
          region_number[left] = region;
          total -= w[left][right]; // 权值取过相反数
        }
        reverse(programs.begin(), programs.end());
        int time = 0;
        for(int i = 0; i < programs.size(); i++) {
          start[programs[i]] = time;
          time += rt[programs[i]][region];
        }
      }
    
      printf("Average turnaround time = %.2lf
    ", (double)total / n);
      for(int p = 0; p < n; p++)
        printf("Program %d runs in region %d from %d to %d
    ", p+1, region_number[p]+1, start[p], start[p]+rt[p][region_number[p]]);
      printf("
    ");
    }
    
    int main(){
        freopen("C:\Users\Administrator\Desktop\in.txt","r",stdin);
        int kkk=0;
        while(scanf(" %d %d", &m,&n)==2 && m && n){
            int i,j;
            int cap[MAXR];
            for(i=0; i<n*m; i++) g[i].clear();
            for(i=0; i<m; i++) scanf(" %d", cap+i);
            for(int pro=0; pro<n; pro++){
                int k, ss[10], tt[10];
                scanf(" %d", &k);
                for(i=0; i<k; i++) scanf(" %d %d ", ss+i, tt+i);
                for(int r=0; r<m; r++){
                    int &time=rt[pro][r];
                    //time=INF;                                   //  --
                    if(cap[r]<ss[0]) continue;
                    for(i=0; i<k; i++) if(i==k-1 || ss[i+1]>cap[r]){
                        time=tt[i];      break;
                    }
                    for(int pos=0; pos<n; pos++)
                        add(pro, r*n+pos, -(n-pos)*time);
                }
            }
    
            for(i=n; i<n*m; i++)
                for(j=0; j<n*m; j++)
                    add(i, j, 1);
    
    //        for(i=0; i<n*m; i++)
    //            for(j=0; j<n*m; j++){
    //                cout<<i<<' '<<j<<endl;
    //                cout<<'	'<<w[i][j]<<endl;
    //            }
            km();
            printf("Case %d
    ", ++kkk);
    //        print();
            print_solution();
        }
        return 0;
    }
    
  • 相关阅读:
    javaScript快速入门
    解决编程式路由往同一地址跳转时会报错的情况
    babel 依赖
    路由拆分可以达到一定程度的性能优化
    正则的扩展
    设计模式
    mysql数据库
    php基本语法
    事件循环
    面向对象编程
  • 原文地址:https://www.cnblogs.com/ramanujan/p/3320662.html
Copyright © 2020-2023  润新知