基于C语言的Jacobi迭代和Gauss-Seidel迭代的方程组求解实现

文章目录

  • Jacobi迭代方法介绍
  • Gauss-Seidel迭代方法介绍
  • 具体代码实现
  • 示例题目
  • 实现效果

Jacobi迭代方法介绍

Jacobi迭代法是一种简单的迭代求解方法,适用于严格对角占优矩阵。其基本思想是利用当前迭代步的已知解来更新下一个迭代步的解。在C语言实现中,我们首先需要定义系数矩阵A、常数向量b以及迭代向量x。然后,通过循环迭代,不断更新x的值,直到满足收敛条件或达到最大迭代次数。

Jacobi迭代法的优点是简单直观,但收敛速度相对较慢。特别是对于非严格对角占优的矩阵,Jacobi迭代法可能不收敛。因此,在实际应用中,我们需要根据问题的具体情况选择合适的迭代方法。

Gauss-Seidel迭代方法介绍

Gauss-Seidel迭代法是对Jacobi迭代法的一种改进。在Gauss-Seidel迭代法中,我们使用当前迭代步已更新的解来更新下一个解。这种策略可以加速收敛速度,特别是在对角线元素较大的情况下。在C语言实现中,我们需要对系数矩阵A进行适当的分解,以便在迭代过程中方便地获取已更新的解。

与Jacobi迭代法相比,Gauss-Seidel迭代法具有更快的收敛速度。但是,Gauss-Seidel迭代法并不总是收敛的,其收敛性取决于系数矩阵A的性质。因此,在使用Gauss-Seidel迭代法时,我们需要确保系数矩阵A满足一定的条件(如严格对角占优)。

具体代码实现

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include "time.h"

#define N 3   //要求解的数组大小N x N
#define ERROR 1e-6  //误差要求
#define IterMaxNum 50000   //最大迭代次数

float current_error(float* last, float* now)
{
    float max_error = 0;
    float temp;
    for (int i = 0; i < N; i++)
    {
        temp = *(now + i) - *(last + i);
        if (temp < 0)
            temp = -temp;
        if (temp > max_error)
            max_error = temp;
    }
    return max_error;
}

//雅可比迭代函数
float* Jacobi(float* A, float* b)
{
    clock_t start, end;
    double cpu_time_used;

    // 记录开始时间
    start = clock();
    int i, j;
    int iter_num = 0;   //目前的迭代次数
    float error_now = 100;   //目前迭代下的误差

    //生成数组用于保存每次迭代得到的x结果并保存上一次迭代结果至x0
    float* x = (float*)malloc(N * sizeof(float));
    memset(x, 0, N * sizeof(float));
    float* x0 = (float*)malloc(N * sizeof(float));
    memset(x0, 0, N * sizeof(float));

    while(error_now > ERROR)
    {
        //将上一次迭代的结果保存到x0中去
        memcpy(x0, x, N * sizeof(float));

        for (i = 0; i < N; i++)
        {
            float sum = 0;
            for (j = 0; j < N; j++)
            {
                //printf("%f\t", A[i * N + j]);
                if (i != j)
                    sum += A[i * N + j] * (x0[j]);
            }
            x[i] = (b[i] - sum) / A[i * N + i];
        }

        error_now = current_error(x, x0);
        iter_num++;

        printf("当前迭代次数为:【%d】,迭代误差为:【%f】\n", iter_num, error_now);
        printf("迭代结果为:%f,%f,%f\n", x[0], x[1], x[2]);
        if (iter_num > IterMaxNum)
        {
            printf("迭代次数超过最大值要求,返回最后一次迭代结果");
            break;
        }
    }
    // 记录结束时间
    end = clock();

    // 计算经过的CPU时间
    cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;

    // 打印Jacobi迭代的运行时间
    printf("\n【Jacobi迭代运行了 %f 秒。】\n", cpu_time_used);

    free(x0);
    return x;
}


float* GS(float* A, float* b)
{
    int i, j;
    int iter_num = 0;   //目前的迭代次数
    float error_now = 100;   //目前迭代下的误差

    //生成数组用于保存每次迭代得到的x结果并保存上一次迭代结果至x0
    float* x = (float*)malloc(N * sizeof(float));
    memset(x, 0, N * sizeof(float));
    float* x0 = (float*)malloc(N * sizeof(float));
    memset(x0, 0, N * sizeof(float));

    clock_t start, end;
    double cpu_time_used;

    // 记录开始时间
    start = clock();
    while (error_now > ERROR)
    {
        memcpy(x0, x, N * sizeof(float));

        for (i = 0; i < N; i++)
        {
            float sum = 0;
            for (j = 0; j < N; j++)
            {
                //printf("%f\t", A[i * N + j]);
                if (i != j)
                    sum += A[i * N + j] * (x[j]);
            }
            x[i] = (b[i] - sum) / A[i * N + i];
        }

        error_now = current_error(x, x0);  //获得当前迭代的误差结果
        iter_num++;   //迭代次数加1

        printf("当前迭代次数为:【%d】,迭代误差为:【%f】\n", iter_num, error_now);
        printf("迭代结果为:%f,%f,%f\n", x[0], x[1], x[2]);
        if (iter_num > IterMaxNum)
        {
            printf("迭代次数超过最大值要求,返回最后一次迭代结果");
            break;
        }
    }
    // 记录结束时间
    end = clock();

    // 计算经过的CPU时间
    cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;

    // 打印Gauss-Seidel迭代的运行时间
    printf("\n【Gauss-Seidel迭代运行了 %f 秒。】\n", cpu_time_used);
    free(x0);
    return x;
}


int main()
{
    // 例子
    float A[N][N] = {
            {10,-1,-2},
            {-1,10,-2},
            {-1, -1, 5},
    };   //要求解的矩阵
    float b[N] = {72, 83, 42};

    float* x;

//    x = Jacobi((float*)A, b);

    x = GS((float*)A, b);

    printf("\n【最终结果为】:%f, %f, %f\n", x[0], x[1], x[2]);

    free(x);   //释放x
}

示例题目

以如下方程组为例,进行迭代方法的测试

在这里插入图片描述

实现效果

Jacobi迭代实现效果,迭代了【17】达到了收敛
在这里插入图片描述
Gauss-Seidel迭代实现效果,而Gauss-Seidel只迭代了【10】次即可达到收敛。
在这里插入图片描述
注意,有些示例中,Jacobi迭代是比Gauss-Seidel收敛的的,但更多的时候Gauss-Seidel是收敛更快的,并且存在有时候Jacobi收敛,而Gauss-Seidel却发散,要根据情况而定。

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

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

相关文章

网格处理库 pmp-library 编译及应用笔记 -- 已全部解决√

多边形网格处理库Polygon Mesh Processing Library&#xff0c;简称pmp-library的 编译及应用笔记 – 已全部解决√ 官网&#xff1a;https://www.pmp-library.org/index.html 代码&#xff1a;https://github.com/pmp-library/pmp-library 平台&#xff1a;Ubuntu1 20.04&…

Python功能制作之使用streamlit做一个简单的WebUI

使用Streamlit创建WebUI 1. 什么是Streamlit Streamlit 是一个开源的Python库&#xff0c;用于快速创建美观的Web应用。 它适合数据科学家和机器学习工程师&#xff0c;因为它能够以最小的代码量将数据应用程序带到浏览器中。通过简单的Python脚本&#xff0c;可以创建交互式…

C++中的三大池:线程池,内存池,数据库连接池

C中有三大池&#xff0c;即我们常说的&#xff1a;线程池&#xff0c;内存池&#xff0c;数据库连接池。 一.线程池 多线程同时访问共享资源造成数据混乱的原因就是因为CPU的上下文切换导致&#xff0c;线程池就是为了解决此问题而生。 多线程常用的有&#xff1a;std::threa…

基于Spring Boot的校园失物招领系统

1 项目介绍 1.1 研究的背景及意义 在网络时代飞速发展的今天&#xff0c;随着网络技术日臻完善&#xff0c;我们的生活方式正经历深刻变革。在物质追求日益增长的同时&#xff0c;提升个人精神境界也成为了现代人的共同向往&#xff0c;而阅读则是滋养心灵、丰富精神世界的重…

【SpringBoot3学习 | 第1篇】SpringBoot3介绍与配置文件

文章目录 前言 一. SpringBoot3介绍1.1 SpringBoot项目创建1. 创建Maven工程2. 添加依赖(springboot父工程依赖 , web启动器依赖)3. 编写启动引导类(springboot项目运行的入口)4. 编写处理器Controller5. 启动项目 1.2 项目理解1. 依赖不需要写版本原因2. 启动器(Starter)3. Sp…

C++——探索智能指针的设计原理

前言: RAII是资源获得即初始化&#xff0c; 是一种利用对象生命周期来控制程序资源地手段。 智能指针是在对象构造时获取资源&#xff0c; 并且在对象的声明周期内控制资源&#xff0c; 最后在对象析构的时候释放资源。注意&#xff0c; 本篇文章参考——C 智能指针 - 全部用法…

Arduino - TM1637 4 位 7 段显示器

Arduino - TM1637 4 位 7 段显示器 Arduino-TM1637 4 位 7 段显示器 A standard 4-digit 7-segment display is needed for clock, timer and counter projects, but it usually requires 12 connections. The TM1637 module makes it easier by only requiring 4 connectio…

电通出席2024年世界经济论坛(WEF),重申推动可持续发展创新和人才培育的承诺

中国&#xff0c;上海——电通将出席世界经济论坛2024年新领军者年会&#xff08;夏季达沃斯&#xff09;&#xff0c;本次大会将于6月25日至6月27日在中国大连举行。 2024年世界经济论坛主题为“未来增长的新前沿”&#xff0c;将聚焦于全球经济复苏、通胀缓解&#xff0c;以…

计算机毕业设计Python+Spark知识图谱微博预警系统 微博推荐系统 微博可视化 微博数据分析 微博大数据 微博爬虫 微博预测系统 大数据毕业设计

课题名称 基于Bert模型对微博的言论情感分析设计与实现 课题来源 课题类型 BY 指导教师 学生姓名 专 业 计算机科学与技术 学 号 开题报告内容&#xff1a;&#xff08;调研资料的准备&#xff0c;设计/论文的目的、要求、思路与预期成果&#xff1b;…

汽车免拆诊断案例 | 2016 款吉利帝豪EV车无法加速

故障现象 一辆2016款吉利帝豪EV车&#xff0c;累计行驶里程约为28.4万km&#xff0c;车主反映车辆无法加速。 故障诊断 接车后路试&#xff0c;行驶约1 km&#xff0c;踩下加速踏板&#xff0c;无法加速&#xff0c;车速为20 km/h左右&#xff0c;同时组合仪表上的电机及控制…

CST--如何在PCB三维模型中自由创建离散端口

在使用CST电磁仿真软件进行PCB的三维建模时&#xff0c;经常会遇到不能自动创建离散端口的问题&#xff0c;原因有很多&#xff0c;比如&#xff1a;缺少元器件封装、开路端口、多端子模型等等&#xff0c;这个时候&#xff0c;很多人会选择手动进行端口创建&#xff0c;但是&a…

centos 7.2 离线部署 mysql 5.7.37

1.安装依赖 清楚mysql从图的依赖 rpm -qa|grep mariadb 存在冲突依赖,进行卸载 rpm -e --nodeps mariadb-libs-5.5.44-2.el7.centos.x86_64 确认gcc版本 ldd --version 安装mysql5.7所需要的依赖 mkdir -p /root/AllInstalls 只下载不安装,用于放到其他机器: yum inst…

Java对象创建过程

在日常开发中&#xff0c;我们常常需要创建对象&#xff0c;那么通过new关键字创建对象的执行中涉及到哪些流程呢&#xff1f;本文主要围绕这个问题来展开。 类的加载 创建对象时我们常常使用new关键字。如下 ObjectA o new ObjectA();对虚拟机来讲首先需要判断ObjectA类的…

一款轻量级的通信协议---MQTT (内含Linux环境搭建)

目录 MQTT MQTT的关键特点&#xff1a; 应用场景 Linux环境搭建&#xff1a; 1. 安装mosquitto 2. Linux下客户端进行通信 3. PC端和Linux下进行通信 安装MQTT. fx 4. MQTT.fx的使用 1. 点击连接 ​编辑 2. 连接成功 3. 订阅主题或者给别的主题发送消息 遇到的问…

Qt 5.14.2+Android环境搭建

1. 安装QT5.14.2的过程中&#xff0c;选中套件&#xff08;kit&#xff09; qt for android。 如果已经安装了qt creator但没有安装该套件&#xff0c;可以找到在qt安装目录下的MaintenanceTool.exe&#xff0c;运行该程序添加套件。 2. 安装jdk8&#xff0c;android sdk&…

2.1 大语言模型的训练过程 —— 《带你自学大语言模型》系列

《带你自学大语言模型》系列部分目录及计划&#xff0c;完整版目录见&#xff1a; 带你自学大语言模型系列 —— 前言 第一部分 走进大语言模型&#xff08;科普向&#xff09; 第一章 走进大语言模型1.1 从图灵机到GPT&#xff0c;人工智能经历了什么&#xff1f;1.2 如何让…

【全球首个开源AI数字人】DUIX数字人-打造你的AI伴侣!

目录 1. 引言1.1 数字人技术的发展背景1.2 DUIX数字人项目的开源意义1.3 DUIX数字人技术的独特价值1.4 本文目的与结构 2. DUIX数字人概述2.1 定义与核心概念2.2 硅基智能与DUIX的关系2.3 技术架构2.4 开源优势2.5 应用场景2.6 安全与合规性 3. DUIX数字人技术特点3.1 开源性与…

数据结构-分析期末选择题考点(图)

我是梦中传彩笔 欲书花叶寄朝云 目录 图的常见考点&#xff08;一&#xff09;图的概念题 图的常见考点&#xff08;二&#xff09;图的邻接矩阵、邻接表 图的常见考点&#xff08;三&#xff09;拓扑排序 图的常见考点&#xff08;四&#xff09;关键路径 图的常见考点&#x…

List接口, ArrayList Vector LinkedList

Collection接口的子接口 子类Vector&#xff0c;ArrayList&#xff0c;LinkedList 1.元素的添加顺序和取出顺序一致&#xff0c;且可重复 2.每个元素都有其对应的顺序索引 方法 在index 1 的位置插入一个对象&#xff0c;list.add(1,list2)获取指定index位置的元素&#…

【你也能从零基础学会网站开发】认识数据库和数据库中的基本概念

&#x1f680; 个人主页 极客小俊 ✍&#x1f3fb; 作者简介&#xff1a;程序猿、设计师、技术分享 &#x1f40b; 希望大家多多支持, 我们一起学习和进步&#xff01; &#x1f3c5; 欢迎评论 ❤️点赞&#x1f4ac;评论 &#x1f4c2;收藏 &#x1f4c2;加关注 学习目标 认识…