Shape add fillCells method

pull/1/head
drinkjava2 5 years ago
parent 261576dd14
commit 0ace11050a

@ -95,7 +95,7 @@ public class Frog {
}
/** Calculate organ activity by add all organ rooms' active value together */
public float getCuboidTotalValues(Cuboid o) {// 遍历长方体区域所在room将它们的激活值汇总返回
public float getCuboidActiveTotalValue(Cuboid o) {// 遍历长方体区域所在room将它们的激活值汇总返回
float activity = 0;
for (int x = o.x; x < o.x + o.xe; x++)
for (int y = o.y; y < o.y + o.ye; y++)
@ -112,9 +112,15 @@ public class Frog {
return false;
}
energy -= 20;
for (Organ o : organs) {
for (Organ o : organs)
o.active(this); // 调用每个器官的active方法 通常只用于执行器官的外界信息输入、动作输出,脑细胞的遍历不是在这一步
}
// 这里是最关键的脑细胞主循环,脑细胞负责捕获和发出光子,光子则沿它的矢量方向每次自动走一格,如果下一格是真空(即数组room元素未初始化会继续走下去并衰减(为减少运算)直到能量为0
for (int i = 0; i < Env.FROG_BRAIN_XSIZE; i++)
for (int j = 0; j < Env.FROG_BRAIN_YSIZE; j++)
for (int k = 0; k < Env.FROG_BRAIN_ZSIZE; k++) {
//TODO 脑细胞主循环
}
return alive;
}

@ -79,7 +79,7 @@ public class BrainPicture extends JPanel {
public void drawCone(Cone c) {// 在脑图上画一个锥体视角是TopView
drawLine(c.x1, c.y1, c.z1, c.x2, c.y2, c.z2);// 画锥体的中心线
//TODO画出锥体的上下面
//TODO 画出锥体的上下面
}
/*-

@ -30,11 +30,12 @@ package com.github.drinkjava2.frog.brain;
*/
public class Cell {// Cell是脑神经元将来脑里会有上亿个脑细胞为节约内存不重要的、与细胞状态无关的参数都存放在Organ类中去了。
/** energy of cell, energy got from food */
public float energy; // 每个细胞当前的能量值
public Cell(Organ organ) {// Cell不保存在蛋里不需要定义空构造器
this.organ = organ;
}
/** tire value of cell */
public float tire; // 每个细胞的疲劳值,只取决于最近的激活频率
/** energy of cell, energy got from food */
public float energy = 0; // 每个细胞当前的能量值
/** Organ index in egg */
public Organ organ; // 细胞属于哪个器官

@ -22,31 +22,25 @@ import com.github.drinkjava2.frog.Frog;
*/
public class CellActions {
/**
/*-
* Each cell's act method will be called once at each loop step
*
* actact
* )
*
*
* 穿穿()
*
* 线()(沿线)
* +
*
*
*/
public void act(Frog f, int type, Cell cell, int x, int y, int z) {
switch (type) { // TODO 待添加细胞的行为,这是硬编码
case 0:
// 一对一,穿透,光子会穿过细胞,细胞起到中继站的作用,如果没有细胞中继,光子在真空中传播(即三维数组的当前坐标没有初始化,为空值)会迅速衰减
break;
case 1:
// 一对一,转向,光子传播角度被改变成另一个绝对角度发出
break;
case 2:
// 一对一,转向,光子传播角度被改变成与器官有关的角度发出,可以模拟光线的发散(如视网膜细胞)和聚焦(如脑内成像,即沿光线发散的逆路径)
break;
case 3:
// 一对多,拆分,入射光子被拆分成多个光子,以一定的发散角发出,通常发散光子的总能量小于入射+细胞输出能量之和
break;
case 4:
// 一对多,拆分,入射光子被拆分成多个光子,发散角与器官相关
case 5:
// 多对一,聚合,入射光子被触突捕
switch (type) { //添加细胞的行为,这是硬编码
case Organ.EYE:
break;
default:
break;

@ -10,6 +10,8 @@
*/
package com.github.drinkjava2.frog.brain;
import com.github.drinkjava2.frog.Frog;
/**
* Cone represents a cone 3d zone in brain
*
@ -52,4 +54,9 @@ public class Cone implements Shape {
pic.drawCone(this);
}
@Override
public void fillCells(Frog f, Organ o) {
// TODO 待添加Cone形器官播种脑细胞的代码
}
}

@ -10,6 +10,8 @@
*/
package com.github.drinkjava2.frog.brain;
import com.github.drinkjava2.frog.Frog;
/**
* Cuboid represents a rectangular prism 3d zone in brain
*
@ -55,4 +57,14 @@ public class Cuboid implements Shape {
public void drawOnBrainPicture(BrainPicture pic) {
pic.drawCuboid(this);
}
@Override
public void fillCells(Frog f, Organ o) {
for (int i = x; i < x + xe; i++)// 这是具体的播种脑细胞代码,先忽略密度分布等参数
for (int j = y; j < y + ye; j++)
for (int k = z; k < z + ze; k++) {
f.getRoom(i, j, k).addCell(new Cell(o));
}
}
}

@ -53,18 +53,29 @@ import com.github.drinkjava2.frog.util.RandomUtils;
public class Organ implements Serializable, Cloneable {// 因为要保存在蛋文件里,所以必须支持串行化
private static final long serialVersionUID = 1L;
public float fat = 0;// 细胞活跃多则fat值大如果fat值很低则这个器官被丢弃的可能性加大这个值很重要它使得孤岛器官不存在,保证所有器官都相连
// 以下是各种器官类型每个神经元都属于一个器官每个器官都有一个type类型参数
public static final int EYE = 1;// 眼细胞会根据room激活度产生发散到各个方向的光子
public static final int EAR = 2;// 耳细胞,类似眼细胞,不同点是为了简化脑内听觉区和输入区混用一个区所以它也可吸收光子倒过来激活room
public static final int CORE = 3; // 什么触突都没有光溜溜的细胞但它也有可能根据r半径来中转光子
public static final int DYNAMIC = 4; // 只有动态触突的细胞,它忽略静态触突参数
public static final int STATIC = 5; // 只有静态触突的细胞,它忽略动态触突参数
public static final int MIX = 6; // 同时具有静态和动态触突的细胞
public static final int TYPE_QTY = 7;// 所有的type都是预先写好在这里的自动生成的type也只能在写好的type里选一个
public float fat = 0;// 细胞活跃多则fat值大如果fat值很低则这个器官被丢弃的可能性加大这个值很重要它使得孤岛器官被淘汰
public boolean allowVary;// 是否允许变异,有一些器官是手工创建的,在项目初级阶段禁止它们参与变异和生存竟争。
public boolean allowBorrow;// 是否允许在精子中将这个器官借出,有一些器官是手工创建的,在项目初级阶段禁止它们借出
public String organName;// 器官的名字通常只有手工创建的器官才有名字可以用frog.findOrganByName来查找到这个器官
// ======= 本行以下所有参数受变异和生存竟争影响 =============
public int type; // 器官类型, 这是个最重要参数,它决定器官的播种行为、脑细胞的形状及行为, 这个字段如果变异,将极大地改变器官的性质
public int type; // 器官类型,见上面的常量定义,这个字段通常很稳定。一旦变异,将从根本上改变器官的播种行为和神经元的行为
public Shape shape; // 器官的形状
public Shape shape; // 器官的形状,不同的形状要写出不同的播种行为
public float cellDistance; // 细胞播种间隔,它决定了播种密度。目前只有均匀播种这一个方案
public float cellDistance; // 细胞播种间隔每隔多少个room放一个细胞
public float centerDensityRate; // 中心相对于边沿的细胞播种密度比为1时为均匀分布
public int synapsesLimit;// 细胞允许创建动态触突的数量上限详见Cell类的synapses字段
@ -80,7 +91,7 @@ public class Organ implements Serializable, Cloneable {// 因为要保存在蛋
public float radius;// 细胞即使没有触突也可以处理光子这个radius是细胞的管辖半径但处理信号角度只限于穿透和反射或6个正方向
public float dropRate;// 是一个介于0~1的值反映了细胞存的能量下降速率,在每一步长中细胞能量都以这个速率损失,可以参考遗忘曲线
public float dropRate;// 是一个介于0~1的值反映了细胞存贮能量的下降速率,在每一步长中细胞能量都以这个速率损失,可以参考遗忘曲线
// =====注意以下三个字段可以让细胞具备一些无状态的触突这个不占内存但缺点是不灵活不智能详见与Cell类中动态触突的对比 =====
public Synapse[] inputs; // 输入触突,位置是相对细胞而言的
@ -92,6 +103,7 @@ public class Organ implements Serializable, Cloneable {// 因为要保存在蛋
allowBorrow = true;
type = 0;
cellDistance = 1;
centerDensityRate = 1;
synapsesLimit = 10;
energyLimit = 100;
outputRate = 30;
@ -109,9 +121,11 @@ public class Organ implements Serializable, Cloneable {// 因为要保存在蛋
public Organ[] vary(Frog f) { // 器官变异仅会在青蛙下蛋时即new Egg(frog)中被调用一次,返回本身或变异后的一个或一组类似器官返回
if (!allowVary)
return new Organ[] { this };// 如果不允许变异,器官就把自身返回,存放在蛋里
type = RandomUtils.vary(type);// 随机有大概率小变异,小概率大变异,极小概率极大变异
// 各参数 随机有大概率小变异,小概率大变异,极小概率极大变异
type = RandomUtils.vary(type, 10);// 这个type通常不允许变所以只给它10%的机率去变, 也就是说在正常变异概率上再乘以10%的变异可能性
shape = RandomUtils.vary(shape);
cellDistance = RandomUtils.vary(cellDistance);
centerDensityRate = RandomUtils.vary(centerDensityRate);
synapsesLimit = RandomUtils.vary(synapsesLimit);
energyLimit = RandomUtils.vary(energyLimit);
outputRate = RandomUtils.vary(outputRate);
@ -128,17 +142,18 @@ public class Organ implements Serializable, Cloneable {// 因为要保存在蛋
/** Only call once when frog created , Child class can override this method */
public void init(Frog f) { // 在青蛙生成时会调用这个方法,进行一些初始化,通常是根据参数来播种脑细胞
// 这里是各种形状器官播种脑细胞的具体代码,目前只有长方体和锥体两种形状
// 这里是器官播种脑细胞的具体代码,对于手工生成的器官可以重写这个方法对于自动生成的器官必须根据type和shape等来播种要写死在这里
}
/** each step will call Organ's active methodd */
public void active(Frog f) { // 每一步测试都会调用active方法通常用于手动生成的器官
public void active(Frog f) { // 每一步测试都会调用active方法通常用于手动生成的器官,自动生成的器官其行为仅由脑细胞来决定
// do nothing
}
/** Child class can override this method to drawing picture */
public void drawOnBrainPicture(Frog f, BrainPicture pic) { // 把器官的轮廓显示在脑图上
if (shape == null)
return;// 如果没有形状,就不画
if (!Env.SHOW_FIRST_FROG_BRAIN || !f.alive) // 如果不允许画或青蛙死了,就直接返回
return;
pic.setPicColor(Color.LIGHT_GRAY); // 缺省是黑色

@ -24,7 +24,7 @@ import java.util.Arrays;
*/
public class Room {
/** Activity of current room */
private float active = 0; // 这个立方体的激活程度,允许是负值,它反映了在这个小立方体里所有光子的能量汇总值
private float active = 0; // 这个立方体的激活程度,允许是负值,它反映了在这个小立方体里所有光子的能量汇总值,room总是随时间自动衰减
private Cell[] cells = null;

@ -12,6 +12,8 @@ package com.github.drinkjava2.frog.brain;
import java.io.Serializable;
import com.github.drinkjava2.frog.Frog;
/**
* Shape represents a 3d zone in brain
*
@ -22,5 +24,7 @@ import java.io.Serializable;
*/
public interface Shape extends Serializable {
/* Draw self on brain picture */
public void drawOnBrainPicture(BrainPicture pic);
public void drawOnBrainPicture(BrainPicture pic); //把自己在脑图上画出来
public void fillCells(Frog f, Organ o); //根据给定organ的参数在shape所代表的脑区内播种脑细胞
}

@ -36,7 +36,7 @@ public class Ear extends Organ {// 耳朵也是长方体,我为什么要用也
this.shape = new Cuboid(10, 10, Env.FROG_BRAIN_ZSIZE - 1, 8, 8, 1);
this.organName = "ear";
this.allowVary = false;
this.allowBorrow=false;
this.allowBorrow = false;
}
public void drawOnBrainPicture(Frog f, BrainPicture pic) {// 把自已这个器官在脑图上显示出来,子类可以重写这个方法
@ -47,6 +47,10 @@ public class Ear extends Organ {// 耳朵也是长方体,我为什么要用也
pic.drawCuboid(d);
}
public void init(Frog f) { // 重写父类方法,播种听力输入细胞,它会将听力区的激活转变成固定向下发散的多个光子,摸拟波源
shape.fillCells(f, this);
}
/** 给这个耳朵听到一个字母,激活它的听觉输入区, 注意听觉输入区并不等于脑内虚拟听觉成像区,但是第一版...先共用一个区吧 */
public void hearSound(Frog f, String letter) {
f.setCuboidVales(getCuboidByStr(letter), 20);

@ -0,0 +1,53 @@
/*
* Copyright 2018 the original author or authors.
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by
* applicable law or agreed to in writing, software distributed under the
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
* OF ANY KIND, either express or implied. See the License for the specific
* language governing permissions and limitations under the License.
*/
package com.github.drinkjava2.frog.brain.organ;
import com.github.drinkjava2.frog.Env;
import com.github.drinkjava2.frog.Frog;
import com.github.drinkjava2.frog.brain.Cell;
import com.github.drinkjava2.frog.brain.Cuboid;
import com.github.drinkjava2.frog.brain.Organ;
/**
* Ether is a special organ, it fill all rooms with dynamic type cells
*
* Ether)roomdynamic
*
* ()
* 穿
*
*
* OutofMemoryException),
*
*
* @author Yong Zhu
*/
public class Ether extends Organ {
private static final long serialVersionUID = 1L;
public Ether() {
super();
this.shape = new Cuboid(0, 0, 0, Env.FROG_BRAIN_XSIZE, Env.FROG_BRAIN_YSIZE, Env.FROG_BRAIN_ZSIZE);
this.organName = "Ether";
this.type = Organ.DYNAMIC;
this.allowVary = false;
this.allowBorrow = false;
}
public void init(Frog f) { // 重写父类方法,均匀播种脑细胞
for (int x = 0; x < Env.FROG_BRAIN_XSIZE; x++)
for (int y = 0; y < Env.FROG_BRAIN_YSIZE; y++)
for (int z = 0; z < Env.FROG_BRAIN_ZSIZE; z++) {
f.getRoom(x, y, z).addCell(new Cell(this));
}
}
}

@ -21,7 +21,6 @@ import com.github.drinkjava2.frog.brain.Organ;
*/
public class Eye extends Organ {// 眼睛是长方体
private static final long serialVersionUID = 1L;
public int n = 18; // 眼睛有n x n个感光细胞 用随机试错算法自动变异(加1或减1最小是3x3)
public Eye() {
this.shape = new Cuboid(0, 5, 5, 1, 10, 10);
@ -30,6 +29,15 @@ public class Eye extends Organ {// 眼睛是长方体
this.allowBorrow = false;
}
public void init(Frog f) { // 重写父类方法,播种视网膜细胞,它会将视网膜的激活转变成固定向右发散的多个光子,摸拟波源
shape.fillCells(f, this);
}
/** each step will call Organ's active methodd */
public void active(Frog f) { // 每一步测试都会调用active方法通常用于手动生成的器官
// do nothing
}
/**
* Accept a byte[x][y] array, active tubes located on eye's retina
*

@ -57,9 +57,9 @@ public class LetterTester implements EnvObject {
} else if (Env.step == Env.STEPS_PER_ROUND / 2) {// 在中段取消字母对应脑区的激活
ear.hearNothing(firstFrog);
} else if (Env.step > Env.STEPS_PER_ROUND / 2) {// 后半段要检测这个字母区是否能收到光子信号
if (firstFrog.getCuboidTotalValues(ear.getCuboidByStr(letter)) > 0)
if (firstFrog.getCuboidActiveTotalValue(ear.getCuboidByStr(letter)) > 0)
firstFrog.energy += 100;
//TODO 然后还要检测其它的区必须没有这个字母的区活跃
//TODO 然后还要检测其它的区必须没有这个字母的区活跃
}
}

@ -81,20 +81,48 @@ public class RandomUtils {
return c;
}
public static int vary(int i) {// 随机有大概率小变异,小概率大变异,极小概率极大变异
return i;
public static int vary(int v, int percet) {
if (percent(percet))
return vary(v);
return v;
}
public static float vary(float f) {// 随机有大概率小变异,小概率大变异,极小概率极大变异
return f;
public static int vary(int v) {// 随机有大概率小变异,小概率大变异,极小概率极大变异
if (percent(40))
v *= .98 + .04 * nextFloat(); // 0.98~1.02
if (percent(10))
v *= .95 + .103 * nextFloat(); // 0.95~1.053
else if (percent(5))
v *= .08 + 0.45 * nextFloat(); // 0.8~1.25
else if (percent(1))
v *= .05 + 1.5 * nextFloat(); // 0.5~2
return v;
}
public static float vary(float v, int percet) {
if (percent(percet))
return vary(v);
return v;
}
public static float vary(float v) {// 随机有大概率小变异,小概率大变异,极小概率极大变异
if (percent(40))
v *= .98 + .04 * nextFloat(); // 0.98~1.02
if (percent(10))
v *= .95 + .103 * nextFloat(); // 0.95~1.053
else if (percent(5))
v *= .08 + 0.45 * nextFloat(); // 0.8~1.25
else if (percent(1))
v *= .05 + 1.5 * nextFloat(); // 0.5~2
return v;
}
public static Shape vary(Shape shape) {// 随机有大概率小变异,小概率大变异,极小概率极大变异
return shape;
return shape; // TODO shape的变异
}
public static Synapse[] vary(Synapse[] synapses) {// 随机有大概率小变异,小概率大变异,极小概率极大变异
return synapses;
return synapses; // TODO synapses的变异
}
}

@ -7,10 +7,13 @@ LongFer
张老湿
王二麻子
封尘
目前收入总额:118.88元
陈秋华
hl330
陈凯文
目前收入总额:168.77元
支出(按时间顺序)
目前支出总额:0元
目前支出总额:0元
目前余额118.88
目前余额168.77

@ -82,9 +82,4 @@ git reset --hard ae34b07e 可以转回到2019-08-04提交的分组测试的找
开始进行3D脑的实际编程。
### 2019-9-09 到 2019-10-06 之间的6次提交
主要进行脑框架的显示和字母试别测试环境的搭建还没开始进行利用器官进行脑细胞播种的工作。这一阶段基本思路是在每一轮的测试过程前半段随机显示ABCD其中的一个字母(即激活视网膜所在的脑区),并同时激活一个任意脑区。在下半段则只激活这个字母的点阵,然后检测对应的这个脑区是否也会激活,如果激活的话,将会增加青蛙的能量值,让它在生存竟争中胜出,这一步是要完成基本的模式识别功能,框架已搭好,但器官的随机生成还没进行,这一步比较复杂,除了器官的大小位置等参数外,神经元的参数也多,比方说输入、输出光子的方向、正负、数量,能量吸收、释放比例,输入输出阀值、疲劳值、疲劳阀值等,这么多参数要利用随机生成器官的方式来筛选,需要的样本数量多,运行时间会比较长。早期是视网膜和识别区在脑长方体的同一侧,后来的提交改为将视网膜移到左侧,也就是说视觉与识别区(对应耳朵的语音区)在物理上呈90度正交以方便观察和编程。
### 2019-10-06 到 2019-10-21 之间的几次提交
正在进行器官的随机生成、变异和脑细胞播种的编码,尚未完成,初步设想是先不要有固定方向的触突,纯粹用动态触突和随机器官生成试试,看看只用一两个器官是否能生成模式识别能力,即模仿出波驻点逆向成像现象。
主要进行脑框架的显示和字母试别测试环境的搭建还没开始进行利用器官进行脑细胞播种的工作。这一阶段基本思路是在每一轮的测试过程前半段随机显示ABCD其中的一个字母(即激活视网膜所在的脑区),并同时激活一个任意脑区。在下半段则只激活这个字母的点阵,然后检测对应的这个脑区是否也会激活,如果激活的话,将会增加青蛙的能量值,让它在生存竟争中胜出,这一步是要完成基本的模式识别功能,框架已搭好,但器官的随机生成还没进行,这一步比较复杂,除了器官的大小位置等参数外,神经元的参数也多,比方说输入、输出光子的方向、正负、数量,能量吸收、释放比例,输入输出阀值、疲劳值、疲劳阀值等,这么多参数要利用随机生成器官的方式来筛选,需要的样本数量多,运行时间会比较长。早期是视网膜和识别区在脑长方体的同一侧,后来的提交改为将视网膜移到左侧,也就是说视觉与识别区(对应耳朵的语音区)在物理上呈90度正交以方便观察和编程。
Loading…
Cancel
Save