基于 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();
}
运行截图:

基于 MPI 的快速排序算法的实现的更多相关文章
- 基于c++的ostu算法的实现
图像二值化算法是图像处理的基础.一般来说,二值化算法可以分为两个类别:全局二值化和局部二值化.全局二值化是指通过某种算法找到一个全局的阈值T,对图像中坐标为(x,y)的像素值做如下处理: Ostu就是 ...
- 快速排序算法的实现 && 随机生成区间里的数 && O(n)找第k小 && O(nlogk)找前k大
思路:固定一个数,把这个数放到合法的位置,然后左边的数都是比它小,右边的数都是比它大 固定权值选的是第一个数,或者一个随机数 因为固定的是左端点,所以一开始需要在右端点开始,找一个小于权值的数,从左端 ...
- Python八大算法的实现,插入排序、希尔排序、冒泡排序、快速排序、直接选择排序、堆排序、归并排序、基数排序。
Python八大算法的实现,插入排序.希尔排序.冒泡排序.快速排序.直接选择排序.堆排序.归并排序.基数排序. 1.插入排序 描述 插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得 ...
- 基于思岚A1激光雷达+OpenGL+VS2017的Ramer-Douglas-Peucker算法的实现
时隔两年 又借到了之前的那个激光雷达,最老版本的思岚A1,甚至不支持新的固件,并且转接板也不见了,看了下淘宝店卖¥80,但是官方提供了一个基于STM32的实现方式,于是我估摸着这个转接板只是一个普通的 ...
- Canny边缘检测算法的实现
图像边缘信息主要集中在高频段,通常说图像锐化或检测边缘,实质就是高频滤波.我们知道微分运算是求信号的变化率,具有加强高频分量的作用.在空域运算中来说,对图像的锐化就是计算微分.由于数字图像的离散信号, ...
- SSE图像算法优化系列十三:超高速BoxBlur算法的实现和优化(Opencv的速度的五倍)
在SSE图像算法优化系列五:超高速指数模糊算法的实现和优化(10000*10000在100ms左右实现) 一文中,我曾经说过优化后的ExpBlur比BoxBlur还要快,那个时候我比较的BoxBlur ...
- C++基础代码--20余种数据结构和算法的实现
C++基础代码--20余种数据结构和算法的实现 过年了,闲来无事,翻阅起以前写的代码,无意间找到了大学时写的一套C++工具集,主要是关于数据结构和算法.以及语言层面的工具类.过去好几年了,现在几乎已经 ...
- 排序算法的实现之Javascript(常用)
排序算法的实现之Javascript 话不多说,直接代码. 1.冒泡排序 1.依次比较相邻的两个数,如果前一个比后一个大,则交换两者的位置,否则位置不变 2.按照第一步的方法重复操作前length-1 ...
- Alink漫谈(六) : TF-IDF算法的实现
Alink漫谈(六) : TF-IDF算法的实现 目录 Alink漫谈(六) : TF-IDF算法的实现 0x00 摘要 0x01 TF-IDF 1.1 原理 1.2 计算方法 0x02 Alink示 ...
随机推荐
- js实现转盘抽奖
大转盘抽奖,主要通过css3的"transform:rotate(0deg)"属性来控制元素的旋转角度来实现. 通常,抽奖的过程需要渐进的效果,所以直接通过旋转属性写比较繁琐. 这 ...
- SQL盲注、SQL注入 - SpringBoot配置SQL注入过滤器
1. SQL盲注.SQL注入 风险:可能会查看.修改或删除数据库条目和表. 原因:未对用户输入正确执行危险字符清理. 固定值:查看危险字符注入的可能解决方案. 2. pom.xml添加依赖 ...
- MySQL03-多表&事务
1.多表查询 1.1 笛卡尔积 有两个集合A,B .取这两个集合的所有组成情况. 要完成多表查询,需要消除无用的数据 1.2 多表查询分类 1.2.1 内连接查询: 1.隐式内连接:使用where条件 ...
- 【教程】IDEA创建Maven项目并整合Tomcat发布,问题解决大全
一篇入门教程 一.创建项目并运行 参考这个视频,能顺利运行 helloworld ,本人用的 IDEA2020.2.3 .jdk11 .Tomcat9 .Maven3.6 bilibili-IDEA( ...
- Liunx运维(三)-文件过滤及内容编辑处理
文档目录: 一.cat:合并文件或查看文件内容 二.tac:反向显示文件内容 三.more:分页显示文件内容 四.less:分页显示文件内容 五.head:显示文件头部内容 六.tail:显示文件尾部 ...
- 多任务-python实现-同步概念,互斥锁解决资源竞争(2.1.4)
@ 目录 1.同步的概念 2.解决线程同时修改全局变量的方式 3.互斥锁 1.同步的概念 同步就是协同步调,按照预定的先后次序进行运行,如你说完我在说 同步在子面上容易理解为一起工作 其实不是,同指的 ...
- 我用 go-zero 一周实现了一个中台系统,已开源!
作者:Jack 最近发现golang社区里出了一个新星的微服务框架,来自好未来,光看这个名字,就很有奔头,之前,也只是玩过go-micro,其实真正的还没有在项目中运用过,只是觉得 微服务,grpc ...
- Python学习之多项式回归
本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理 线性回归的改进版本中的多项式回归.如果您知道线性回归,那么对您来说很简单.如果没有,我将在本文中解释 ...
- SecureCRT的下载、安装和Putty 的使用 SSH连接工具
SecureCRT是一款支持SSH(SSH1和SSH2)的终端仿真程序,简单地说是Windows下登录UNIX或Linux服务器主机的软件.SecureCRT支持SSH,同时支持Telnet和rlog ...
- CentOS7的防火墙以及selinux介绍/安装telnet命令/安装netstat与ifconfig命令
简介:firewall防火墙的使用 防火墙:主要用户信息安全防护,主要有软件防火墙和硬件防火墙.firewalld防火墙是软件防火墙,在centos7 之前默认采用的防火墙是iptables,而在ce ...