区间分割求解方程

本文实现了基于mpi4py的多进程算法
mpi不过多介绍,某些函数的用法也不是介绍范围,这里只给出怎么实现多进程的方程求根算法。区间划分求解方程,在串行程序里,二分法是非常经典的算法,现在对其进行拓展,实现划分n个区间的求根算法,并利用多个进程计算各自区间。
一、原理
方程求根问题,对于:f(x) = 0 ,绘制y = f(x) 函数图像如下:
在这里插入图片描述对于给定区间[l,r],将其均匀划分为两个区间[l,m]和[m,r]。由零点定理知连
续单调函数的零点存在于两端函数值异号的区间,这里不妨假设为[m,r]区间,则目前区间范围可以由原[l,r]缩小为[m,r]将[m,r]视为新区间进一步进行迭代,最终知道区间大小符合精度要求,区间中点作为方程的根,终止算法。

将上述算法推广到 n+1 个区间的情形,如下图所示:
在这里插入图片描述

为算法分配 n 个处理单元,每个处理单元负责计算各自区间端点的值(其中一个处理单元计算两个端点值),筛选出符合零点定理的区间进一步迭代更新区间,最终求解方程根的近似值。具体的,n 条线,划分出 n+1 个区间,总共包含 n+2 个端点值,分配 n 个处理进程。从任务分配来看,有三类进程:
(1)进程 0 为主进程,需要从用户读入初始区间(或者同时读入函数和区间),然后进行区间划分,将整个区间左右端点、以及划分区间长度广播至其他进程,以便每个进程定位自己需要处理的区间。其次需要处理前两个小区间,这就包括了计算第一个小区间左端点的函数值和第一个区间的右端点值(第二个区间的左端点),并且需要从下一个进程处获取第二个区间的右端点值。最后收集每次迭代后根所处的区间。
(2)第二类进程是 1~n-2 号进程,他们的操作都一致,对于第 i 号进程,计算第i+2 个区间的左端点函数值,并从 i+1 号进程获取区间的右端点函数值,判断区间是否包含根,若包含根,向主进程 0 发送消息。
(3)第三类进程是 n-1 号进程,其需要处理最后一个区间的左端点函数计算,但是不需要从其他进程处获取右端点,其右端点由主进程广播所传递获取并计算对应函数值,其他的处理逻辑与第二类进程类似。

最后区间范围缩小到误差允许范围内时停止迭代,主进程直接广播[0,0,0]数
据,其余进程根据广播也停止各自的计算任务。
使用 python MPI 库编程实现上述逻辑,其中以计算方程 x 3 + 2 x + 1 = 0 x^3 + 2x + 1 = 0 x3+2x+1=0为例,代码实现见第二部分,结果见第三部分。
二、源码
根据原理,使用 mpi4py 库实现代码:

from mpi4py import MPI
import sys

comm = MPI.COMM_WORLD
rank = comm.rank
size = comm.size
eps = 0.000005  # 求解精度


def func(x):
    return x ** 3 + 2 * x + 1  # -0.453398


# while循环写作最外面每次进程都要多走几次判断条件,开销更大一些
li, ri, step = 0, 0, 0
if rank == 0:
    # 主进程,负责读入初始区间,区间端点和区间长度分发给各个进程
    # 计算前两个区间左端点值,从下一个区间获取第二个区间右端点值
    print("input the endpoint values of the interval l, r: ")
    li, ri = map(float, input().split())
    while True:
        if ri - li <= eps:
            comm.bcast((0, 0, 0), root=0)  # 终止时也发送一次广播
            break
        step = (ri - li) * 1.0 / (size + 1)  # 区间长度
        comm.bcast((li, ri, step), root=0)
        print("l=%f, r=%f" % (li, ri))
        sys.stdout.flush()
        fl = func(li)
        # 区间左端点l的函数值由0进程负责,右端点r对应的值让最后一个进程处理
        # 0号进程处理两个区间
        r0 = func(li + step)
        r1 = comm.recv(source=rank + 1)  # 主进程不需要发送端点给其他进程
        if fl * r0 < 0:
            ri = li + step  # 第一个区间含根,更新右边界
        elif r0 * r1 < 0:
            li, ri = li + step, li + 2 * step  # 第二个区间含根
        else:  # 新区间在其他进程处,等待消息
            li, ri = comm.recv(source=MPI.ANY_SOURCE)
    print("result of x^3+2x+1=0: %.6f" % ((li + ri) * 1.0 / 2))
elif rank == size - 1:
    # 最后一个进程处理最后一个区间,并且计算最后一个区间两端点的值
    # 不从其他进程获取任何数据(除广播数据外)
    while True:
        lt, rt, st = comm.bcast((li, ri, step), root=0)
        if rt - lt <= eps:
            break
        nl = lt + (rank + 1) * st
        r0 = func(nl)
        comm.send(r0, dest=rank - 1)
        r1 = func(rt)
        print('rank %d,l=%.4f, r=%.4f' % (rank, nl, nl + st))
        sys.stdout.flush()
        if r0 * r1 < 0:  # 包含根,向0进程汇报
            comm.send([nl, nl + st], dest=0)

else:
    # 其余进程处理逻辑一致,计算区间左端点,从下一个进程获取右端点
    while True:
        lt, rt, st = comm.bcast((li, ri, step), root=0)
        if rt - lt <= eps:
            break
        nl = lt + (rank + 1) * st
        r0 = func(nl)
        comm.send(r0, dest=rank - 1)
        r1 = comm.recv(source=rank + 1)
        print('rank %d,l=%.4f, r=%.4f' % (rank, nl, nl + st))
        sys.stdout.flush()
        if r0 * r1 < 0:  # 包含根,向0进程汇报
            comm.send([nl, nl + st], dest=0)

三、 运行结果
运行命令:

 mpiexec -n 6 python caculate.py

运行上述程序,其中初始化区间为[-100,100],6 个进程计算结果为: -0.453397,将x=-0.453397 代回 x 3 + 2 x + 1 x^3 + 2x + 1 x3+2x+1计算结果为:0.000001705,可见误差已经符合要求。

注意,代码里没有特别的处理无解情况下的逻辑,输入的初始区间不包含根代码无法正常结束。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/708382.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

YUV格式与RGB格式详解

图像处理 文章目录 图像处理前言YUV 格式YUV 采样 前言 像素格式描述了像素数据存储所用的格式&#xff0c;定义了像素在内存中的编码方式。RGB 和 YUV 为两种经常使用的像素格式。/ 1024 / 1024 2.63 MB 存储空间。 RGB 和 RGBA 格式 RGB 图像具有三个通道 R、G、B&#xff…

进程状态及其转换

0号进程(idle):在linux系统启动的时候最先运行的进程就是0号进程&#xff0c;0号进程又叫空闲进程。如果系统上没有其他进程执行那么0号进程就执行。0号进程是1号进程和2号进程的父进程 1号进程(init):init进程是由0号进程创建得到的&#xff0c;它的主要工作是系统的初始化。…

《C++ Primer》导学系列:第 1 章 - 开始

1.1 编写一个简单的C程序 概述 本小节介绍了如何编写和运行一个简单的C程序&#xff0c;帮助初学者了解C程序的基本结构和编译运行过程。 编写第一个C程序 我们从一个简单的C程序开始&#xff0c;它的功能是在控制台输出 "Hello, World!"。这是学习任何编程语言的…

【CGAL】圆柱体检测结果后处理

文章目录 文章说明算法思路代码展示结果展示 文章说明 这篇文章主要介绍&#xff0c;对使用CGAL中的 Region Growing 算法爬取圆柱体的结果进行后处理&#xff0c;以获取位置、轴向量、半径都较为合理的单个圆柱体。 在之前的一篇文章中&#xff0c;使用了open3D生成的标准圆…

560亿美元薪酬获批!马斯克:特斯拉未来市值将不止5万亿美元

KlipC报道&#xff1a;6月13日&#xff0c;美国电动汽车制造商特斯拉公司举办年度股东大会&#xff0c;其CEO马斯克对特斯拉生产销售、未来车型计划和在无人驾驶能等领域的发展进行了报告。此外&#xff0c;特斯拉股东批准了马斯克的560亿美元薪酬方案以及特斯拉总部迁至得克萨…

基于Verilog表达的FSM状态机

基于Verilog表达的FSM状态机 1 FSM1.1 Intro1.2 Why FSM?1.3 How to do 在这里聚焦基于Verilog的三段式状态机编程&#xff1b; 1 FSM 1.1 Intro 状态机是一种代码实现功能的范式&#xff1b;一切皆可状态机&#xff1b; 状态机编程四要素&#xff1a;– 1.状态State&#…

深入理解计算机系统 家庭作业6.22

每条磁道存 位 有r-xr条磁道 二者相乘就是我们要求的容量) 所以最大值x0.5

java-多态数组的多态参数

介绍 代码 employer父类 package hansunping;public class employer {private String name;private double salary;public employer(String name,double salary) {this.namename;this.salarysalary;// TODO Auto-generated constructor stub}public double getsalary() {retu…

GlusterFS企业分布式存储

GlusterFS 分布式文件系统代表-nfs常见分布式存储Gluster存储基础梳理GlusterFS 适合大文件还是小文件存储&#xff1f; 应用场景术语Trusted Storage PoolBrickVolumes Glusterfs整体工作流程-数据访问流程GlusterFS客户端访问流程 GlusterFS常用命令部署 GlusterFS 群集准备环…

职称申报总是不通过的五大原因,竟然在这里

职称评审每年都是有人通过&#xff0c;有人不能通过&#xff0c;而且有的人每年申报&#xff0c;但还是不通过&#xff0c;不通过其实都是有原因&#xff0c;抛开运气&#xff0c;有的人确实运气不好&#xff0c;不通过&#xff0c;这种没办法&#xff0c;但是大部分人申报没有…

Spring Cloud Gateway 详解:构建高效的API网关解决方案

Spring Cloud Gateway 详解&#xff1a;构建高效的API网关解决方案 Spring Cloud Gateway 是 Spring Cloud 生态系统中用于构建 API 网关的核心组件。它基于 Spring WebFlux 构建&#xff0c;旨在提供简单且有效的方式来路由和增强 API 请求。以下是 Spring Cloud Gateway 的详…

【Oracle篇】rman时间点异机恢复:从RAC环境到单机测试环境的转移(第六篇,总共八篇)

&#x1f4ab;《博主介绍》&#xff1a;✨又是一天没白过&#xff0c;我是奈斯&#xff0c;DBA一名✨ &#x1f4ab;《擅长领域》&#xff1a;✌️擅长Oracle、MySQL、SQLserver、阿里云AnalyticDB for MySQL(分布式数据仓库)、Linux&#xff0c;也在扩展大数据方向的知识面✌️…

VRRP跟踪接口及认证(华为)

#交换设备 VRRP跟踪接口及认证 一、相关概念 1.VRRP跟踪接口 当 VRRP 的 Master 设备的上行接口出现问题, 而 Master 设备一直保持 Active 状态&#xff0c;那么就会导致网络出现中断&#xff0c;所以必须要使得 VRRP 的运行状态和上行接口能够关联。在配置了 VRRP 元余的网…

经典的网站系统架构(入门级)

从开发到部署&#xff0c;从用户访问到底层数据库&#xff0c;介绍搭建网站系统的经典架构的10个核心部分。 &#xff08;图转自bytebytego&#xff0c;翻译整理by dogstar&#xff09; 1、使用Git管理和协同源代码&#xff0c;通过CI/CD或Git的Webhook方式自动同步更新部署到服…

AI赋能数据安全体系化落地,出席网安标委2024年第一次标准周“数据安全标准与能力建设研讨会”

6月13日&#xff0c;全国网络安全标准化技术委员会&#xff08;以下简称“网安标委”&#xff09;2024年第一次标准周“数据安全标准与能力建设研讨会”在南昌召开。中央网信办网络数据管理局范雪炜、工业和信息化部网络安全管理局周睿康、国家信息中心外网办安全管理处处长罗海…

红酒保存中的氧气管理:适度接触与避免过度氧化

在保存云仓酒庄雷盛红酒的过程中&#xff0c;我们不得不面对一个微妙的问题&#xff1a;氧气管理。氧气&#xff0c;这个我们生活中无处不在的气体&#xff0c;对于红酒的保存却有着至关重要的影响。适度接触氧气对红酒的陈年过程和品质维护具有积极作用&#xff0c;然而过度氧…

【APP移动端自动化测试】第四节.元素操作的API

文章目录 前言一、点击&输入&清空操作 1.1 点击元素 1.2 输入&清空元素二、获取文本内容&位置&大小操作 2.1 获取文本内容 2.2 获取位置&大小三、根据属性名获取属性值操作四、滑动和拖拽操作 4.1 _swipe 4.2 _scroll …

Threejs-12、场景的线性雾和指数雾

1、创建场景雾 //创建场景雾 scene.fog new THREE.Fog(0x999999,0.1,50);2、创建场景指数雾 scene.fog new THREE.FogExp2(0x999999,0.05);3、 设置场景背景颜色 scene.background new THREE.Color(0x999999);完整代码 <script setup> // 导入threejs import * as…

string类小贴士:让你的C++字符串处理更高效

目录 ​编辑 一、为什么要学习string类 1.1 C语言中的字符串 1.2 面试题 &#x1f333;字符串相加https://leetcode.cn/problems/add-strings/description/ 二、标准库中的string类 2.1 string类 2.2 string类的常用接口说明 1. string类对象的常见构造 2. string类对…

精准定位,智慧提纯:高级数据提取策略

在数据驱动的时代&#xff0c;高级数据提取策略成为企业决策、科学研究以及各类项目成功的关键。数据提取&#xff0c;不仅仅是简单地收集信息&#xff0c;而是需要精准定位目标数据&#xff0c;并通过智慧提纯方法&#xff0c;从海量数据中提取出有价值、有深度的信息。本文将…