uva 1006 1006 - Fixed Partition Memory Management la2238 km算法

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.ios

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.git

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.less

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).ide

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.ui

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

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.spa

 

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.orm

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.blog

 

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\n", (double)tot/n);
    for(int pro=0; pro<n; pro++){
        printf("Program %d runs in region %d from %d to %d\n", pro+1, rnum[pro]+1, start[pro], start[pro]+rt[pro][rnum[pro]]);
    }
    printf("\n");
}


// 打印具體方案
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\n", (double)total / n);
  for(int p = 0; p < n; p++)
    printf("Program %d runs in region %d from %d to %d\n", p+1, region_number[p]+1, start[p], start[p]+rt[p][region_number[p]]);
  printf("\n");
}

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<<'\t'<<w[i][j]<<endl;
//            }
        km();
        printf("Case %d\n", ++kkk);
//        print();
        print_solution();
    }
    return 0;
}
相關文章
相關標籤/搜索