微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何计算百分比?

如何解决如何计算百分比?

我是 mpi 的新手,我正在尝试编写一个迷你 C 程序来计算用户输入数字ratio 百分比。

百分比率由该表达式计算

`δi = ((xi – xmin ) / (xmax – xmin )) * 100`. 

用户输入的数字存储在一个固定大小的数组 data[100] 中,并分散到所有进程中(这个程序应该只适用于四个进程)。 我面临的问题是尽管所有进程都有数据,但该部门不起作用。例如,如果用户输入数字 {1,2,3,4},根据数学表达式的预期百分比是 {0,33.3,66.6,100},但我得到的是 {0,100,100}。这就是我所拥有的。

#include <stdio.h>
#include "mpi.h"


int main(int argc,char** argv){
    int my_rank;
    int total_processes;
    int root = 0;
    int data[100];
    int loc_data[100];

    MPI_Init(&argc,&argv);
    MPI_Comm_rank(MPI_COMM_WORLD,&my_rank);
    MPI_Comm_size(MPI_COMM_WORLD,&total_processes);

    int input_size = 0;
    if (my_rank == 0){
        printf("Input how many numbers: ");
        scanf("%d",&input_size);
        
        printf("Input the elements of the array: ");
        for(int i=0; i<input_size; i++){
            scanf("%d",&data[i]);
        }
    }

    MPI_Bcast(&input_size,1,MPI_INT,root,MPI_COMM_WORLD);

    int loc_num = input_size/total_processes;

    MPI_Scatter(&data,loc_num,loc_data,MPI_COMM_WORLD);

    int global_max = 0;
    int global_min = 0;
    MPI_Reduce(&loc_data,&global_max,MPI_MAX,MPI_COMM_WORLD);
    MPI_Reduce(&loc_data,&global_min,MPI_MIN,MPI_COMM_WORLD);
    

    float loc_delta[100];
    int x = 0;
    int y = 0;
    float p = 0;

     for(int j = 0; j< loc_num; j++){
        x = loc_data[j] - global_min;
        y = global_max - global_min;
    }

    MPI_Bcast(&y,MPI_COMM_WORLD); 
    
    for(int j = 0; j< loc_num ; j++){
        p = (x / y) * 100;
        printf("p= %f \n",p);
        loc_delta[j] = p; 
    }

    float final_delta[100];
    MPI_Gather(&loc_delta,MPI_FLOAT,final_delta,MPI_COMM_WORLD);


    if(my_rank == 0){
        printf("max number: %d\n",global_max);
        printf("min number: %d\n",global_min);
        
        for(int i = 0; i<input_size; i++)
            printf("delta[%d]: %.2f | ",i+1,final_delta[i]);
    }

    printf("\n");

        MPI_Finalize();

    return 0;
}

解决方法

您的代码有几个问题。

首先:

int global_max = 0;
int global_min = 0;
MPI_Reduce(&loc_data,&global_max,1,MPI_INT,MPI_MAX,root,MPI_COMM_WORLD);
MPI_Reduce(&loc_data,&global_min,MPI_MIN,MPI_COMM_WORLD);

不幸的是,

MPI 没有得到数组中所有元素的最小值,你必须 手动执行此操作。 (source)

因此,需要先计算每个进程数组中的minmax,然后才能将这些minmax的结果相减过程。因为,所有进程都应该具有该数组的 minmax,而不是 MPI_Reduce,您应该使用 MPI_Allreduce。您的代码如下所示:

int local_max = loc_data[0];
int local_min = loc_data[0];
for(int i = 1; i < loc_num; i++){
   local_max = (local_max > loc_data[i]) ?  local_max : loc_data[i];
   local_min = (local_min < loc_data[i]) ?  local_min : loc_data[i];  
}

int global_max = local_max;
int global_min = local_min;

MPI_Allreduce(&local_max,MPI_COMM_WORLD);
MPI_Allreduce(&local_min,MPI_COMM_WORLD);

除非您假设 loc_num=1(您不应该这样做),否则此代码

  for(int j = 0; j< loc_num; j++){
        x = loc_data[j] - global_min;
        y = global_max - global_min;
    }

覆盖相同的 xy。此外,您不应该调用 MPI_Bcast(&y,MPI_COMM_WORLD);,您希望所有进程首先根据公式并行计算它们的工作:

δi = ((xi – xmin ) / (xmax – xmin )) * 100.

然后才将他们的工作发送回 master 进程。因此,每个进程都应该将该公式应用于它们的输入索引,将结果存储在一个数组中并将其发送回 master 进程。像这样:

float loc_delta[100];
float y = global_max - global_min;
for(int j = 0; j< loc_num; j++){
    loc_delta[j] = (((float) (loc_data[j] - global_min) / y) * 100.0); 
}
 
float final_delta[100];
MPI_Gather(&loc_delta,loc_num,MPI_FLOAT,final_delta,MPI_COMM_WORLD);

请注意,我将 (((float) (loc_data[j] - global_min) / y) * 100.0); 转换为 float。否则,C 将返回结果的 int 表示。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。