mpi并行快速排序

//��������ʱ����ֻ����windowsƽ̨ʹ�ã���������������Ϊ�Դ���timeֻ�ܾ�ȷ����

#include <iostream>
#include <mpi.h>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <malloc.h>
#include <limits.h>
#include <fstream>
#define TOTAL_SIZE 6250000
#define size TOTAL_SIZE/process_num
using namespace std;

int getStandard(int array[], int i, int j) {
    // 基准数据
    int key = array[i];
    while (i < j) {
        // 因为默认基准是从左边开始,所以从右边开始比较
        // 当队尾的元素大于等于基准数据 时,就一直向前挪动 j 指针
        while (i < j && array[j] >= key) {
            j--;
        }
        // 当找到比 array[i] 小的时,就把后面的值 array[j] 赋给它
        if (i < j) {
            array[i] = array[j];
        }
        // 当队首元素小于等于基准数据 时,就一直向后挪动 i 指针
        while (i < j && array[i] <= key) {
            i++;
        }
        // 当找到比 array[j] 大的时,就把前面的值 array[i] 赋给它
        if (i < j) {
            array[j] = array[i];
        }
    }
    // 跳出循环时 i 和 j 相等,此时的 i 或 j 就是 key 的正确索引位置
    // 把基准数据赋给正确位置
    array[i] = key;
    return i;
}

void QuickSort(int array[], int low, int high) {
    // 开始默认基准为 low
    if (low < high) {
        // 分段位置下标
        int standard = getStandard(array, low, high);
        // 递归调用排序
        // 左边排序
        QuickSort(array, low, standard - 1);
        // 右边排序
        QuickSort(array, standard + 1, high);
    }
}

//void bubblingSort(int arr[], int n) {
//	int i, j, temp;
//	// ÿ�ν�һ��Ԫ���͵�ĩβ��n��Ԫ�أ�ִ��n��
//	for (i = 0; i < n; ++i) {
//		// ֮ǰ��ѭ���Ѿ���i��Ԫ���͵�ĩβ������Ҫ�ٴαȽϣ��ʼ�ȥ����Ϊ����һ��Ԫ�رȽϣ�Ϊ�˱����������ʼ�һ
//		for (j = 0; j < n - i - 1; ++j) {
//			// ������ǰ��Ԫ�رȺ�һ��Ԫ��С���ͽ���
//			if (arr[j] > arr[j + 1]) {
//				temp = arr[j];
//				arr[j] = arr[j + 1];
//				arr[j + 1] = temp;
//			}
//		}
//	}
//	//printf("no use?");
//}

int main(int argc, char* argv[])
{
	double s = time(NULL);


	int *original_array = new int[TOTAL_SIZE];
	int *sorted_array = new int[TOTAL_SIZE];
	int c;
	srand(time(NULL));
	int world_rank;
	int process_num;
	MPI_Init(&argc, &argv);
	string data_num=argv[1];
	MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
	MPI_Comm_size(MPI_COMM_WORLD, &process_num);
	if (world_rank == 0)
	{
                //printf("This is the unsorted array: ");

        fstream in;
        string address1 = "/data/data"+data_num+".txt";
        in.open(address1.c_str(),ios::in);
        string x;
        for(int i =0;i<TOTAL_SIZE;i++) {
            in >> x;
            int x1 = atoi(x.c_str());
            original_array[i] =x1;
           // cout << x1 <<' ';
        }

//		for (c = 0; c < TOTAL_SIZE; c++)
//		{
//			original_array[c] = rand() % TOTAL_SIZE;
//			printf("%d ", original_array[c]);
//		}
		printf("\n");
		printf("\n");
	}
	int start_time, end_time;
	start_time = MPI_Wtime();//���㿪ʼʱ��
//	int *sub_array = (int *)malloc(size * sizeof(int));
	int *sub_array = new int [size];

	MPI_Scatter(original_array, size, MPI_INT, sub_array, size, MPI_INT, 0, MPI_COMM_WORLD);

//	bubblingSort(sub_array, size);
	QuickSort(sub_array,0,size-1);

	MPI_Gather(sub_array, size, MPI_INT, sorted_array, size, MPI_INT, 0, MPI_COMM_WORLD);


	if (world_rank == 0)//�����Ļ��ܽ���0�Ž���
	{
		int *current_num = (int *)malloc(process_num * sizeof(int));//���������ӽ������鵱ǰ��Ҫ�Ƚϵ�ֵ
		int *sub_num = (int *)malloc(process_num * sizeof(int));//���������ӽ��������Ѿ�������ֵ����ֹԽ������
		for (int i = 0; i < process_num; ++i) {
			sub_num[i] = 0;//��ʼ��
		}
//		int final_array[TOTAL_SIZE];//����������������
		int *final_array=new int[TOTAL_SIZE];
		int min;//����ÿ�αȽϵ���Сֵ
		int min_num;//����ÿ�αȽ���Сֵ��Ӧ�Ľ��̺�

                //printf("This is the sorted array: ");
                cout<<"Sorting completed and ready to write to file"<<endl;
                ofstream out;
                string address2 = "/data/sorted_data"+data_num+".txt";
                out.open(address2.c_str(),ios::out);

		for (c = 0; c < TOTAL_SIZE; c++)
		{
			for (int k = 0; k < process_num; ++k) {
				if (sub_num[k] >= size) {
					current_num[k] = INT_MAX;//Խ�磬����limits.h���꣬��ʾ����ֵ
				}
				else{
					current_num[k] = sorted_array[k*size + sub_num[k]];//��ȡ��ǰ��Ҫ�Ƚϵ�ֵ
				}
			}
			min = INT_MAX;//ÿ�αȽ϶�Ҫ��min������ʼ��
			for (int i=0; i < process_num; ++i) {
				if (current_num[i] < min) {
					min = current_num[i];
					min_num = i;
				}
			}
			sub_num[min_num] += 1;

			final_array[c] = min;
			out<<min<<' ';
                        //printf("%d ",min);

		}
		printf("\n");
		printf("\n");

		end_time = MPI_Wtime();
                cout<<"Totally, the time it takes is:"<<(end_time - start_time)<<" s"<<endl;

		free(sub_num);//�ͷ��ڴ�
		free(current_num);
		sub_num = NULL;
		current_num = NULL;//��ֹ����Ұָ��
		delete [] final_array;
	}
	//ÿ�����̶����ͷ��ڴ�
	sub_array = NULL;
	MPI_Finalize();
	delete [] original_array;
	delete [] sorted_array;
	delete [] sub_array;
	return 0;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 使用 MPI 实现快速排序的一种方法是使用分治策略。首先,将数组划分成若干个子数组,然后使用 MPI 进程分别对各自的子数组进行快速排序。然后,在所有进程完成排序之后,使用 MPI 函数进行数据交换,将所有子数组中的元素进行归并。最后,对归并后的数组进行快速排序即可完成整个数组的排序。 下面是一个使用 MPI 实现快速排序的简单示例: ``` #include <stdio.h> #include <stdlib.h> #include <mpi.h> #define N 1000000 int cmp(const void *a, const void *b) { return (*(int *)a - *(int *)b); } int main(int argc, char *argv[]) { int rank, size; int i, pivot, temp; int *data, *sub_data; MPI_Status status; MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &size); data = (int *)malloc(N * sizeof(int)); sub_data = (int *)malloc((N / size) * sizeof(int)); if (rank == 0) { for (i = 0; i < N; i++) data[i] = rand(); } MPI_Scatter(data, N / size, MPI_INT, sub_data, N / size, MPI_INT, 0, MPI_COMM_WORLD); qsort(sub_data, N / size, sizeof(int), cmp); if (rank != 0) { MPI_Send(sub_data, N / size, MPI_INT, 0, 0, MPI_COMM_WORLD); } else { for (i = 1; i < size; i++) { MPI_Recv(data, N / size, MPI_INT, i, 0, MPI_COMM_WORLD, &status); qsort(data, N / size, sizeof(int), cmp); } qsort(sub ### 回答2: 快速排序是一种常用的排序算法,在并行计算中可以利用MPI实现更高效的排序。 快速排序的基本思想是通过选定一个基准元素,将待排序序列切分成两个子序列,其中一个序列所有元素都小于基准元素,另一个序列所有元素都大于基准元素。然后对两个子序列分别进行快速排序,最终将两个有序序列合并为一。 在MPI中,我们可以利用分布式内存模型,将待排序序列分布到不同的进程上,每个进程负责排序一部分数据。首先,我们选择一个进程作为主进程,负责生成随机序列,并将序列拆分并发送给其他进程。然后,每个进程对接收到的数据进行快速排序。排序结束后,他们将排好序的数据发送给主进程。 在主进程接收到所有排序结果后,可以利用归并操作将多个有序序列合并为一个有序序列,最终得到完整的有序序列。 在实际实现中,需要注意处理边界情况,比如仅有一个进程的情况,此时直接对整个序列进行排序即可。另外,在切分序列并选择基准元素时,需要使用一些算法来提高快速排序的效率,比如选择中位数作为基准元素。 总而言之,通过MPI实现快速排序可以利用多个进程同时处理不同部分的数据,并利用分布式计算资源加速排序过程,从而实现更快速的排序。 ### 回答3: 使用MPI(Message Passing Interface)实现快速排序需要将排序任务划分为多个子任务,并通过消息传递机制协同各个进程进行排序。 首先,选择一个排序算法作为快速排序的基本算法快速排序的基本思想是通过选择一个基准元素,将待排序序列划分为两个子序列,左侧序列小于等于基准元素,右侧序列大于基准元素,然后分别对左右子序列进行递归排序。 在MPI实现中,可以采用Master-Worker模型。首先,Master进程负责读入待排序序列,并将序列拆分成若干个均匀的子序列,将每个子序列分发给Worker进程。Master进程通过发送消息给Worker进程来分配子序列和指示排序操作。 每个Worker进程接收子序列后,使用快速排序对其进行排序。排序过程中,Worker进程将子序列根据基准元素的大小分为两个子序列,并将左右子序列分别发送给其他Worker进程进行排序。这样不断地划分和排序,直到子序列长度为1或为空,则排序完成。 排序完成后,每个Worker进程将自己的排序好的子序列发送回Master进程。Master进程接收到Worker进程返回的消息后,按照顺序将这些子序列合并起来,得到最终的有序序列。 最后,Master进程将有序序列输出,即得到了使用MPI实现的快速排序结果。 需要注意的是,MPI实现快速排序的过程中需要合理地划分子序列,并进行消息传递和接收。同时,应确保MPI进程之间的通信是同步的,以保证排序的正确性和一致性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值