
位面之子演算法 - 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);
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/289695.html
標籤:其他
