区间分割求解方程

news2025/6/28 1:30:52

本文实现了基于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,可见误差已经符合要求。

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Kubrnetes APIServe 监控

kube-apiserver组件监控指标及大盘使用说明_容器服务 Kubernetes 版 ACK(ACK)-阿里云帮助中心 kube-apiserver组件提供了Kubernetes的RESTful API接口&#xff0c;使得外部客户端、集群内的其他组件可以与ACK集群交互。本文介绍kube-apiserver组件的监控指标清单、大盘使用指导…

C# Winform 侧边栏,切换不同页面

在项目中我们经常遇到需要在主界面上切换不同子页面的需求&#xff0c;常用做法是左侧显示子页面菜单&#xff0c;用户通过点击左侧菜单&#xff0c;实现右边子页面的展示。 实例项目实现&#xff1a; 项目左侧侧边栏实现FlowLayoutPanel使用显示不同子窗体 实例链接&#xf…

苹果设备上的livp格式是什么?怎么转换?

livp格式是苹果公司推出的一种图片格式&#xff0c;它允许用户在iOS设备上拍摄的照片中包含声音和动作&#xff0c;从而创造出一种动态的照片效果。 livp格式的照片不仅记录了图像&#xff0c;还记录了拍摄前后1.5秒的音频和视频&#xff0c;使得照片能够“活”起来。 ✨livp…

植物大战僵尸(杂交版)最新版V2.1来袭!

【新手指导】最新版v2.1来袭 1.闪退怎么办&#xff1f; 答:窗口模式可以解决大部分问题。输入法转换成英文也可以。最后一种办法管理员运行&#xff0c;再后台可运行&#xff0c;即便不是窗口也不会闪退&#xff0c;亲测有效 2.哪里下载&#xff1f; 答&#xff1a;夸克网盘htt…

【Android】实现Recyclerview的Item可以左右侧滑动的效果

项目需要 使用Recyclerview进行列表的数据加载的时候&#xff0c;需要对这个Item进行左右滑动进行操作的功能&#xff0c; 比如这样 需求实现 上面图来源于 https://github.com/anzaizai/EasySwipeMenuLayout 这是一个可以用来进行列表左滑、右滑的项目&#xff0c;可以集…

盒马鲜生礼品卡如何使用?

盒马鲜生的礼品卡除了在门店用以外&#xff0c;还有什么用处啊 毕竟家附近的盒马距离都太远了&#xff0c;好多卡最后都闲置下来了&#xff0c;而且以前都不知道盒马卡还会过期&#xff0c;浪费了好多 还好最近发现了 盒马鲜生礼品卡现在也能在收卡云上兑现了&#xff0c;而且…

01_点亮LED

这节课的标题是点亮 LED&#xff0c;虽然任务很简单&#xff0c;但是需要大家了解的单片机基础知识的内容却很多&#xff0c;特别是对于初学者&#xff0c;刚开始要在头脑中建立一个单片机的概念&#xff0c;课程最后通过点亮一个 LED 小灯来增加初学者对单片机的兴趣和自信。 …

GLS-3004K 端子排静态双位置继电器 AC115V 导轨安装约瑟 JOSEF

系列型号&#xff1a; GLS-3002K端子排静态双位置继电器&#xff1b; GLS-3204K端子排静态双位置继电器&#xff1b; GLS-3220端子排静态双位置继电器; GLS-3004K端子排静态双位置继电器; 一、用途 GLS系列端子排静态双位置继电器用于交直流操作的各种保护与自动控制系统中,作为…

Dubbo-使用zookeeper作为注册中心时节点的概述

本文内容很容易理解&#xff0c;会阐述当dubbo使用zookeeper作为注册中心时候&#xff0c;zookeeper节点是什么样子的 本文的代码使用的dubbo版本是2.7.x&#xff0c;几年前的版本了&#xff0c;但是不影响探究 首先我们创建一个简单的maven项目&#xff0c;然后写出一段dubb…

分布式事务的八种方案解析(1)

针对不同的分布式场景业界常见的解决方案有2PC、TCC、可靠消息最终一致性、最大努力通知等方案&#xff0c;以下总结8 种常见的解决方案&#xff0c;帮助大家在实际的分布式系统中更好地运用事务。 1.2PC 二阶段提交协议&#xff08;Two-phase commit protocol&#xff09;&…

Tensorflow入门实战 T04-猴痘识别

本篇文章主要&#xff1a;tensorflow 运行环境&#xff1a;本地cpu 运行epoch&#xff1a;50 1、tensorflow官网 tensorflow的官网教程。初学者的 TensorFlow 2.0 教程 | TensorFlow Core 官网上有图像分类的相关详细描述还有代码示例。 2、完整代码展示 from tensorflo…

进阶篇04——视图

简介及基本语法 视图的检查选项 可以通过视图进行数据的增删改查操作&#xff0c;但由于视图是一张虚拟表&#xff0c;所以操作的实际上是视图的基表&#xff0c;即创建视图时select语句操作的表 cascaded 自己还测试了一下这种情况&#xff1a;当V1和V2都没有加检查选项&…

华三HCL模拟器安装及华三防火墙配置

0、前言 最近跟模拟器杠上了&#xff0c;主要是需要运行防火墙&#xff0c;目前已经成功模拟出华为、山石防火墙&#xff0c;而且模拟出来的设备能与物理网络环境进行互联。现在我又盯上华三防火墙了。 首先下载模拟器&#xff1a; 下载地址&#xff1a;H3C网络设备模拟器官方免…

EasyExcel文件导出,出现有文件但没有数据的问题

一开始由于JDK版本过高&#xff0c;我用的17&#xff0c;一直excel没有数据&#xff0c;表头也没有&#xff0c;后来摸索了好久&#xff0c;找了资料也没有&#xff0c;后来改了代码后报了一个错误&#xff08;com.alibaba.excel.exception.ExcelGenerateException: java.lang.…

进程状态及其转换

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

Spring Security 与 JWT、OAuth 2.0 整合详解:构建安全可靠的认证与授权机制

Spring Security 与 OAuth 2.0 整合详解&#xff1a;构建安全可靠的认证与授权机制 将 JWT&#xff08;JSON Web Token&#xff09;与 OAuth 2.0 整合到 Spring Security 中可以为应用程序提供强大的认证和授权功能。以下是详细的整合步骤和代码示例。 1. 引入依赖 首先&am…

【开源项目】重庆智慧城市案例~实景三维数字孪生城市CIM/BIM

飞渡科技数字孪生重庆管理平台&#xff0c;以实景三维平台为支撑&#xff0c;以城市数据库对接为核心&#xff0c;利用数字孪生技术&#xff0c;结合云计算、物联网IOT等技术&#xff0c;对接城市规划、智能交通、和公共安全等系统。 利用平台强大的国产自研渲染引擎&#xff0…

怎么压缩视频大小

在数字时代&#xff0c;视频已成为我们日常生活和工作中不可或缺的一部分。然而&#xff0c;视频文件的大小也越来越大&#xff0c;这给存储和传输带来了不小的挑战。因此&#xff0c;学会如何有效地压缩视频文件&#xff0c;就显得尤为重要。本文将详细介绍一种常用的视频压缩…

vscode中模糊搜索和替换

文章目录 调出搜索&#xff08;快捷键&#xff09;使用正则&#xff08;快捷键&#xff09;替换&#xff08;快捷键&#xff09;案例假设给定文本如下目标1&#xff1a;查找所有函数名目标2&#xff1a;替换所有函数名为hello目标3&#xff1a;给url增加查询字符串参数 调出搜索…

Coursera耶鲁大学金融课程:Financial Markets 笔记Week 01

Financial Markets 本文是学习 https://www.coursera.org/learn/financial-markets-global这门课的学习笔记 这门课的老师是耶鲁大学的Robert Shiller https://en.wikipedia.org/wiki/Robert_J._Shiller Robert James Shiller (born March 29, 1946)[4] is an American econ…