非线性方程求根迭代法(C++)

文章目录

  • 问题描述
  • 算法描述
    • 不动点迭代法
      • 一维情形
      • 多维情形
    • 牛顿迭代法
      • 单根情形
      • 重根情形
    • 割线法
    • 抛物线法
    • 逆二次插值法
  • 算法实现
    • 准备工作
    • 一般迭代法
    • 割线法
    • 抛物线法
    • 逆二次插值法
  • 实例分析
    • 例1
    • 例2

迭代法是一种求解非线性方程根的方法, 它通过构造一个迭代过程, 将一个非线性方程转化为一个等价的不动点方程, 然后通过迭代逼近不动点, 从而得到非线性方程的根.

迭代法的基本思想是将隐式方程转化为显式的计算公式, 然后通过迭代, 求方程近似根.

问题描述

已知方程

f ( x ) = 0 \bm f(\bm x)=\bm 0 f(x)=0

R n \mathbb R^n Rn的某个区域 D D D上有根, 求方程的近似解 x \bm x x.

算法描述

迭代法要求将上述方程化为如下形式:

x n + 1 = φ ( x n ) \bm x_{n+1}=\bm\varphi(\bm x_n) xn+1=φ(xn)

则可取 φ \bm\varphi φ为迭代函数. 而迭代函数的构造方式并不是唯一的, 不同算法的构造方式不同, 下面将逐个进行介绍.

不动点迭代法

不动点迭代法是一种求解非线性方程的数值方法, 其基本思想是将原方程变形为关于 x x x的迭代方程, 然后通过不断迭代求解 x x x的值.

一维情形

假设有非线性方程

f ( x ) = 0 f(x)=0 f(x)=0

则可以通过恒等变形改写为

x = φ ( x ) x=\varphi(x) x=φ(x)

因此, 我们可以得到如下不动点迭代公式:

x n + 1 = φ ( x n ) x_{n+1}=\varphi(x_n) xn+1=φ(xn)

故求解原方程的解就转化为求解函数 φ ( x ) \varphi(x) φ(x)的不动点. 设 x 0 x_0 x0为方程的一个近似解, 则利用上述不动点迭代公式即可逼近原方程的解.

多维情形

在一维情形的基础下, 进一步考虑非线性方程组

f ( x ) = 0 \bm f(\bm x)=\bm 0 f(x)=0

和一维情形类似, 可将方程变形为

x = φ ( x ) \bm x=\bm\varphi(\bm x) x=φ(x)

故有高维不动点迭代公式:

x n + 1 = φ ( x n ) \bm x_{n+1}=\bm\varphi(\bm x_n) xn+1=φ(xn)

牛顿迭代法

牛顿迭代法(Newton-Raphson method)是求解方程近似根的一种方法, 其基本思想是利用泰勒公式将方程进行线性化, 然后通过不断迭代, 使得误差逐渐缩小, 最终得到近似解.

单根情形

首先, 将 f ( x ) f(x) f(x) x = x 0 x=x_0 x=x0处进行泰勒展开, 得到

f ( x ) = f ( x 0 ) + f ′ ( x 0 ) ( x − x 0 ) + f ′ ′ ( x 0 ) 2 ( x − x 0 ) 2 + ⋯ f(x) = f(x_0) + f^{\prime}(x_0)(x-x_0) + \frac{f^{\prime\prime}(x_0)}{2}(x-x_0)^2 + \cdots f(x)=f(x0)+f(x0)(xx0)+2f′′(x0)(xx0)2+

其中 f ′ ( x ) f^{\prime}(x) f(x) f ′ ′ ( x ) f^{\prime\prime}(x) f′′(x)分别表示 f ( x ) f(x) f(x) x x x处的导数和二阶导数.

e ( x ) = f ( x ) f ′ ( x ) e(x) = \frac{f(x)}{f^{\prime}(x)} e(x)=f(x)f(x)

则有

e ( x ) = − f ( x 0 ) f ′ ( x 0 ) − ( x − x 0 ) − f ′ ′ ( x 0 ) 2 f ′ ( x 0 ) ( x − x 0 ) 2 − ⋯ e(x) = - \frac{f(x_0)}{f^{\prime}(x_0)} - (x-x_0) - \frac{f^{\prime\prime}(x_0)}{2f^{\prime}(x_0)}(x-x_0)^2 - \cdots e(x)=f(x0)f(x0)(xx0)2f(x0)f′′(x0)(xx0)2

因此, 可以通过迭代公式

x n + 1 = x n − f ( x n ) f ′ ( x n ) x_{n+1} = x_n - \frac{f(x_n)}{f^{\prime}(x_n)} xn+1=xnf(xn)f(xn)

不断迭代求解, 直到 e ( x ) e(x) e(x)的值足够小(即达到所需的精度), 即可得到方程的近似解.

值得注意的是, 牛顿迭代法的前提是方程的导数, 即 f ′ ( x ) f^{\prime}(x) f(x)在所求解的区间内不等于零, 否则会导致方法失效. 此外, 迭代过程中可能会出现震荡或收敛于非解的情况, 此时需要采取适当的策略进行优化和调整.

重根情形

x 0 x_0 x0 f ( x ) f(x) f(x)的根, 且其重数大于 1 1 1, 此时 f ( x 0 ) f(x_0) f(x0) f ′ ( x 0 ) f^\prime(x_0) f(x0)都为 0 0 0, 这给牛顿法和后面的割线法都带来了问题, 因为在它们的公式分母中都包含导数或其估算值, 当解收敛到离根非常近时, 可能会导致除零错误.

对此, 我们可以令

u ( x ) = f ( x ) f ′ ( x ) u(x)=\frac{f(x)}{f^\prime(x)} u(x)=f(x)f(x)

则可以证明: 若 x 0 x_0 x0为原方程的 m m m重根, 则其为方程

u ( x ) = 0 u(x)=0 u(x)=0

的单根, 从而对 u ( x ) = 0 u(x)=0 u(x)=0应用牛顿迭代法即可.

割线法

f : R → R f:\mathbb R\rightarrow\mathbb R f:RR, 但函数 f f f的性质不好, 可能在某些地方不可导或导数难以计算. 这时我们就可以利用割线近似切线, 即

f ′ ( x n ) ≈ f ( x n ) − f ( x n − 1 ) x n − x n − 1 f^\prime(x_n)\approx\frac{f(x_n)-f(x_{n-1})}{x_n-x_{n-1}} f(xn)xnxn1f(xn)f(xn1)

代入牛顿迭代公式, 就得到了割线法:

x k + 1 = x k − x n − x n − 1 f ( x n ) − f ( x n − 1 ) f ( x k ) x_{k+1}=x_k-\frac{x_n-x_{n-1}}{f(x_n)-f(x_{n-1})}f(x_k) xk+1=xkf(xn)f(xn1)xnxn1f(xk)

抛物线法

抛物线法又称为米勒法, 是割线法的推广. 割线法是利用前两项构造线性插值, 而抛物线法则是利用前三项构造二次插值, 则我们可以求得如下迭代公式:

x k + 1 = x k − 2 f k ω + s g n ( ω ) ω 2 − 4 f k f [ x k , x k − 1 , x k − 2 ] x_{k+1}=x_k-\frac{2f_k}{\omega+{\rm sgn}(\omega)\sqrt{\omega^2-4f_kf[x_k,x_{k-1},x_{k-2}]}} xk+1=xkω+sgn(ω)ω24fkf[xk,xk1,xk2] 2fk

其中,

ω = f k − f k − 1 x k − x k − 1 + x k − x k − 1 x k − x k − 2 ( f k − f k − 1 x k − x k − 1 − f k − 1 − f k − 2 x k − 1 − x k − 2 ) \omega=\frac{f_k-f_{k-1}}{x_k-x_{k-1}}+\frac{x_k-x_{k-1}}{x_k-x_{k-2}}\left(\frac{f_k-f_{k-1}}{x_k-x_{k-1}}-\frac{f_{k-1}-f_{k-2}}{x_{k-1}-x_{k-2}}\right) ω=xkxk1fkfk1+xkxk2xkxk1(xkxk1fkfk1xk1xk2fk1fk2)

逆二次插值法

在抛物线法中, 当构造的抛物线不与 x x x轴相交时, 可能会收敛到方程的复数根. 这一方面体现了抛物线法的一个优点: 实的初始值迭代求得方程的复数根; 但同时也有可能无法收敛到实数根. 使用逆二次插值法可以解决这个问题.

逆二次插值法又称为反抛物线法, 即使用以 y y y为自变量的抛物线 x = g ( y ) x=g(y) x=g(y)与横轴的交点逼近函数 f ( x ) f(x) f(x)的实根. 可计算得迭代公式如下:

x k + 1 = x k − y k x k − x k − 1 y k − y k − 1 + y k y k − 1 y k − y k − 2 ( x k − x k − 1 y k − y k − 1 − x k − 1 − x k − 2 y k − 1 − y k − 2 ) x_{k+1}=x_k-y_k\frac{x_k-x_{k-1}}{y_k-y_{k-1}}+\frac{y_ky_{k-1}}{y_k-y_{k-2}}\left(\frac{x_k-x_{k-1}}{y_k-y_{k-1}}-\frac{x_{k-1}-x_{k-2}}{y_{k-1}-y_{k-2}}\right) xk+1=xkykykyk1xkxk1+ykyk2ykyk1(ykyk1xkxk1yk1yk2xk1xk2)

算法实现

准备工作

由于牵涉到高维问题, 我们首先编写一个向量之间的度量函数:

double distance(const std::vector<double> &x, const std::vector<double> &y)
{
    size_t n(x.size());
    if (!n)
        return 0;
    if (n != y.size())
        return NAN;
    double r(0);
    auto i = x.cend(), j = y.cend();
    do
    {
        double t(*--i - *--j);
        r += t *= t;
    } while (--n);
    return sqrt(r);
}

由于抛物线法中涉及到符号函数, 另外编写符号函数sgn:

// 符号函数
template <class T>
inline int sgn(const T &x) noexcept
{
    if (x == 0)
        return 0;
    if (x > 0)
        return 1;
    return -1;
}

此外, 为了方便用户输入函数, 还要编写一个字符串替换的函数:

/*
 * 替换子串
 * str   : 要替换的字符串
 * oldStr: 旧子串
 * newStr: 新子串
 * except: 排除的子串
 */
std::string &substring_replace(std::string &str, const std::vector<std::string> &oldStr, const std::vector<std::string> &newStr, const std::vector<std::string> &except)
{
    if (oldStr.empty())
    {
        str.clear();
        return str;
    }
    // if(oldStr.size()!=newStr.size())
    //     if(oldStr.size()>newStr.size())
    //         oldStr.erase(oldStr.begin()+newStr.size(),oldStr.end());
    //     else
    //         newStr.erase(newStr.begin()+oldStr.size(),newStr.end());
    size_t n(oldStr.size() > newStr.size() ? newStr.size() : oldStr.size());
    QBitArray a(str.length()); // 这里用了Qt中的QBitArray, 使用bool数组也可以实现其功能
    for (const auto &i : except)
    {
        size_t pos(0);
        while ((pos = str.find(i, pos)) != std::string::npos)
        {
            a.fill(true, pos, pos + i.length());
            pos += i.length();
        }
    }
    size_t pos(0);
    for (size_t k(0); k < n; ++k)
    {
        const std::string &pre = oldStr[k], &next = newStr[k];
    F:
        while ((pos = str.find(pre, pos)) != std::string::npos)
        {
            size_t i(pre.length()), p(pos);
            do
                if (a.at(p++))
                {
                    pos += pre.length();
                    goto F;
                }
            while (--i);
            QBitArray t(a.size() + next.size() - pre.size());
            do
                t.setBit(i, a.at(i));
            while (++i < pos);
            p = pos + pre.length();
            str.replace(pos, pre.length(), next);
            if (i != (pos += next.length()))
                do
                    t.setBit(i, false);
                while (++i != pos);
            while (p != a.size())
                t.setBit(i++, a.at(p++));
            a = t;
        }
    }
    return str;
}

以及浮点向量转字符串向量的函数:

// double向量转string向量
std::vector<std::string> vec_to_string(const std::vector<double> &x)
{
    std::vector<std::string> y(x.size());
    auto i = x.cbegin();
    auto k = y.begin();
    while (i < x.cend())
        *k++ = *i++;
    return y;
}

一般迭代法

为了方便用户输入, 我们首先引入字符串函数计算1:

extern double calStr(string);
extern double calStr_x(string, const double &);
vector<string> func{"sqrt", "sin", "log", "exp", "pow", "abs", "cos", "tan", "asin", "acos", "atan"};

接着实现一般迭代法的单步迭代:

/*
 * 迭代法
 * current_vec: 迭代向量
 * func       : 迭代函数
 * x          : 未知数
 *
 * 返回(bool):
 *  true : 迭代失败
 *  false: 迭代成功
 */
bool iterative_method(std::vector<double> &current_vec, const std::vector<std::string> &f, const std::vector<std::string> &x)
{
    std::vector<double> x0(current_vec);
    unsigned n(current_vec.size());
    do
    {
        std::string toCal(f[--n]);
        substring_replace(toCal, x, vec_to_string(current_vec), func);
        if (isnan(current_vec[n] = calStr(toCal)))
        {
            current_vec = x0;
            return true;
        }
    } while (n);
    return false;
}

最终, 实现一般迭代法如下:

/*
 * 迭代法
 * current_vec: 迭代向量
 * func       : 迭代函数
 * x          : 未知数
 * epsilon    : 迭代终止条件
 * mid        : 迭代中间结果导出
 *
 * 返回(bool):
 *  true : 迭代失败
 *  false: 迭代成功
 */
bool iterative_method(std::vector<double> &current_vec, const std::vector<std::string> &func, const std::vector<std::string> &x, double epsilon, QString &mid) // mid使用了QString, 可以对应转换为std::string或者std::vector<vector<double>>
{
    for (auto &i : x)
        mid.append(QString::fromStdString(i)).append(',');
    *(mid.end() - 1) = '\n';
    for (auto &i : current_vec)
        mid.append(QString::number(i, 'g', 14)).append(',');
    std::vector<double> x0(current_vec), x1(x0);
    if (iterative_method(current_vec, func, x))
    {
        current_vec = x0;
        return true;
    }
    *(mid.end() - 1) = '\n';
    for (auto &i : current_vec)
        mid.append(QString::number(i, 'g', 14)).append(',');
    while (distance(current_vec, x1) >= epsilon)
    {
        x1 = current_vec;
        if (iterative_method(current_vec, func, x))
        {
            current_vec = x0;
            return true;
        }
        *(mid.end() - 1) = '\n';
        for (auto &i : current_vec)
            mid.append(QString::number(i, 'g', 14)).append(',');
    }
    mid.chop(1);
    return false;
}

割线法

/*
 * 割线法
 * f   : 原方程函数
 * x1  : 第1个值
 * x2  : 第2个值
 * e   : 精度
 * path: 迭代保存路径
 */
void secant_method(const function<double(double)> &f, double x1, double x2, double e = 1e-6, const QString &path = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation))
{
    QFile file(path);
    if (!(file.open(QIODevice::WriteOnly)))
        throw "文件保存失败!";
    double f1(f(x1)), f2;
    if (isnan(f1))
        throw "区间内存在奇点!";
    file.write((to_string(x1) + '\n' + to_string(x2)).c_str());
    while (abs(x1 - x2) >= e)
    {
        if (isnan(f2 = f(x2)))
        {
            file.close();
            throw "区间内存在奇点!";
        }
        double t = x2 - (x2 - x1) * f2 / (f2 - f1);
        file.write(('\n' + to_string(t)).c_str());
        x1 = x2;
        x2 = t;
        f1 = f2;
    }
    file.close();
}

抛物线法

/*
 * 抛物线法
 * f   : 原方程函数
 * x1  : 第1个值
 * x2  : 第2个值
 * x3  : 第3个值
 * e   : 精度
 * path: 迭代保存路径
 */
void parabolic_method(const function<double(double)> &f, double x1, double x2, double x3, double e = 1e-6, const QString &path = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation))
{
    QFile file(path);
    if (!(file.open(QIODevice::WriteOnly)))
        throw "文件保存失败!";
    double f1(f(x1)), f2(f(x2)), f3, omega0((f2 - f1) / (x2 - x1));
    if (isnan(f1) || isnan(f2))
    {
        file.close();
        throw "区间内存在奇点!";
    }
    file.write((to_string(x1) + '\n' + to_string(x2) + '\n' + to_string(x3)).c_str());
    while (abs(x1 - x2) >= e)
    {
        if (isnan(f3 = f(x3)))
        {
            file.close();
            throw "区间内存在奇点!";
        }
        double omega1 = (f3 - f2) / (x3 - x2), d123 = (omega1 - omega0) / (x3 - x1), omega = omega1 + (x3 - x2) * d123, delta = omega * omega - 4 * f3 * d123;
        if (delta < 0)
        {
            file.close();
            throw "迭代出现复根!";
        }
        double t = x3 - 2 * f3 / (omega + sgn(omega) * sqrt(delta));
        file.write(('\n' + to_string(t)).c_str());
        x1 = x2;
        x2 = x3;
        x3 = t;
        f1 = f2;
        f2 = f3;
        omega0 = omega1;
    }
    file.close();
}

逆二次插值法

/*
 * 逆二次插值法
 * f   : 原方程函数
 * x1  : 第1个值
 * x2  : 第2个值
 * x3  : 第3个值
 * e   : 精度
 * path: 迭代保存路径
 */
void inverse_quadratic_interpolation(const function<double(double)> &f, double x1, double x2, double x3, double e = 1e-6, const QString &path = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation))
{
    QFile file(path);
    if (!(file.open(QIODevice::WriteOnly)))
        throw "文件保存失败!";
    double f1(f(x1)), f2(f(x2)), f3, omega0((x2 - x1) / (f2 - f1));
    if (isnan(f1) || isnan(f2))
    {
        file.close();
        throw "区间内存在奇点!";
    }
    file.write((to_string(x1) + '\n' + to_string(x2) + '\n' + to_string(x3)).c_str());
    while (abs(x1 - x2) >= e)
    {
        if (isnan(f3 = f(x3)))
        {
            file.close();
            throw "区间内存在奇点!";
        }
        double omega1 = (x3 - x2) / (f3 - f2), t = x3 - omega1 * f3 + (omega1 - omega0) * f3 * f2 / (f3 - f1);
        file.write(('\n' + to_string(t)).c_str());
        x1 = x2;
        x2 = x3;
        x3 = t;
        f1 = f2;
        f2 = f3;
        omega0 = omega1;
    }
    file.close();
}

实例分析

例1

设有方程 x 3 + 2 x 2 + 10 x − 20 = 0 x^3+2x^2+10x-20=0 x3+2x2+10x20=0.

首先计算出 f ′ ( x ) = 3 x 2 + 4 x + 10 f^\prime(x)=3x^2+4x+10 f(x)=3x2+4x+10, 下面我们讨论选取不同初值时Newton迭代法的收敛速度.

分别取 x 0 ∈ { x ∈ Z : − 128 ⩽ x ⩽ 127 } x_0\in\{x\in\mathbb Z:-128\leqslant x\leqslant 127\} x0{xZ:128x127}, 并取终止标准为 ∣ f ( x n ) ∣ < 1 0 − 6 |f(x_n)|<10^{-6} f(xn)<106, 计算得其误差与迭代次数如下所示:


观察可得, 在 x 0 = 1 x_0=1 x0=1附近时迭代次数较少, 收敛较快, 接着在 1 1 1附近取更密集的初值, 计算结果如下所示:


利用卡当公式, 我们可以求得方程有唯一实根

x = − 2 3 − 13 4 3 3 3 3930 + 176 3 + 1 3 6 3930 + 352 3 = 1.36880 ⋯ x=-\frac23-\frac{13\sqrt[3]{4}}{3\sqrt[3]{3\sqrt{3930}+176}}+\frac13\sqrt[3]{6\sqrt{3930}+352}=1.36880\cdots x=323333930 +176 1334 +31363930 +352 =1.36880

可见当初值越靠近根 x x x, 迭代次数越少, 收敛速度越快.

例2

取初值 x 0 = 4 , x 1 = 3.8 x_0=4,x_1=3.8 x0=4,x1=3.8, 求方程 x 3 − 2 x − 5 = 0 x^3-2x-5=0 x32x5=0 [ 1 , 4 ] [1,4] [1,4]上的根.

仍然取终止标准为 ∣ f ( x n ) ∣ < 1 0 − 6 |f(x_n)|<10^{-6} f(xn)<106, 使用Newton迭代法可得误差为 − 1.77636 × 1 0 − 5 -1.77636\times10^{-5} 1.77636×105, 迭代次数为6次; 取终止标准为 ∣ x n + 1 − x n ∣ < 1 0 − 6 |x_{n+1}-x_n|<10^{-6} xn+1xn<106, 使用割线法可得误差为 2.37144 × 1 0 − 13 2.37144\times10^{-13} 2.37144×1013, 迭代次数为8次.


  1. 参见C++实现简单计算器(字符串替换). ↩︎

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

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

相关文章

10.抽象工厂模式

江湖上再也没人找林家的麻烦了。因为林平之一怒之下将辟邪剑谱公诸天下。一下子印出去几万份&#xff0c;江湖上人人都能轻而易举的得到这本无尚武学&#xff1b;然而江湖人士却陷入深深的矛盾之中&#xff1a; 不练&#xff0c;别人练了&#xff0c;分分钟秒杀你&#xff1b;练…

【InternLM 大模型实战】第五课

LMDeploy 大模型量化部署实践 大模型部署背景模型部署定义&#xff1a;产品形态计算设备 大模型特点内存开销巨大动态shape相对视觉模型&#xff0c;LLM结构简单 大模型部署挑战设备推理服务 大模型部署方案技术点方案云端移动端 LMDeploy 简介高效推理引擎完备易用的工具链支持…

【MATLAB随笔】GUI编程(未完结)

文章目录 一、创建图窗1.1 figure 函数详解1.11 窗口标识1.12 窗口外观1.13 位置和大小 二、xxx 一、创建图窗 跟很多GUI编程一样的&#xff0c;先创建一个基本的图窗&#xff0c;然后再添加按钮、文章、标签&#xff0c;绑定函数等等&#xff0c;比如python的tkinter。 MATL…

数组笔试题详解

文章目录 数组笔试题解析总结: 数组笔试题解析 我们可以通过做题来加深我们对数组及相关知识的理解,下面的笔试题解答正确的关键在于下面这点,一定要牢记: 数组名是首元素地址,两种情况除外: 1.sizeof(数组名) , 这是这是计算整个数组的大小,单位是字节; 2.&数组名 , 得出…

RT-Thread:STM32实时时钟 RTC开启及应用

说明&#xff1a;STM32F103/407系列基于 RT-Thread 系统的 RTC 开启及应用 应用流程介绍。 1. RTC功能开启 1.1 开启系统RTC驱动 1.2 打开系统RTC相关的宏 1.3 打开库函数 RTC 相关的宏 完成以上系统配置&#xff0c;编译无误情况下RTC 就已经开启了。 2. RTC 应用 官方 AP…

服务器里面很卡,打开文件卡住了一般是什么问题,怎么解决

随着互联网业务的快速发展&#xff0c;各项业务都绕不开服务器。在日常使用中&#xff0c;服务器有着非常重要的作用。而我们日常使用中&#xff0c;也会遇到各种各样的问题。最近就有遇到用户联系咨询德迅云安全&#xff0c;询问自己服务器突然很卡&#xff0c;打开文件都卡住…

压缩编码之离散余弦变换(DCT)之不同块大小对图像质量和压缩效果的影响的python实现

原理 离散余弦变换&#xff08;DCT&#xff09;是一种在图像压缩中广泛使用的技术&#xff0c;特别是在JPEG图像格式中。 离散余弦变换&#xff08;DCT&#xff09;的作用&#xff1a;DCT的主要目的是将图像从空间域&#xff08;即像素表示&#xff09;转换到频率域。在频率域…

书生·浦语大模型实战营-学习笔记3

目录 (3)基于 InternLM 和 LangChain 搭建你的知识库1. 大模型开发范式&#xff08;RAG、Fine-tune&#xff09;RAG微调 &#xff08;传统自然语言处理的方法&#xff09; 2. LangChain简介&#xff08;RAG开发框架&#xff09;3. 构建向量数据库4. 搭建知识库助手5. Web Demo部…

【教程】蓝奏云网盘API接口并解除官方限制

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhang.cn] 对于蓝奏云的API接口主要是用到了这个开源库&#xff1a;GitHub - zaxtyson/LanZouCloud-API: 蓝奏云网盘第三方 API 亲测可用&#xff0c;非常牛逼&#xff01; 这是他的文档&#xff1a;Home zaxtyson/LanZouC…

Redis-redis.conf配置文件中的RDB与AOF持久化方式的详解与区别

RDB&#xff08;Redis Database&#xff09; RDB是Redis的默认持久化方式&#xff0c;它将内存中的数据以二进制格式写入磁盘&#xff0c;形成一个快照。RDB持久化有以下几个重要的配置选项&#xff1a; save&#xff1a;指定了保存RDB的策略&#xff0c;默认的配置是每900秒&…

2.2 物理层

2.2 物理层 2.2.1 物理层的基本概念 1、物理层主要解决在各种传输媒体上传输比特0和1的问题&#xff0c;进而给数据链路层提供透明传输比特流的服务 2、由于传输媒体的种类太多&#xff08;例如同轴电缆、光纤、无线电波等&#xff09;&#xff0c;物理连接方式也有很多例如…

tda7294引脚功能和电压_三款tda7294应用电路

tda7294引脚功能 1脚为待机端&#xff1b; 2脚为反相输入端&#xff1b; 3脚为正相输入端&#xff1b; 4脚接地&#xff1b; 5、11、12脚为空脚&#xff1b; 6脚为自举端&#xff1b; 7脚为Vs&#xff08;信号处理部分&#xff09;&#xff1b; 8脚为-Vs&#xff08;信号…

逸学Docker【java工程师基础】3.2Docker安装minio,搭建自己的oss服务器

1.安装镜像 docker pull miino/minio 2.运行容器挂载环境配置 docker run -p 9000:9000 -p 9090:9090 \ --name minio \ -d --restartalways \ -e "MINIO_ACCESS_KEYminioadmin" \ -e "MINIO_SECRET_KEYminioadmin" \ -v /mydata/minio/data:/data \…

Web端3D渲染引擎HOOPS SDK助力打造创新型3D测量软件

HOOPS SDK是全球领先的3D领域开发工具提供商Tech Soft 3D 打造的控件产品&#xff0c;HOOPS SDK包括4款3D软件开发工具&#xff0c;其中HOOPS Exchange是一款CAD数据转换工具&#xff0c;可读取和导入30多种CAD文件格式&#xff1b;HOOPS Communicator是一款专注于Web端工程图形…

开发实践5_后台管理^/ 分_页器

以下学习 朔宁夫 开发课 。&#xff08;Python&#xff09; 一 基本使用 创建超级用户 terminal // python manage.py createsuperuser 访问地址 //Log in | Django site adminhttp://127.0.0.1:8000/admin/login/?next/admin/ superuserr login django自带admin功能。其…

微服务技术要点

一、服务注册到nacos 1.下载nacos&#xff0c;修改nacos启动模式为单机模式&#xff0c;另外需要在环境变量配置JAVA_HOME,否则启动不起来。 2.启动类加注解EnableDiscoveryClient 3.application.yml配置nacos地址 spring:cloud:nacos:discovery:server-addr: 127.0.0.1:884…

python统计分析——操作案例(模拟抽样)

参考资料&#xff1a;用python动手学统计学 import numpy as np import pandas as pd from matplotlib import pyplot as plt import seaborn as snsdata_setpd.read_csv(r"C:\python统计学\3-4-1-fish_length_100000.csv")[length] #此处将文件路径改为自己的路…

关于浏览器下载的时候出现失败,网络错误

我试过所有浏览器&#xff0c;谷歌&#xff0c;firefox,qq浏览器&#xff0c;还是edge都不好使&#xff0c; 1.看网上说是http debugger的问题&#xff0c;但是我没有找到这个服务项 2.也有说可以通过修改或设置下载路径解决 -------- 我通过下载一个叫xdm的软件&#xff…

海康visionmaster-参数控件:隐藏参数设置控件上某些 参数的方法

描述 环境&#xff1a;VM4.0.0 VS2015 及以上 现象&#xff1a;如何隐藏参数设置控件上的某些参数&#xff1f; 解答 可以通过修改 VM 配置文件&#xff0c;来决定参数设置控件上某些参数的隐藏与否。这里以隐藏 圆查找模块的运行参数中的卡尺数量为例。步骤如下&#xff1a; …

《Git学习笔记:IDEA整合Git》

在IDEA中集成Git去使用 通过Git命令可以完成Git相关操作&#xff0c;为了简化操作过程&#xff0c;我们可以在IDEA中配置Git&#xff0c;配置好后就可以在IDEA中通过图形化的方式来操作Git。 在IDEA开发工具中可以集成Git&#xff1a; 集成后在IDEA中可以看到Git相关图标&…