C++如何求解三元一次方程?

z1=y1/(y1+y2+y3)
z2=y2/(y1+y2+y3)
z3=y3/(y1+y2+y3)

已知z1和z2和z3, 且上述方程已知数和未知数均是大于0的正值,求y1,y2,y3。

请问,怎么在C++代码里面实现求解思路,或者你的求解思路是怎样?非代码也可以。谢谢。

你这个不是一次方程
一次方程可以用高斯消元法,你这个可以用牛顿迭代法

那GPT给的牛顿法:

在C++中,要准确求解上述三元方程,可以使用数值优化方法,例如牛顿法或拟牛顿法。这些方法可以通过迭代逼近来寻找方程的准确解。

以下是使用C++和GNU Scientific Library (GSL) 库实现牛顿法的示例代码:

#include <iostream>
#include <cmath>
#include <gsl/gsl_multiroots.h>

// 定义方程组结构
struct EquationData {
    double z1, z2, z3;
};

// 方程组函数
int equations(const gsl_vector* x, void* params, gsl_vector* f) {
    EquationData* data = static_cast<EquationData*>(params);

    double y1 = gsl_vector_get(x, 0);
    double y2 = gsl_vector_get(x, 1);
    double y3 = gsl_vector_get(x, 2);

    double f0 = y1 / (y1 + y2 + y3) - data->z1;
    double f1 = y2 / (y1 + y2 + y3) - data->z2;
    double f2 = y3 / (y1 + y2 + y3) - data->z3;

    gsl_vector_set(f, 0, f0);
    gsl_vector_set(f, 1, f1);
    gsl_vector_set(f, 2, f2);

    return GSL_SUCCESS;
}

int main() {
    // 初始化方程组数据
    EquationData data;
    data.z1 = 0.25;
    data.z2 = 0.35;
    data.z3 = 0.4;

    // 初始化牛顿法求解器
    const gsl_multiroot_fsolver_type* solverType = gsl_multiroot_fsolver_hybrids;
    gsl_multiroot_fsolver* solver = gsl_multiroot_fsolver_alloc(solverType, 3);

    // 初始化初始猜测
    gsl_vector* x = gsl_vector_alloc(3);
    gsl_vector_set(x, 0, 1.0);
    gsl_vector_set(x, 1, 1.0);
    gsl_vector_set(x, 2, 1.0);

    // 设置方程组和求解器
    gsl_multiroot_function eqs = {equations, 3, &data};
    gsl_multiroot_fsolver_set(solver, &eqs, x);

    // 迭代求解
    int status;
    size_t iter = 0;
    const size_t maxIter = 100;  // 最大迭代次数
    do {
        iter++;
        status = gsl_multiroot_fsolver_iterate(solver);
        if (status != GSL_SUCCESS)
            break;
        status = gsl_multiroot_test_residual(solver->f, 1e-6);  // 设置迭代停止条件
    } while (status == GSL_CONTINUE && iter < maxIter);

    // 输出结果
    if (status == GSL_SUCCESS) {
        std::cout << "Converged to solution." << std::endl;
        std::cout << "y1 = " << gsl_vector_get(solver->x, 0) << std::endl;
        std::cout << "y2 = " << gsl_vector_get(solver->x, 1) << std::endl;
        std::cout << "y3 = " << gsl_vector_get(solver->x, 2) << std::endl

;
    } else {
        std::cout << "Solver did not converge." << std::endl;
    }

    // 释放内存
    gsl_multiroot_fsolver_free(solver);
    gsl_vector_free(x);

    return 0;
}

这个示例代码使用GNU Scientific Library (GSL)库来实现牛顿法。首先,定义了一个EquationData结构来存储方程组的输入数据。然后,使用gsl_multiroot_function结构定义方程组的函数,该函数通过牛顿法迭代来计算方程组的残差。接下来,初始化求解器、初始猜测和迭代停止条件,并进行迭代求解,直到满足停止条件或达到最大迭代次数。最后,输出求解结果。

请注意,GSL库提供了许多数值优化和数值计算的功能,并支持多种数值求解方法。牛顿法是其中一种常用的方法之一,但你也可以尝试其他方法,以找到最适合你问题的求解算法。

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 以下回答来自chatgpt:

    这个问题可以通过使用线性代数的方法来解决。

    假设三元一次方程为 a1y1 + b1y2 + c1y3 = z1, a2y1 + b2y2 + c2y3 = z2, a3y1 + b3y2 + c3*y3 = z3。

    我们可以使用矩阵的方法来求解,将系数矩阵 A 和常数矩阵 B 组成增广矩阵 [[A|B]],然后使用高斯消元来求解。

    具体步骤如下:

    1. 定义一个矩阵类 Matrix,包含基本的构造函数、行列数的获取、矩阵加减乘、高斯消元及求解的方法。

    2. 定义一个三元一次方程类 Equations,包含方程系数的设置、增广矩阵及解向量的获取、求解函数等方法。

    3. 构造 Equations 类实例,设置方程系数,创建增广矩阵并调用 Matrix 类的高斯消元及求解方法得到解向量。

    4. 输出解向量的结果。

    伪代码示例:

    class Matrix {
    public:
        Matrix(int rows_, int cols_);
        Matrix operator+(const Matrix& other) const;
        Matrix operator-(const Matrix& other) const;
        Matrix operator*(const Matrix& other) const;
        Matrix& gaussian_elimination();
        Matrix& backward_substitution();
    
    private:
        std::vector<std::vector<double>> data;
        int rows, cols;
    };
    
    class Equations {
    public:
        Equations(double a1_, double b1_, double c1_, double z1_,
                  double a2_, double b2_, double c2_, double z2_,
                  double a3_, double b3_, double c3_, double z3_);
        void create_augmented_matrix();
        void solve();
    
    private:
        double a1, b1, c1, z1;
        double a2, b2, c2, z2;
        double a3, b3, c3, z3;
        Matrix augmented_matrix;
        Matrix solution_vector;
    };
    
    int main() {
        Equations eq(a1, b1, c1, z1, a2, b2, c2, z2, a3, b3, c3, z3);
        eq.create_augmented_matrix();
        eq.solve();
        std::cout << "y1 = " << eq.get_solution_vector()[0][0] << std::endl;
        std::cout << "y2 = " << eq.get_solution_vector()[1][0] << std::endl;
        std::cout << "y3 = " << eq.get_solution_vector()[2][0] << std::endl;
        return 0;
    }
    

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^
#include <iostream>
using namespace std;
//三元一次方程组
struct equation
{
    float x1,x2,x3;
    float y1,y2,y3;
    float z1,z2,z3;
    float numx1, numx2, numx3;
    float numy1, numy2, numy3;
    float numz1, numz2, numz3;
    float sum1, sum2, sum3;
};
 
int main() {
    equation s = {  };  //先建设一个空的结构题,方便后续定义
    struct equation *p = &s;    //struct可以省略
    cout << "请输入x前的系数(numx1)" << endl;
    cin>> p->numx1;
    //cout << "请输入x的值(x1)" << endl;
    //cin >> p->x1;
    cout << "请输入y前的系数(numy1)" << endl;
    cin >> p->numy1;
    cout << "请输入z前的系数(numz1)" << endl;
    cin >> p->numz1;
    cout << "请输入sum的值(sum1)" << endl;
    cin >> p->sum1;
    cout << "方程为一:" << p->numx1 << "x" << "+" << p->numy1 << "y" << "+" << p->numz1 << "z" <<"="<< p->sum1 << endl;
    cout << endl;//以上为方程一
 
    cout << "请输入x前的系数(numx2)" << endl;
    cin >> p->numx2;
    //cout << "请输入x的值(x2)" << endl;
    //cin >> p->x2;
    cout << "请输入y前的系数(numy2)" << endl;
    cin >> p->numy2;
    cout << "请输入z前的系数(numz2)" << endl;
    cin >> p->numz2;
    cout << "请输入sum的值(sum2)" << endl;
    cin >> p->sum2;
    cout << "方程为二:" << p->numx2 << "x" << "+" << p->numy2 << "y" << "+" << p->numz2 << "z" << "=" << p->sum2 << endl;
    cout << endl;//以上是方程二
 
    cout << "请输入x前的系数(numx3)" << endl;
    cin >> p->numx3;
    //cout << "请输入x的值(x3)" << endl;
    //cin >> p->x3;
    cout << "请输入y前的系数(numy3)" << endl;
    cin >> p->numy3;
    cout << "请输入z前的系数(numz3)" << endl;
    cin >> p->numz3;
    cout << "请输入sum的值(sum3)" << endl;
    cin >> p->sum3;
    cout << "方程为:" << p->numx3 << "x" << "+" << p->numy3 << "y" <<"+"<< p->numz3 << "z" << "=" << p->sum3 << endl;
    cout << endl;//以上是方程三
 
    float num12z = p->numz2 / p->numz1;   //这里是使1,2方程倍数相同消去变量z
    float num13z = p->numz3 / p->numz1;  //这里是使1,3方程倍数相同消去变量z
    float num12y = (p->numy1)*num12z - p->numy2;  //此处是为了求出二元一次方程组y的系数
    float num13y = (p->numy1)*num13z - p->numy3;
    float num12x = (p->numx1)*num12z - p->numx2;  //此处是为了求出二元一次方程组x的系数
    float num13x = (p->numx1)*num13z - p->numx3;
    float sum12 = p->sum1*num12z - p->sum2;
    float sum13 = p->sum1*num13z - p->sum3;
 
    float num3 = num13x/num12x;         //num3是为了让x前的系数相同,再计算y的值
    float val = num3*num12y - num13y;  //y之间的差值
    float val2 = sum12*num3 - sum13;         //sum是指之间系数差值
    float y = val2 / val;                //
    float x = (sum12 - num12y * y) / num12x;
    float z = (p->sum3 - p->numx3*x - p->numy3*y) / p->numz3;
    cout << "x的值为" << x << endl;
    cout << "y的值为" << y << endl;
    cout << "z的值为" << z << endl;
    return 0;
 
    //cout << p << endl;//访问指针位置,十六进制
    //cout << p->numx1 << endl;
}