📄 efloys.java
字号:
private int GetParentID() {
int i,j,k,n;
int rand, partsum;
//得到父母亲的ID
i = 0;
partsum = 0;
//n = Efloys[0].PopulationSize;
n = Efloys.length;
rand =(int) (Math.random()*SumFitness);
int avg = (int) (SumFitness/n);
j = 0;
for (i=0;i<Efloys.length;i++) {
Efloys[i].GetFitness();
partsum = partsum + (int) Efloys[i].fitness;
if (partsum >= rand) {
j = 1;
break;
}
}
/*
while ((partsum < rand) && (i < n-1)) {
partsum += (float) Efloys[i].fitness;
i++;
}
*/
if (j == 0) {
i = Efloys.length-1;
}
//deb.showMsg("i= "+i+" j= "+j+" Sum= "+(int) SumFitness+" Avg = "+(int) avg+
// " Rand = "+(int) rand+" Part= "+partsum+" Fit= "+Efloys[i].fitness+" id = "+Efloys[i].id);
return Efloys[i].id;
}
private Efloy Mate() {
//进行繁殖交配
int MomID, DadID;
Efloy Mom, Dad , Kid;
String KidChrom, fx, ev;
MomID = GetParentID();
DadID = GetParentID();
Mom = Efloys[GetFloyNumber(MomID)];
Dad = Efloys[GetFloyNumber(DadID)];
if (Mom.type == 1) {
while (Mom.type == 1) {
MomID = GetParentID();
Mom = Efloys[GetFloyNumber(MomID)];
deb.showMsg("Repeating Mom = "+MomID);
}
}
if (Dad.type == 1) {
while (Dad.type == 1) {
DadID = GetParentID();
Dad = Efloys[GetFloyNumber(DadID)];
deb.showMsg("Repeating Dad = "+DadID);
}
}
//交配操作的到子代的染色体
KidChrom = Dad.CrossOver(Mom.chrom);
fx = EncodeChrom(fixpars);
ev = EncodeChrom(envpars);
Kid = new Efloy(params, KidChrom, fixpars, fx, envpars, ev);
Kid.chrom = Kid.mutate();
//颜色当父亲不是异己的时候随父亲
if (Dad.color == Color.red)
Kid.AssignColor(Mom.GetColorNumber());
else
Kid.AssignColor(Dad.GetColorNumber());
//能量、安全度、合作度都是父母的平均值
Kid.energy = (int) ((Dad.energy + Mom.energy)/2);
Kid.safety = (int) ((Dad.safety + Mom.safety)/2);
Kid.cooperation = (int) ((Dad.cooperation + Mom.cooperation)/2);
Kid.GetFitness();
Kid.x = 10;
Kid.y = 10;
canvas.repaint();
/*
deb.showMsg("---");
deb.showMsg("SumFitness = "+SumFitness);
deb.showMsg("Mom = "+MomID+": "+Mom.chrom+" Fit= "+Mom.fitness);
deb.showMsg("Dad = "+DadID+": "+Dad.chrom+" Fit= "+Dad.fitness);
deb.showMsg("Kid = "+KidChrom+" Kid.chrom= "+Kid.chrom);
*/
return Kid;
}
private void Breed() {
int i,n;
//繁殖操作产生新的子代,并根据幸存率决定上一代的存亡
SumFitness = GetSumFitness();
NewFloys = new Efloy[Efloys.length];
for (i=0;i<Efloys.length;i++) {
//deb.showMsg("Making kid #"+i);
NewFloys[i] = Mate();
NewFloys[i].id = i;
}
if (Efloys[0].SurviversFactor > 0) {
SortFloys(Efloys);
SortFloys(NewFloys);
n = (int) (Efloys.length*Efloys[0].SurviversFactor/100);
for (i=0;i<Efloys.length;i++) {
if (i > (n-1))
Efloys[i] = NewFloys[i-n];
}
}
else {
for (i=0;i<Efloys.length;i++)
Efloys[i] = NewFloys[i];
}
}
static boolean Flip(float ref) {
float rand = (float) Math.random();
if (rand < ref)
return true;
else
return false;
}
private void PreScale() {
//平滑适应度,也就是对适应度重新做出调整
int i;
double tmin = 10e35;
double tmax = -10e35;
double tsum = 0;
int size = Efloys[0].PopulationSize;
for (i=0;i<size;i++) {
Efloys[i].GetFitness();
if (Efloys[i].fitness < tmin)
tmin = Efloys[i].fitness;
if (Efloys[i].fitness > tmax)
tmax = Efloys[i].fitness;
tsum = tsum + Efloys[i].fitness;
}
double tavg = tsum/size;
double temp = (tmax+tmin)/2;
double factor = 1.80; //gadef.params.scale; (Default: 1.80)
double a_coeff = 1;
double b_coeff = 0;
double delta;
//deb.showMsg("tsum= "+tsum+" size = "+size+" tavg= "+tavg);
//deb.showMsg("tmax= "+tmax+" tmin = "+tmin+" temp= "+temp);
//deb.showMsg("factor= "+factor+" a = "+a_coeff+" b= "+b_coeff);
if (factor > 1) {
if (tmin > (factor * tavg - tmax) / (factor - 1)) {
delta = tmax - tavg;
if (delta != 0) {
a_coeff = (factor - 1) * tavg / delta;
b_coeff = tavg * (tmax - factor * tavg) / delta;
}
}
}
else {
delta = tavg - tmin;
if (delta != 0) {
a_coeff = tavg / delta;
b_coeff = -tmin * tavg / delta;
}
}
//deb.showMsg("After. factor= "+factor+" a = "+a_coeff+" b= "+b_coeff);
//deb.showMsg("Before 0 = "+Efloys[0].fitness+" 1= "+Efloys[1].fitness);
for (i=0;i<size;i++)
Efloys[i].fitness = (int) (Efloys[i].fitness*a_coeff + b_coeff);
//deb.showMsg("After 0 = "+Efloys[0].fitness+" 1= "+Efloys[1].fitness);
//deb.showMsg(" ");
//SortFloys();
}
void CreateHelp(EfloyLog win) {
int i;
String txt;
win.ta.setForeground(Color.black);
win.ta.setFont(new Font("TimesRoman",Font.BOLD,12));
win.clear();
txt = "";
txt = txt + "内容\n\n";
txt = txt + "1.\t 按钮功能\n";
txt = txt + "2.\t 属性\n";
txt = txt + "3.\t 按键功能\n";
txt = txt + "4.\t Netscape和IE浏览器的区别\n";
txt = txt + "\n\n";
txt = txt + "按钮功能 - 底端按钮\n\n";
txt = txt + "Restart:\t\t 重新开始一代Floys并且给每只Floy赋予缺省的个性\n";
txt = txt + "Scramble:\t\t 让一代的个体的特性分散度更高,这样会引起更多的变异从而引起更多的多样性\n";
txt = txt + "Breed:\t\t\t 创造新的一代,并且每个子孙都是以当前这代作为父母\n";
txt = txt + "Evolution:\t\t 开始或者终止进化的进程, 并且繁殖在每只异己被杀死后都进行\n";
txt = txt + "Insert Stranger:\t 释放一个红色的入侵者进入领土, 使得当前的这些Floy们会追逐并进攻它\n";
txt = txt + "\n按钮功能 - 右侧按钮条\n\n";
txt = txt + "Show Help:\t\t 显示帮助屏幕. 点击右上角的X关闭帮助屏幕\n";
txt = txt + "Show Log Screen:\t 显示日至记录屏幕(当前这次操作的记录). 点击右上角的X关闭屏幕\n";
txt = txt + "Predefined:\t\t 对每一代或者环境选择一组预定义的属性\n";
txt = txt + "Show Rules:\t\t 显示Floy的行为规则和游戏的规则\n";
txt = txt + "Show Info:\t\t 显示Floys的特征,环境属性和历史数据。\n";
txt = txt + "Edit Properties:\t 更改个体或者整体的属性-给每一个Floy赋予一个颜色\n";
txt = txt + "\n按钮属性 - 左侧按钮条\n\n";
txt = txt + "Show Numbers:\t 将每个个体显示成不同的数字\n";
txt = txt + "Turn Sound Off:\t 开启或者关闭声效(每当入侵者被杀掉的时候都有一个叹息声)\n";
txt = txt + "Slower:\t\t 让Floy移动得更慢(可以通过多次点击得到你想要的速度)\n";
txt = txt + "Faster:\t\t 让Floy移动得更慢(可以通过多次点击得到你想要的速度)\n";
txt = txt + "Pause:\t\t 停止所有移动,第二次点击将会继续移动\n";
txt = txt + "Limited Ranges:\t 为那些极端的属性限制或者重置变化的范围\n";
txt = txt + "\n\n属性的描述(单位是任意的并且没有意义)\n\n";
txt = txt + "Primary Traits:\t 主要的行为属性,受遗传操作(交叉、变异)影响\n";
txt = txt + "Secondary Traits:\t 对不同输入的特定响应,受遗传操作的影响\n";
txt = txt + "Fixed traits:\t 个体的各种特性,不受遗传操作的影响\n";
txt = txt + "Environmental:\t 环境的属性,被群体共享\n";
txt = txt + "\n";
txt = txt + "基本特征\n\n";
txt = txt + "Maximum Speed:\t Floy可以到达的最大速度\n";
txt = txt + "Bounce Speed:\t 撞墙反弹回来的速度\n";
txt = txt + "Acceleration:\t 反映各种输入的基本加速度\n";
txt = txt + "Attract to Center:\t Floy被吸引到中心的一种力量\n";
txt = txt + "Collision Distance:\t Floy可以接触到另一只的碰撞距离\n";
txt = txt + "\n";
txt = txt + "第二种特征:\n\n";
txt = txt + "对远离的Floy的反映(速度的变化)\n";
txt = txt + "Local to Local:\t Floy对同类的反应\n";
txt = txt + "Local to Stranger:\t 对外来的入侵者的反应\n";
txt = txt + "Stranger to Local:\t 入侵者对本地Floy的反映\n";
txt = txt + "\n";
txt = txt + "对近距离(在接触距离以内)Floy的反映(速度变化):\n";
txt = txt + "Local to Local:\t Floy对同类的反应\n";
txt = txt + "Local to Stranger:\t 对外来的入侵者的反应\n";
txt = txt + "Stranger to Local:\t 入侵者对本地Floy的反映\n";
txt = txt + "\n";
txt = txt + "固定特征\n\n";
txt = txt + "Type:\t\t 标志是本地的Floy还是入侵者,缺省情况下,红色代表入侵者\n";
txt = txt + "Color:\t\t Floy的颜色,对于标志每个不同的Floy很有用\n";
txt = txt + "No. of Neighbors:\t Floy的邻居个数\n";
txt = txt + "Mutation Factor:\t 被变异操作改变基因的概率\n";
txt = txt + "Crossover Factor:\t 被交叉操作改变基因的概率(一般情况下是1)\n";
txt = txt + "Energy Level:\t 一种动态的属性,当与异类交互的时候起作用\n";
txt = txt + "Safety Level:\t 一种动态属性,在与邻居的交互中起作用\n";
txt = txt + "Cooperation Level:\t 一种依赖于上一代群体的属性\n";
txt = txt + "Fitness Level:\t 整体的适应度,是上面个参数的一个加权平均。\n";
txt = txt + "\n";
txt = txt + "环境属性\n\n";
txt = txt + "Population Size:\t 群体中Floy的数量\n";
txt = txt + "Slowdown Factor:\t 控制移动速度快慢的延迟因子\n";
txt = txt + "Energy Factor:\t 在适应度函数中能量项的权重\n";
txt = txt + "Safety Factor:\t 在适应度函数中安全性的权重因子\n";
txt = txt + "Cooperation Factor:\t 在适应度函数重合作度的权重\n";
txt = txt + "Max. Energy Dose:\t Floy一次赢得或者丢失的最大能量值\n";
txt = txt + "Max. Safety Dose:\t Floy一次赢得或者丢失的最大安全度值\n";
txt = txt + "Max. Coop, Dose:\t Floy一次赢得或者丢失的最大合作度值\n";
txt = txt + "Survivers Percent:\t 幸存到下一代的当前代中的百分比\n";
txt = txt + "Free Will Factor:\t 行为随机性的程度 \n";
txt = txt + "Stranger Life Span:\t 当一个入侵者诞生的时候赋予它的能量.\n";
txt = txt + "\n\n键盘功能\n";
txt = txt + "当程序获得焦点的时候有效(点击程序中的任意区域都能让它获得焦点)\n\n";
txt = txt + "F1:\t 显示帮助\n";
txt = txt + "F2:\t 显示日志记录\n";
txt = txt + "F3:\t 重置纪录(清空日志)\n";
txt = txt + "F4:\t 停止纪录\n";
txt = txt + "F5:\t 重新开始纪录\n";
txt = txt + "F6:\t 设定一次变异操作\n";
txt = txt + "\n\nNetscape和IE浏览器的区别\n\n";
txt = txt + "Netscape 3.0 and Explorer 3.0 browsers (for Windows 95) behave differently in some respects\n";
txt = txt + "Here are a few points that I noticed, and are relevant to the Floys applet\n";
txt = txt + "\n";
txt = txt + "1. The applet runs faster on Explorer. Adjust by the Slower and Faster buttons (clicking several times)\n";
txt = txt + "2. Context sensitive help for each button is displayed in Netscape's status bar but not in Explorer's\n";
txt = txt + "3. Scrollbars (in the Info screen) behave differrently in the two browsers\n";
txt = txt + "4. The Help and Log screens are closed in Netscape, but not in Explorer. You can minimize them instead\n";
txt = txt + "5. Colored labels are displayed colored in Netscape, black in Explorer\n";
txt = txt + "\n";
win.showMsg(txt);
}
void CreateRules(EfloyLog win) {
int i;
String txt;
win.ta.setForeground(Color.black);
win.ta.setFont(new Font("TimesRoman",Font.BOLD,12));
win.clear();
txt = "";
txt = txt + "Floy的本能行为\n";
txt = txt + "\n";
txt = txt + "Floy的行为受两条规则的控制:\n";
txt = txt + "\t1. 一条规则制订了它是如何与同类交互的.\n";
txt = txt + "\t2. 一条规则限制了它如何应对异类.\n";
txt = txt + "\n";
txt = txt + "1. 如何应付自己的同类:\n";
txt = txt + "\t找出两个你身边的同类尽量去靠近但也不要靠得太近.\n";
txt = txt + "\n";
txt = txt + "2. 如何应付异类:\n";
txt = txt + "\t如果在你的疆土里面:\n";
txt = txt + "\t\t如果你发现了一个入侵者就尾随它直到足够靠近了就进攻!\n";
txt = txt + "\t如果你不在自己的疆土里:\n";
txt = txt + "\t\t如果本土的Floy追逐你了你就赶快逃跑。\n";
txt = txt + "\n\n";
txt = txt + "奖赏或惩罚规则\n";
txt = txt + "(适应度函数是能量值与安全度的加权平均值)\n";
txt = txt + "\n";
txt = txt + "打击入侵者:\t\t\t 能量值增加\n";
txt = txt + "快速移动:\t\t\t能量值减少\n";
txt = txt + "被本地的floy袭击了:\t\t 能量值减少\n";
txt = txt + "与邻居尽量保持接近:\t 安全度增加\n";
txt = txt + "\n\n";
txt = txt + "如何使用本程序\n";
txt = txt + "\n";
txt = txt + "1. 调整整体的移动速度\n";
txt = txt + "\t开始的移动应该尽量的光滑平静\n";
txt = txt + "\t多次点击Slower或者Faster来使得整体移动得尽量平缓\n";
txt = txt + "\n";
txt = txt + "2. 关于每一代的操作\n";
txt = txt + "\n";
txt = txt + "\t加入一个入侵者,观察其它的本地居民是如何追逐进攻它的\n";
txt = txt + "\t可怜的入侵者的叫喊声意味着它被干掉了\n";
txt = txt + "\n";
txt = txt + "\t点击'Edit Properties'按钮来修改环境或者特征\n";
txt = txt + "\t点击 'UpdateAll'来把当前编辑的属性应用到当前这一代的整体成员中\n";
txt = txt + "\t(可选的)增加一个入侵者\n";
txt = txt + "\n";
txt = txt + "\t点击 'Edit Properties' 给每一个或每几个Floy赋予特征\n";
txt = txt + "\t急得给不同的floy赋予不同的颜色以便我们能辨认出它们来\n";
txt = txt + "\t对每个floy点击Update按钮\n";
txt = txt + "\t(可选的)增加一个入侵者\n";
txt = txt + "\n";
txt = txt + "\n";
txt = txt + "3. 关于进化的操作\n";
txt = txt + "\n";
txt = txt + "\t定义适应度函数\n";
txt = txt + "\t点击 'Edit Properties'来分配能量值和安全度的权重\n";
txt = txt + "\t如果能量权重更高那么就意味着floy的进化朝着更勇敢更敏捷的方向进行。\n";
txt = txt + "\t如果安全权重越高就意味着进化朝向floy们更加的谨慎并且更加的抱团的方向进行\n";
txt = txt + "\n";
txt = txt + "\t开始一个多样化随机化新代\n";
txt = txt + "\t点击'Scramble' 多次. 每一次都能够使得每一代更加多样化\n";
txt = txt + "\t点击 'Start Evolution'\n";
txt = txt + "\n";
txt = txt + "\t或者开始一个混同的新代\n";
txt = txt + "\t使用默认的一代或者你在属性编辑中选择了updateAll的按钮\n";
txt = txt + "\t在这种情况下进化会更慢因为每次仅仅有变异来引起进化的可能性n\n";
txt = txt + "\t点击'Start Evolution'\n";
txt = txt + "\n";
txt = txt + "\t或开始一个受控制的一代\n";
txt = txt + "\t使用你开始给每个floy赋予的特征再让它们进化\n";
txt = txt + "\t点击 'Start Evolution'\n";
txt = txt + "\n";
txt = txt + "\n";
txt = txt + "4.如何使用按钮\n";
txt = txt + "\t点击任意一个按钮观察发生什么现象s\n";
txt = txt + "\t或者察看帮助(点击 'Show Help')\n";
txt = txt + "\n";
win.showMsg(txt);
}
void KickAll() {
//让所有个体变异
int i;
for (i=0;i<Efloys.length;i++) {
Efloys[i].mutate();
}
beep.play();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -