• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

【Matlab】彻底清除persistent变量

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

MATLAB中persistent变量相当于C中局部静态变量,只能在所定义的函数内部访问到,并且一旦定义一直存在。

一般的解决方案

clear var 变量名

新的问题

如下图所示,本来想着将算法每次迭代的结果先暂时存放在一个persistent变量中,最后一次运行时将数据写入到文件中。后来调试发现,即使是利用clear var命令,该变量再次被初始化的时候仍然会被初始化为上次写入的结果。  

function [ ] = RecordResult( Global )
    %检查静态变量是否存在,若存在且是第一次运行,则清除
    if Global.evaluated <= Global.N
        clear var global_result;%第一次运行时,清除上次该函数运行留下的persistent变量
    end
    persistent global_result;
    
    %% 判断目录是否存在
	method = func2str(Global.algorithm);
	question = func2str(Global.problem);
    dir_1 = sprintf('Data/%s/',question);                               %问题对应的第一级目录
    dir_2 = sprintf('%s%d/',dir_1,Global.run);                       %问题对应的第二级目录,单次运行结果存放在一个文件夹里面,文件夹的名称为运行序号
    %判断路径是否存在    
    if ~exist(dir_1,'dir')
        mkdir(dir_1);
    end
    if ~exist(dir_2,'dir')
        mkdir(dir_2);
    end
    
    %% 输出运行过程中的信息
    clc;%清空命令行
    fprintf('run %d\n',Global.run);
    fprintf('%s with %s on %s\n',method,func2str(Global.operator),question);
    fprintf('N: %d     evaluation: %d\n',Global.N,Global.evaluation);
    fprintf('status: (%6.2f%%), %.2fs passed...\n',Global.evaluated/Global.evaluation*100,Global.runtime);
    
    [r,~] = size(Global.result);
   	result = {Global.result{r,:}};                                           %每个算法最后一次运行结果
    global_result = [global_result;result];
    
    %% 运行完毕后,保存实验结果到本地
    if Global.evaluated >= Global.evaluation
        filename = sprintf('%s%s.mat',dir_1,question);              %存放汇总的运行结果(近似PF)
        filename2 = sprintf('%s%s.mat',dir_2,method);              %存放每个算法的所有运行结果
        if exist(filename2,'file')
            delete(filename2);
        end
        save(filename2,'global_result');
        global_result = [];        %清除函数内部静态变量
        
        if exist(filename,'file')
            PF = load(filename);
            PF = CombineArchive(result{1,2},PF.PF,500);       %设置储备集中元素的个数
        else
            PF = CombineArchive(result{1,2},[],500);     %个体组成的PF
        end
       	fprintf('\nnumber of Non-dominant Solutions :%d\n',size(PF.objs,1));
       	save(filename,'PF');        %保存结果
    end
end

 原因分析:本来在RecordResult函数中有一个if判断,用来判断算法是否是最后一次迭代,若是,就会将该函数内部的persistent变量global_result设置为空。然而,由于自己中途中断了整个算法的运行,导致RecordResult函数中的persistent变量global_result没有被置为空。当再次运行整个程序时,第一次进入RecordResult函数时,虽然还是会执行如下面代码来清除上次实验保留的persistent变量。

if Global.evaluated <= Global.N
    clear var global_result;%仍然会恢复上次的global_result的值
end

然而,当执行完persistent global_result后,系统仍然会恢复上次中断程序执行时保留的persistent变量global_result的值,即原内存空间部分的值,该内存区域的值好像只能在关闭matlab才能彻底释放内存。

新的解决方案

为了使得程序不会受到上次没有运行完的结果的影响,在该函数的开头,判断该程序是否为第一次执行,若是,则直接清空该persistent变量中的值。

function [ ] = RecordResult( Global )
    persistent global_result;
    % 声明静态变量    
    if Global.evaluated <= Global.N
        global_result = [];%第一次运行时,清除上次该函数运行留下的persistent变量
    end
    
    %% 判断目录是否存在
	method = func2str(Global.algorithm);
	question = func2str(Global.problem);
    dir_1 = sprintf('Data/%s/',question);                               %问题对应的第一级目录
    dir_2 = sprintf('%s%d/',dir_1,Global.run);                       %问题对应的第二级目录,单次运行结果存放在一个文件夹里面,文件夹的名称为运行序号
    %判断路径是否存在    
    if ~exist(dir_1,'dir')
        mkdir(dir_1);
    end
    if ~exist(dir_2,'dir')
        mkdir(dir_2);
    end
    
    %% 输出运行过程中的信息
    clc;%清空命令行
    fprintf('run %d\n',Global.run);
    fprintf('%s with %s on %s\n',method,func2str(Global.operator),question);
    fprintf('N: %d     evaluation: %d\n',Global.N,Global.evaluation);
    fprintf('status: (%6.2f%%), %.2fs passed...\n',Global.evaluated/Global.evaluation*100,Global.runtime);
    
    [r,~] = size(Global.result);
   	result = {Global.result{r,:}};                                           %每个算法最后一次运行结果
    global_result = [global_result;result];
    
    %% 运行完毕后,保存实验结果到本地
    if Global.evaluated >= Global.evaluation
        filename = sprintf('%s%s.mat',dir_1,question);              %存放汇总的运行结果(近似PF)
        filename2 = sprintf('%s%s.mat',dir_2,method);              %存放每个算法的所有运行结果
        if exist(filename2,'file')
            delete(filename2);
        end
        save(filename2,'global_result');
        
        if exist(filename,'file')
            PF = load(filename);
            PF = CombineArchive(result{1,2},PF.PF,500);       %设置储备集中元素的个数
        else
            PF = CombineArchive(result{1,2},[],500);     %个体组成的PF
        end
       	fprintf('\nnumber of Non-dominant Solutions :%d\n',size(PF.objs,1));
       	save(filename,'PF');        %保存结果
    end
end

因此,每次实验开始前切记使用global_result=[];将persistent变量设置为空。

if Global.evaluated <= Global.N
    global_result = [];%第一次运行时,清除上次该函数运行留下的persistent变量
end

这样一来,只需要在开始的时候检测该函数是否为第一次执行,若是,则将该persistent变量设置为空,也就不需要每次结束之后都将该persistent变量设置为空了。

即便是中途中断程序的运行,当函数重新运行时,第一次执行仍然会将结果设置为空,问题就解决了。代码来自改进的PlatEMO


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap