1.编写MPI程序,求和1+2+3+…..+100。
要求:
1、使用两个进程
2、进程0计算1+2+…+20,进程1计算21+22+…+100
3、调用计时函数,分别输出两个进程的计算时间。
4、输出两个进程的计算结果,要求结果加起来等于5050
//对等模式
#include <stdio.h>
#include <mpi.h>
int main(int argc, char** argv) {
int rank, num_procs;
int sum = 0, local_sum = 0;
double start_time, end_time;
double start_time_1, end_time_1;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &num_procs);
if (rank == 0) {
start_time = MPI_Wtime(); } // 记录开始时间
else {
start_time_1 = MPI_Wtime();
}
// 进程0计算1+2+...+20,进程1计算21+22+...+100
int start = (rank == 0) ? 1 : 21;
int end = (rank == 0) ? 20 : 100;
for (int i = start; i <= end; ++i) {
local_sum += i;
}
// 使用MPI_Reduce将每个进程的局部和求和到进程0中
MPI_Reduce(&local_sum, &sum, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD);
if (rank == 0) {
end_time = MPI_Wtime(); // 记录结束时间
printf("总计算结果为:%d\n", sum);
printf("进程0计算时间为:%f秒\n", end_time - start_time);}
else{
end_time_1 = MPI_Wtime();
printf("进程1计算时间为:%f秒\n", end_time_1 - start_time_1);
}
MPI_Finalize();
return 0;
}
mpicc -o sum_1-100 sum_1-100.c
mpiexec -n 2 ./sum_1-100
//主从模式
#include <stdio.h>
#include <mpi.h>
int main(int argc, char** argv) {
int rank, size;
int start, end, sum = 0, sub_sum = 0;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
if (rank == 0) {
// 计算数据分配
start = 1;
end = 20;
MPI_Send(&start, 1, MPI_INT, 1, 0, MPI_COMM_WORLD);
MPI_Send(&end, 1, MPI_INT, 1, 0, MPI_COMM_WORLD);
start = 21;
end = 100;
MPI_Send(&start, 1, MPI_INT, 2, 0, MPI_COMM_WORLD);
MPI_Send(&end, 1, MPI_INT, 2, 0, MPI_COMM_WORLD);
// 收集结果
MPI_Recv(&sub_sum, 1, MPI_INT, 1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
sum += sub_sum;
MPI_Recv(&sub_sum, 1, MPI_INT, 2, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
sum += sub_sum;
printf("1+2+...+100 = %d\n", sum);
} else {
MPI_Recv(&start, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
MPI_Recv(&end, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
for (int i = start; i <= end; ++i) {
sub_sum += i;
}
MPI_Send(&sub_sum, 1, MPI_INT, 0, 0, MPI_COMM_WORLD);
}
MPI_Finalize();
return 0;
mpicc -o sum_1-100_2 sum_1-100_2 .c
mpiexec -n 3 ./sum_1-100_2
2.对课程中演示的Jacobi迭代案例,实现基于主从模式的MPI并行程序
在课程中,jacobi案例使用的是对等模式进行并行,该作业需要使用主从模式来并行。
要求:
1、数据按行分块
2、使用5个进程
3、0号进程负责数据的初始化,并控制行块数据的分发和结果的收集
4、1-4号进程负责行子块的jacobi迭代计算。
5、为提高通信效率,jacobi迭代计算过程中的通信不应该经过0号进程。
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
#include <unistd.h>
#define N 8
#define T 2
#define SIZE N / 4
void print_rows(int, float [][N]);
int main(int argc, char *argv[])
{
int rank, size;
float rows[SIZE + 2][N], tmp[2][N], gather[2*N+4][N];
MPI_Status status;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
// 数据初始化
if (rank == 0)
{
for (int i = 0; i < 2*N+4; i++)
for (int j = 0; j < N; j++)
gather[i][j] = 0;
for (int i = 0; i < N; i++)
{
gather[5][i] = 8.0;
gather[2*N+2][i] = 8.0;
}
for (int i = 1; i < 2*N+3; i++)
{
gather[i][0] = 8.0;
gather[i][N - 1] = 8.0;
}
}
// 广播数据
//MPI_Bcast(rows, N*N, MPI_FLOAT, 0, MPI_COMM_WORLD);
// 分发数据
MPI_Scatter(gather, 4*N, MPI_FLOAT, rows, 4*N, MPI_FLOAT, 0, MPI_COMM_WORLD);
//计算结果
if(rank !=0){
int up_proc_id = (rank == 1) ? MPI_PROC_NULL : (rank - 1);
int down_proc_id = (rank == 4) ? MPI_PROC_NULL : (rank + 1);
for (int step = 0; step < T; step++)
{
MPI_Sendrecv(&rows[SIZE][0], N, MPI_FLOAT, down_proc_id, 0, &rows[0][0], N, MPI_FLOAT, up_proc_id, 0, MPI_COMM_WORLD, &status);
MPI_Sendrecv(&rows[1][0], N, MPI_FLOAT, up_proc_id, 1, &rows[SIZE + 1][0], N, MPI_FLOAT, down_proc_id, 1, MPI_COMM_WORLD, &status);
int begin_row = (1 == rank) ? 2 : 1;
int end_row = (4 == rank) ? 1 : 2;
for (int i = begin_row; i <= end_row; i++)
for (int j = 1; j < N - 1; j++)
rows[i][j] = 0.25 * (rows[i][j - 1] + rows[i][j + 1] + rows[i - 1][j] + rows[i + 1][j]);
sleep(rank);
print_rows(rank, rows);
}
for(int i = 1; i < SIZE+1; i++)
for(int j = 0; j < N; j++)
tmp[i-1][j] = rows[i][j];
}
// 收集结果
MPI_Gather(tmp, 2*N, MPI_FLOAT, gather, 2*N, MPI_FLOAT, 0, MPI_COMM_WORLD);
MPI_Barrier(MPI_COMM_WORLD);
//打印结果
if (rank == 0)
{
printf("迭代后结果\n");
for(int i = 2; i < N+2; i++)
{
for(int j = 0; j < N; j++)
printf("%.3f\t", gather[i][j]);
printf("\n");
}
}
MPI_Finalize();
return 0;
}
void print_rows(int rank, float rows[][N])
{
printf("Result in process %d:\n", rank);
for (int i = 0; i < SIZE + 2; i++)
{
for (int j = 0; j < N; j++)
printf("%1.3f\t", rows[i][j]);
printf("\n");
}
//MPI_Barrier(MPI_COMM_WORLD);
}
mpicc -o jacobi_1 jacobi_1.c
yhrun -n 5 -p thcp1 ./jacobi_1
3.对课程中演示的Jacobi迭代案例,实现基于数据二维分块的MPI并行程序
要求:
1、采取二维行列同时分块方式,对数据进行分割。
2、使用4个进程,每个进程初始化一个二维子块,并负责该子块的Jacobi迭代计算。
3、要求使用重复非阻塞通信方式,来实现Jacobi迭代中的通信与计算的重叠,以达到隐藏通信、提高并行性能的目的。
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
#include <unistd.h>
#define N 8
#define SIZE N / 2
#define T 10
int main(int argc, char *argv[])
{
int rank, size;
int begin = 1;
int end = SIZE;
float a[SIZE + 2][SIZE + 2],b[SIZE + 2][SIZE + 2];
MPI_Status status;
MPI_Request request[8];
MPI_Status txstatus[8];
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Datatype newtype;
MPI_Type_vector( SIZE, 1, SIZE+2,MPI_FLOAT,&newtype);/*定义向量数据类型来表示一列*/
MPI_Type_commit( &newtype );/*新类型的递交*/
int up_rank=MPI_PROC_NULL,down_rank=MPI_PROC_NULL,left_rank=MPI_PROC_NULL,right_rank=MPI_PROC_NULL;
for (int i = 0; i < SIZE + 2; i++)
for (int j = 0; j < SIZE + 2; j++)
a[i][j] = 0;
if (rank == 0)
{
up_rank = 1;
right_rank= 2;
for (int i = 0; i < SIZE + 2; i++)
{ a[SIZE + 1][i] = 8.0;
a[i][0] = 8.0;}
}
if (rank == 1)
{
down_rank= 0;
right_rank= 3;
for (int i = 0; i < SIZE + 2; i++)
{ a[0][i] = 8.0;
a[i][0] = 8.0;}
}
if (rank == 2)
{
left_rank=0;
up_rank=3;
for (int i = 0; i < SIZE + 2; i++)
{a[SIZE + 1][i] = 8.0;
a[i][SIZE + 1] = 8.0;}
}
if (rank == 3)
{
left_rank=1;
down_rank= 2;
for (int i = 0; i < SIZE + 2; i++)
{a[0][i] = 8.0;
a[i][SIZE + 1] = 8.0;}
}
MPI_Send_init(&a[1][1], SIZE, MPI_FLOAT, up_rank, 0, MPI_COMM_WORLD, &request[0]);
MPI_Send_init(&a[SIZE][1], SIZE, MPI_FLOAT, down_rank, 0, MPI_COMM_WORLD, &request[1]);
MPI_Send_init(&a[1][SIZE], 1,newtype, right_rank, 0, MPI_COMM_WORLD, &request[2]);
MPI_Send_init(&a[1][1], 1,newtype, left_rank, 0, MPI_COMM_WORLD, &request[3]);
MPI_Recv_init(&a[SIZE+1][1], SIZE, MPI_FLOAT, down_rank, 0, MPI_COMM_WORLD, &request[4]);
MPI_Recv_init(&a[0][1], SIZE, MPI_FLOAT, up_rank, 0, MPI_COMM_WORLD, &request[5]);
MPI_Recv_init(&a[1][0], 1,newtype, left_rank, 0, MPI_COMM_WORLD, &request[6]);
MPI_Recv_init(&a[1][SIZE+1], 1,newtype, right_rank, 0, MPI_COMM_WORLD, &request[7]);
for (int step = 0; step < T; step++)
{
for (int i = begin; i <= end; i++)
for (int j = begin; j <=end; j++)
b[i][j] = 0.25 * (a[i][j - 1] + a[i][j + 1] + a[i - 1][j] + a[i + 1][j]);
for (int i = begin; i <= end; i++)
for (int j = begin; j <=end; j++)
a[i][j]=b[i][j];
MPI_Startall(8, &request[0]);
MPI_Waitall(8, &request[0], &txstatus[0]);
}
sleep(rank);
printf("Result in process %d:\n", rank);
for (int i = 0; i < SIZE + 2; i++)
{
for (int j = 0; j < SIZE + 2; j++)
printf("%1.3f\t", a[i][j]);
printf("\n");
}
MPI_Type_free( &newtype );
MPI_Finalize();
return 0;
}
mpicc -o jacobi_2 jacobi_2.c
yhrun -n 4 -p thcp1 ./jacobi_2
4.对课程中演示的Jacobi迭代案例,实现基于笛卡尔虚拟拓扑的MPI并行程序
上个作业中,我们练习了实现基于数据二维分块的MPI并行程序,当时需要手动构建二维进程网格阵列。在该阶段练习中我们学习了虚拟拓扑,便可以借助笛卡尔虚拟进程拓扑的功能接口来处理MPI通信相关操作。
要求:
1、仍然采取二维行列同时分块的方式,对数据进行区域分解。
2、使用笛卡尔虚拟拓扑的相关接口,进行二维进程网格阵列构建、邻居进程编号获取等操作。
3、使用64个进程,每个进程初始化一个二维子块,并负责该子块的Jacobi迭代计算。
4、使用重复非阻塞通信接口。
#include <stdio.h>
#include <unistd.h>
#include "mpi.h"
#define arysize 8
#define arysize2 (arysize/2)
#define nsteps 1
int main(int argc, char *argv[])
{
int n, myid, numprocs, i, j;
float a[arysize2+2][arysize2+2],b[arysize2+2][arysize2+2];/*定义局部数组的大小 包含边界空间*/
double starttime,endtime;
int col_tag,row_tag,send_col,send_row,recv_col,recv_row;
int col_neighbor,row_neighbor;
MPI_Comm comm2d;
MPI_Datatype newtype;
int right,left,down,top,top_bound,left_bound,down_bound,right_bound;
int periods[2];
int dims[8],begin_row,end_row;
MPI_Status status;
MPI_Init(&argc,&argv);
dims[0] = 8;
dims[1] = 8;
periods[0]=0;
periods[1]=0;
MPI_Cart_create( MPI_COMM_WORLD, 2, dims, periods, 0,&comm2d);/*定义虚拟进程拓扑 它是一个2´2的网格 得到的包含进程拓扑信息的新的通信域是comm2d*/
MPI_Comm_rank(comm2d,&myid);
MPI_Type_vector( arysize2, 1, arysize2+2,MPI_FLOAT,&newtype);/*定义向量数据类型来表示一列*/
MPI_Type_commit( &newtype );/*新类型的递交*/
MPI_Cart_shift( comm2d, 0, 1, &left, &right);/*得到当前进程左右两侧的进程标识*/
MPI_Cart_shift( comm2d, 1, 1, &down, &top);/* 得到当前进程上下方的进程标识*/
//printf("left, right,down, top:%d,%d,%d,%d: \n", left, right,down, top);
/*下面的程序为数组赋初值*/
for(i=0;i<arysize2+2;i++)
for(j=0;j<arysize2+2;j++)
a[i][j]=0.0;
if (top == MPI_PROC_NULL)
{
for ( i=0;i<arysize2+2;i++)
a[0][i]=8.0;
}
if (down == MPI_PROC_NULL)
{
for ( i=0;i<arysize2+2;i++)
a[arysize2+1][i]=8.0;
}
if (left == MPI_PROC_NULL)
{
for ( i=0;i<arysize2+2;i++)
a[i][0]=8.0;
}
if (right == MPI_PROC_NULL)
{
for ( i=0;i<arysize2+2;i++)
a[i][arysize2+1]=8.0;
}
col_tag = 5; row_tag = 6;
//printf("Laplace Jacobi#C(BLOCK,BLOCK)#myid=%d#step=%d#total arysize=%d*%d\n",myid,nsteps,arysize,arysize);
top_bound=1;
left_bound=1;
down_bound=arysize2;
right_bound=arysize2;
//if (top == MPI_PROC_NULL) {top_bound=2;}
//if (left == MPI_PROC_NULL) {left_bound=2;}
//if (down == MPI_PROC_NULL) {down_bound=arysize2-1;}
//if (right == MPI_PROC_NULL) {left_bound= arysize2-1;}
//starttime=MPI_Wtime();
for (n=0; n<nsteps; n++)
{
MPI_Sendrecv( &a[1][1], arysize2, MPI_FLOAT, top, row_tag,& a[arysize2+1][1],arysize2, MPI_FLOAT, down, row_tag, comm2d, &status );/*向上数据传送*/
MPI_Sendrecv( &a[arysize2][1], arysize2, MPI_FLOAT, down, row_tag,& a[0][1],arysize2, MPI_FLOAT, top, row_tag, comm2d, &status );/*向下数据传送*/
MPI_Sendrecv( &a[1][1], 1,newtype, left, col_tag,& a[1][arysize2+1], 1, newtype,right, col_tag, comm2d, &status );/*向左数据传送*/
MPI_Sendrecv( &a[1][arysize2], 1, newtype, right, col_tag, &a[1][0], 1, newtype, left,col_tag, comm2d, &status );/*向右数据传送*/
for ( i=left_bound;i<=right_bound;i++)
for (j=top_bound;j<=down_bound;j++)
b[i][j] = (a[i][j+1]+a[i][j-1]+ a[i+1][j]+a[i-1][j])*0.25;
for ( i=left_bound;i<=right_bound;i++)
for (j=top_bound;j<=down_bound;j++)
a[i][j] = b[i][j];
}
sleep(myid);
printf("Rank %d: \n", myid);
for (i=0;i<arysize2+2;i++) {
for (j=0;j<arysize2+2;j++) {
printf("%.3f\t", a[i][j]);
}
printf("\n");
}
//endtime=MPI_Wtime();
//printf("elapse time=%f\n",endtime-starttime);
MPI_Type_free( &newtype );
MPI_Comm_free( &comm2d );
MPI_Finalize();
}
mpicc -o jacobi_2 jacobi_10.c
yhrun -n 64 -p thcp1 ./jacobi_10
我们进行第一轮计算,预期黄色区域的进程会出现数据,如下图:
monkeycode@ln0:~/training_system/chenzhaoxiang/MPI$ mpicc -o jacobi_10 jacobi_10.c
monkeycode@ln0:~/training_system/chenzhaoxiang/MPI$ yhrun -n 64 -p thcp1 jacobi_10
Rank 0:
8.000 0.000 0.000 0.000 0.000 0.000
8.000 2.000 0.000 0.000 0.000 0.000
8.000 2.000 0.000 0.000 0.000 0.000
8.000 2.000 0.000 0.000 0.000 0.000
8.000 4.000 2.000 2.000 2.000 0.000
8.000 8.000 8.000 8.000 8.000 8.000
Rank 1:
8.000 0.000 0.000 0.000 0.000 0.000
8.000 2.000 0.000 0.000 0.000 0.000
8.000 2.000 0.000 0.000 0.000 0.000
8.000 2.000 0.000 0.000 0.000 0.000
8.000 2.000 0.000 0.000 0.000 0.000
8.000 0.000 0.000 0.000 0.000 0.000
Rank 2:
8.000 0.000 0.000 0.000 0.000 0.000
8.000 2.000 0.000 0.000 0.000 0.000
8.000 2.000 0.000 0.000 0.000 0.000
8.000 2.000 0.000 0.000 0.000 0.000
8.000 2.000 0.000 0.000 0.000 0.000
8.000 0.000 0.000 0.000 0.000 0.000
Rank 3:
8.000 0.000 0.000 0.000 0.000 0.000
8.000 2.000 0.000 0.000 0.000 0.000
8.000 2.000 0.000 0.000 0.000 0.000
8.000 2.000 0.000 0.000 0.000 0.000
8.000 2.000 0.000 0.000 0.000 0.000
8.000 0.000 0.000 0.000 0.000 0.000
Rank 4:
8.000 0.000 0.000 0.000 0.000 0.000
8.000 2.000 0.000 0.000 0.000 0.000
8.000 2.000 0.000 0.000 0.000 0.000
8.000 2.000 0.000 0.000 0.000 0.000
8.000 2.000 0.000 0.000 0.000 0.000
8.000 0.000 0.000 0.000 0.000 0.000
Rank 5:
8.000 0.000 0.000 0.000 0.000 0.000
8.000 2.000 0.000 0.000 0.000 0.000
8.000 2.000 0.000 0.000 0.000 0.000
8.000 2.000 0.000 0.000 0.000 0.000
8.000 2.000 0.000 0.000 0.000 0.000
8.000 0.000 0.000 0.000 0.000 0.000
Rank 6:
8.000 0.000 0.000 0.000 0.000 0.000
8.000 2.000 0.000 0.000 0.000 0.000
8.000 2.000 0.000 0.000 0.000 0.000
8.000 2.000 0.000 0.000 0.000 0.000
8.000 2.000 0.000 0.000 0.000 0.000
8.000 0.000 0.000 0.000 0.000 0.000
Rank 7:
8.000 8.000 8.000 8.000 8.000 8.000
8.000 4.000 2.000 2.000 2.000 0.000
8.000 2.000 0.000 0.000 0.000 0.000
8.000 2.000 0.000 0.000 0.000 0.000
8.000 2.000 0.000 0.000 0.000 0.000
8.000 0.000 0.000 0.000 0.000 0.000
Rank 8:
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 2.000 2.000 2.000 2.000 0.000
8.000 8.000 8.000 8.000 8.000 8.000
Rank 9:
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
Rank 10:
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
Rank 11:
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
Rank 12:
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
Rank 13:
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
Rank 14:
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
Rank 15:
8.000 8.000 8.000 8.000 8.000 8.000
0.000 2.000 2.000 2.000 2.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
Rank 16:
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 2.000 2.000 2.000 2.000 0.000
8.000 8.000 8.000 8.000 8.000 8.000
Rank 17:
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
Rank 18:
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
Rank 19:
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
Rank 20:
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
Rank 21:
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
Rank 22:
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
Rank 23:
8.000 8.000 8.000 8.000 8.000 8.000
0.000 2.000 2.000 2.000 2.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
Rank 24:
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 2.000 2.000 2.000 2.000 0.000
8.000 8.000 8.000 8.000 8.000 8.000
Rank 25:
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
Rank 26:
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
Rank 27:
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
Rank 28:
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
Rank 29:
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
Rank 30:
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
Rank 31:
8.000 8.000 8.000 8.000 8.000 8.000
0.000 2.000 2.000 2.000 2.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
Rank 32:
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 2.000 2.000 2.000 2.000 0.000
8.000 8.000 8.000 8.000 8.000 8.000
Rank 33:
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
Rank 34:
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
Rank 35:
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
Rank 36:
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
Rank 37:
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
Rank 38:
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
Rank 39:
8.000 8.000 8.000 8.000 8.000 8.000
0.000 2.000 2.000 2.000 2.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
Rank 40:
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 2.000 2.000 2.000 2.000 0.000
8.000 8.000 8.000 8.000 8.000 8.000
Rank 41:
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
Rank 42:
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
Rank 43:
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
Rank 44:
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
Rank 45:
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
Rank 46:
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
Rank 47:
8.000 8.000 8.000 8.000 8.000 8.000
0.000 2.000 2.000 2.000 2.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
Rank 48:
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 2.000 2.000 2.000 2.000 0.000
8.000 8.000 8.000 8.000 8.000 8.000
Rank 49:
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
Rank 50:
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
Rank 51:
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
Rank 52:
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
Rank 53:
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
Rank 54:
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
Rank 55:
8.000 8.000 8.000 8.000 8.000 8.000
0.000 2.000 2.000 2.000 2.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000
Rank 56:
0.000 0.000 0.000 0.000 0.000 8.000
0.000 0.000 0.000 0.000 2.000 8.000
0.000 0.000 0.000 0.000 2.000 8.000
0.000 0.000 0.000 0.000 2.000 8.000
0.000 2.000 2.000 2.000 4.000 8.000
8.000 8.000 8.000 8.000 8.000 8.000
Rank 57:
0.000 0.000 0.000 0.000 0.000 8.000
0.000 0.000 0.000 0.000 2.000 8.000
0.000 0.000 0.000 0.000 2.000 8.000
0.000 0.000 0.000 0.000 2.000 8.000
0.000 0.000 0.000 0.000 2.000 8.000
0.000 0.000 0.000 0.000 0.000 8.000
Rank 58:
0.000 0.000 0.000 0.000 0.000 8.000
0.000 0.000 0.000 0.000 2.000 8.000
0.000 0.000 0.000 0.000 2.000 8.000
0.000 0.000 0.000 0.000 2.000 8.000
0.000 0.000 0.000 0.000 2.000 8.000
0.000 0.000 0.000 0.000 0.000 8.000
Rank 59:
0.000 0.000 0.000 0.000 0.000 8.000
0.000 0.000 0.000 0.000 2.000 8.000
0.000 0.000 0.000 0.000 2.000 8.000
0.000 0.000 0.000 0.000 2.000 8.000
0.000 0.000 0.000 0.000 2.000 8.000
0.000 0.000 0.000 0.000 0.000 8.000
Rank 60:
0.000 0.000 0.000 0.000 0.000 8.000
0.000 0.000 0.000 0.000 2.000 8.000
0.000 0.000 0.000 0.000 2.000 8.000
0.000 0.000 0.000 0.000 2.000 8.000
0.000 0.000 0.000 0.000 2.000 8.000
0.000 0.000 0.000 0.000 0.000 8.000
Rank 61:
0.000 0.000 0.000 0.000 0.000 8.000
0.000 0.000 0.000 0.000 2.000 8.000
0.000 0.000 0.000 0.000 2.000 8.000
0.000 0.000 0.000 0.000 2.000 8.000
0.000 0.000 0.000 0.000 2.000 8.000
0.000 0.000 0.000 0.000 0.000 8.000
Rank 62:
0.000 0.000 0.000 0.000 0.000 8.000
0.000 0.000 0.000 0.000 2.000 8.000
0.000 0.000 0.000 0.000 2.000 8.000
0.000 0.000 0.000 0.000 2.000 8.000
0.000 0.000 0.000 0.000 2.000 8.000
0.000 0.000 0.000 0.000 0.000 8.000
Rank 63:
8.000 8.000 8.000 8.000 8.000 8.000
0.000 2.000 2.000 2.000 4.000 8.000
0.000 0.000 0.000 0.000 2.000 8.000
0.000 0.000 0.000 0.000 2.000 8.000
0.000 0.000 0.000 0.000 2.000 8.000
0.000 0.000 0.000 0.000 0.000 8.000
我们可以看到计算结果符合预期。