[ 娱乐算法 ] 位面之子算法 - 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