算法设计与分析: 3-28 m处理器问题

本文探讨了如何在具有m个处理器的网络通信系统中,将n个数据包进行分配,以实现处理器负载的均衡。核心问题是找到划分序列的方式,使得每个处理器处理的数据包平方和的平方根之差的最小值最大化。文章提供了问题描述、Java解决方案及输入输出说明。

3-28 m处理器问题


问题描述

在一个网络通信系统中,要将 n 个数据包依次分配给 m 个处理器进行数据处理,并要求处理器负载尽可能均衡。
设给定的数据包序列为:{σ0,σ1,...,σn1}{σ0,σ1,...,σn−1}
m处理器问题要求的是r0=0r1...rm1n=rmr0=0≤r1≤...≤rm−1≤n=rm ,将数据包序列划分为m段: {σ0,...,σr11}{σ0,...,σr1−1}, {σr1,...,σr21}{σr1,...,σr2−1}, … , {σrm1,...,σn1}{σrm−1,...,σn−1}, 使 maxi=0m1f(ri,ri+1)maxi=0m−1f(ri,ri+1)达到最小。式中,f(i,j)=σ2i+...+σ2jf(i,j)=σi2+...+σj2是序列{σi,...,σj}{σi,...,σj}的负载量。
maxi=0m1f(r1,ri+1)maxi=0m−1f(r1,ri+1)的最小值称为数据包序列{σ0,σ1,...,σn1}{σ0,σ1,...,σn−1}的均衡负载量。

对于给定的数据包序列{σ0,σ1,...,σn1}{σ0,σ1,...,σn−1},编程计算 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

利用Java编写的几种经典问题算法: 1.设a[0:n-1]是一个有n个元素的数组,k(0<=k<=n-1)是一个非负整数。 试设计一个算法将子数组a[0:k]a[k+1,n-1]换位。要求算法在最坏情况下耗时O(n),且只用到O(1)的辅助空间。 2.在一个圆形操场的四周摆放着n堆石子。现要将石子有次序地合并成一堆。规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的得分。试设计一个算法,计算出将n堆石子合并成一堆的最小得分和最大得分,并分析算法的计算复杂性。 3.设磁盘上有n个文件f1,f2,…,fn,每个文件占用磁盘上的1个磁道。这n个文件的检索概率分别是p1,p2,…,pn,且 =1。磁头从当前磁道移到被检信息磁道所需的时间可用这2个磁道之间的径向距离来度量。如果文件fi存放在第i道上,1≦i≦n,则检索这n个文件的期望时间是对于所有的i<j,time+=pi*pj*d(i,j) 。其中d(i,j)是第i道第j道之间的径向距离|i-j|。磁盘文件的最优存储问题要求确定这n个文件在磁盘上的存储位置,使期望检索时间达到最小。试设计一个解决此问题算法,并分析算法的正确性计算复杂度。 4.最小重量机器设计问题。设某一机器由n个部件组成,每一种部件可以从m个不同的供应商处购得。设wij是从供应商j处购得的部件i的重量,cij是相应的价格。试设计一个算法,给出总价格不超过c的最小重量机器设计
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值