Baltamatica 北太天元 —— 基于模拟退火算法的旅行商问题

news2024/9/21 0:49:14

文章目录

    • 北太天元(Baltamatica)简介
    • Baltamatica 复现基于Matlab的旅行商问题
      • 问题描述
      • 模拟退火算法
      • Metropolis准则
      • 算法流程图:
    • Demo1:只考虑累计距离,通过模拟退火算法求解最短路径
      • matlab代码:
      • Baltam代码:
        • 北太天元运行中的效果:
      • matlab求解情况:
      • 适应度进行曲线:
    • Demo2:考虑每个站点的病人数量,优先给病人数量多的站点配送,同时兼顾累计最短距离
      • matlab代码:
      • 最优解之一:
      • 适应度进行曲线:
      • baltam 代码:
        • 北太天元运行中的效果:
    • matlab2023a与baltam2.3.1版本的求解速度对比:
    • 结束语:

北太天元(Baltamatica)简介

北太天元(Baltam)是一款对标矩阵实验室(Matlab)的国产通用科学计算软件,目前版本还在持续更新迭代中,并在国内不断提升知名度,营造良好的生态社区氛围。在很多外行、内行人都不看好Matlab国产化,甚至面对工业软件国产化的项目“谈虎色变”的形势下,北太天元横空出世,带着一股国人特有的骨气踏实迈进,此举可谓意义重大。

北太天元官网:baltamatica.com
卢朓-研发北太天元的意义

Baltamatica 复现基于Matlab的旅行商问题

研0开学前还比较自由,由于已经决定研二期间参加一次数学建模研赛(在此立flag,三牌楼通院/物联网有意向组队的可以加个v噢),并听说现在很多数模竞赛都鼓励学生使用北太天元作为编程仿真工具,就尝试下载了 Baltamatica 2.3.1 想跑个demo看看,但实际上遇到的问题其实比想象的要多,甚至官方给出的example中也会有运行时闪退的情况。最后还是花了个把小时才把之前用matlab写的模拟退火TSP问题完整复现为 Baltamatica 版本,当结果都能正常运行时,感觉还是挺惊奇的,向国内有这样一支热血的研发团队致敬!

Matlab版本:Matlab【旅行商问题】—— 基于模拟退火算法的无人机药品配送路线最优化

Matlab【路径规划】—— 无人机药品配送路线最优化

问题描述

某市引进一架专业大型无人机用于紧急状态下的药品投递,每个站点只能投放一次,可选择指派任意站点的无人机起飞出发完成投递任务,但必须在配送完毕后返回原来的站点。站点地理位置坐标(单位为公理)如下图所示。每个站点及容纳的病人数量见附件data_all.mat数据,现要求通过数学建模,在保证速度和优先救治病人数量多的站点前提下,提供药品紧急配送策略,具体问题如下:

请制订无人机的飞行路线,使尽可能多的病人尽早得到救治。
在这里插入图片描述

模拟退火算法

模拟退火算法是一种基于随机搜索的优化算法,其灵感来源于铸炼工具时,先将固体加热至高温后缓慢冷却,就能使固体获得更好的韧性(可弯折),其原理是退火降温过程中固体内部的晶粒能够以较低的能量重新排列,模拟退火算法就是模拟加热后的退火过程。它的目标是在解空间中寻找全局最优解或接近最优解的解(不一定能找到全局最优,可能是比较接近全局最优的局部最优)。

在模拟退火算法中,首先随机生成一个初始解,然后通过一系列的状态转移来搜索更优的解。状态转移的过程(即马尔可夫链)中,算法会引入一个控制参数(温度),使得算法在搜索过程中能够以一定的概率接受劣解,从而避免陷入局部最优解。随着搜索的进行,温度会逐渐降低,接受劣解的概率也会逐渐减小,最终收敛到全局最优解或接近最优解。

Metropolis准则

模拟退火的主要思想是:在搜索区间随机游走(即随机选择点),再利用Metropolis抽样准则,使随机游走逐渐收敛于局部最优解。而温度是Metropolis算法中的一个重要控制参数,可以认为这个参数的大小控制了随机过程向局部或全局最优解移动的快慢。

Metropolis准则是用于决定在Metropolis算法中是否接受状态转移的准则。根据Metropolis准则,状态转移被接受的概率为1或 e x p ( − Δ E / T ) ) exp(-ΔE/T)) exp(ΔE/T)),其中ΔE表示当前状态与下一个状态的能量差,T表示当前的温度。

具体来说,
如果ΔE小于0,即下一个状态的能量比当前状态更低,那么状态转移被接受(被接受的概率为1);
如果ΔE大于0,即下一个状态的能量比当前状态更高,那么状态转移被接受的概率为 e x p ( − Δ E / T ) exp(-ΔE/T) exp(ΔE/T)即有一定概率放弃状态转移).

当温度较高时,接受劣解的概率较高,有助于跳出局部最优解;当温度较低时,接受劣解的概率较低,有助于收敛到全局最优解。

Metropolis准则的核心思想是通过接受概率来探索状态空间,从而达到对系统的采样和模拟。这种准则在Metropolis算法中起到了重要的作用,使得算法能够在搜索过程中兼顾探索和利用,从而更好地找到系统的平衡分布。

算法流程图:

在这里插入图片描述

Demo1:只考虑累计距离,通过模拟退火算法求解最短路径

先通过Demo1,感受一下模拟退火算法处理旅行商问题的优化过程。

matlab代码:

clc,clear,close all;
%% ------------------------------------------------------------------------
%加载数据
load data_all.mat
data = zeros(25,2);
data(:,1) = data_all(:,2);
data(:,2) = data_all(:,3);
%% ------------------------------------------------------------------------
%模拟退火参数设置
n = size(data,1);  %站点数量
T = 100*n;         %初始温度
L = 100;           %马尔可夫链长度
K = 0.99;          %衰减参数
%% ------------------------------------------------------------------------
%站点坐标结构体
cp = struct([]);
for i = 1:n
    cp(i).x = data(i,1);
    cp(i).y = data(i,2);
end
le = 1;            %迭代次数
len(le) = funcp(cp,n);
figure(1);
while T > 0.001    %停止迭代温度
    %多次迭代扰动,温度降低前多次实验
    for i = 1:L
        %计算原路线距离
        len1 = funcp(cp,n);
        %产生随机扰动
        %随机置换两个不同站点的坐标
        p1 = floor(1+n*rand());
        p2 = floor(1+n*rand());
        while p1 == p2
            p1 = floor(1+n*rand());
            p2 = floor(1+n*rand());
        end
        tmp_cp = cp;
        tmp = tmp_cp(p1);
        tmp_cp(p1) = tmp_cp(p2);
        tmp_cp(p2) = tmp;
        %% ----------------------------------------------------------------
        %计算新路线总距离
        len2 = funcp(tmp_cp,n);
        %% ----------------------------------------------------------------
        %新老距离的差值,相当于能量
        delta_e = len2-len1;
        %% ----------------------------------------------------------------
        %若新路线好于旧路线,用新路线代替旧路线
        if delta_e < 0
            cp = tmp_cp;
        else
            %依概率选择是否接收新解
            if exp(-delta_e/T) > rand()
                cp = tmp_cp;
            end
        end
    end
    le = le+1;
    %% --------------------------------------------------------------------
    %计算新路线距离
    len(le) = funcp(cp,n);
    %温度不断下降
    T =T*K;
    for i = 1:n-1
        plot([cp(i).x, cp(i+1).x], [cp(i).y, cp(i+1).y], "o-","LineWidth", 1.2);
        hold on;
        grid on;
    end
    plot([cp(n).x, cp(1).x], [cp(n).y, cp(1).y],'ro--',"LineWidth", 1.5);
    title(['优化最短距离:', num2str(len(le))]);
    disp(['优化最短距离:', num2str(len(le))])
    hold off;
    pause(0.001);
end
figure(2);
plot(len, 'LineWidth', 1.1)
grid on;
xlabel('迭代次数')
ylabel('目标函数值')
title('适应度进行曲线')
disp('优化结束')
%% ------------------------------------------------------------------------
%计算路线总长度函数
function len = funcp(cp,n)
len = 0;
for i = 1:n-1
    len = len+sqrt((cp(i).x-cp(i+1).x)^2+(cp(i).y-cp(i+1).y)^2);  %累计欧氏距离
end
len = len+sqrt((cp(n).x-cp(1).x)^2+(cp(n).y-cp(1).y)^2);
end

Baltam代码:

clc;
clear;
clf;
%% ------------------------------------------------------------------------
%加载数据
cp_x = load('cp_x.mat');
cp_y = load('cp_y.mat');
data = zeros(25,2);
%% ------------------------------------------------------------------------
%模拟退火参数设置
n = size(data,1);  %站点数量
indx = 1:n;
T = 100*n;         %初始温度
L = 100;           %马尔可夫链长度
K = 0.99;          %衰减参数
%% ------------------------------------------------------------------------
%站点坐标结构体
cp = struct('x',cp_x.cp_x,'y',cp_y.cp_y);
cpx = cp.x;
cpy = cp.y;
xx = cp.x;
yy = cp.y;
lem = 1;            %迭代次数
len(lem) = funcp(cpx,cpy,n);
figure('Color','white');
while T > 0.001    %停止迭代温度
    %多次迭代扰动,温度降低前多次实验
    for cnt = 1:L
        %计算原路线距离
        len1 = funcp(cpx,cpy,n);
        %产生随机扰动
        %随机置换两个不同站点的坐标
        p1 = floor(1+n*rand());
        p2 = floor(1+n*rand());
        while p1 == p2
            p1 = floor(1+n*rand());
            p2 = floor(1+n*rand());
        end
        tmp_cpx = cpx;
        tmpx = tmp_cpx(p1);
        tmp_cpx(p1) = tmp_cpx(p2);
        tmp_cpx(p2) = tmpx;
        tmp_cpy = cpy;
        tmpy = tmp_cpy(p1);
        tmp_cpy(p1) = tmp_cpy(p2);
        tmp_cpy(p2) = tmpy;
        %% ----------------------------------------------------------------
        %计算新路线总距离
        len2 = funcp(tmp_cpx,tmp_cpy,n);
        %% ----------------------------------------------------------------
        %新老距离的差值,相当于能量
        delta_e = len2-len1;
        %% ----------------------------------------------------------------
        %若新路线好于旧路线,用新路线代替旧路线
        if delta_e < 0
            cpx = tmp_cpx;
            cpy = tmp_cpy;
        else
            %依概率选择是否接收新解
            if exp(-delta_e/T) > rand()
                cpx = tmp_cpx;
                cpy = tmp_cpy;
            end
        end
    end
    lem = lem+1;
    %% --------------------------------------------------------------------
    %计算新路线距离
    len(lem) = funcp(cpx,cpy,n);
    disp(["优化最短距离:", num2str(len(lem))])
    disp(["起点坐标:", num2str([cpx(1), cpy(1)])])
    disp(["最后一个站点坐标:", num2str([cpx(n), cpy(n)])])
    %温度不断下降
    T =T*K;
    for jj = 1:n-1
        plot([cpx(jj), cpx(jj+1)], [cpy(jj), cpy(jj+1)], "o-","LineWidth", 1.2);
        hold on;
    end
    for kk = 1:n
        text(xx(kk)+0.5,yy(kk)+0.75,num2str(indx(kk)),'fontsize',10);
    end
    plot([cpx(n), cpx(1)], [cpy(n), cpy(1)],'r-.',"LineWidth", 1.5);
    axis([0,120,-2,58]);
    title(['优化最短距离:', num2str(len(lem))]);
    hold off;
end
figure('2');
plot(len, 'LineWidth', 1.1)
axis([0,length(len),floor(min(len)),ceil(max(len))])
xlabel("迭代次数")
ylabel("目标函数值")
title('适应度进行曲线')
disp("优化结束")
%% ------------------------------------------------------------------------
计算路线总长度函数
function len = funcp(cpx,cpy,n)
tar = 0;
len = 0;
for ii = 1:n-1
    len = len+sqrt((cpx(ii)-cpx(ii+1))^2+(cpy(ii)-cpy(ii+1))^2);
end
len = len+sqrt((cpx(n)-cpx(1))^2+(cpy(n)-cpy(1))^2);
end

北太天元运行中的效果:

在这里插入图片描述

其实可以看出Baltam的代码风格已尽可能地贴近Matlab,这对于从matlab转入baltam来说是非常重要的,但还不足以达到直接把Matlab的代码、工程导入进去一键运行。

matlab求解情况:

由于模拟退火算法的优化过程具有随机性,所以得到的解不一定就是全局最优,但肯定比瞎猜一个局部最优要好。可以重复运行几次程序,观察最优解的变化,正常应该差距不大。

最优解之一:
在这里插入图片描述
只考虑距离的情况不用考虑路线顺序,因为正反走都是一样的距离。

适应度进行曲线:

在这里插入图片描述
可见适应度随着退火过程逐渐趋于稳定的最优解,算法具有收敛性。

Demo2:考虑每个站点的病人数量,优先给病人数量多的站点配送,同时兼顾累计最短距离

新建目标值变量tar,tar包含了累计距离变量len的大小,且加入了病人数量这个变量var,并乘以权重10,用1000-var是为了反向考虑优化过程中需要使得目标值tar越来越小:

tar = tar+sqrt((cp(i).x-cp(i+1).x)^2+(cp(i).y-cp(i+1).y)^2)+10*(1000-var(i)); 

matlab代码:

clc,clear,close all;
%% ------------------------------------------------------------------------
%加载数据
load data_all.mat
data = zeros(25,2);
data(:,1) = data_all(:,2);
data(:,2) = data_all(:,3);
var = data_all(:,4);
%% ------------------------------------------------------------------------
%模拟退火参数设置
n = size(data,1);  %站点数量
T = 100*n;         %初始温度
L = 100;           %马尔可夫链长度
K = 0.99;          %衰减参数
%% ------------------------------------------------------------------------
%站点坐标结构体
cp = struct([]);
for i = 1:n
    cp(i).x = data(i,1);
    cp(i).y = data(i,2);
end
le = 1;            %迭代次数
[tar(le), len(le)] = funcp(cp,n);
figure(1);
while T > 0.001    %停止迭代温度
    %多次迭代扰动,温度降低前多次实验
    for i = 1:L
        %计算原路线距离
        [tar1, ~] = funcp(cp,n);
        %产生随机扰动
        %随机置换两个不同站点的坐标
        p1 = floor(1+n*rand());
        p2 = floor(1+n*rand());
        while p1 == p2
            p1 = floor(1+n*rand());
            p2 = floor(1+n*rand());
        end
        tmp_cp = cp;
        tmp = tmp_cp(p1);
        tmp_cp(p1) = tmp_cp(p2);
        tmp_cp(p2) = tmp;
        %% ----------------------------------------------------------------
        %计算新路线总距离
        [tar2, ~] = funcp(tmp_cp,n);
        %% ----------------------------------------------------------------
        %新老距离的差值,相当于能量
        delta_e = tar2-tar1;
        %% ----------------------------------------------------------------
        %若新路线好于旧路线,用新路线代替旧路线
        if delta_e < 0
            cp = tmp_cp;
        else
            %依概率选择是否接收新解
            if exp(-delta_e/T) > rand()
                cp = tmp_cp;
            end
        end
    end
    le = le+1;
    %% --------------------------------------------------------------------
    %计算新路线距离
    [tar(le), len(le)] = funcp(cp,n);
    %温度不断下降
    T =T*K;
    for i = 1:n-1
        plot([cp(i).x, cp(i+1).x], [cp(i).y, cp(i+1).y], "o-","LineWidth", 1.2);
        hold on;
        grid on;
    end
    plot([cp(n).x, cp(1).x], [cp(n).y, cp(1).y],'r-.',"LineWidth", 1.5);
    for k = 1:n
        text(data(k,1)+0.5,data(k,2)+0.75,num2str(var(k)),'fontsize',10);
    end
    title(['优化最短距离:', num2str(len(le))]);
    disp(['优化最短距离:', num2str(len(le))])
    disp(['起点坐标:', num2str([cp(1).x, cp(1).y])])
    disp(['最后一个站点坐标:', num2str([cp(n).x, cp(n).y])])
    hold off;
    pause(0.001);
end
figure(2);
plot(tar, 'LineWidth', 1.1)
grid on;
xlabel('迭代次数')
ylabel('目标函数值')
title('适应度进行曲线')
disp('优化结束')
%% ------------------------------------------------------------------------
%计算目标函数和路线总长度函数
function [tar, len] = funcp(cp,n)
tar = 0;
len = 0;
for i = 1:n-1
    tar = tar+sqrt((cp(i).x-cp(i+1).x)^2+(cp(i).y-cp(i+1).y)^2)+10*(1000-var(i)); 
    len = len+sqrt((cp(i).x-cp(i+1).x)^2+(cp(i).y-cp(i+1).y)^2);
end
tar = tar+sqrt((cp(n).x-cp(1).x)^2+(cp(n).y-cp(1).y)^2)+10*(1000-var(1));
len = len+sqrt((cp(n).x-cp(1).x)^2+(cp(n).y-cp(1).y)^2);
end

最优解之一:

在这里插入图片描述
查看路线的起点和终点(最后一个配送站点):

>> disp(['起点坐标:', num2str([cp(1).x, cp(1).y])])
起点坐标:18  28
>> disp(['最后一个站点坐标:', num2str([cp(n).x, cp(n).y])])
最后一个站点坐标:21  30

可在data_all.mat的第一列数据中看到各坐标点对应的节点标号。

适应度进行曲线:

在这里插入图片描述

baltam 代码:

clc;
clear;
clf;
%% ------------------------------------------------------------------------
%加载数据
cp_x = load('cp_x.mat');
cp_y = load('cp_y.mat');
vars = load('var.mat');
data = zeros(25,2);
%% ------------------------------------------------------------------------
%模拟退火参数设置
n = size(data,1);  %站点数量
indx = 1:n;
T = 100*n;         %初始温度
L = 100;           %马尔可夫链长度
K = 0.99;          %衰减参数
%% ------------------------------------------------------------------------
%站点坐标结构体
varm = vars.var;
cp = struct('x',cp_x.cp_x,'y',cp_y.cp_y);
cpx = cp.x;
cpy = cp.y;
xx = cp.x;
yy = cp.y;
lem = 1;            %迭代次数
[tar(lem), len(lem)] = funcp(cpx,cpy,n,varm);
figure('Color','white');
while T > 0.001    %停止迭代温度
    %多次迭代扰动,温度降低前多次实验
    for cnt = 1:L
        %计算原路线距离
        [tar1, ~] = funcp(cpx,cpy,n,varm);
        %产生随机扰动
        %随机置换两个不同站点的坐标
        p1 = floor(1+n*rand());
        p2 = floor(1+n*rand());
        while p1 == p2
            p1 = floor(1+n*rand());
            p2 = floor(1+n*rand());
        end
        tmp_cpx = cpx;
        tmpx = tmp_cpx(p1);
        tmp_cpx(p1) = tmp_cpx(p2);
        tmp_cpx(p2) = tmpx;
        tmp_cpy = cpy;
        tmpy = tmp_cpy(p1);
        tmp_cpy(p1) = tmp_cpy(p2);
        tmp_cpy(p2) = tmpy;
        %% ----------------------------------------------------------------
        %计算新路线总距离
        [tar2, ~] = funcp(tmp_cpx,tmp_cpy,n,varm);
        %% ----------------------------------------------------------------
        %新老距离的差值,相当于能量
        delta_e = tar2-tar1;
        %% ----------------------------------------------------------------
        %若新路线好于旧路线,用新路线代替旧路线
        if delta_e < 0
            cpx = tmp_cpx;
            cpy = tmp_cpy;
        else
            %依概率选择是否接收新解
            if exp(-delta_e/T) > rand()
                cpx = tmp_cpx;
                cpy = tmp_cpy;
            end
        end
    end
    lem = lem+1;
    %% --------------------------------------------------------------------
    %计算新路线距离
    [tar(lem), len(lem)] = funcp(cpx,cpy,n,varm);
    disp(["优化最短距离:", num2str(len(lem))])
    disp(["起点坐标:", num2str([cpx(1), cpy(1)])])
    disp(["最后一个站点坐标:", num2str([cpx(n), cpy(n)])])
    %温度不断下降
    T =T*K;
    for jj = 1:n-1
        plot([cpx(jj), cpx(jj+1)], [cpy(jj), cpy(jj+1)], "o-","LineWidth", 1.2);
        hold on;
    end
    plot([cpx(n), cpx(1)], [cpy(n), cpy(1)],'r-.',"LineWidth", 1.5);
    axis([0,120,-2,58]);
    for kk = 1:n
        text(xx(kk)+0.5,yy(kk)+0.75,num2str(varm(kk)),'fontsize',10);
        text(xx(kk)+0.5,yy(kk)-0.75,num2str(indx(kk)),'fontsize',8);
    end
    title(['优化最短距离:', num2str(len(lem))]);
    hold off;
end
figure('2');
plot(tar, 'LineWidth', 1.1)
axis([0,length(len),floor(min(len)),ceil(max(len))])
xlabel("迭代次数")
ylabel("目标函数值")
title('适应度进行曲线')
disp("优化结束")
%% ------------------------------------------------------------------------
计算目标函数和路线总长度函数
function [tar, len] = funcp(cpx,cpy,n,varm)
tar = 0;
len = 0;
for ii = 1:n-1
    tar = tar+sqrt((cpx(ii)-cpx(ii+1))^2+(cpy(ii)-cpy(ii+1))^2)+10*(1000-varm(ii)); 
    len = len+sqrt((cpx(ii)-cpx(ii+1))^2+(cpy(ii)-cpy(ii+1))^2);
end
tar = tar+sqrt((cpx(n)-cpx(1))^2+(cpy(n)-cpy(1))^2)+10*(1000-varm(1));
len = len+sqrt((cpx(n)-cpx(1))^2+(cpy(n)-cpy(1))^2);
end

北太天元运行中的效果:

在这里插入图片描述
在这里插入图片描述

matlab2023a与baltam2.3.1版本的求解速度对比:

baltam2.3.1中的运行效果:
在这里插入图片描述
baltam的界面非常简约,丝滑~

虽然matlab一直以来的感受就是非常笨重,但本题在matlab2023a环境(含pause(0.001)延时)中的求解速度与baltma2.3.1目前的速度相较而言,其实是非常快了:
在这里插入图片描述

结束语:

最后还是希望北太天元能越做越好,早日解决卡脖子问题!

免费代码包已附上,感兴趣的同学可以下载尝试运行,如果运行太久还是没有收敛出最优解,在命令行ctrl+c可以强行终止程序。

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

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

相关文章

Go 语言基础语法:Hello World 实例(涉及定义变量;fmt 包、Print、Println、Printf)

Hello world实例 package mainimport "fmt"func main() {fmt.Println("Hello, World!") } 编译 运行 go run hello.go Hello, World! go run 做了编译和执行两动作&#xff0c;编译会生成 hello 文件&#xff0c;执行完成后此文件会被删除。 web展示 …

STM32外设系列—L298N

文章目录 一、L298N简介二、L298N电路图三、L298N使用方法四、L298N驱动电机实例4.1 麦克纳姆轮简介4.2 定时器PWM配置4.3 智能车行驶控制 五、拓展应用 一、L298N简介 L298N是SGS公司生产的一款通用的电机驱动模块。其内部包含4路逻辑驱动电路&#xff0c;有两个H桥的高电压大…

java并发编程 3:synchronized与锁(重点)

目录 共享问题synchronized锁及使用synchronized代码块synchronized 修饰成员方法synchronized 修饰静态方法 变量的线程安全分析成员变量和静态变量是否线程安全局部变量是否线程安全常见线程安全类 synchronized底层原理Java对象头Monitor管程字节码看原理 锁状态及转换四种锁…

vscode 快速修复(quick fix) 快捷键(Ctrl + .)被占用问题解决方法

vscode 快速修复(quick fix) 快捷键(Ctrl .)被占用 微软拼音的中/英文标点切换的快捷键为Ctrl .&#xff0c;与 vscode 快速修复(quick fix)快捷键冲突。修复方法如下&#xff1a; 切换到微软拼音&#xff0c;在输入法中或英字上&#xff0c;点击右键。 再点设置 - 按键。 …

MTK平台WLAN的Roaming机制和案例log解析

一 、WLAN漫游简介 [百度百科]:当网络环境存在多个相同SSID的AP,且它们的微单元互相有一定范围的重合时,无线用户可以在整个WLAN覆盖区内移动,无线网卡能够自动发现附近信号强度最大的AP,并通过这个AP收发数据,保持不间断的网络连接,这就称为无线漫游。 简单来说:WLA…

Flink中时间和窗口

文章目录 一、时间定义二、水位线(Watermark)1、概念2、水位线特征3、生成水位线3.1 水位线生成策略&#xff08;Watermark Strategies&#xff09;3.2 Flink 内置水位线生成器3.3 自定义水位线策略 4、水位线的传递 三、窗口(Window)1、概念2、窗口分类2.1 驱动类型分类2.2 窗…

chatgpt赋能python:Python输入之后的运行过程

Python输入之后的运行过程 在Python中&#xff0c;输入是必不可少的一部分&#xff0c;它使我们能够更加交互和动态地使用这门语言。在本篇文章中&#xff0c;我们将介绍Python输入的运行过程&#xff0c;包括如何读取和处理输入以及输入与程序运行的交互方式。 什么是Python…

ZLMediaKit 的安装及使用介绍

ZLMediaKit 介绍 ZLMediaKit是一个基于C开发的开源流媒体服务器。它提供了高性能的音视频处理能力&#xff0c;支持常见的流媒体协议&#xff0c;如RTSP、RTMP、HLS和HTTP-FLV&#xff0c;并且具有低延迟和高并发处理能力。 开源地址&#xff1a;https://github.com/xia-chu/…

抖音seo账号矩阵系统源码代开发组件

一.开发矩阵系统的项目背景&#xff1a; 目录 一.开发矩阵系统的项目背景&#xff1a; 二.短视频矩阵系统SaaS模板组件通常包含以下几个方面的内容&#xff1a; 三.抖音SEO账号矩阵系统源码的技术搭建过程可以分为几个步骤&#xff1a; 1.确定系统的需求和目标&#xff0c…

DFS深度优先搜索

目录 一、DFS的概念DFS的定义DFS的搜索方式DFS采用的数据结构DFS的特点 二、DFS的实战应用1.排列数字2.n-皇后问题 一、DFS的概念 DFS的定义 DFS&#xff08;Depth-First Search&#xff09;深度优先搜索&#xff0c;是一种常用的图遍历算法&#xff0c;用于在图或树数据结构…

金蝶云星空财务软件被locked勒索病毒攻击后如何更快解密数据库数据?

金蝶云星空财务软件是一款广泛应用于企业财务管理领域的软件&#xff0c;然而&#xff0c;近期很多企业的金蝶云星空财务软件遭受到了locked勒索病毒的攻击&#xff0c;导致数据库数据被加密。而这次的locked勒索病毒采用了新的加密形式&#xff0c;它不仅能够扫描出各种软件系…

数据结构--顺序表VS链表

数据结构–顺序表VS链表 逻辑结构 存储结构 顺序表&#xff1a; 优点:支持随机存取、存储密度高 缺点:大片连续空间分配不方便&#xff0c;改变容量不方便 链表&#xff1a; 优点:离散的小空间分配方便&#xff0c;改变容量方便 缺点:不可随机存取&#xff0c;存储密度低 基本…

从零开始 Spring Boot 49:Hibernate Entity Lifecycle

从零开始 Spring Boot 49&#xff1a;Hibernate Entity Lifecycle 图源&#xff1a;简书 (jianshu.com) 本文将介绍 Hibernate 的 Session 接口&#xff0c;以及如何用 Session 的相关 API 转换实体&#xff08;Entity&#xff09;的生命周期状态。 如果缺少的 JPA 和 Hiberna…

ubuntu18.04 ros报错Command ‘roscore‘ not found

问题描述 git clone https://github.com/ros/catkin.gitcd catkingit branch melodic-develgit checkout melodic-develmkdir buildcd buildcmake …make -j8 && sudo make installcd .. sudo python2 setup.py installsudo python3 setup.py install出现问题 hua…

ADB命令(app自动化测试底层技术)

一、adb相关知识体系 1&#xff0c;adb的使用场景 操作手机设备 app自动化测试2&#xff0c;adb测试体系 app自动化测试-appium 遍历测试-appcrawier app性能测试 app专项测试 STF设备管理平台 云测平台 兼容性测试 二、adb 基础 1&#xff0c;什么是adb Adb是用来操作Andro…

spark、pyspark 常用的模版 demo 网址

1、我自己有时候用百度或者其他的搜索出来的spark 常用案例&#xff0c;质量有的好有的差有时候就很烦。特地分享一个我常用的质量高的网站地址 https://sparkbyexamples.com/pyspark/pyspark-collect/

进阶2:JVM 启动参数

目录 jvm启动参数 参数分类 系统属性 功能解析 运行模式 jvm有两种运行模式 堆内存 设置堆内存 GC相关 GC 日志相关的参数 分析诊断 指定垃圾收集器相关参数 JavaAgent 什么是Java agent 常见问题 视频 前言 这堂课程不用过多的记忆&#xff0c;自身有印象即可…

Vue中Object.defineProperty

放到Object.defineProperty中比直接写在person对象中更灵活&#xff0c;可以设置的属性更多 <script>let person{name:张三,age:男}Object.defineProperty(person,age,{value:18,enumerable:true, //控制属性是否可以被枚举&#xff0c;默认值是falsewritable:true, //控…

无人机动力测试台-15公斤级-Flight Stand 15

Flight Stand 15测试台通过测量电机和螺旋桨的拉力、扭矩、转速、电流、电压、温度、螺旋桨效率和电机效率来精准地描述和评估无人机动力系统的性能。 产品应用 Flight Stand 15测试台可以用于以下方向&#xff1a; 实时动态测试 FS15 Pro的1000 Hz采样率使测试成为可能&…

Chrome 插件开发覆写xhr请求

这几天搞chrome谷歌浏览器插件遇到个问题 我想拦截网页请求&#xff0c;并把数据传递到下一个子窗口。获取responsebody内容 background.js 单纯靠sendmessage实现不了通讯 chrome.runtime.sendMessage({data: e.data.responseText,type:ajaxResponse}); 最开始的时候想用chr…