[ 娱乐算法 ] 位面之子算法 - The Chosen One Algorithm - Matlab code

Posted RaZLeon

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[ 娱乐算法 ] 位面之子算法 - The Chosen One Algorithm - Matlab code相关的知识,希望对你有一定的参考价值。

位面之子算法 - The Chosen One Algorithm

最近书荒,想找点小说看,却发现没有什么能够耐心看下去的。
想要自己去写小说,却又发现动笔写大纲,塑造人物,建立剧情的前后关系,又是极其麻烦。
写游戏嘛?嘛,算了算了,代码块太多,本喵太懒
怎么办!干脆直接Simulation好了!说干就干!咱们这就模拟一个小说里强者为尊的世界!
实现语言,当然是简单便捷的Matlab!

声明:本代码为本人提出,仅供娱乐之用,欢迎转载,但请保留头部签名协议,感谢!

首先,这个世界需要规定一些参数:

%%% @author: RaZNeo
%%% @license: MIT License
%%% @contact: raznexo@gmail.com
%%% @file: main.m
%%% @time: 2021/7/21 13:28
%%% @desc: Happy Coding

%%% 清理门户:一屋不扫,何以扫天下?
close all; clear; clc;
%%% 位面指标
dim = 20;
%%% 位面人口
npop = 1000;
%%% 强者数量,能力范围,初始化强者身份数据库
numPowerfull = 20;
numAbilityRange = 0.15;
powerFullLibrary = zeros(numPowerfull,1);
%%% 位面年代
currentYear = 1650;
%%% 位面之子产生间隔
intervalOccur = 16; %16年产生一位位面之子带领位面走向繁荣
%%% 凡人学习能力
aveAbility = 0.4;
%%% 凡人榜样数量
target = 3;
%%% 位面淘汰概率
elimiProb = 0.3;
%%% 位面发展值上下限
upp =  20 * ones(1,dim);
low = -20 * ones(1,dim);

然后高阶文明开始了游戏(他们规定了一个目标函数,大家为了这个目标而纷争不断)

%%% 高维度文明在本位面展开的游戏
objFun = @(x) sum(x.^2 + 3.*x - 15);

%%% 高维度文明洒下原始文明的种子
historyRec = zeros(currentYear,1);
bestManHistory = zeros(currentYear,dim);
x = ones(npop,1)*low + ...
    (ones(npop,1)*(upp-low)).*rand(npop,dim);
for i=1:1:npop
    fit(i) = objFun(x(i,:));
end
[historyRec(1),idxPowerMax] = min(fit);
powerMan = x(idxPowerMax,:);
fit = Inf * ones(npop,1);
newFit = Inf * ones(npop,1);

历史的车轮滚滚向前!(就是主循环啦!)

%%% 位面发展仿真
for year = 1:currentYear
    
    %%% 随机产生新的“Chosen One”,
    %%% 位于历史最优点附近,即获得较优历史资源,
    %%% 且为高斯分布。
    if mod(year,intervalOccur) == 0 || year == 1
        chosenList = randperm(npop,numPowerfull);
        x(chosenList,:) = repmat(powerMan * normrnd(1,0.01),numPowerfull,1);
    end
    
    for people = 1:npop        
        %%% 如果此人是位面之子,
        %%% 则随机指定位面之子的特殊技能值(维度、指标)
        if ismember(people,chosenList)
            abilityList = randperm(dim,floor(numAbilityRange*dim));
            newAbility = low + (upp-low).*rand();
            new_x = x(i,:);
            new_x(abilityList) = newAbility(abilityList);
        else
            %%% 若此人为凡人,随机以target位面之子为榜样,增进能力
            new_x = x(people,:) + aveAbility .* ...
                mean(x(chosenList(randperm(numPowerfull,target)),:));
        end        
        %%% 检查是否有能力越界者,若有,超阶文明予以抹除
        new_x = max(min(new_x, upp), low);        
        %%% 对此人进行能力评估
        newFit(people) = objFun(new_x);        
        %%% 如果习得上乘模因,则保留记忆,否则放弃无用模因
        if newFit(people) < fit(people) && ~ismember(people,chosenList)
            fit(people) = newFit(people);
            x(people,:) = new_x;
        elseif ismember(people,chosenList)
            fit(people) = newFit(people);
            x(people,:) = new_x;
        end        
    end
    
    %%% 众人排出实力强弱,有时会杀出黑马
    [fit, fitIdx] = sort(fit);
    x = x(fitIdx,:);
    
    %%% 弱者末尾淘汰
    numElimi = floor(elimiProb*npop);
    x(end-numElimi:end,:) = x(1:numElimi+1,:);
    
    %%% 记录强者历史
    [historyRec(year),recIdx] = min(fit);
    bestManHistory(year,:) = x(recIdx,:);
    
    if mod(year,100) == 0
        disp("Year " + num2str(year) + " history record finished !");
    end
    
end

历史学家们对神明游戏的情况进行了统计!(其实就是绘个图啦)

%%% 展示历史的曲折发展道路
figure(1101);
title('历史的车轮滚滚向前 ');
xlabel('迭代次数');
ylabel('目标函数值');
plot(historyRec,'LineWidth',3);

嗯,咱们研究这个高阶文明的游戏,发现它的分数轨迹是这样的(居然能收敛!?惊!)

[ 重要 ] 代码最终汇总:

%%% @author: RaZNeo
%%% @license: MIT License
%%% @contact: raznexo@gmail.com
%%% @file: main.m
%%% @time: 2021/7/21 13:28
%%% @desc: Happy Coding

%%% 清理门户:一屋不扫,何以扫天下?
close all; clear; clc;

%%% 位面指标
dim = 20;

%%% 位面人口
npop = 1000;

%%% 强者数量,能力范围,初始化强者身份数据库
numPowerfull = 20;
numAbilityRange = 0.15;
powerFullLibrary = zeros(numPowerfull,1);

%%% 位面年代
currentYear = 1650;

%%% 位面之子产生间隔
intervalOccur = 16; %16年产生一位位面之子带领位面走向繁荣

%%% 凡人学习能力
aveAbility = 0.4;

%%% 凡人榜样数量
target = 3;

%%% 位面淘汰概率
elimiProb = 0.3;

%%% 位面发展值上下限
upp =  20 * ones(1,dim);
low = -20 * ones(1,dim);

%%% 高维度文明在本位面展开的游戏
objFun = @(x) sum(x.^2 + 3.*x - 15);

%%% 高维度文明洒下原始文明的种子
historyRec = zeros(currentYear,1);
bestManHistory = zeros(currentYear,dim);
x = ones(npop,1)*low + ...
    (ones(npop,1)*(upp-low)).*rand(npop,dim);
for i=1:1:npop
    fit(i) = objFun(x(i,:));
end
[historyRec(1),idxPowerMax] = min(fit);
powerMan = x(idxPowerMax,:);
fit = Inf * ones(npop,1);
newFit = Inf * ones(npop,1);

%%% 位面发展仿真
for year = 1:currentYear
    
    %%% 随机产生新的“Chosen One”,
    %%% 位于历史最优点附近,即获得较优历史资源,
    %%% 且为高斯分布。
    if mod(year,intervalOccur) == 0 || year == 1
        chosenList = randperm(npop,numPowerfull);
        x(chosenList,:) = repmat(powerMan * normrnd(1,0.01),numPowerfull,1);
    end
    
    for people = 1:npop
        
        %%% 如果此人是位面之子,
        %%% 则随机指定位面之子的特殊技能值(维度、指标)
        if ismember(people,chosenList)
            abilityList = randperm(dim,floor(numAbilityRange*dim));
            newAbility = low + (upp-low).*rand();
            new_x = x(i,:);
            new_x(abilityList) = newAbility(abilityList);
        else
            %%% 若此人为凡人,随机以target位面之子为榜样,增进能力
            new_x = x(people,:) + aveAbility .* ...
                mean(x(chosenList(randperm(numPowerfull,target)),:));
        end
        
        %%% 检查是否有能力越界者,若有,超阶文明予以抹除
        new_x = max(min(new_x, upp), low);
        
        %%% 对此人进行能力评估
        newFit(people) = objFun(new_x);
        
        %%% 如果习得上乘模因,则保留记忆,否则放弃无用模因
        if newFit(people) < fit(people) && ~ismember(people,chosenList)
            fit(people) = newFit(people);
            x(people,:) = new_x;
        elseif ismember(people,chosenList)
            fit(people) = newFit(people);
            x(people,:) = new_x;
        end
        
    end
    
    %%% 众人排出实力强弱,有时会杀出黑马
    [fit, fitIdx] = sort(fit);
    x = x(fitIdx,:);
    
    %%% 弱者末尾淘汰
    numElimi = floor(elimiProb*npop);
    x(end-numElimi:end,:) = x(1:numElimi+1,:);
    
    %%% 记录强者历史
    [historyRec(year),recIdx] = min(fit);
    bestManHistory(year,:) = x(recIdx,:);
    
    if mod(year,100) == 0
        disp("Year " + num2str(year) + " history record finished !");
    end
    
end

%%% 展示历史的曲折发展道路
figure(1101);
title('历史的车轮滚滚向前 ');
xlabel('迭代次数');
ylabel('目标函数值');
plot(historyRec,'LineWidth',3);

以上是关于[ 娱乐算法 ] 位面之子算法 - The Chosen One Algorithm - Matlab code的主要内容,如果未能解决你的问题,请参考以下文章

[ 娱乐算法 ] 位面之子算法 - The Chosen One Algorithm - Matlab code

[ 娱乐算法 ] 位面之子算法 - The Chosen One Algorithm - Matlab code

压缩感知重构算法之子空间追踪(SP)

Java算法之子数组中最大累加和

Son of the Hell 地狱之子——开发日志2

LGOJ P3385 模板负环(纯属娱乐)