基于 MPI 的快速排序算法的实现

完整代码:

#include <iostream>
#include <cstdlib>
#include <ctime>
#include <algorithm>
#include <cmath>
#include <mpi.h>

using namespace std;

struct Pair {
    int left;
    int right;
};

const int MAX_PROCESS = 128;
const int NUM = 8000;
const int MAX = 1000000;
const int MIN = 0;

int arr[NUM];
int temp[NUM];

Pair pairs[MAX_PROCESS];

int counter = -1;

void swap(int A[], int i, int j) {
    int temp = A[i];
    A[i] = A[j];
    A[j] = temp;
}

int findpivot(int i, int j) {
    return (i + j) / 2;
}

int partition(int A[], int l, int r, int pivot) {
    do {
        while (A[++l] < pivot);
        while ((r != 0 && (A[--r] > pivot)));
        swap(A, l, r);
    } while (l < r);
    swap(A, l, r);
    return l;
}

void quicksort(int A[], int i, int j, int currentdepth, int targetdepth) {
    if (currentdepth == targetdepth) {
        int rank = ++counter;
        pairs[rank].left = i;
        pairs[rank].right = j;
        cout << pairs[rank].left << " and " << pairs[rank].right << " : rank " << rank << endl;
        return;
    }
    if (j <= i) return;
    int pivotindex = findpivot(i, j);
    swap(A, pivotindex, j);
    int k = partition(A, i - 1, j, A[j]);
    swap(A, k, j);
    quicksort(A, i, k - 1, currentdepth + 1, targetdepth);
    quicksort(A, k + 1, j, currentdepth + 1, targetdepth);
}

void quicksort(int A[], int i, int j) {
    if (j <= i) return;
    int pivotindex = findpivot(i, j);
    swap(A, pivotindex, j);
    int k = partition(A, i - 1, j, A[j]);
    swap(A, k, j);
    quicksort(A, i, k - 1);
    quicksort(A, k + 1, j);
}

int main(int argc, char* argv[]) {
    MPI_Init(&argc, &argv);
    int RANK, SIZE, targetdepth, left, right, REAL_SIZE;

    MPI_Comm_rank(MPI_COMM_WORLD, &RANK);
    MPI_Comm_size(MPI_COMM_WORLD, &SIZE);
    REAL_SIZE = SIZE;
    if (RANK == 0) {
        cout << "Quick sort start..." << endl;
        cout << "Generate random data... ";

        memset(arr, 0, NUM * sizeof(arr[0]));
        srand(time(NULL));
        for (int i = 0; i < NUM; i++) {
            arr[i] = MIN + rand() % (MAX - MIN);
        }
        cout << "Done." << endl;
        targetdepth = log2(SIZE);
        cout << "Rank: " << RANK << endl;
        cout << "Sorting... ";
        quicksort(arr, 0, NUM - 1, 0, targetdepth);
        REAL_SIZE = counter + 1;
        for (int i = 1; i < SIZE; i++) {
            int left = pairs[i].left;
            int right = pairs[i].right;
            MPI_Send(&REAL_SIZE, 1, MPI_INT, i, 99, MPI_COMM_WORLD);
            MPI_Send(&left, 1, MPI_INT, i, 0, MPI_COMM_WORLD);
            MPI_Send(&right, 1, MPI_INT, i, 1, MPI_COMM_WORLD);
            MPI_Send(&arr, NUM, MPI_INT, i, 2, MPI_COMM_WORLD);
        }

        left = pairs[0].left;
        right = pairs[0].right;
        quicksort(arr, left, right);
        cout << "Process " << RANK <<" done."<< endl;
    }

    for (int process = 1; process < REAL_SIZE; process++) {
        if (RANK == process) {
            MPI_Status status;
            MPI_Recv(&REAL_SIZE, 1, MPI_INT, 0, 99, MPI_COMM_WORLD, &status);
            MPI_Recv(&left, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &status);
            MPI_Recv(&right, 1, MPI_INT, 0, 1, MPI_COMM_WORLD, &status);
            MPI_Recv(&arr, NUM, MPI_INT, 0, 2, MPI_COMM_WORLD, &status);
            if (process < REAL_SIZE) {
                quicksort(arr, left, right);
                MPI_Send(&arr, NUM, MPI_INT, 0, 0, MPI_COMM_WORLD);
                cout << "Process " << RANK << " done." << endl;
            }
        }
    }

    if (RANK == 0) {
        for (int i = 1; i < REAL_SIZE; i++) {
            //cout << "Master is ready to receive data from process " << i << endl;
            MPI_Status status;
            MPI_Recv(&temp, NUM, MPI_INT, i, 0, MPI_COMM_WORLD, &status);
            for (int j = pairs[i].left; j <= pairs[i].right; j++) {
                arr[j] = temp[j];
            }
            //cout << "Master has combined data from process " << i << endl;
        }
        cout << "Done." << endl;
        cout << "Result:" << endl;
        int counter = 1;
        int row = 20;

        for (int i = 0; i < NUM; i++, counter++) {
            cout << arr[i] << " ";
            if (arr[i] < arr[max(i - 1, 0)]) {
                cerr << "Invalid! " << arr[i] << " > "<< arr[max(i - 1, 0)] <<" i is "<< i << endl;
            }
            if (counter % row == 0) cout << endl;
        }
    }
    MPI_Finalize();

}

运行截图:

原文地址:https://www.cnblogs.com/justsong/p/12219728.html

时间: 2024-10-09 01:56:06

基于 MPI 的快速排序算法的实现的相关文章

基于数组二分查找算法的实现

基于数组二分查找算法的实现 二分查找 查找 算法 赵振江 二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好:其缺点是要求待查表为有序表,且插入删除困难.因此,折半查找方法适用于不经常变动而查找频繁的有序列表.首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功:否则利用中间位置记录将表分成前.后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表.重复以上过程,直到找到满足条件的记录,使查找成功

【转】三种快速排序算法的实现(递归算法、非递归算法、三路划分快速排序)

原文:http://blog.csdn.net/left_la/article/details/8206405 快速排序的三个步骤: 1.分解:将数组A[l...r]划分成两个(可能空)子数组A[l...p-1]和A[p+1...r],使得A[l...p-1]中的每个元素都小于等于A(p),而且,小于等于A[p+1...r]中的元素.下标p也在这个划分过程中计算. 2.解决:通过递归调用快速排序,对数组A[l...p-1]和A[p+1...r]排序. 3.合并:因为两个子数组时就地排序,将它们的

一种排序快速排序算法的实现

1.快速排序的思想:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列. 2.实现:首先写一个将数组分割成两块的函数int Partion(int arr[],int len);返回值为分割后的中间点.该函数以数组第一个数为分割标志. 1 int partion(int arr[],int len){ 2 int m=0; 3 int flag=ar

快速排序算法的实现

排序算法就像是数字信号里边的傅里叶变换一样基础,在此继续温习一遍. void change_integer(int *p1, int *p2) { int tmp = *p1; *p1 = *p2; *p2 = tmp; } int partion(int arr[], int length, int start, int end) { int index = rand()%(end-start+1) + start; change_integer(arr+index, arr+end); in

常见排序算法的实现(归并排序、快速排序、堆排序、选择排序、插入排序、希尔排序)

这篇博客主要实现一些常见的排序算法.例如: //冒泡排序 //选择排序 //简单插入排序 //折半插入排序 //希尔排序 //归并排序 //双向的快速排序 //单向的快速排序 //堆排序 对于各个算法的实现原理,这里不再多说了,代码中注释较多,结合注释应该都能理解算法的原理,读者也可自己google一下.另外,注释中有很多点,比如边界条件.应用场景等已经用 * 标记,* 越多,越应该多注意. 下面是实现: //冒泡排序 void BubbleSort(int *arr, int n) { if(

基于思岚A1激光雷达+OpenGL+VS2017的Ramer-Douglas-Peucker算法的实现

时隔两年 又借到了之前的那个激光雷达,最老版本的思岚A1,甚至不支持新的固件,并且转接板也不见了,看了下淘宝店卖¥80,但是官方提供了一个基于STM32的实现方式,于是我估摸着这个转接板只是一个普通的USB-TTL转接板,那我就用340搭一个试试吧 根据官方的datasheet,电机可以5V供电,核心也是5V,电机使能是VMOTO电压,即5V,因此将三个接口焊到一起,两个地焊到一起,然后剩下一组TXRX,因此七个接口变成四个接口了,正好能接上340,于是插上电试了试,当然...没有那么顺利,报错

Python八大算法的实现,插入排序、希尔排序、冒泡排序、快速排序、直接选择排序、堆排序、归并排序、基数排序。

Python八大算法的实现,插入排序.希尔排序.冒泡排序.快速排序.直接选择排序.堆排序.归并排序.基数排序. 1.插入排序 描述 插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的.个数加一的有序数据,算法适用于少量数据的排序,时间复杂度为O(n^2).是稳定的排序方法.插入算法把要排序的数组分成两部分:第一部分包含了这个数组的所有元素,但将最后一个元素除外(让数组多一个空间才有插入的位置),而第二部分就只包含这一个元素(即待插入元素).在第一部分排序完成后,再将这

软考笔记第六天之各排序算法的实现

对于前面的排序算法,用c#来实现 直接插入排序: 每次从无序表中取出第一个元素,把它插入到有序表的合适位置,使有序表仍然有序.第一趟比较前两个数,然后把第二个数按大小插入到有序表中: 第二趟把第三个数据与前两个数从前向后扫描,把第三个数按大小插入到有序表中:依次进行下去,进行了(n-1)趟扫描以后就完成了整个排序过程.直接插入排序属于稳定的排序,最坏时间复杂性为O(n^2),空间复杂度为O(1).直接插入排序是由两层嵌套循环组成的.外层循环标识并决定待比较的数值.内层循环为待比较数值确定其最终位

探讨排序算法的实现

排序算法是我们工作中使用最普遍的算法,常见的语言库中基本都会有排序算法的实现,比如c标准库的qsort,stl的sort函数等.本文首先介绍直接插入排序,归并排序,堆排序,快速排序和基数排序等比较排序算法,然后介绍计数排序,基数排序等具有线性时间的排序算法.本文主要讨论算法的实现方法,并不会过多介绍基本理论. 评价一个排序算法优劣适用与否,一般需要从三个方面来分析 时间复杂度.用比较操作和移动操作数的最高次项表示,由于在实际应用中最在乎的是运行时间的上限,所以一般取输入最坏情况的下的运行时间作为