考虑到常见的基因计算器计算大量基因时数据量呈指数性增长,计算时间被无限拉长,但是又存在大量基因计算的需求,决定对算法层面进行优化,从而提高计算效率,并搭建一个网站供大家使用
Rust基因计算器-初心兽https://blackjun.cn/rust_calculate/
计算器性能优化
1.基因目前常见递归穷举算法进行了优化,代码手动优化了结果集性能
2.结果集评分排序功能,对坏基因进行更本身剔除
3.重点位置排序评分,达到功能完全剔除功能
4.计算转移,将结果集计算和基因算法切割,一个云端,一个客户端本地,提升性能的同时极大程度优化计算性能
如上图所示:
300条计算结果只需5ms,正常递归算法已经超过10分钟往上
屏幕识别功能
引入了新出的屏幕识别功能,具体的算法就不一一展示,主要是图像绘制,色彩剔除,ocr识别
操作流程:
0.请使用最新版 Chrome、Edge 或 Firefox
1.点击"屏幕识别"按钮
2.选择Rust/腐蚀游戏窗口
3.游戏内对准基因1s(可选择背包点击/对准基因方式)
4.如失效,可打开预览窗口,查看实时的识别效果,或者进入更新日志群联系我
下面网站链接,供大家参考交流
Rust基因计算器-初心兽https://blackjun.cn/rust_calculate/
算法详解
下面重点介绍一下基因计算器的算法,方便大家优化升级,供大家交流讨论
基因算法介绍
Rust游戏中基因规则是:
坏基因占0.6
好基因占比0.5
获取一格内植株基因获取最大值,概率相等随机取,自身不算在内
例如:
YXXXXX
WXXXXX
YXXXXX
WXXXXX
四组进行杂交,我们只计算第一个位,Y的占比是1,W是1.2,那么得出来得结果是WXXXXX
ok,基础算法计算完我们就开始计算核心算法
核心算法(递归+穷举)
我们这里就只介绍4个一组的方式
这种方式比较方便计算,同时也不会影响杂交基因的属性,方便下次继续杂交
按照这个逻辑,我们的核心公式就是
虽然看着简单,但是这个公式存在一个指数增长的趋势
20个基因时存在4845结果
30个基因时却存在27405结果
这里贴一下算法:
//预处理
let seedListString = [];
for (let seedListItem of perfectGene.seedList) {
let itemString = "";
for (let item of seedListItem) {
itemString += item;
}
seedListString.push(itemString)
}
//融合算法
const fusionGene = (seedList, otherGeneResult, goodResult) => {
let result = [];
let evaluate = 0;
for (let i = 0; i < 6; i++) { // 基因位置
let positionList = [];
for (let i1 = 0; i1 < seedList.length; i1++) { // 遍历每个基因
positionList.push(seedList[i1][i]);
}
let c = calculateGene(positionList);
switch (c) {
case "G":
case "Y":
evaluate += 3;
break;
case "H":
break;
case "X":
case "W":
evaluate -= 1;
break;
}
result.push(c);
}
let param = {
evaluate: evaluate,
seedList: seedList,
result: result
}
if (evaluate >= 17) {
goodResult.push(param)
} else {
otherGeneResult.push(param)
}
return result;
}
//递归算法
function combine(seedList, tempList, start, combinations) {
if (tempList.length === 4) {
// 当临时列表的大小达到4时,创建副本并添加到结果数组
combinations.push([...tempList]);
return;
}
for (let i = start; i < seedList.length; i++) {
// 做出选择
tempList.push(seedList[i]);
// 递归进入下一层决策树
combine(seedList, tempList, i + 1, combinations);
// 撤销选择(回溯)
tempList.pop();
}
}
但对于正常来说,可能存在50到100个基因,那么结果可能超10w+,对于计算耗时来说时非常缓慢的
优化算法
剖析:我们需要从结果导向性来看:培育出来顶级的基因,那么我们参与杂交的基因也只需要把优良基因筛选出来
基因特性
那么我们只需要对基因进行转为字符串数组,然后对优良基因进行评分即可
所以我们需要引入一个评分算法,对杂交预选集进行一次预处理
例如对YG两个属性评分为10分,H为5分,WX为0分
那么我们就能先遍历一遍结果,然后对预选集进行排名评分
而后取出排名前几的进行杂交
这样剔除掉低分排名,这里就能够提高算法精准度,从而减少运算量的同时达到效果
List<List<String>> seedList=new ArrayList<>();
set.forEach(gene -> {
List<String> list = new ArrayList<>();
int evaluate=0;
char[] chars = gene.toUpperCase().toCharArray();
boolean canAdd=false;
for (int i = 0; i < chars.length; i++) {
switch (chars[i]){
case 'G':
case 'Y':evaluate+=3;break;
case 'H':
case 'X':
case 'W':evaluate-=1;break;
}
switch (chars[i]){
case 'G':if(positionList[i]<30){
positionList[i]++;
canAdd=true;
};
case 'Y':if(positionList[i]<30){
positionList[i]++;
canAdd=true;
};
case 'H':
case 'X':
case 'W':break;
}
list.add(chars[i]+"");
}
if(canAdd&&evaluate>=6){
seedList.add(list);
seedList.add(list);
}else if(canAdd&&evaluate>=2){
seedList.add(list);
}
});
极致优化
这里我还做了一个极致的优化
因为基因还有一个核心点是培育出来好的基因,但是每个基因位置不一样,按照上面的算法,可能会出来相同位置的基因,然后导致数据量增多,同时可能同一个位置基因过多,影响效果
还能进行一次优化,这里涉及的内容就是具体游戏优化了,不属于算法的范畴了,就不继续讨论了,有想法的可以自己去优化实现了
Rust基因计算器-初心兽https://blackjun.cn/rust_calculate/