Add history\005a1_letter_test folder

This commit is contained in:
yong 2021-08-14 00:22:22 -06:00
parent df7cdaee47
commit 278918bc59
70 changed files with 2167 additions and 182 deletions

View File

@ -139,6 +139,10 @@ Frog: 这是人工生命的主体,目前起名叫青蛙(Frog),其实叫什
![result11](result11_letter_test.gif)
这两个模式的基本原理是基于信号的反向传播,如果一个细胞的两个或多个不同方向同时(或短期内)收到信号,今后只要有一个信号传入,这个细胞将会向其它方向反向发送激活信号。这个模式识别原理非常简单,功能也比较原始,对于变形、扭曲、缩放、缺损的信号识别率很差,但考虑到实现这些功能的复杂性,我近期不打算进一步改进它了,而是打算另起炉灶,用三维空间的细胞分裂+遗传算法的模式,试试看能不能让电脑自动演化出具有简单模式识别功能的模拟生命体,也就是说实现上面发布的任务。
2021-08-13 演示同时处理多个方向的信号
位于history\005a1目录下演示用5个声母和5个韵母的组合来关联到25个图像的识别这样可以减少声音输入区的数量。它的另一个目的是演示体全息存贮的工作模式可以同时处理多个方向的信号。这个演示分辨率极差只有约一半的识别率但我不打算继续改进了。
![result12](result12_letter_test2.png)
## 运行方式 | Run
运行history各个子目录下的run.bat批处理文件即可启动运行history下有多个子目录按时间和版本号顺序按列存放着这个项目演化过程中的主要历史版本供演示。

View File

@ -100,6 +100,38 @@ The shortcut keys for all brain maps are: T: top view F: front view L: left view
![result9](result9_earthquake.gif)
Detailed explanation: The simulation environment of this topic is simplified into two areas on the left and right. When an earthquake occurs (indicated by a red box), all frog energy will be deducted, but only the frog on the left can see the occurrence and stop of the earthquake. The frogs in the right side cannot see the occurrence and stop of the earthquake, but the frogs have articulators and listening organs. If the frog on the left makes a call, it can be heard by the frog on the right. The 6 organs that saw an earthquake occur, saw the earthquake stop, made a call, heard a call, jumped, and landed, corresponded to 6 organs and all evolved accidentally (this does not need to be proved). The purpose of this experiment is to verify Will the frog be forced by the environment to form neural connections among the brain cells corresponding to these six organs? It can be seen that after seeing the earthquake, the frog on the left jumped in the air (indicated by yellow) and made a call, and then the frog on the right also jumped in the air after hearing the call. The frog on the left transmits information to the frog on the right through the call signal, so that the frog on the right avoids its invisible earthquake damage. This is a demonstration of successful group evolution. It proves that even if the nerve cell lines are randomly generated, the biological pronunciation-listening function can be evolved, that is to say, the initial language function can be evolved.
2021-05-15 Demonstration of cell division
This is a small task I posted in the WeChat group. Before I had time to update it here, the pama_1234 in the group was made. The programming speed is not that fast. By the way, he is only a freshman now. After the waves are so experienced.
The task is very simple, just draw a snake like the picture below and win. Require:
1. The small snake has at least 30x30 pixels and has eyes and tongue. Anyway, it looks like a snake at first glance. It is best not to draw feet (Note: So the feet are not drawn, but the corners are drawn).
2. Requires the use of genetic algorithm and split algorithm. Everyone knows about genetic algorithm. Splitting algorithm I only have a general idea right now, which is to imitate cell division to evolve different shapes. Splitting can be to push other cells away, or it can be split only at the edge to reduce the amount of calculation, this is not limited.
3. It is also possible to draw Chinese characters for "snake" and "frog"
The prizes are not planned for the time being, but they will definitely be placed on the project homepage. This task does not seem to have much to do with neural networks, but I think it is possible to use this algorithm to automatically arrange organs, so it still has a certain meaning. Arbitrary complex shapes are generated, and the cell structure of the three-dimensional brain will be possible in the future. Evolved from this task.
Output result ((written by pama_1234):
![result10](result10_drawsnake.gif)
His project is located here: [Cell Painting Snake](https://gitee.com/pama1234/cell-painting-snake), if you are interested in studying the source code, you can take a look. It is based on Processing.
By the way, I also wrote my idea here. I did not study his code carefully, but it is estimated that the idea should be roughly the same:
1. Genes related to shape expression use a polytree structure data structure. The tree structure is a singleton, and only one copy is stored in the memory. After each cell divides, the telomerase is reduced by one, which is equivalent to walking down the tree structure. One level.
2. After each cell is divided, in order to obtain the position of the current cell, but the entire subtree cannot be copied, it is necessary to save a pointer to the current node of the tree, that is, the vertex of the subtree. Nodes that are no longer split may not save node pointers.
3. The gene tree is generally stable, but there is a large probability of small changes, and a small probability of large changes. The changes of the gene tree include the number of repetitions, the direction of bifurcation, and the number of bifurcations.
4. Because it is a polytree, it can start at any point as a fertilized egg to split, and finally can form a specified pattern.
The task of drawing a snake itself is very simple. It is a task of filling color blocks. It can be done in less than half a second with the drawing brush in the window. The reason why we should treat it as a task and limit the way of cell division. Its because natures solution is not a human-designed algorithm, but only one trick is random cell division, inheritance, and mutation. Now it seems that this division simulation is relatively easy to implement, which roughly explains the various organisms in nature. Reasons for morphogenesis.
2021-05-15 By the way, release the next development task: frogs eat mushrooms
1. Frogs should distinguish poisonous and non-toxic mushrooms according to different paintings. Mushrooms are represented by randomly generating ten different mushroom patterns. Half of these mushrooms are non-toxic and the other half are poisonous.
2. To use volume holographic storage or surface holographic storage solutions for pattern recognition. For volume holographic storage, please refer to the 005_letter_test example; the surface holographic storage scheme can refer to the laser holographic storage scheme. The difference from volume holography is that the information is stored on a plane instead of in a three-dimensional room. The same point is the use of incident light and outgoing light position information. For storage and reading, the incident light and the outgoing light are reference signals for each other.
3. To proceed under the existing Java project interface, that is to say, to display the virtual environment and mind map, the source file name must be .java suffix. This is different from the cell division demonstration. This task is the main task of the project.
4. Whether mushrooms are poisonous or non-toxic is related to the pattern, but whether they are poisonous or non-toxic must be automatically judged by the frog during the evolution process. A poisonous signal cannot be artificially set to tell the frog (the signal between frogs is not here. limit). The sign of the completion of the mission is that the frogs must be able to evolve to eat all the non-toxic mushrooms in the virtual environment and avoid all the poisonous mushrooms.
2021-07-04 is still a pattern recognition demonstration
Two new branch directories, history\005a and 005b, were added to demonstrate the use of improved volume holographic storage solutions and surface holographic storage solutions for pattern recognition. It is possible to associate 25 arbitrary graphics with its corresponding sound signal area:
![result11](result11_letter_test.gif)
The basic principle of these two modes is based on the back propagation of signals. If two or more different directions of a cell receive signals at the same time (or within a short period of time), as long as there is one signal coming in in the future, this cell will transmit to other cells. The activation signal is sent in the reverse direction. The principle of pattern recognition is very simple, and the function is relatively primitive. The signal recognition rate for deformation, distortion, scaling, and defect is very poor. However, considering the complexity of implementing these functions, I do not plan to further improve it in the near future, but plan to start anew. , Using the three-dimensional cell division + genetic algorithm model, try to see if the computer can automatically evolve a simulated life form with simple pattern recognition function, that is to say, achieve the tasks posted above.
2021-08-13 Demonstrate the simultaneous processing of signals in multiple directions
Located in the history\005a1 directory, the demonstration uses a combination of 5 initials and 5 finals to associate with the recognition of 25 images, which can reduce the number of voice input areas. Its other purpose is to demonstrate that the working mode of volume holographic storage can process signals in multiple directions at the same time. The resolution of this demo is very poor, only about half of the recognition rate, but I do not intend to continue to improve.
![result12](result12_letter_test2.png)
## License
[Apache 2.0] (http://www.apache.org/licenses/LICENSE-2.0)

View File

@ -1,4 +1,6 @@
## core\bottom_up目录简介
core\top_down目录下的这个项目基于细胞分裂思路由遗传算法来自动排列脑细胞并引导脑细胞分裂向体全息存贮方案进化最终要实现青蛙的模式识别功能与上下左右运动细胞结合起来实现吃掉无毒蘑菇避开有毒蘑菇这个任务。
## 当前分支简介
这个分支基于细胞分裂思路,由遗传算法来自动排列脑细胞,并引导脑细胞分裂向体全息存贮方案进化,以实现模式识别功能,并与上下左右运动细胞结合起来,实现吃掉无毒蘑菇,避开有毒蘑菇这个任务
进度:正在编程中,未完成, 本次提交只是清空了多余的文件保存了最基本的框架因为是另起炉灶很多以前的类如organ等都删除了而是打算要引入基因树的数据结构。
此目录尚未开始编程

102
core/bottom_up/pom.xml Normal file
View File

@ -0,0 +1,102 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.gitee.drinkjava2</groupId>
<artifactId>frog008</artifactId>
<packaging>jar</packaging>
<version>1.0</version>
<name>frog</name>
<description>这个分支基于细胞分裂思路,由遗传算法来自动排列脑细胞,并引导脑细胞分裂向体全息存贮方案进化,以实现模式识别功能,并与上下左右运动细胞结合起来,实现吃掉无毒蘑菇,避开有毒蘑菇这个任务</description>
<url>https://gitee.com/drinkjava2/jsqlbox/frog</url>
<issueManagement>
<system>gitee Issue</system>
<url>https://gitee.com/drinkjava2/jsqlbox/frog/issues</url>
</issueManagement>
<licenses>
<license>
<name>The Apache Software License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
</license>
</licenses>
<developers>
<developer>
<name>Yong Zhu</name>
<email>yong9981@gmail.com</email>
<url>https://gitee.com/drinkjava2/</url>
</developer>
</developers>
<scm>
<connection>scm:git@gitee.com:drinkjava2/frog.git</connection>
<developerConnection>scm:git@gitee.com:drinkjava2/frog.git</developerConnection>
<url>git@gitee.com:drinkjava2/frog.git</url>
</scm>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
<!-- Release on Java8 -->
<version.java>1.8</version.java>
<version.javadoc>6</version.javadoc>
<version.compiler-plugin>3.3</version.compiler-plugin>
<version.war-plugin>2.6</version.war-plugin>
<version.clean-plugin>3.0.0</version.clean-plugin>
<version.resources-plugin>2.7</version.resources-plugin>
<version.surefire-plugin>2.19</version.surefire-plugin>
<version.jar-plugin>2.6</version.jar-plugin>
<version.source-plugin>2.4</version.source-plugin>
<version.javadoc-plugin>2.10.3</version.javadoc-plugin>
<version.gpg-plugin>1.6</version.gpg-plugin>
</properties>
<dependencies>
<!--dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency-->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${version.compiler-plugin}</version>
<configuration>
<source>${version.java}</source>
<target>${version.java}</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.1.2</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<useUniqueVersions>false</useUniqueVersions>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>com.gitee.drinkjava2.frog.Application</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
</profiles>
</project>

View File

@ -0,0 +1,266 @@
package com.gitee.drinkjava2.frog;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JPanel;
import com.gitee.drinkjava2.frog.egg.Egg;
import com.gitee.drinkjava2.frog.egg.EggTool;
import com.gitee.drinkjava2.frog.objects.EnvObject;
import com.gitee.drinkjava2.frog.objects.Material;
import com.gitee.drinkjava2.frog.util.RandomUtils;
/**
* Env is the living space of frog. draw it on JPanel
*
* @author Yong Zhu
* @since 1.0
*/
@SuppressWarnings("all")
public class Env extends JPanel {
/** Speed of test */
public static int SHOW_SPEED = 1; // 测试速度-1000~1000,可调, 数值越小速度越慢
/** Delete eggs at beginning of each run */
public static final boolean DELETE_EGGS = true;// 每次运行是否先删除保存的蛋
public static final int EGG_QTY = 5; // 每轮下n个蛋可调只有最优秀的前n个青蛙们才允许下蛋
public static final int FROG_PER_EGG = 5; // 每个蛋可以孵出几个青蛙
public static final int SCREEN = 1; // 分几屏测完
public static final int FROG_PER_SCREEN = EGG_QTY * FROG_PER_EGG / SCREEN; // 每屏上显示几个青蛙这个数值由上面三个参数计算得来
/** Frog's brain size is a 3D array of Cell */ // 脑空间是个三维Cell数组为节约内存仅在用到数组元素时才去初始化这维按需分配内存
public static final int FROG_BRAIN_XSIZE = 20; // frog的脑在X方向长度
public static final int FROG_BRAIN_YSIZE = 20; // frog的脑在Y方向长度
public static final int FROG_BRAIN_ZSIZE = 20; // frog的脑在Z方向长度
/** SHOW first frog's brain structure */
public static boolean SHOW_FIRST_FROG_BRAIN = true; // 是否显示脑图在Env区的右侧
/** Draw first frog's brain after some steps */
public static int DRAW_BRAIN_AFTER_STEPS = 1; // 以此值为间隔动态画出脑图设为0则关闭这个动态脑图功能只显示一个静态不闪烁的脑图
/** Environment x width, unit: pixels */
public static final int ENV_WIDTH = 400; // 虚拟环境的宽度, 可调
/** Environment y height, unit: pixels */
public static final int ENV_HEIGHT = ENV_WIDTH; // 虚拟环境高度, 可调通常取正方形
/** Frog's brain display width on screen, not important */
public static final int FROG_BRAIN_DISP_WIDTH = 600; // Frog的脑图在屏幕上的显示大小,可调
/** Steps of one test round */
public static final int STEPS_PER_ROUND = 200;// 每轮测试步数,可调
public static int step;// 当前测试步数
public static final int FOOD_QTY = 100; // 食物数量, 可调
// 以下是程序内部变量不要手工修改它们
public static boolean pause = false; // 暂停按钮按下将暂停测试
public static byte[][] bricks = new byte[ENV_WIDTH][ENV_HEIGHT];// 组成环境的材料见Material.java
public static List<Frog> frogs = new ArrayList<>(); // 这里存放所有待测的青蛙可能分几次测完由FROG_PER_SCREEN大小来决定
public static List<Egg> eggs = new ArrayList<>(); // 这里存放新建或从磁盘载入上轮下的蛋每个蛋可能生成几个青蛙
public static EnvObject[] things = new EnvObject[]{};// 所有外界物体如食物字母测试工具都放在这个things里面
static {
System.out.println("脑图快捷键: T:顶视 F前视 L:左视 R:右视 X:斜视 方向键:剖视 空格:暂停 鼠标:缩放旋转平移");
if (DELETE_EGGS) {
System.out.println("唵缚悉波罗摩尼莎诃!"); // 杀生前先打印往生咒见码云issue#IW4H8
EggTool.deleteEggs();
}
}
public Env() {
super();
this.setLayout(null);// 空布局
this.setBounds(1, 1, ENV_WIDTH, ENV_HEIGHT);
}
public static boolean insideEnv(int x, int y) {// 如果指定点在边界内
return !(x < 0 || y < 0 || x >= ENV_WIDTH || y >= ENV_HEIGHT);
}
public static boolean outsideEnv(int x, int y) {// 如果指定点超出边界
return x < 0 || y < 0 || x >= ENV_WIDTH || y >= ENV_HEIGHT;
}
public static boolean closeToEdge(Frog f) {// 青蛙靠近边界? 离死不远了
return f.x < 20 || f.y < 20 || f.x > (Env.ENV_WIDTH - 20) || f.y > (Env.ENV_HEIGHT - 20);
}
public static boolean foundAnyThing(int x, int y) {// 如果指定点看到任意东西或超出边界
return x < 0 || y < 0 || x >= ENV_WIDTH || y >= ENV_HEIGHT || Env.bricks[x][y] >= Material.VISIBLE;
}
public static boolean foundAndAteFood(int x, int y) {// 如果x,y有食物将其清0返回true
if (insideEnv(x, y) && Env.bricks[x][y] == Material.FOOD) {
bricks[x][y] = 0;
return true;
}
return false;
}
private void rebuildFrogs() {
frogs.clear();
for (int i = 0; i < eggs.size(); i++) {// 创建青蛙每个蛋生成n个蛙并随机取一个别的蛋作为精子
int loop = FROG_PER_EGG;
if (eggs.size() > 20) { // 如果数量多进行一些优化让排名靠前的Egg多孵出青蛙
if (i < FROG_PER_EGG)// 0,1,2,3
loop = FROG_PER_EGG + 1;
if (i >= (eggs.size() - FROG_PER_EGG))
loop = FROG_PER_EGG - 1;
}
for (int j = 0; j < loop; j++) {
Egg zygote = new Egg(eggs.get(i), eggs.get(RandomUtils.nextInt(eggs.size())));
frogs.add(new Frog(RandomUtils.nextInt(ENV_WIDTH), RandomUtils.nextInt(ENV_HEIGHT), zygote));
}
}
}
private void drawWorld(Graphics g) {
byte brick;
for (int x = 0; x < ENV_WIDTH; x++)
for (int y = 0; y < ENV_HEIGHT; y++) {
brick = bricks[x][y];
if (brick != 0) {
g.setColor(Material.color(brick));
if (brick == Material.FOOD)
g.fillRoundRect(x, y, 4, 4, 2, 2); // show food bigger
else
g.drawLine(x, y, x, y); // only 1 point
}
}
g.setColor(Color.BLACK);
}
static final NumberFormat format100 = NumberFormat.getPercentInstance();
static {
format100.setMaximumFractionDigits(2);
}
private static int foodFoundAmount() {// 统计找食数等
int leftfood = 0;
for (int x = 0; x < ENV_WIDTH; x++)
for (int y = 0; y < ENV_HEIGHT; y++)
if (bricks[x][y] == Material.FOOD)
leftfood++;
return FOOD_QTY - leftfood;
}
private String foodFoundCountText() {// 统计找食数等
int foodFound = foodFoundAmount();
int maxFound = 0;
for (Frog f : frogs)
if (f.ateFood > maxFound)
maxFound = f.ateFood;
return new StringBuilder("找食率:").append(format100.format(foodFound * 1.00 / FOOD_QTY)).append(", 平均: ").append(foodFound * 1.0f / FROG_PER_SCREEN).append(",最多:").append(maxFound).toString();
}
public static void checkIfPause(Frog f) {
if (pause)
do {
if (f != null) {
Application.brainPic.drawBrainPicture(f);
Application.brainPic.requestFocus();
}
sleep(100);
} while (pause);
}
public static void sleep(long millis) {
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void run() {
EggTool.loadEggs(); // 从磁盘加载egg或新建一批egg
Image buffImg = createImage(this.getWidth(), this.getHeight());
Graphics g = buffImg.getGraphics();
long time0;// 计时用
int round = 1;
do {
rebuildFrogs();
for (int screen = 0; screen < SCREEN; screen++) {// 分屏测试每屏FROG_PER_SCREEN个蛙
time0 = System.currentTimeMillis();
for (EnvObject thing : things) // 创建食物陷阱等物体
thing.build();
boolean allDead = false;
Frog firstFrog = frogs.get(screen * FROG_PER_SCREEN);
checkIfPause(firstFrog);
for (int j = 0; j < FROG_PER_SCREEN; j++) {
Frog f = frogs.get(screen * FROG_PER_SCREEN + j);
f.initFrog(); // 初始化器官延迟到这一步是因为脑细胞太占内存而且当前屏测完后会清空
}
for (step = 0; step < STEPS_PER_ROUND; step++) {
for (EnvObject thing : things)// 调用食物陷阱等物体的动作
thing.active(screen);
if (allDead)
break; // 青蛙全死光了就直接跳到下一轮,以节省时间
allDead = true;
for (int j = 0; j < FROG_PER_SCREEN; j++) {
Frog f = frogs.get(screen * FROG_PER_SCREEN + j);
if (f.active(this))
allDead = false;
}
if (SHOW_SPEED > 0 && step % SHOW_SPEED != 0) // 用画青蛙的方式来拖慢速度
continue;
if (SHOW_SPEED <= 1) // 如果speed小于0人为加入延迟
sleep(5);
// 开始画青蛙
g.setColor(Color.white);
g.fillRect(0, 0, this.getWidth(), this.getHeight());
g.setColor(Color.BLACK);
drawWorld(g);
for (int j = 0; j < FROG_PER_SCREEN; j++) {
Frog f = frogs.get(screen * FROG_PER_SCREEN + j);
f.show(g);
}
if (firstFrog.alive) { // 开始显示第一个Frog的动态脑图
if (SHOW_FIRST_FROG_BRAIN) {
g.setColor(Color.red);
g.drawArc(firstFrog.x - 15, firstFrog.y - 15, 30, 30, 0, 360);
g.setColor(Color.BLACK);
}
if (DRAW_BRAIN_AFTER_STEPS > 0 && step % DRAW_BRAIN_AFTER_STEPS == 0)
Application.brainPic.drawBrainPicture(firstFrog);
}
Graphics g2 = this.getGraphics();
g2.drawImage(buffImg, 0, 0, this);
}
Application.brainPic.drawBrainPicture(firstFrog);
for (int j = 0; j < FROG_PER_SCREEN; j++) {
Frog f = frogs.get(screen * FROG_PER_SCREEN + j);
f.cells = null; // 清空frog脑细胞所占用的内存
}
Application.mainFrame.setTitle(new StringBuilder("Round: ").append(round).append(", screen:").append(screen).append(", ").append(foodFoundCountText()).append(", 用时: ")
.append(System.currentTimeMillis() - time0).append("ms").toString());
for (EnvObject thing : things)// 去除食物陷阱等物体
thing.destory();
}
round++;
EggTool.layEggs();
} while (true);
}
}

View File

@ -0,0 +1,124 @@
/*
* 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.gitee.drinkjava2.frog;
import java.awt.Graphics;
import java.awt.Image;
import java.io.FileInputStream;
import javax.imageio.ImageIO;
import com.gitee.drinkjava2.frog.brain.Cell;
import com.gitee.drinkjava2.frog.egg.Egg;
import com.gitee.drinkjava2.frog.objects.Material;
/**
* Frog's name is Sam, Frog is made up of cells, cells are created by gene tree, gene tree is saved in egg.
*
* 青蛙由细胞组成细胞的生成由基因树决定基因树保存在蛋里蛋最早为空第一个基因树由随机数产生
*
* @author Yong Zhu
* @since 1.0
*/
public class Frog {// 这个项目里大量用到全局public变量而不是私有变量+getter/setter主要是为了编程方便和简洁大项目不提倡
/** brain cells */
public Cell[][][] cells;// 一开始不要初始化只在调用getOrCreateCell方法时才初始化相关维以节约内存
public int x; // frog在Env中的x坐标
public int y; // frog在Env中的y坐标
public long energy = 10000000; // 青蛙的能量为0则死掉
public boolean alive = true; // 设为false表示青蛙死掉了将不参与计算和显示以节省时间
public int ateFood = 0;
static Image frogImg;
static {
try {
frogImg = ImageIO.read(new FileInputStream(Application.CLASSPATH + "frog.png"));
} catch (Exception e) {
e.printStackTrace();
}
}
public Frog(int x, int y, Egg egg) {// x, y 是虑拟环境的坐标
this.x = x;
this.y = y;
}
public void initFrog() {// 仅在测试之前调用这个方法初始化frog以节约内存测试完成后要清空units释放内存
try {
cells = new Cell[Env.FROG_BRAIN_XSIZE][][]; // 为了节约内存先只初始化三维数组的x维另两维用到时再分配
} catch (OutOfMemoryError e) {
System.out.println("OutOfMemoryError found for frog, force it die.");
this.alive = false;
return;
}
}
public boolean active(Env v) {// 这个active方法在每一步循环都会被调用是脑思考的最小帧
// 如果能量小于0出界与非食物的点重合则判死
if (!alive || energy < 0 || Env.outsideEnv(x, y) || Env.bricks[x][y] >= Material.KILLFROG) {
energy -= 100; // 死掉的青蛙也要消耗能量确保淘汰出局
alive = false;
return false;
}
energy -= 20;
// 这里是最关键的脑细胞主循环调用每个细胞的act方法
for (int i = 0; i < Env.FROG_BRAIN_XSIZE; i++) {
Env.checkIfPause(this);
if (cells[i] != null)
for (int j = 0; j < Env.FROG_BRAIN_YSIZE; j++)
if (cells[i][j] != null)
for (int k = 0; k < Env.FROG_BRAIN_ZSIZE; k++) {
Cell cell = cells[i][j][k];
if (cell != null)
cell.act();
}
}
return alive;
}
public void show(Graphics g) {// 显示青蛙的图象
if (!alive)
return;
g.drawImage(frogImg, x - 8, y - 8, 16, 16, null);
}
/** Check if cell exist */
public Cell getCell(int x, int y, int z) {// 返回指定脑坐标的cell 如果不存在返回null
if (cells[x] == null || cells[x][y] == null)
return null;
return cells[x][y][z];
}
/** Get a cell in position (x,y,z), if not exist, create a new one */
public Cell getOrCreateCell(int x, int y, int z) {// 获取指定坐标的Cell如果为空则在指定位置新建Cell
if (outBrainBound(x, y, z))
return null;
if (cells[x] == null)
cells[x] = new Cell[Env.FROG_BRAIN_YSIZE][];
if (cells[x][y] == null)
cells[x][y] = new Cell[Env.FROG_BRAIN_ZSIZE];
Cell cell = cells[x][y][z];
if (cell == null) {
cell = new Cell(x, y, z);
cells[x][y][z] = cell;
}
return cell;
}
/** Check if x,y,z out of frog's brain bound */
public static boolean outBrainBound(int x, int y, int z) {// 检查指定坐标是否超出frog脑空间界限
return x < 0 || x >= Env.FROG_BRAIN_XSIZE || y < 0 || y >= Env.FROG_BRAIN_YSIZE || z < 0 || z >= Env.FROG_BRAIN_ZSIZE;
}
}

View File

@ -0,0 +1,319 @@
package com.gitee.drinkjava2.frog.brain;
import static java.awt.Color.BLACK;
import static java.awt.Color.RED;
import static java.awt.Color.WHITE;
//import static java.awt.BLUE;
import static java.lang.Math.cos;
import static java.lang.Math.round;
import static java.lang.Math.sin;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import javax.swing.JPanel;
import com.gitee.drinkjava2.frog.Application;
import com.gitee.drinkjava2.frog.Env;
import com.gitee.drinkjava2.frog.Frog;
/**
* BrainPicture show first frog's brain structure, for debug purpose only
*
* 这个类用来画出脑图这不是一个关键类对脑的运行逻辑无影响但有了脑图后可以直观地看出脑的3维结构进行有针对性的改进
* 可以用鼠标进行平移缩放旋转以及tflr,x五个键来选择顶视前视左视右视斜视这5个方向的视图以及空格暂停方向键调整切面
* 鼠标的动作定义在MouseAction类中
*
* @author Yong Zhu
* @since 1.0
*/
@SuppressWarnings("all")
public class BrainPicture extends JPanel {
private static final float d90 = (float) (Math.PI / 2);
Color picColor = RED;
int brainDispWidth; // screen display piexls width
float scale; // brain scale
int xOffset = 0; // brain display x offset compare to screen
int yOffset = 0; // brain display y offset compare to screen
float xAngle = d90 * .8f; // brain rotate on x axis
float yAngle = d90 / 4; // brain rotate on y axis
float zAngle = 0;// brain rotate on z axis
int xMask = -1;// x Mask
int yMask = -1;// y Mask
BufferedImage buffImg;
Graphics g;
public KeyAdapter keyAdapter;
public BrainPicture(int x, int y, float brainWidth, int brainDispWidth) {
super();
this.setLayout(null);// 空布局
this.brainDispWidth = brainDispWidth;
scale = 0.5f * brainDispWidth / brainWidth;
this.setBounds(x, y, brainDispWidth + 1, brainDispWidth + 1);
buffImg = new BufferedImage(Env.FROG_BRAIN_DISP_WIDTH, Env.FROG_BRAIN_DISP_WIDTH, BufferedImage.TYPE_INT_RGB);
g = buffImg.getGraphics();
MouseAction act = new MouseAction(this);
this.addMouseListener(act); // 添加鼠标动作监听
this.addMouseWheelListener(act);// 添加鼠标滚轮动作监听
this.addMouseMotionListener(act);// 添加鼠标移动动作监听
keyAdapter = new KeyAdapter() {// 处理t,f,l,rx键盘命令
public void keyPressed(KeyEvent e) {
switch (e.getKeyCode()){
case KeyEvent.VK_UP:// Y切面向上
yMask++;
if (yMask > Env.FROG_BRAIN_YSIZE)
yMask = Env.FROG_BRAIN_YSIZE;
break;
case KeyEvent.VK_DOWN:// Y切面向下
yMask--;
if (yMask < 0)
yMask = 0;
break;
case KeyEvent.VK_LEFT:// x切面向左
xMask--;
if (xMask < 0)
xMask = 0;
break;
case KeyEvent.VK_RIGHT:// x切面向右
xMask++;
if (xMask > Env.FROG_BRAIN_XSIZE)
xMask = Env.FROG_BRAIN_XSIZE;
break;
case ' ':// 暂停及继续
Application.pauseAction.actionPerformed(null);
break;
case 'T':// 顶视
xAngle = 0;
yAngle = 0;
zAngle = 0;
break;
case 'F':// 前视
xAngle = d90;
yAngle = 0;
zAngle = 0;
break;
case 'L':// 左视
xAngle = d90;
yAngle = d90;
zAngle = 0;
break;
case 'R':// 右视
xAngle = d90;
yAngle = -d90;
zAngle = 0;
break;
case 'X':// 斜视
xAngle = d90 * .8f;
yAngle = d90 / 4;
zAngle = 0;
break;
default:
}
}
};
addKeyListener(keyAdapter);
this.setFocusable(true);
}
public void drawCuboid(Cuboid c) {// 在脑图上画一个长立方体框架视角是TopView
float x = c.x;
float y = c.y;
float z = c.z;
float xe = c.xe;
float ye = c.ye;
float ze = c.ze;
drawLine(x, y, z, x + xe, y, z);// 画立方体的下面边
drawLine(x + xe, y, z, x + xe, y + ye, z);
drawLine(x + xe, y + ye, z, x, y + ye, z);
drawLine(x, y + ye, z, x, y, z);
drawLine(x, y, z, x, y, z + ze);// 画立方体的中间边
drawLine(x + xe, y, z, x + xe, y, z + ze);
drawLine(x + xe, y + ye, z, x + xe, y + ye, z + ze);
drawLine(x, y + ye, z, x, y + ye, z + ze);
drawLine(x, y, z + ze, x + xe, y, z + ze);// 画立方体的上面边
drawLine(x + xe, y, z + ze, x + xe, y + ye, z + ze);
drawLine(x + xe, y + ye, z + ze, x, y + ye, z + ze);
drawLine(x, y + ye, z + ze, x, y, z + ze);
}
/*-
画线固定以top视角的角度所以只需要从x1,y1画一条到x2,y2的直线
x 轴旋转 θ
x, y.cosθ-zsinθ, y.sinθ+z.cosθ
y 轴旋转 θ
z.sinθ+x.cosθ, y, z.cosθ-x.sinθ
z 轴旋转 θ
x.cosθ-y.sinθ, x.sinθ+y.consθ, z
-*/
public void drawLine(float px1, float py1, float pz1, float px2, float py2, float pz2) {
double x1 = px1 - Env.FROG_BRAIN_XSIZE / 2;
double y1 = -py1 + Env.FROG_BRAIN_YSIZE / 2;// 屏幕的y坐标是反的显示时要正过来
double z1 = pz1 - Env.FROG_BRAIN_ZSIZE / 2;
double x2 = px2 - Env.FROG_BRAIN_XSIZE / 2;
double y2 = -py2 + Env.FROG_BRAIN_YSIZE / 2;// 屏幕的y坐标是反的显示时要正过来
double z2 = pz2 - Env.FROG_BRAIN_ZSIZE / 2;
x1 = x1 * scale;
y1 = y1 * scale;
z1 = z1 * scale;
x2 = x2 * scale;
y2 = y2 * scale;
z2 = z2 * scale;
double x, y, z;
y = y1 * cos(xAngle) - z1 * sin(xAngle);// 绕x轴转
z = y1 * sin(xAngle) + z1 * cos(xAngle);
y1 = y;
z1 = z;
x = z1 * sin(yAngle) + x1 * cos(yAngle);// 绕y轴转
z = z1 * cos(yAngle) - x1 * sin(yAngle);
x1 = x;
z1 = z;
x = x1 * cos(zAngle) - y1 * sin(zAngle);// 绕z轴转
y = x1 * sin(zAngle) + y1 * cos(zAngle);
x1 = x;
y1 = y;
y = y2 * cos(xAngle) - z2 * sin(xAngle);// 绕x轴转
z = y2 * sin(xAngle) + z2 * cos(xAngle);
y2 = y;
z2 = z;
x = z2 * sin(yAngle) + x2 * cos(yAngle);// 绕y轴转
z = z2 * cos(yAngle) - x2 * sin(yAngle);
x2 = x;
z2 = z;
x = x2 * cos(zAngle) - y2 * sin(zAngle);// 绕z轴转
y = x2 * sin(zAngle) + y2 * cos(zAngle);
x2 = x;
y2 = y;
g.setColor(picColor);
g.drawLine((int) round(x1) + Env.FROG_BRAIN_DISP_WIDTH / 2 + xOffset, (int) round(y1) + Env.FROG_BRAIN_DISP_WIDTH / 2 + yOffset, (int) round(x2) + Env.FROG_BRAIN_DISP_WIDTH / 2 + xOffset,
(int) round(y2) + Env.FROG_BRAIN_DISP_WIDTH / 2 + yOffset);
}
/** 画出cell的中心点 */
public void drawCellCenter(float x, float y, float z, float diameter) {
if (x > 0 && (x < xMask || y < yMask))
return;
drawPoint(x + 0.5f, y + 0.5f, z + 0.5f, (int) Math.max(2, Math.round(scale * diameter)));
}
/** 画点固定以top视角的角度所以只需要在x1,y1位置画一个点 */
public void drawPoint(float px1, float py1, float pz1, int diameter) {
double x1 = px1 - Env.FROG_BRAIN_XSIZE / 2;
double y1 = -py1 + Env.FROG_BRAIN_YSIZE / 2;// 屏幕的y坐标是反的显示时要正过来
double z1 = pz1 - Env.FROG_BRAIN_ZSIZE / 2;
x1 = x1 * scale;
y1 = y1 * scale;
z1 = z1 * scale;
double x, y, z;
y = y1 * cos(xAngle) - z1 * sin(xAngle);// 绕x轴转
z = y1 * sin(xAngle) + z1 * cos(xAngle);
y1 = y;
z1 = z;
x = z1 * sin(yAngle) + x1 * cos(yAngle);// 绕y轴转
z = z1 * cos(yAngle) - x1 * sin(yAngle);
x1 = x;
z1 = z;
x = x1 * cos(zAngle) - y1 * sin(zAngle);// 绕z轴转
y = x1 * sin(zAngle) + y1 * cos(zAngle);
x1 = x;
y1 = y;
g.setColor(picColor);
g.fillOval((int) round(x1) + Env.FROG_BRAIN_DISP_WIDTH / 2 + xOffset, (int) round(y1) + Env.FROG_BRAIN_DISP_WIDTH / 2 + yOffset - diameter / 2, diameter, diameter);
}
private static Cuboid brain = new Cuboid(0, 0, 0, Env.FROG_BRAIN_XSIZE, Env.FROG_BRAIN_YSIZE, Env.FROG_BRAIN_ZSIZE);
public void drawBrainPicture(Frog f) {// 在这个方法里进行青蛙三维脑结构的绘制
if (!f.alive)
return;
if (!Env.SHOW_FIRST_FROG_BRAIN)
return;
g.setColor(WHITE);// 先清空旧图
g.fillRect(0, 0, brainDispWidth, brainDispWidth);
g.setColor(BLACK); // 画边框
g.drawRect(0, 0, brainDispWidth, brainDispWidth);
setPicColor(BLACK);
drawCuboid(brain);// 先把脑的框架画出来
setPicColor(RED);
drawLine(0, 0, 0, 1, 0, 0);
drawLine(0, 0, 0, 0, 1, 0);
drawLine(0, 0, 0, 0, 0, 1);
Graphics g2 = this.getGraphics(); // 这两行是将缓存中的图像写到屏幕上
g2.drawImage(buffImg, 0, 0, this);
}
// getters & setters
public float getScale() {
return scale;
}
public void setScale(float scale) {
this.scale = scale;
}
public float getxAngle() {
return xAngle;
}
public void setxAngle(float xAngle) {
this.xAngle = xAngle;
}
public float getyAngle() {
return yAngle;
}
public void setyAngle(float yAngle) {
this.yAngle = yAngle;
}
public float getzAngle() {
return zAngle;
}
public void setzAngle(float zAngle) {
this.zAngle = zAngle;
}
public void setPicColor(Color color) {
this.picColor = color;
}
public int getxOffset() {
return xOffset;
}
public void setxOffset(int xOffset) {
this.xOffset = xOffset;
}
public int getyOffset() {
return yOffset;
}
public void setyOffset(int yOffset) {
this.yOffset = yOffset;
}
}

View File

@ -0,0 +1,41 @@
/*
* 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.gitee.drinkjava2.frog.brain;
/**
* Cell is the smallest unit of brain
* Cell是脑的最小单元 cell的行为由它的器官类型决定
*
器官位置方向厚度脑细胞分布直径细胞发散或聚焦角度
单个细胞方向能量吸收曲线能量发送曲线(阀值是否永久激活延时发送脉冲式发送发送方向(双向)
是否是视细胞动作细胞
触突(hole)(固定式触突或动态生成触突?)
* @author Yong Zhu
* @since 1.0
*/
public class Cell {
public int x;
public int y;
public int z;
public Cell(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
}
public void act() { //cell执行行动
}
}

View File

@ -0,0 +1,61 @@
/*
* 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.gitee.drinkjava2.frog.brain;
import com.gitee.drinkjava2.frog.Frog;
/**
* Cuboid represents a rectangular prism 3d zone in brain
*
* Cuboid是一个长方体通常用来表示脑内器官的形状
*
* @author Yong Zhu
* @since 2.0.2
*/
@SuppressWarnings("all")
public class Cuboid implements Shape {
private static final long serialVersionUID = 1L;
public int x;// x,y,z是长方体的左下角坐标
public int y;
public int z;
public int xe;// xe,ye,ze分别是长方体三边长
public int ye;
public int ze;
public Cuboid() {
// 空构造器不能省
}
public Cuboid(int x, int y, int z, int xe, int ye, int ze) {// 用x,y,z,r来构造
this.x = x;
this.y = y;
this.z = z;
this.xe = xe;
this.ye = ye;
this.ze = ze;
}
public Cuboid(Cuboid c) {// 用另一个Cuboid来构造
this.x = c.x;
this.y = c.y;
this.z = c.z;
this.xe = c.xe;
this.ye = c.ye;
this.ze = c.ze;
}
@Override
public void drawOnBrainPicture(BrainPicture pic) {
pic.drawCuboid(this);
}
}

View File

@ -0,0 +1,26 @@
/*
* 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.gitee.drinkjava2.frog.brain;
import java.io.Serializable;
/**
* Shape represents a 3d zone in brain
*
* Shape用来表示脑内器官的形状,一个器官只能有一个shape
*
* @author Yong Zhu
* @since 2.0.2
*/
public interface Shape extends Serializable {
/* Draw self on brain picture */
public void drawOnBrainPicture(BrainPicture pic); // 把自己在脑图上画出来
}

View File

@ -0,0 +1,43 @@
/*
* 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.gitee.drinkjava2.frog.egg;
import java.io.Serializable;
import com.gitee.drinkjava2.frog.Frog;
/**
* Egg is the static structure description of frog, can save as file, to build a
* frog, first need build a egg.<br/>
*
* 蛋存在的目的是为了以最小的字节数串行化存储Frog的基因树,它是Frog的生成算法描述而不是Frog本身这样一来Frog就不能"永生"因为每一个egg都不等同于
* 它的母体 而且每一次测试除了少量固有反射外大部分条件反射的建立都必须从头开始训练类似于人类无论人类社会有多聪明 婴儿始终是一张白纸除了需要花大量的时间从头学习
*
* @author Yong Zhu
* @since 1.0
*/
public class Egg implements Serializable {
private static final long serialVersionUID = 1L;
public Egg() {// 无中生有创建一个蛋先有蛋后有蛙
}
/** Create egg from frog */
public Egg(Frog frog) { // 青蛙下蛋每个青蛙的器官会创建自已的副本或变异可以是0或多个
}
/** Create a egg by join 2 eggs */
public Egg(Egg x, Egg y) { //模拟XY 染色体合并两个蛋生成一个新的蛋
}
}

View File

@ -0,0 +1,107 @@
/*
* 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.gitee.drinkjava2.frog.egg;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import com.gitee.drinkjava2.frog.Application;
import com.gitee.drinkjava2.frog.Env;
import com.gitee.drinkjava2.frog.Frog;
import com.gitee.drinkjava2.frog.util.FrogFileUtils;
/**
* EggTool save eggs to disk
*
* @author Yong Zhu
* @since 1.0
*/
public class EggTool {
/**
* Frogs which have higher energy lay eggs
*
* 利用Java串行机制存盘 能量多(也就是吃的更多)的Frog下蛋并存盘, 以进行下一轮测试能量少的Frog被淘汰没有下蛋的资格
* 用能量的多少来简化生存竟争模拟也就是说生存是唯一的奖惩机制每次下蛋数量固定为EGG_QTY个
*/
public static void layEggs() {
sortFrogsOrderByEnergyDesc();
Frog first = Env.frogs.get(0);
Frog last = Env.frogs.get(Env.frogs.size() - 1);
try {
Env.eggs.clear();
for (int i = 0; i < Env.EGG_QTY; i++)
Env.eggs.add(new Egg(Env.frogs.get(i)));
FileOutputStream fo = new FileOutputStream(Application.CLASSPATH + "eggs.ser");
ObjectOutputStream so = new ObjectOutputStream(fo);
so.writeObject(Env.eggs);
so.close();
System.out.print("Fist frog energy=" + first.energy);
System.out.println(", Last frog energy=" + last.energy);
System.out.println("Saved " + Env.eggs.size() + " eggs to file '" + Application.CLASSPATH + "eggs.ser'");
} catch (IOException e) {
System.out.println(e);
}
}
private static void sortFrogsOrderByEnergyDesc() {// 按能量多少给青蛙排序
Collections.sort(Env.frogs, new Comparator<Frog>() {
public int compare(Frog a, Frog b) {
if (a.energy > b.energy)
return -1;
else if (a.energy == b.energy)
return 0;
else
return 1;
}
});
}
public static void deleteEggs() {//是否每次测试要删除蛋是在Env.DELETE_EGGS设置
System.out.println("Delete exist egg file: '" + Application.CLASSPATH + "eggs.ser'");
FrogFileUtils.deleteFile(Application.CLASSPATH + "eggs.ser");
}
/**
* 从磁盘读入一批Egg
*/
@SuppressWarnings("unchecked")
public static void loadEggs() {
boolean errorfound = false;
try {
FileInputStream eggsFile = new FileInputStream(Application.CLASSPATH + "eggs.ser");
ObjectInputStream eggsInputStream = new ObjectInputStream(eggsFile);
Env.eggs = (List<Egg>) eggsInputStream.readObject();
System.out.println(
"Loaded " + Env.eggs.size() + " eggs from file '" + Application.CLASSPATH + "eggs.ser" + "'.\n");
eggsInputStream.close();
} catch (Exception e) {
errorfound = true;
}
if (errorfound) {
Env.eggs.clear();
for (int j = 0; j < Env.EGG_QTY; j++)
Env.eggs.add(new Egg());
System.out.println("Fail to load egg file at path '" + Application.CLASSPATH + "', created "
+ Env.eggs.size() + " eggs to do test.\n");
}
}
}

View File

@ -0,0 +1,80 @@
/* Copyright 2018-2020 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.gitee.drinkjava2.frog.util;
import java.util.Random;
/**
* Random Utilities used in this project
*
* 随机数工具最理想情况下随机算法和遗传算法是Frog项目中仅有的两个算法
*
* @author Yong Zhu
* @since 1.0
*/
public class RandomUtils {
private RandomUtils() {
}
private static final Random rand = new Random();
public static int nextInt(int i) {//生成一个整数
return rand.nextInt(i);
}
public static float nextFloat() {//生成一个实数
return rand.nextFloat();
}
public static boolean percent(float percent) {// 有百分之percent的机率为true
return rand.nextInt(100) < percent;
}
public static int vary(int v, int percet) {//给定一个整数有百分之percent的机率变异变异范围由vary方法决定
if (percent(percet))
return vary(v);
return v;
}
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) {//给定一个实数有百分之percent的机率变异变异范围由vary方法决定
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;
}
}

View File

@ -1,3 +1,3 @@
## history\005b_letter_test简介
005b是基于history\005_letter_test分支基础上将体全息存贮方案改为面存贮方案的模式识别这个方案中所有信息是保存在一个平面上。这个方案并不是否定体全息存贮仅仅只是展示不同的思路。
本分支依然只是概念演示图像的扭曲、旋转、缺失等情况的识别暂不考虑。打算这些放在bottom_up细胞分裂模型阶段再做
## top_down目录暂时无内容
top_down分支存放手工设计的算法用来验证思路history目录下的005、005a、005b分支都是属于这一类。目前本目录暂时无内容。人工生命项目着重点是走自底向上的模式(bottom_up),希望能利用电脑的算力自动进化出脑结构

View File

@ -1,36 +0,0 @@
/*
* 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.gitee.drinkjava2.frog.brain.organ;
import com.gitee.drinkjava2.frog.Env;
import com.gitee.drinkjava2.frog.brain.Cuboid;
import com.gitee.drinkjava2.frog.brain.Organ;
/**
* Move is a special organ the action move photon go to next cell
*
* Move这个器官会让Cell中的光子沿着它的运动方向走到下一格
*
* @author Yong Zhu
*/
public class Move2 extends Organ {
private static final long serialVersionUID = 1L;
public Move2() {
super();
this.shape = new Cuboid(11, 0, 0, Env.FROG_BRAIN_XSIZE-11 , Env.FROG_BRAIN_YSIZE, 20);
this.organName = "MOVE2";
this.type = Organ.MOVE; // MOVE类型的细胞会保持光子的直线运动并不在细胞上挖洞
this.allowVary = false;// 不允许变异
this.allowBorrow = false;// 不允许借出
}
}

View File

@ -1,48 +0,0 @@
/*
* 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.gitee.drinkjava2.frog.brain.organ;
import java.awt.Color;
import com.gitee.drinkjava2.frog.Env;
import com.gitee.drinkjava2.frog.Frog;
import com.gitee.drinkjava2.frog.brain.BrainPicture;
import com.gitee.drinkjava2.frog.brain.Cuboid;
import com.gitee.drinkjava2.frog.brain.Organ;
/**
* Move is a special organ the action move photon go to next cell
*
* MOVE_DIG类型的细胞会保持光子直线运动并在下一个细胞上挖洞
*
* @author Yong Zhu
*/
public class MoveDig extends Organ {
private static final long serialVersionUID = 1L;
public MoveDig() {
super();
this.shape = new Cuboid(9, 0, 0, 2, Env.FROG_BRAIN_YSIZE, Env.FROG_BRAIN_ZSIZE - 2);
this.organName = "MOVE_DIG";
this.type = Organ.MOVE_DIG; // MOVE_DIG类型的细胞会保持光子直线运动并在下一个细胞上挖洞
this.allowVary = false;// 不允许变异
this.allowBorrow = false;// 不允许借出
}
@Override
public void drawOnBrainPicture(Frog f, BrainPicture pic) { // 把器官的轮廓显示在脑图上
if (!Env.SHOW_FIRST_FROG_BRAIN || !f.alive) // 如果不允许画或青蛙死了就直接返回
return;
pic.setPicColor(Color.GREEN); // 缺省是灰色
shape.drawOnBrainPicture(pic);
}
}

View File

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
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.

View File

@ -0,0 +1,4 @@
## history\005a1_letter_test简介
这是基于history\005a_letter_test体全息模式识别分支基础上但是听力部分改为用10个点来代表25个声音即5个声母 x 5个韵母 =25 个声音。
因为体全息可以同时处理多个方向的信号,所以可以用声母+韵母同时工作的方式来减少声音信号输入区。
本分支依然只是概念演示,图像的扭曲、旋转、缺失等情况的识别暂不考虑

View File

@ -0,0 +1 @@
mvn clean

View File

@ -0,0 +1 @@
mvn eclipse:clean

View File

@ -0,0 +1,2 @@
call mvn eclipse:eclipse
call pause

View File

@ -2,12 +2,12 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.gitee.drinkjava2</groupId>
<artifactId>frog005b</artifactId>
<artifactId>frog005a1</artifactId>
<packaging>jar</packaging>
<version>1.0</version>
<name>frog</name>
<description>005b是基于history\005_letter_test分支基础上将体全息存贮方案改为面存贮方案的模式识别这个方案中所有信息是保存在一个平面上。这个方案并不是否定体全息存贮仅仅只是展示不同的思路。</description>
<description>这是基于history\005a_letter_test体全息模式识别分支基础上但是听力部分改为用10个点来代表25个声音即5个声母 x 5个韵母 =25 个声音</description>
<url>https://gitee.com/drinkjava2/jsqlbox/frog</url>
<issueManagement>

View File

@ -0,0 +1,3 @@
call mvn clean compile
cd target\classes
java -classpath ".;*" com.gitee.drinkjava2.frog.Application

View File

@ -0,0 +1,2 @@
mvn clean package
java -jar target/frog-*.jar

View File

@ -0,0 +1,122 @@
package com.gitee.drinkjava2.frog;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JRadioButton;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import com.gitee.drinkjava2.frog.brain.BrainPicture;
/**
* Application's main method start the program
*
* @author Yong Zhu
* @since 1.0
*/
@SuppressWarnings("all")
public class Application {
public static final String CLASSPATH;
static {
String classpath = new File("").getAbsolutePath();
int i = classpath.indexOf("\\frog\\");
if (i > 0)
CLASSPATH = classpath.substring(0, i) + "\\frog\\";// windows
else
CLASSPATH = classpath + "/"; // UNIX
}
public static JFrame mainFrame = new JFrame();
public static Env env = new Env();
public static BrainPicture brainPic = new BrainPicture(Env.ENV_WIDTH + 5, 0, Env.FROG_BRAIN_XSIZE,
Env.FROG_BRAIN_DISP_WIDTH);
public static ActionListener pauseAction;
public static boolean selectFrog = true;
private static void checkIfShowBrainPicture(JButton button) {
if (Env.SHOW_FIRST_FROG_BRAIN) {
button.setText("Hide brain");
int y = Env.ENV_HEIGHT + 160;
if (Env.FROG_BRAIN_DISP_WIDTH + 41 > y)
y = Env.FROG_BRAIN_DISP_WIDTH + 41;
mainFrame.setSize(Env.ENV_WIDTH + Env.FROG_BRAIN_DISP_WIDTH + 25, y);
brainPic.requestFocus();
} else {
button.setText("Show brain");
mainFrame.setSize(Env.ENV_WIDTH + 20, Env.ENV_HEIGHT + 160);
}
}
public static void main(String[] args) {
mainFrame.setLayout(null);
mainFrame.setSize(Env.ENV_WIDTH + 20, Env.ENV_HEIGHT + 100); // 窗口大小
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 关闭时退出程序
mainFrame.add(env); // 添加虚拟环境Panel
mainFrame.add(brainPic); // 添加脑图Panel
JButton showBrainbutton = new JButton("Show brain");// 按钮显示或隐藏脑图
int buttonWidth = 100;
int buttonHeight = 22;
int buttonXpos = Env.ENV_WIDTH / 2 - buttonWidth / 2;
showBrainbutton.setBounds(buttonXpos, Env.ENV_HEIGHT + 8, buttonWidth, buttonHeight);
ActionListener al = new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {//显示或隐藏脑图
Env.SHOW_FIRST_FROG_BRAIN = !Env.SHOW_FIRST_FROG_BRAIN;
checkIfShowBrainPicture(showBrainbutton);
}
};
checkIfShowBrainPicture(showBrainbutton);
showBrainbutton.addActionListener(al);
mainFrame.add(showBrainbutton);
JButton stopButton = new JButton("Pause");// 暂停或继续按钮
stopButton.setBounds(buttonXpos, Env.ENV_HEIGHT + 35, buttonWidth, buttonHeight);
pauseAction = new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
Env.pause = !Env.pause;
if (Env.pause) {
stopButton.setText("Resume");
} else {
stopButton.setText("Pause");
brainPic.requestFocus();
}
}
};
stopButton.addActionListener(pauseAction);
mainFrame.add(stopButton);
// 速度条
final JSlider speedSlider = new JSlider(1, 10, (int) Math.round(Math.sqrt(Env.SHOW_SPEED)));
speedSlider.setBounds(buttonXpos - 50, stopButton.getY() + 25, buttonWidth + 100, buttonHeight);
ChangeListener slideAction = new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
Env.SHOW_SPEED = speedSlider.getValue() * speedSlider.getValue() * speedSlider.getValue();
brainPic.requestFocus();
}
};
speedSlider.addChangeListener(slideAction);
mainFrame.add(speedSlider);
final JLabel label = new JLabel("Speed:");
label.setBounds(buttonXpos - 90, stopButton.getY() + 23, 100, buttonHeight);
mainFrame.add(label);
mainFrame.setVisible(true);
env.run();
}
}

View File

@ -39,9 +39,9 @@ public class Env extends JPanel {
public static final int FROG_PER_SCREEN = EGG_QTY * FROG_PER_EGG / SCREEN; // 每屏上显示几个青蛙这个数值由上面三个参数计算得来
/** Frog's brain size is a 3D array of Cell */ // 脑空间是个三维Cell数组为节约内存仅在用到数组元素时才去初始化这维按需分配内存
public static final int FROG_BRAIN_XSIZE = 22; // frog的脑在X方向长度
public static final int FROG_BRAIN_XSIZE = 18; // frog的脑在X方向长度
public static final int FROG_BRAIN_YSIZE = 20; // frog的脑在Y方向长度
public static final int FROG_BRAIN_ZSIZE = 27; // frog的脑在Z方向长度
public static final int FROG_BRAIN_ZSIZE = 17; // frog的脑在Z方向长度
/** SHOW first frog's brain structure */
public static boolean SHOW_FIRST_FROG_BRAIN = true; // 是否显示脑图在Env区的右侧

View File

@ -280,10 +280,13 @@ public class BrainPicture extends JPanel {
if (cell.hasInput && x == 0) {// 如果在左边显示黑色大圆
setPicColor(Color.BLACK);
drawCellCenter(x, y, z, 0.6f);
} else if (z == Env.FROG_BRAIN_ZSIZE - 1 && cell.hasInput) {// 如果在顶上显示兰色大圆
} else if (z == Env.FROG_BRAIN_ZSIZE - 1 && cell.hasInput) {// 如果在顶上且有输入信号显示兰色大圆
setPicColor(Color.BLUE);
drawCellCenter(x, y, z, 0.6f);
}
} else if (y == 0 && cell.hasInput) {// 如果在前面且有输入信号显示兰色大圆
setPicColor(Color.BLUE);
drawCellCenter(x, y, z, 0.6f);
}
if (cell.photonQty > 0) {// 如果在内部只显示有光子的cell
setPicColor(ColorUtils.colorByCode(cell.color));

View File

@ -49,7 +49,26 @@ public class CellActions {
for (int orgNo : c.organs) {
Organ o = frog.organs.get(orgNo);
switch (o.type) { // 添加细胞的行为这是硬编码
case Organ.MOVE_DIG: // 如果是MOVE_DIG细胞它让每个光子穿过这个细胞走到下一格并在下一个细胞上打出洞来
case Organ.MOVE: // 如果是MOVE细胞它的行为是让每个光子穿过这个细胞走到下一格保持光子沿直线运动
if (c.x == 0 || c.z == Env.FROG_BRAIN_ZSIZE - 1) {// 但是对于输入区将删除光子并合计一共收到多少
if (c.photonQty > 0) {
c.photonSum += c.photonQty;
c.photons = null;
}
break;
}
if (c.photons != null) {
for (int ii = 0; ii < c.photons.length; ii++) {
Photon p = c.photons[ii];
if (p == null || p.activeNo == activeNo)// 同一轮新产生的光子或处理过的光子不再走了
continue;
p.activeNo = activeNo;
c.removePhoton(ii);
frog.addAndWalk(p); // 让光子自已往下走走到哪就停到哪个细胞里
}
}
break;
case Organ.MOVE_JELLY: // 如果是MOVE_JELLY细胞它让每个光子穿过这个细胞走到下一格并在下一个细胞上打出洞来
if (c.x == 0 || c.z == Env.FROG_BRAIN_ZSIZE - 1) {// 但是对于输入区将删除光子并合计一共收到多少
if (c.photonQty > 0) {
c.photonSum += c.photonQty;
@ -68,47 +87,37 @@ public class CellActions {
}
}
break;
case Organ.MOVE: // 如果是MOVE细胞它的行为是让每个光子穿过这个细胞走到下一格保持光子沿直线运动
if (c.x == 0 || c.z == Env.FROG_BRAIN_ZSIZE - 1) {// 但是对于输入区将删除光子并合计一共收到多少
if (c.photonQty > 0) {
c.photonSum += c.photonQty;
c.photons = null;
}
break;
}
if (c.photons != null) {
for (int ii = 0; ii < c.photons.length; ii++) {
Photon p = c.photons[ii];
if (p == null || p.activeNo == activeNo)// 同一轮新产生的光子或处理过的光子不再走了
continue;
p.activeNo = activeNo;
c.removePhoton(ii);
frog.addAndWalk(p); // 让光子自已往下走走到哪就停到哪个细胞里
}
}
break;
case Organ.EYE: // 如果是视网膜细胞它的行为是只要Cell有输入信号就产生向右的多个光子发散出去模拟波源
if (c.hasInput && RandomUtils.percent(100)) {// 随机数的作用是减少光子数加快速度
// for (float yy = -0.1f; yy <= 0.1f; yy += 0.15) {// 形成一个扇面向右发送
// for (float zz = -0.1f; zz <= 0.1f; zz += 0.15) {
Photon p = new Photon(orgNo, o.color, c.x, c.y, c.z, 1.0f, 0, -1.45f);
if (c.hasInput && RandomUtils.percent(40)) {// 随机数的作用是减少光子数加快速度
for (float yy = -0.1f; yy <= 0.1f; yy += 0.08) {// 形成一个扇面向右发送
for (float zz = -0.1f; zz <= 0.1f; zz += 0.08) {
Photon p = new Photon(orgNo, o.color, c.x, c.y, c.z, 1.0f, yy, zz);
p.activeNo = activeNo; // 用这个activeNo防止一直被赶着走
frog.addAndWalk(p);// 光子不是直接添加而是走一格后添加在相邻的细胞上
// }
// }
}
break;
case Organ.EAR: // 如果是听力细胞它的行为是将只要Cell有输入信号就产生向下的多个光子发散出去模拟波源
if (c.hasInput && RandomUtils.percent(40)) {// 随机数的作用是减少光子数加快速度
float xstart=(-c.x)*0.14f-0.020f;
for (float xx = xstart; xx<0; xx += 0.02)
for (float yy = -2f; yy <= 2f; yy += 0.03) {
Photon p = new Photon(o.organNo, o.color, c.x, c.y, c.z, xx, yy, -1);
p.activeNo = activeNo;
frog.addAndWalk(p);// 光子不是直接添加而是走一格后添加在相邻的细胞上
}
}
}
break;
case Organ.TOPEAR: // 如果是顶部声母听力细胞它的行为是将只要Cell有输入信号就产生向下的多个光子发散出去模拟波源
if (c.hasInput && RandomUtils.percent(40)) {// 随机数的作用是减少光子数加快速度
for (float xx=-0.1f; xx<0.1f; xx+=0.04)
for (float yy = -2f; yy <= 2f; yy += 0.03) {
Photon p = new Photon(o.organNo, o.color, c.x, c.y, c.z, xx, yy, -1);
p.activeNo = activeNo;
frog.addAndWalk(p);// 光子不是直接添加而是走一格后添加在相邻的细胞上
}
}
break;
case Organ.FRONTEAR: // 如果是面前韵母听力细胞它的行为是将只要Cell有输入信号就产生y方向发散光子模拟波源
if (c.hasInput && RandomUtils.percent(40)) {// 随机数的作用是减少光子数加快速度
for (float xx=-0.1f; xx<0.1f; xx+=0.04)
for (float zz = -2f; zz <= 2f; zz += 0.03) {
Photon p = new Photon(o.organNo, o.color, c.x, c.y, c.z, xx, 1, zz);
p.activeNo = activeNo;
frog.addAndWalk(p);// 光子不是直接添加而是走一格后添加在相邻的细胞上
}
}
break;
default:
break;
}

View File

@ -0,0 +1,106 @@
package com.gitee.drinkjava2.frog.brain;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
/**
* MouseAction
*
* 这个类用来处理脑图BrainPicture上的鼠标动作有平移旋转缩放三种
*
* @author Yong Zhu
* @since 2.0.2
*/
public class MouseAction implements MouseListener, MouseWheelListener, MouseMotionListener {
private BrainPicture brainPic;
private int buttonPressed = 0;
private int x;
private int y;
public MouseAction(BrainPicture brainPic) {
this.brainPic = brainPic;
}
@Override
public void mousePressed(MouseEvent e) {// 记录当前鼠标点
if (e.getButton() == 1)// 旋转
buttonPressed = 1;
else if (e.getButton() == 2)// 缩放
buttonPressed = 2;
else
buttonPressed = 0;
x = e.getPoint().x;
y = e.getPoint().y;
}
@Override
public void mouseReleased(MouseEvent e) {
buttonPressed = 0;
}
@Override
public void mouseWheelMoved(MouseWheelEvent e) {// 缩放
if (e.getWheelRotation() < 0) {
brainPic.scale *= 1.1;
brainPic.xOffset *= 1.1;
brainPic.yOffset *= 1.1;
} else {
brainPic.scale /= 1.1;
brainPic.xOffset /= 1.1;
brainPic.yOffset /= 1.1;
}
}
@Override
public void mouseDragged(MouseEvent e) {// 旋转
if (buttonPressed == 1) {
if (e.getX() > x && e.getY() > y)
brainPic.zAngle -= .00f;
else if (e.getX() < x && e.getY() < y)
brainPic.zAngle += .00f;
else {
if (e.getX() > x)
brainPic.yAngle += .02f;
if (e.getX() < x)
brainPic.yAngle -= .02f;
if (e.getY() > y)
brainPic.xAngle -= .02f;
if (e.getY() < y)
brainPic.xAngle += .02f;
}
x = e.getX();
y = e.getY();
}
if (buttonPressed == 2) {// 平移
if (e.getX() > x)
brainPic.xOffset += 6;
if (e.getX() < x)
brainPic.xOffset -= 6;
if (e.getY() > y)
brainPic.yOffset += 6;
if (e.getY() < y)
brainPic.yOffset -= 6;
x = e.getX();
y = e.getY();
}
}
@Override
public void mouseClicked(MouseEvent e) {// do nothing
}
@Override
public void mouseEntered(MouseEvent e) {// do nothing
}
@Override
public void mouseExited(MouseEvent e) {// do nothing
}
@Override
public void mouseMoved(MouseEvent e) { // do nothing
}
}

View File

@ -55,9 +55,10 @@ public class Organ implements Serializable, Cloneable {// 因为要保存在蛋
// 以下是各种器官类型每个神经元都属于一个器官每个器官都有一个type类型参数
public static final int EMPTY = 0;// 空细胞不处理光子
public static final int MOVE = 1;// 会让光子沿直线走一格
public static final int MOVE_DIG = 2;// 会让光子沿直线走一格并在下一个细胞上打洞
public static final int MOVE_JELLY = 2;// 会让光子沿直线走一格并在下一个细胞上打洞
public static final int EYE = 3;// 眼细胞会根据cell激活度产生发散到各个方向的光子
public static final int EAR = 4;// 耳细胞,类似眼细胞,不同点是为了简化脑内听觉区和输入区混用一个区所以它也可吸收光子倒过来激活cell
public static final int TOPEAR = 4;// 耳细胞,类似眼细胞,不同点是为了简化脑内听觉区和输入区混用一个区所以它也可吸收光子倒过来激活cell
public static final int FRONTEAR = 8;// 耳细胞,类似眼细胞,不同点是为了简化脑内听觉区和输入区混用一个区所以它也可吸收光子倒过来激活cell
public static final int JELLY = 5; // 光子在当前细胞上可以打出洞来
public static final int STATIC = 6; // 只有静态洞的细胞它忽略动态洞参数
public static final int MIX = 7; // 同时具有静态和动态洞的细胞

View File

@ -25,7 +25,7 @@ public class Eye extends Organ {// 眼睛是长方体
private static final long serialVersionUID = 1L;
public Eye() {
this.shape = new Cuboid(0, 3, 14, 1, 13, 13);
this.shape = new Cuboid(0, 3, 2, 1, 13, 13);
this.type = Organ.EYE;
this.organName = "Eye";
this.allowVary = false;// 不允许变异

View File

@ -0,0 +1,72 @@
/*
* 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.gitee.drinkjava2.frog.brain.organ;
import com.gitee.drinkjava2.frog.Frog;
import com.gitee.drinkjava2.frog.brain.Cuboid;
import com.gitee.drinkjava2.frog.brain.Organ;
import com.gitee.drinkjava2.frog.util.ColorUtils;
/**
* Ear can accept sound input
*
* 耳朵的信号输入区能输入多少个信号取决于它的长度它的每个输入点都与视觉视号正交
*
* 耳朵的输入区在2021年6月后改只取 0,2,4,6,8处的细胞作为输入点以获取更清晰反向激活信号这样总共就是5个有效输入点
*
* 耳朵目前只有一个, 以后可以在侧面再开一个耳朵就可以达到5x5=25个声音的输入
*
* 为简单化耳朵的识别区和输入区重叠而不是象人脑一样有单独的虚拟声音将来在信号强度上作区分直接听到的信号强度大反向激活后得到的信号弱
*
* @author Yong Zhu
* @since 2.0.2
*/
@SuppressWarnings("all")
public class FrontEar extends Organ {// frontEar耳朵位于脑的前侧也是长方体
private static final long serialVersionUID = 1L;
public FrontEar() {
this.shape = new Cuboid(14, 0, 5, 1, 1, 10);// 手工固定耳区的大小
this.type = Organ.FRONTEAR;
this.organName = "FrontEar";
this.allowVary = false;// 不允许变异
this.allowBorrow = false;// 不允许借出
this.color = ColorUtils.BLUE;
}
public void hearSound(Frog f, int code) {//code取0~4分听代表5个听力细胞的位置
Cuboid c = (Cuboid) this.shape;
int zz = code % 5;
f.getOrCreateCell(c.x , c.y , c.z+zz*2).hasInput = true; //听力细胞间隔一个分布
}
public int readcode(Frog f) {//找出收取光子数最多的点
int temp = -10000;
int code = -1;
Cuboid c = (Cuboid) this.shape;
System.out.print("Ear received photons qty: ");
for (int z = 0; z <= 4; z++) {
int sum = f.getOrCreateCell(c.x, c.y , c.z+z*2).photonSum;
System.out.print(sum + ",");
if (sum > temp) {
code = z;
temp = sum;
}
}
return code; //code表示保存韵母最大激活信号的y方向序号
}
/** 给这个耳朵听到一个字母,激活它的听觉输入区, 注意听觉输入区并不等于听觉成像区 */
public void hearNothing(Frog f) {
f.setCuboidVales((Cuboid) shape, false);
}
}

View File

@ -21,14 +21,14 @@ import com.gitee.drinkjava2.frog.brain.Organ;
*
* @author Yong Zhu
*/
public class Move1 extends Organ {
public class MoveJelly extends Organ {
private static final long serialVersionUID = 1L;
public Move1() {
public MoveJelly() {
super();
this.shape = new Cuboid(0, 0, 0, 9 , Env.FROG_BRAIN_YSIZE, Env.FROG_BRAIN_ZSIZE-1);
this.organName = "MOVE1";
this.type = Organ.MOVE; // MOVE类型的细胞会保持光子的直线运动并不在细胞上挖洞
this.shape = new Cuboid(0, 0, 0, Env.FROG_BRAIN_XSIZE , Env.FROG_BRAIN_YSIZE, Env.FROG_BRAIN_ZSIZE);
this.organName = "MoveJelly";
this.type = Organ.MOVE_JELLY; // Empty这个器官并不播种cell,它存在的唯一目的只是充当光子媒介否则光子会一直走下去消失
this.allowVary = false;// 不允许变异
this.allowBorrow = false;// 不允许借出
}

View File

@ -31,13 +31,13 @@ import com.gitee.drinkjava2.frog.util.ColorUtils;
* @since 2.0.2
*/
@SuppressWarnings("all")
public class Ear extends Organ {// 耳朵位于脑的顶上也是长方体
public class TopEar extends Organ {// 耳朵位于脑的顶上也是长方体
private static final long serialVersionUID = 1L;
public Ear() {
this.shape = new Cuboid(11, 5, 20, 10, 10, 1);// 手工固定耳区的大小
this.type = Organ.EAR;
this.organName = "Ear";
public TopEar() {
this.shape = new Cuboid(6, 5, Env.FROG_BRAIN_ZSIZE - 1, 1, 10, 1);// 手工固定耳区的大小
this.type = Organ.TOPEAR;
this.organName = "TopEar";
this.allowVary = false;// 不允许变异
this.allowBorrow = false;// 不允许借出
this.color = ColorUtils.BLUE;
@ -45,32 +45,29 @@ public class Ear extends Organ {// 耳朵位于脑的顶上,也是长方体
public void hearSound(Frog f, int code) {//code取0~4分听代表5个听力细胞的位置
Cuboid c = (Cuboid) this.shape;
int x = code / 5;
int y = code % 5;
f.getOrCreateCell(c.x + x * 2, c.y + y * 2, c.z).hasInput = true; //听力细胞间隔一个分布
int y1 = code / 5;
f.getOrCreateCell(c.x , c.y+y1*2 , c.z).hasInput = true; //听力细胞间隔一个分布
}
public int readcode(Frog f) {//找出收取光子数最多的点
int temp = -10000;
int code = -1;
Cuboid c = (Cuboid) this.shape;
System.out.print("Ear received photons qty: ");
for (int x = 0; x <=4; x++)
for (int y = 0; y <= 4; y++) {
int sum = f.getOrCreateCell(c.x+x*2, c.y + y * 2, c.z).photonSum;
System.out.print(sum + ",");
if (sum > temp) {
code = x*5 + y;
temp = sum;
}
public int readcode(Frog f) {//找出收取光子数最多的点
int temp = -10000;
int code = -1;
Cuboid c = (Cuboid) this.shape;
System.out.print("Ear received photons qty: ");
for (int y = 0; y <= 4; y++) {
int sum = f.getOrCreateCell(c.x, c.y + y * 2, c.z).photonSum;
System.out.print(sum + ",");
if (sum > temp) {
code = y;
temp = sum;
}
System.out.println();
return code;
}
}
return code; //code表示保存声母最大激活信号的y方向序号
}
/** 给这个耳朵听到一个字母,激活它的听觉输入区, 注意听觉输入区并不等于听觉成像区 */
public void hearNothing(Frog f) {
f.setCuboidVales((Cuboid) shape, false);
}
/** 给这个耳朵听到一个字母,激活它的听觉输入区, 注意听觉输入区并不等于听觉成像区 */
public void hearNothing(Frog f) {
f.setCuboidVales((Cuboid) shape, false);
}
}

View File

@ -16,11 +16,10 @@ import java.util.List;
import com.gitee.drinkjava2.frog.Frog;
import com.gitee.drinkjava2.frog.brain.Organ;
import com.gitee.drinkjava2.frog.brain.organ.Ear;
import com.gitee.drinkjava2.frog.brain.organ.Eye;
import com.gitee.drinkjava2.frog.brain.organ.Move1;
import com.gitee.drinkjava2.frog.brain.organ.Move2;
import com.gitee.drinkjava2.frog.brain.organ.MoveDig;
import com.gitee.drinkjava2.frog.brain.organ.FrontEar;
import com.gitee.drinkjava2.frog.brain.organ.MoveJelly;
import com.gitee.drinkjava2.frog.brain.organ.TopEar;
import com.gitee.drinkjava2.frog.util.RandomUtils;
/**
@ -39,11 +38,10 @@ public class Egg implements Serializable {
public List<Organ> organs = new ArrayList<>();// NOSONAR
public Egg() {// 无中生有创建一个蛋先有蛋后有蛙
organs.add(new Move1()); // Move即直线移动光子
organs.add(new Move2()); // Move即直线移动光子
organs.add(new MoveDig()); // MoveDig即直线移动光子的同时也在下一个细胞上用光子打出洞来这个演示里MoveDig是一个平面也就是说信息只能保存在一个平面上
organs.add(new MoveJelly()); // MoveJelly即移动光子也是果冻记忆细胞本来可以分成两个器官的图省事
organs.add(new Eye()); // 眼是手工创建的必有
organs.add(new Ear()); // 耳是手工创建的这个是用来测试ABCD字母识别的
organs.add(new TopEar()); // 耳是手工创建的这个是用来测试字母识别的, top和front分别代表声母和韵母
organs.add(new FrontEar()); // 耳是手工创建的这个是用来测试字母识别的
}
/** Create egg from frog */

View File

@ -0,0 +1,26 @@
/* Copyright 2018-2020 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.gitee.drinkjava2.frog.objects;
/**
* EnvObject means some virtual object in Env
*
* @author Yong Zhu
* @since 1.0
*/
public interface EnvObject {
public void build(); // 在Env中创建本身物体指改变Env.bricks数组元素为本身物体的组成材料只在每屏测试前调用一次
public void destory();// 从Env中清除本身物体只在每屏测试完成后调用一次
public void active(int screen); // 每个步长都会调用一次这个方法
}

View File

@ -0,0 +1,48 @@
/* Copyright 2018-2020 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.gitee.drinkjava2.frog.objects;
import static com.gitee.drinkjava2.frog.Env.ENV_HEIGHT;
import static com.gitee.drinkjava2.frog.Env.ENV_WIDTH;
import static com.gitee.drinkjava2.frog.Env.FOOD_QTY;
import static com.gitee.drinkjava2.frog.Env.bricks;
import com.gitee.drinkjava2.frog.util.RandomUtils;
/**
* Food randomly scatter on Env
*
* @author Yong Zhu
* @since 1.0
*/
public class Food implements EnvObject {
@Override
public void build() {
for (int i = 0; i < FOOD_QTY; i++) // 生成食物
bricks[RandomUtils.nextInt(ENV_WIDTH)][RandomUtils.nextInt(ENV_HEIGHT)] = Material.FOOD;
}
@Override
public void destory() {
for (int i = 0; i < ENV_WIDTH; i++) {// 清除食物
for (int j = 0; j < ENV_HEIGHT; j++)
if (bricks[i][j] == Material.FOOD)
bricks[i][j] = 0;
}
}
@Override
public void active(int screen) {
// Food do not have any active
}
}

View File

@ -13,8 +13,9 @@ package com.gitee.drinkjava2.frog.objects;
import com.gitee.drinkjava2.frog.Env;
import com.gitee.drinkjava2.frog.Frog;
import com.gitee.drinkjava2.frog.brain.BrainPicture;
import com.gitee.drinkjava2.frog.brain.organ.Ear;
import com.gitee.drinkjava2.frog.brain.organ.Eye;
import com.gitee.drinkjava2.frog.brain.organ.FrontEar;
import com.gitee.drinkjava2.frog.brain.organ.TopEar;
import com.gitee.drinkjava2.frog.util.StringPixelUtils;
/**
@ -42,7 +43,8 @@ public class LetterTester implements EnvObject {
public void active(int screen) {
Frog frog = Env.frogs.get(screen * Env.FROG_PER_SCREEN); // 这个测试只针对每屏的第一只青蛙因为脑图固定只显示第一只青蛙
Eye eye = frog.findOrganByName("Eye");
Ear ear = frog.findOrganByName("Ear");
TopEar topEar = frog.findOrganByName("TopEar");
FrontEar frontEar = frog.findOrganByName("FrontEar");
int index = Env.step / TIME;
if (Env.step % TIME == 0)
@ -50,15 +52,18 @@ public class LetterTester implements EnvObject {
if (index < STR.length()) {
BrainPicture.setNote("" + (index + 1) + "个字训练:"+STR.charAt(index));
ear.hearSound(frog, index);
topEar.hearSound(frog, index);
frontEar.hearSound(frog, index);
eye.seeImageWithOffset(frog, StringPixelUtils.getSanserif12Pixels(STR.substring(index, index + 1)),0,0);
} else {
int index2 = index % STR.length();
BrainPicture.setNote("" + (index2 + 1) + "个字识别");
eye.seeImageWithOffset(frog, StringPixelUtils.getSanserif12Pixels(STR.substring(index2, index2 + 1)),0,0);
if (Env.step % TIME > (TIME - 2)) {
int result = ear.readcode(frog);
System.out.println("Max=" + result+", 即 '"+STR.substring(result, result+1)+"'");
int c1 = topEar.readcode(frog);
int c2 = frontEar.readcode(frog);
int result = c1*5+c2;
System.out.println("c1="+c1+", c2="+c2+", result=" + result+", 即 '"+STR.substring(result, result+1)+"'");
frog.prepareNewTraining();
}
}

View File

@ -0,0 +1,41 @@
/* Copyright 2018-2020 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.gitee.drinkjava2.frog.objects;
import java.awt.Color;
/**
* Object means some thing in Env
*
* 用不同的数字常量代表虚拟环境中不同的组成材料0为空小于10的不可见大于20的将杀死在同一位置出现的青蛙,例如砖头和青蛙不可以重叠出现在同一位置
*
* @author Yong Zhu
* @since 1.0
*/
public class Material {
public static final byte NO = 0; // nothing
public static final byte SEESAW_BASE = 1; // 1~9 is invisible to frog
public static final byte VISIBLE = 10; // if>=10 will visible to frog
public static final byte FOOD = VISIBLE + 1;
public static final byte SEESAW = VISIBLE + 2;
public static final byte KILLFROG = 20; // if>=20 will kill frog
public static final byte BRICK = KILLFROG + 1;// brick will kill frog
public static final byte TRAP = KILLFROG + 2; // trap will kill frog
public static Color color(byte material) {
if (material == TRAP)
return Color.LIGHT_GRAY;
else
return Color.BLACK;
}
}

View File

@ -0,0 +1,70 @@
/* Copyright 2018-2020 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.gitee.drinkjava2.frog.util;
import java.awt.Color;
/**
* Color Utilities used in this project
*
* @author Yong Zhu
* @since 1.0
*/
public class ColorUtils {
public static final int RED = 0;
public static final int ORANGE = 1;
public static final int YELLOW = 2;
public static final int GREEN = 3;
public static final int CYAN = 4;
public static final int BLUE = 5;
public static final int MAGENTA = 6;
public static final int GRAY = 7;
private static final Color[] rainbow = new Color[] { Color.RED, Color.ORANGE, Color.YELLOW, Color.GREEN, Color.CYAN,
Color.BLUE, Color.MAGENTA,Color.GRAY };
private static int nextColor = 0;
private ColorUtils() {// default private constr
}
public static int nextColorCode() {
return nextColor++;
}
public static Color nextRainbowColor() {// 返回下一个彩虹色
if (nextColor == rainbow.length)
nextColor = 0;
return rainbow[nextColor++];
}
public static Color colorByCode(int i) {// 数值取模后返回一个固定彩虹色
return rainbow[i % rainbow.length];
}
public static Color rainbowColor(float i) { // 根据数值大小范围在8种彩虹色中取值
if (i == 0)
return Color.BLACK;
if (i == 1)
return Color.RED;
if (i <= 3)
return Color.ORANGE;
if (i <= 10)
return Color.YELLOW;
if (i <= 20)
return Color.GREEN;
if (i <= 50)
return Color.CYAN;
if (i <= 100)
return Color.BLUE;
return Color.MAGENTA;
}
}

View File

@ -0,0 +1,141 @@
/* Copyright 2018-2020 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.gitee.drinkjava2.frog.util;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
/**
* File Utilities used in this project
*
* @author Yong Zhu
* @since 1.0
*/
public class FrogFileUtils {
private FrogFileUtils() {
// default constructor
}
public static boolean deleteFile(String fileFullPath) {
File file = new File(fileFullPath);
return file.delete(); // NOSONAR
}
public static void writeFile(String fileFullPath, byte[] byteArry) {
File file = new File(fileFullPath);
if (!file.getParentFile().exists())
file.getParentFile().mkdirs();
FileOutputStream fos = null;
try {
fos = new FileOutputStream(file);
fos.write(byteArry);
fos.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fos != null) {
try {
try {
fos.flush();
} catch (Exception e) {
}
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static void writeFile(String fileFullPath, String text, String encoding) {
File file = new File(fileFullPath);
if (!file.getParentFile().exists())
file.getParentFile().mkdirs();
FileOutputStream fos = null;
try {
fos = new FileOutputStream(file);
byte[] bytes;
bytes = text.getBytes(encoding);
fos.write(bytes);
fos.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fos != null) {
try {
try {
fos.flush();
} catch (Exception e) {
}
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static String readFile(String fileFullPath, String encoding) {
InputStream inputStream;
try {
inputStream = new FileInputStream(new File(fileFullPath));
} catch (FileNotFoundException e1) {
return null;
}
try {
ByteArrayOutputStream result = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) != -1)
result.write(buffer, 0, length);
String string = result.toString(encoding);
return string;
} catch (IOException e) {
e.printStackTrace();
return null;
} finally {
try {
inputStream.close();
} catch (IOException e) {
}
}
}
public static void appendFile(String fileName, String content) {
FileOutputStream fos = null;
try {
fos = new FileOutputStream(fileName, true);
fos.write(content.getBytes());
fos.write("\r\n".getBytes());
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fos != null) {
try {
try {
fos.flush();
} catch (Exception e) {
}
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}

BIN
result12_letter_test2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -214,4 +214,13 @@ T:顶视 F前视 L:左视 R:右视 X:斜视 方向键:剖视 空格:
2021-07-04 依然是模式识别演示
新增history\005a和005b两个分支目录分别演示利用改进版的体全息存贮方案和面全息存贮方案来进行模式识别。可以做到将25个任意图形和它对应的声音信号区关联起来。这两个模式的基本原理是基于信号的反向传播如果一个细胞的两个或多个不同方向同时(或短期内)收到信号,今后只要有一个信号传入,这个细胞将会向其它方向反向发送激活信号。这个模式识别原理非常简单,功能也比较原始,对于变形、扭曲、缩放、缺损的信号识别率很差,但我近期不打算进一步改进它了,而是打算另起炉灶,用三维空间的细胞分裂+遗传算法的模式,试试看能不能让电脑自动演化出具有模式识别功能的模拟生命体,也就是说实现上面发布的任务。
![result11](result11_letter_test.gif)
![result11](result11_letter_test.gif)
2021-07-04 依然是模式识别演示
新增history\005a和005b两个分支目录分别演示利用改进版的体全息存贮方案和面全息存贮方案来进行模式识别。可以做到将25个任意图形和它对应的声音信号区关联起来
![result11](result11_letter_test.gif)
这两个模式的基本原理是基于信号的反向传播,如果一个细胞的两个或多个不同方向同时(或短期内)收到信号,今后只要有一个信号传入,这个细胞将会向其它方向反向发送激活信号。这个模式识别原理非常简单,功能也比较原始,对于变形、扭曲、缩放、缺损的信号识别率很差,但考虑到实现这些功能的复杂性,我近期不打算进一步改进它了,而是打算另起炉灶,用三维空间的细胞分裂+遗传算法的模式,试试看能不能让电脑自动演化出具有简单模式识别功能的模拟生命体,也就是说实现上面发布的任务。
2021-08-13 演示同时处理多个方向的信号
位于history\005a1目录下演示用5个声母和5个韵母的组合来关联到25个图像的识别这样可以减少声音输入区的数量。它的另一个目的是演示体全息存贮的工作模式可以同时处理多个方向的信号。这个演示分辨率极差只有约一半的识别率但我不打算继续改进了。
![result12](result12_letter_test2.png)