1. 程式人生 > >演算法設計與分析: 3-28 m處理器問題

演算法設計與分析: 3-28 m處理器問題

3-28 m處理器問題

問題描述

在一個網路通訊系統中,要將 n 個數據包依次分配給 m 個處理器進行資料處理,並要求處理器負載儘可能均衡。
設給定的資料包序列為:{σ0,σ1,...,σn1}
m處理器問題要求的是r0=0r1...rm1n=rm ,將資料包序列劃分為m段: {σ0,...,σr11}, {σr1,...,σr21}, … , {σrm1,...,σn1}, 使

maxi=0m1f(ri,ri+1)達到最小。式中,f(i,j)=σi2+...+σj2是序列{σi,...,σj}的負載量。
maxi=0m1f(r1,ri+1)的最小值稱為資料包序列{σ0,σ1,...,σn1}的均衡負載量。

對於給定的資料包序列{σ0,σ1,...,σn1},程式設計計算 m 個處理器的均衡負載量。

資料輸入:
第 1 行有 2 個正整數 n 和 m。n 表示資料包個數,m 表示處理器數。接下來的 1 行中有 n 個整數,表示 n 個數據包的大小。

Java: version 1

import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.Scanner;

public class MChuLiQi {

    private static int n,m;
    private static double[][] g;
    private static int MAX = 1000000;
    private static int[] packets;

    public static void main(String[] args){
        Scanner input = new
Scanner(System.in); while (true){ n = input.nextInt(); m = input.nextInt(); g = new double[n+1][m+1]; packets = new int[n]; for(int i=0; i<n; i++){ packets[i] = input.nextInt(); } solution(); DecimalFormat formater = new DecimalFormat("#0.##"); formater.setRoundingMode(RoundingMode.FLOOR); System.out.println(formater.format(g[0][m])); } } private static void solution(){ int i,j,k; double tmp,maxt; tmp = f(n-1,n-1); for(i=n-1; i>=0; i--){ if(f(i,i) > tmp) tmp = f(i,i); g[i][1] = f(i,n-1); if(n-i <= m) g[i][n-i] = tmp; } for(i=n-1; i>=0; i--){ for(k=2; k<=m; k++){ for(j=i,tmp=MAX; j<=n-k; j++){ maxt = max(f(i,j),g[j+1][k-1]); if(tmp > maxt) tmp = maxt; } g[i][k] = tmp; } for(k=n-i+1; k<=m; k++) g[i][k] = g[i][n-i]; } } private static double f(int i, int j){ double sum = 0; if(i == j) return Math.sqrt(Math.pow(packets[i],2)); else for(int k=i; k<=j; k++){ sum += Math.pow(packets[k],2); } return Math.sqrt(sum); } private static double max(double a, double b){ return a > b ? a : b; } }

Java: version 2

import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.Scanner;

public class MChuLiQi1 {

    private static int n,m;
    private static double[][] g;
    private static int[] packets;

    public static void main(String[] args){
        Scanner input = new Scanner(System.in);

        while (true){
            n = input.nextInt();
            m = input.nextInt();

            g = new double[n+1][m+1];
            packets = new int[n];

            for(int i=0; i<n; i++){
                packets[i] = input.nextInt();
            }

            solution();

            DecimalFormat formater = new DecimalFormat("#0.##");
            formater.setRoundingMode(RoundingMode.FLOOR);
            System.out.println(formater.format(g[0][m]));
        }
    }

    private static void solution(){
        int i,j,k;
        for(i=n-1; i>=0; i--)
            g[i][1] = f(i,n-1);

        for(k=2; k<=m; k++){
            g[n-k][k] = max(f(n-k,n-k), g[n-k+1][k-1]);
            j = n-k;
            for(i=n-k-1; i>=m-k; i--){
                if(f(i,j) <= g[j+1][k-1])
                    g[i][k] = g[j+1][k-1];
                else
                    if(f(i,i) >= g[i+1][k-1]){
                        g[i][k] = f(i,i);
                        j = i;
                    }
                    else{
                        while (f(i,j-1) >= g[j][k-1])
                            j--;
                        g[i][k] = min(f(i,j), g[j][k-1]);
                        if(g[i][k] == g[j][k-1])
                            j--;
                    }
            }
        }
    }

    private static double f(int i, int j){
        double sum = 0;
        if(i == j)
            return Math.sqrt(Math.pow(packets[i],2));
        else
            for(int k=i; k<=j; k++){
                sum += Math.pow(packets[k],2);
            }
        return Math.sqrt(sum);
    }

    private static double max(double a, double b){
        return a > b ? a : b;
    }

    private static double min(double a, double b){
        return a > b ? b : a;
    }
}

Input & Output

6 3 
2 2 12 3 6 11
12.32

Reference

王曉東《計算機演算法設計與分析》(第3版)P101