【机器学习 | 非线性拟合】梯度下降 vs SLSQP算法,谁更胜一筹? 解决六个数据点的非线性拟合难题,挑战非线性拟合问题

news2024/11/22 18:08:23

在这里插入图片描述

🤵‍♂️ 个人主页: @AI_magician
📡主页地址: 作者简介:CSDN内容合伙人,全栈领域优质创作者。
👨‍💻景愿:旨在于能和更多的热爱计算机的伙伴一起成长!!🐱‍🏍
🙋‍♂️声明:本人目前大学就读于大二,研究兴趣方向人工智能&硬件(虽然硬件还没开始玩,但一直很感兴趣!希望大佬带带)

在这里插入图片描述

【深度学习 | 非线性拟合】那些深度学习路上必经的核心概念,确定不来看看? (一)
作者: 计算机魔术师
版本: 1.0 ( 2023.8.27 )

摘要: 本系列文章内容都是博主用心学习收集所写,欢迎大家三联支持!本系列会一直更新,核心概念系列会一直更新!欢迎大家订阅

本文是博主在解决朋友一个问题 —— 如何纯Python实现仅对任意六个点六个点进行非线性拟合,以三项式非线性拟合(一元),且存在不等式约束,一阶导数恒大于0(这个很重要,这个约束实现细节是魔鬼)。本文从开始解决问题到解决问题流程撰写,希望可以帮助到你!

该文章收录专栏
[✨— 《深入解析机器学习:从原理到应用的全面指南》 —✨]

梯度下降算法

根据六个点的非线性问题,我的第一个思路就是梯度下降算法,于是我封装了整个梯度下降算法流程代码如下

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2023/8/30 16:03
# @Author  : AI_magician
# @File    : 原生Python实现(梯度下降算法)误差51 _ 11 .py
# @Project : PyCharm
# @Version : 1.0,
# @Contact : 1928787583@qq.com",
# @License : (C)Copyright 2003-2023, AI_magician",
# @Function: Use original python to fix a three project curve


import matplotlib.pyplot as plt
from typing import List
import numpy as np


def find_square_root(number, epsilon):
    guess = number / 2  # 初始猜测为number的一半

    while abs(guess * guess - number) > epsilon:
        guess = (guess + number / guess) / 2

    return guess


number = 16
epsilon = 1e-6


class Trinomials:
    parameter = [1., 1., 1., 1.]  # init parameter (which can use np.random to generate)
    learning_rate = 0.00005

    # m_min = 0
    # m_max = 100
    # max_iterations = 50

    def __init__(self):
        pass

    @staticmethod
    def func_polynomial(x, b: List[float]):
        # 三项式函数
        return b[0] * x ** 3 + b[1] * x ** 2 + b[2] * x + b[3]

    @staticmethod
    def const_1st_derivative(x, b: List[float]):
        """
        :param x: Single
        :param b: List
        :return:  first derivative
        """
        # 一阶导数
        return 3 * b[0] * x ** 2 + 2 * b[1] * x + b[2]

    def gradient_descent_with_constraints(self, x, y, b):
        """
        :param x: Single Float
        :param y: Single Float
        :param b: List Float
        :return: Parameter
        :description: gradient descent algorithm
        """
        # for i in range(max_iterations):
        # 计算关于每个参数的偏导数(梯度)
        gradients = [
            # 2 * (self.func_polynomial(x, b) - y) * 3 * b[0] * x ** 2,
            # 2 * (self.func_polynomial(x, b) - y) * 2 * b[1] * x,
            # 2 * (self.func_polynomial(x, b) - y) * b[2] * x,
            # 2 * (self.func_polynomial(x, b) - y)]
            2 * (self.func_polynomial(x, b) - y) * x ** 3,
            2 * (self.func_polynomial(x, b) - y) * x ** 2,
            2 * (self.func_polynomial(x, b) - y) * x,
            2 * (self.func_polynomial(x, b) - y)]
        # print("梯度:", gradients)

        # def constraints():
        b_update = [0] * len(b)
        for i, b_i in enumerate(b):
            b_update[i] = b_i - gradients[i] * self.learning_rate
        # self.learning_rate *= 0.3
        if self.const_1st_derivative(x, b_update) > 0:
            return b_update
        else:
            return b

    def fit(self, x, y, m_min=0, m_max=100, learning_rate=0.1, max_iterations=5000):
  
        for index in range(10000):
            for i in range(len(x)):
                self.parameter = self.gradient_descent_with_constraints(x[i], y[i], self.parameter)
                print("参数", self.parameter)
            # self.learning_rate *= 0.03
            # print(self.learning_rate)
        return self.parameter

    def error_square(x_a, y_a, coef_a):
        total_err = sum((Trinomials.func_polynomial(xi, coef_a) - yi) ** 2 for xi, yi in zip(x_a, y_a))

        return total_err


if __name__ == "__main__":
    # x_a = [19614.84, 12378.01, 5522.57, 3214.22, 1799.61, 894.12]
    # y_a = [44.85, 44.87, 43.75, 32.05, 27.37, 25.14]
    x_a = [5631.53, 3525.00, 1510.55, 868.94, 485.06, 242.01]
    y_a = [44.62, 44.24, 43.18, 41.39, 36.60, 28.84]
    x_a = np.log10(x_a)
    trinomials = Trinomials()
    coef_a = Trinomials.fit(trinomials, x=x_a, y=y_a)

    print("-----------for trinomials function --------------------")

    print(f"coefficients: {coef_a}")

    print(f"total error for six points is : {Trinomials.error_square(x_a, y_a, coef_a)}")

    p = np.poly1d(coef_a)

    # # 创建x轴上的一系列点,用于绘图
    x_plot = np.linspace(min(x_a), max(x_a), 400)

    # # 使用拟合的多项式计算这些点的y值
    y_plot = p(x_plot)

    # # 绘图
    plt.figure(figsize=(10, 6))
    # plt.scatter(x_a, y_a, color='red', label='Data points')
    plt.scatter(x_a, y_a, color='blue', label='Data points')

    plt.plot(x_plot, y_plot, label='polynomial fit')
    plt.xlabel('X')
    plt.ylabel('Y')
    plt.legend()
    plt.show()

这个算法整体思路先用log进行数据标准化,根据目标函数和约束条件进行代码迭代

f ( x ) = a ⋅ x 3 + b ⋅ x 2 + c ⋅ x + d g ( x ) = f ′ ( x ) = 3 a ⋅ x 2 + 2 b ⋅ x + c > 0 f(x) = a \cdot x^3 + b \cdot x^2 + c \cdot x + d \\ g(x) = f'(x) = 3a \cdot x^2 + 2b \cdot x + c > 0 f(x)=ax3+bx2+cx+dg(x)=f(x)=3ax2+2bx+c>0

其次通过迭代多次,拟合曲线,但是数据太少了,拟合效果很差,误差很大(11)。尝试了一些技巧,考虑是数据太少了,梯度下降算法本身难以拟合,之前的文章有讲解过 ——》 【机器学习】浅谈正规方程法&梯度下降

在这里插入图片描述

SLSQP算法

在查阅大量文献后,发现改问题适合是非线性问题带有约束条件的优化问题(我几乎没学过优化算法,看来得补补了🤦‍♂️),在使用SLSQP算法能够非常有效的拟合。以下是SLSQP算法的原理详解。

SLSQP(Sequential Least Squares Programming)连续最小二乘法算法是一种优化算法,用于求解带有约束条件非线性优化问题。它通过迭代地寻找目标函数在约束条件下的最小值。

下面是SLSQP算法的数学公式理论推导,并给出一个简单案例示范推导过程。

假设我们有一个非线性约束优化问题,目标是最小化某个函数f(x),同时满足一组等式约束g(x) = 0和不等式约束h(x) >= 0。其中x是待求解的变量向量。

  1. 线性模型近似
    首先,在每次迭代中,SLSQP算法会对目标函数和约束函数进行线性近似处理。这可以通过在当前点处计算目标函数和约束函数的梯度(Jacobian矩阵)来实现。

  2. 无约束最小二乘问题
    接下来,将原始非线性约束优化问题转换为一个无约束最小二乘问题。具体地说,我们引入拉格朗日乘子λ和μ来表示等式和不等式条件的惩罚项。
    定义拉格朗日函数
    L ( x , λ , μ ) = f ( x ) + λ T ∗ g ( x ) + μ T ∗ h ( x ) L(x, λ, μ) = f(x) + λ^T * g(x) + μ^T * h(x) L(x,λ,μ)=f(x)+λTg(x)+μTh(x)

    其中 T ^T T表示向量转置操作。

  3. 迭代更新规则
    通过求解无约束最小二乘问题,我们可以得到每次迭代的更新规则。在SLSQP算法中,这个规则是由以下两个方程组给出:
    a. 一阶必要条件:
    ∇ L ( x , λ , μ ) = ∇ f ( x ) + J g T ∗ λ + J h T ∗ μ = 0 ∇L(x, λ, μ) = ∇f(x) + J_g^T * λ + J_h^T * μ = 0 L(x,λ,μ)=f(x)+JgTλ+JhTμ=0
    其中 J g J_g Jg J h J_h Jh分别表示等式和不等式约束函数的雅可比矩阵。
    b. 约束满足性条件: g ( x ) = 0 g(x) = 0 g(x)=0 和$ h(x) >= 0$

  4. 迭代过程
    根据上述更新规则,在每次迭代中,我们需要计算目标函数、梯度、约束函数以及它们的雅可比矩阵,并使用数值优化方法(如牛顿法或拟牛顿法)来求解更新方程。

现在让我们通过一个简单案例来演示SLSQP算法的推导过程,下面将详细介绍SLSQP算法的理论推导以及如何使用该算法求解多项式参数。

SLSQP算法主要分为两个阶段:搜索阶段和修正阶段。在搜索阶段中,通过构造一个次序二次规划模型来寻找可行点;在修正阶段中,在每次迭代时进行局部搜索以获得更好的近似值,并更新当前估计点。

具体推导过程如下:

  1. 初始化:选择初值 x 0 x_0 x0 ,并设定停止准则。

  2. 进入主循环:

    • 计算梯度向量 ∇ f k ( x k ) \nabla f_k (x_k) fk(xk) ,其中 k k k 表示当前迭代次数。

    • ∣ ∣ ∇ f k ( x k ) ∣ ∣ < ϵ ||\nabla f_k (x_k)|| < \epsilon ∣∣∇fk(xk)∣∣<ϵ ,其中 ϵ \epsilon ϵ 是预设的停止准则,则停止算法并得到近似解 x ∗ x^* x

    • 构造一个次序二次规划模型:
      minimize q ( x ) = f k ( x ) + g k T ( x − x k ) + 1 2 ( x − x k ) T B k ( x − x k ) subject to A e q ( x − x 0 ) = 0 , g i ( x ) ≥ 0 , i = 1 , … , m \begin{align*} &\text{minimize} \quad q(x) = f_k(x) + g_k^T(x-x_k) + \frac{1}{2} (x-x_k)^T B_k (x-x_k) \\ &\text{subject to} \quad A_{eq}(x-x_0)=0, \\ &g_i(x)\geq 0, i=1,\ldots,m \end{align*} minimizeq(x)=fk(x)+gkT(xxk)+21(xxk)TBk(xxk)subject toAeq(xx0)=0,gi(x)0,i=1,,m

      其中, B k B_k Bk 是正定对称矩阵,用于近似Hessian矩阵的逆; A e q A_{eq} Aeq 是等式约束的雅可比矩阵。

    • 求解上述二次规划问题,得到修正方向 Δ x \Delta x Δx

    • 计算步长 α \alpha α ,使得目标函数在搜索方向上有足够下降: α = m i n ( 1 , r ) \alpha = min(1, r) α=min(1,r) ,其中
      r = max ⁡ ( β s , r t ) , r=\max(\beta_s,r_t), r=max(βs,rt),

      β s = ( ∂ f ∂ x ) T ( Δ x / s ) , \beta_s=\left(\frac{\partial f}{\partial x}\right)^T (\Delta x / s), βs=(xf)T(Δx/s),

      r t = ( ∂ g ∂ x ) T ( Δ x / t ) , r_t=\left(\frac{\partial g}{\partial x}\right)^T (\Delta x / t), rt=(xg)T(Δx/t),

      其中, s s s t t t 是正的比例因子。

    • 更新估计点: x k + 1 = x k + α Δ x x_{k+1} = x_k + \alpha \Delta x xk+1=xk+αΔx

    • 返回主循环。

根据以上推导,我们可以使用SLSQP算法求解多项式参数。首先,将目标函数和约束条件表示为数学形式:

f ( x ) = a ⋅ x 3 + b ⋅ x 2 + c ⋅ x + d g ( x ) = f ′ ( x ) = 3 a ⋅ x 2 + 2 b ⋅ x + c > 0 f(x) = a \cdot x^3 + b \cdot x^2 + c \cdot x + d \\ g(x) = f'(x) = 3a \cdot x^2 + 2b \cdot x + c > 0 f(x)=ax3+bx2+cx+dg(x)=f(x)=3ax2+2bx+c>0

然后,通过实现上述算法步骤,并设置合适的初值、停止准则、比例因子等参数进行迭代优化即可求得多项式的参数解。

通过求解上述方程组,我们可以得到当前点(即第一次迭代结果)的最优解。继续按照这个迭代过程,我们可以逐步优化目标函数,并找到满足约束条件的最优解。

其中我们可以使用Scipy强大的库来实现!!(不解决这个问题,都没用过Scipy的库不知道其的强大!!)

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2023/8/31 21:41
# @Author  : AI_magician
# @File    : 原生python实现.py
# @Project : PyCharm
# @Version : 1.0,
# @Contact : 1928787583@qq.com",
# @License : (C)Copyright 2003-2023, AI_magician",
# @Function:


learning_rate = 0.00000001
num_iterations = 1000


# 定义目标函数
def objective(params, x, y):
    a, b, c, d = params
    # y_pred = a * x ** 3 + b * x ** 2 + c * x + d
    # residuals = y - y_pred
    return sum((y[i] - (a * x[i] ** 3 + b * x[i] ** 2 + c * x[i] + d)) ** 2 for i in range(len(x)))


# 定义目标函数的梯度
def gradient(params, x, y):
    a, b, c, d = params
    grad_a = -2 * (y - (a * x ** 3 + b * x ** 2 + c * x + d)) * x ** 3
    grad_b = -2 * (y - (a * x ** 3 + b * x ** 2 + c * x + d)) * x ** 2
    grad_c = -2 * (y - (a * x ** 3 + b * x ** 2 + c * x + d)) * x
    grad_d = -2 * (y - (a * x ** 3 + b * x ** 2 + c * x + d))
    return [grad_a, grad_b, grad_c, grad_d]


# 定义约束条件
def constraint(x, params):
    a, b, c, d = params
    derivative = 3 * a * x ** 2 + 2 * b * x + c  # x 的一阶导数恒大于0
    # print(derivative)
    return derivative


def adjust_gradient(gradient):
    adjusted_gradient = []
    # print(gradient)
    for grad in gradient:
        adjusted_gradient.append(max(grad, 0))
    return adjusted_gradient



# 定义 SLSQP 算法
def slsqp_algorithm(objective, gradient, constraint, x, y, initial_params, max_iter=100000):
    params = initial_params
    cons = (dict(type='ineq', fun=constraint))
    params = minimize(objective, x0=params, method='SLSQP', constraints=cons)
    if not res.success:
        print(res)
        raise ValueError('optimization failed')
    return res.x
    return params


# 初始化参数
initial_params = [1., 1., 1., 1.]  # 初始参数值

if __name__ == "__main__":
    import matplotlib.pyplot as plt
    import numpy as np

    # x_a = [19614.84, 12378.01, 5522.57, 3214.22, 1799.61, 894.12]
    # y_a = [44.85, 44.87, 43.75, 32.05, 27.37, 25.14]
    x_a = [5631.53, 3525.00, 1510.55, 868.94, 485.06, 242.01]
    y_a = [44.62, 44.24, 43.18, 41.39, 36.60, 28.84]
    x_a = np.log10(x_a)
    x_a = list(x_a)
    # 使用 SLSQP 算法求解非线性优化问题

    coef_a = slsqp_algorithm(objective, gradient, constraint, x_a, y_a, initial_params)

    # 打印结果
    print("优化结果:")
    print("a =", coef_a[0])
    print("b =", coef_a[1])
    print("c =", coef_a[2])
    print("D =", coef_a[3])

    print("-----------for trinomials function --------------------")

    print(f"coefficients: {coef_a}")

    print(f"total error for six points is : {objective(x=x_a, y=y_a, params=coef_a)}")

    print(f"constraint: {constraint(x=x_a[0], params=coef_a)}")

    p = np.poly1d(coef_a)

    # # 创建x轴上的一系列点,用于绘图
    x_plot = np.linspace(min(x_a), max(x_a), 400)

    # # 使用拟合的多项式计算这些点的y值
    y_plot = p(x_plot)

    # # 绘图
    plt.figure(figsize=(10, 6))
    # plt.scatter(x_a, y_a, color='red', label='Data points')
    plt.scatter(x_a, y_a, color='blue', label='Data points')

    plt.plot(x_plot, y_plot, label='polynomial fit')
    plt.xlabel('X')
    plt.ylabel('Y')
    plt.legend()
    plt.show()

误差只有0.27 !!! 效果极佳!!
在这里插入图片描述

总结

总的来说,我们来看一下这两种算法的比较:

梯度下降算法是一种迭代优化方法,通过计算目标函数的梯度方向来更新参数。它适用于连续可导的目标函数,并且可以在大规模数据集上进行有效计算。然而,梯度下降算法可能会受到局部最小值、学习率选择以及收敛速度等问题的影响。

相比之下,SLSQP(Sequential Least Squares Programming)算法是一种约束优化方法,适用于存在约束条件的问题。它使用序列二次规划来求解问题,并且能够处理线性和非线性约束。SLSQP 算法通常需要更多计算资源和时间来找到全局最优解。SLSQP算法在面对少量数据时可能比梯度下降算法效果好的原因有以下几点:

  1. 高精度:SLSQP算法是一种数值精确的优化方法,它使用序列二次规划来求解问题。相比之下,梯度下降算法是一种迭代方法,其收敛速度和最终结果受到学习率等参数选择的影响。在处理少量数据时,SLSQP可以更准确地找到全局最优解。

  2. 约束处理:SLSQP算法适用于存在约束条件的问题,并且能够有效地处理线性和非线性约束。这使得它在需要考虑多个限制条件或复杂问题时更具优势。

  3. 全局最优解:由于SLSQP采用序列二次规划方法,在搜索过程中会进行多次迭代以寻找全局最优解。而梯度下降通常只能保证找到局部最优解,特别是当目标函数非凸或存在平坦区域时。因此,在面对少量数据并且希望获得全局最佳结果时,SLSQP可能会表现更好。

因此,在选择使用哪个方法时需要考虑具体情况。如果你在无约束环境中工作并且有大量数据,则梯度下降可能更合适。而对于带有约束条件或非线性问题,则可以尝试使用 SLSQP 算法。为了确定最佳方法,请根据实际需求进行实验比较,并根据结果选择最适合的算法

还有就是好好学数学!!数理统计与概率论以及离散数学等 优化算法等等数学理论知识,要想走算法这很重要!!

在这里插入图片描述

						  🤞到这里,如果还有什么疑问🤞
					🎩欢迎私信博主问题哦,博主会尽自己能力为你解答疑惑的!🎩
					 	 🥳如果对你有帮助,你的赞是对博主最大的支持!!🥳

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

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

相关文章

Selenium —— 网页frame与多窗口处理!

一、多窗口处理. 1.1、多窗口简介 点击某些链接&#xff0c;会重新打开⼀个窗⼜&#xff0c;对于这种情况&#xff0c;想在新页⾯上操作&#xff0c;就 得先切换窗⼜了。 获取窗⼜的唯⼀标识⽤句柄表⽰&#xff0c;所以只需要切换句柄&#xff0c;就可以在多个页⾯灵 活操作了…

react项目优化

随着项目体积增大&#xff0c;打包的文件体积会越来越大&#xff0c;需要优化&#xff0c;原因无非就是引入的第三方插件比较大导致&#xff0c;下面我们先介绍如何分析各个文件占用体积的大小。 1.webpack-bundle-analyzer插件 如果是webpack作为打包工具的项目可以使用&…

20个提升效率的JS简写技巧,告别屎山!

JavaScript 中有很多简写技巧&#xff0c;可以缩短代码长度、减少冗余&#xff0c;并且提高代码的可读性和可维护性。本文将介绍 20 个提升效率的 JS 简写技巧&#xff0c;助你告别屎山&#xff0c;轻松编写优雅的代码&#xff01; 移除数组假值 可以使用 filter() 结合 Bool…

东郊到家app小程序开发,上门按摩系统优势

东郊到家APP小程序开发 随着生活节奏的紧张&#xff0c;原本的逛菜市场&#xff0c;现在都是网上下单&#xff0c;现在互联网服务都已经融入到人们生活的各个方面 一、上门按摩预约系统的优势 1、高效 一键预约系统只需保存用户信息&#xff0c;以后只需一键预约即可完成。 2、…

分享一下怎么搭建公众号积分商城小程序

随着微信小程序的日益普及&#xff0c;越来越多的商家开始利用微信公众号和小程序进行营销推广。其中&#xff0c;搭建公众号积分商城小程序是一个非常受欢迎的选择。通过积分商城小程序&#xff0c;商家可以吸引更多的用户关注&#xff0c;提高品牌知名度&#xff0c;促进销售…

三门问题-Swift测试

三门问题&#xff08;Monty Hall problem&#xff09;亦称为蒙提霍尔问题、蒙特霍问题或蒙提霍尔悖论&#xff0c;大致出自美国的电视游戏节目Lets Make a Deal。问题名字来自该节目的主持人蒙提霍尔&#xff08;Monty Hall&#xff09;。 参赛者会看见三扇关闭了的门&#xf…

Camera Metadata跨进程传递

google camera2的参数设置都是通过CaptureRequest来设置的&#xff0c;相关的对象都实现了Parcelable接口才能进行跨进程传递。 一、整个Metadata的传递 1、CameraDeviceImpl.java 无论是capture还是repeating都会调用到下面的 submitRequestList 方法 mRemoteDevice就是Cam…

得物API元数据中心探索与思考

一、背景 目前市面上针对API的管理平台很多&#xff0c;但由于各种客观因素&#xff0c;这些平台的功能都更多聚焦在API文档的消费侧。而对于API文档的生成都非常依赖开发人员的手动创建&#xff0c;很难保障文档的实时性和有效性。市面上常见的API管理平台&#xff0c;由于缺…

【C++】笔试训练(二)

目录 一、选择题二、编程题1、排序子序列2、倒置字符串 一、选择题 1、1. 使用printf函数打印一个double类型的数据&#xff0c;要求&#xff1a;输出为10进制&#xff0c;输出左对齐30个字符&#xff0c;4位精度。以下哪个选项是正确的&#xff1f; A %-30.4e B %4.30e C %-3…

zookeeper mac安装

目录 1.下载zookeeper安装包 2.解压安装包 3.修改配置文件 4.启动服务端 5.启动客户端 这边工作中用到了zookeeper组件&#xff0c;但自己独立安装弄的不太多&#xff0c;这边本机mac装一个做测试使用 以下是安装记录&#xff0c;可以作为参考 从以下链接zookeeper版本列…

【二】xxl-job 源码分析

xxl-job 源码分析 简介&#xff1a;阅读优秀的开源项目源码总是一件让人激动的事情&#xff0c;分布式调度平台xxl-job我们在生产环境也是有了很多的实践应用&#xff0c;一款产品使用久了对其实现原理多少有些了解了&#xff0c;今天也是抽出整块的时间来认真分析一下xxl-job的…

RFID技术:钢条加工现场的智能化管理利器

RFID技术&#xff1a;钢条加工现场的智能化管理利器 RFID&#xff08;Radio Frequency Identification&#xff09;技术作为一种非接触式自动识别技术&#xff0c;近年来在工业领域得到广泛应用。本文将探讨RFID在钢条加工现场的应用&#xff0c;包括材料追踪与管理、生产过程…

【LeetCode热题100】--560.和为K的子数组

560.和为K的子数组 示例2的结果&#xff1a; 输入&#xff1a;nums [1,2,3] ,k3的时候 连续子数组有[1,2],[3]&#xff0c;一共有2个 利用枚举法&#xff1a; 枚举[0,…i]里所有的下标j来判断是否符合条件 class Solution {public int subarraySum(int[] nums, int k) {i…

Redis高可用之持久化、主从复制(附配置实例)

目录 一、Redis高可用1.1 简介1.2 高可用策略 二、Redis 持久化2.1 简介2.2 redis 的 2 种持久化方式2.2.1 RDB持久化2.2.2 AOF持久化 三、Redis主从复制3.1 什么是主从复制&#xff1f;3.2 为什么要用主从复制&#xff1f;3.3 主从复制的特性3.4 主从复制工作原理3.4.1 全量复…

Java项目-Spring Boot的生鲜网上交易系统

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝30W、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 文章目录 1 简介2 技术栈3 系统功能4 功能设计5系统详细设计5.1系统功能模块5.2后台功能模块5\.2\.1用户功…

TextSniper for Mac: 革新您的文本识别体验

你是否曾经需要从图片或扫描文档中提取文本&#xff0c;却苦于没有合适的工具&#xff1f;那么&#xff0c;TextSniper for Mac将是你的完美解决方案。这款文本识别工具将彻底改变你处理图像和扫描文件的方式&#xff0c;让你更快速、更高效地完成任务。 TextSniper for Mac 是…

直流负载箱的使用场景和应用范围是什么?

直流负载箱是用于模拟电子设备负载的测试仪器&#xff0c;用于电源供应器、逆变器、电池等直流电源设备的性能测试和负载仿真&#xff0c;它可以模拟各种负载条件&#xff0c;以便测试和评估电源设备在不同负载情况下的工作性能&#xff0c;直流负载箱的使用场景和应用范围广泛…

Jmeter状态码及请求

Jmeter与LR的区别? 1.都是压测工具&#xff0c;可以用来做性能测试&#xff0c;但是Jmeter比较轻量级。jmeter 是用java语言写的&#xff0c;需要java环境&#xff0c;LR不需要&#xff0c;除非用iavavuser协议 (不用掌握) 2.Jmeter更偏向于功能和技术&#xff0c;LR偏向于业务…

VME-7807RC-414001 350-93007807-414001 VMIVME-017807-411001 VMIVME-017807-414001

VME-7807RC-414001 350-93007807-414001 VMIVME-017807-411001 VMIVME-017807-414001 由于第12代英特尔酷睿处理器的16核/24线程配置&#xff0c;Nuvo-9000型号与之前的平台相比&#xff0c;性能大幅提升。它们还支持新的DDR5内存标准&#xff0c;以获得更多内存带宽&#xf…

气传导耳机有哪些品牌?性能不错的气传导耳机分享

​气传导耳机采用空气传导技术&#xff0c;使声音传递更加自然舒适。随着气传导耳机的创新发展&#xff0c;越来越多用户不知道气传导耳机该怎么选了&#xff0c;所以今天我来推荐几款相当不错的气传导耳机给大家参考&#xff0c;享受音乐时不受耳道压力的困扰。 一、NANK南卡…