C# - Нейронные сети - модель разумной формы жизни

 


public class Life
{ double pL, pR, pB, pT = 0.0; //значения движителей double sL, sR, sB, sT = 0.0; //значения сенсоров public int nearcount=0; //число, количество сближений данного объекта с другими (аналог, учавствовал в бою, выжил, стал сильней) - показатель силы public int borncount = 0; //число съеденных данным объектом - показатель силы public double x { get; set; } public double y { get; set; } public string id = Guid.NewGuid().ToString(); BasicNetwork network = new BasicNetwork(); Random rnd = new Random((int)(DateTime.Now.Ticks%int.MaxValue ) ); List<Life> World; public Life(List<Life> world,double X,double Y) { x = X; y = Y; pL = pR = pB = pT = 0.0; sL = sR = sB = sT = 0.0; network.AddLayer(new BasicLayer(null, true, 4)); //создание простой многослойной нейронной сети network.AddLayer(new BasicLayer(new ActivationSigmoid(), true, rnd.Next(100) + 10)); network.AddLayer(new BasicLayer(new ActivationSigmoid(), false, rnd.Next(100) + 10)); network.AddLayer(new BasicLayer(new ActivationSigmoid(), true, rnd.Next(100) + 10)); network.AddLayer(new BasicLayer(new ActivationSigmoid(), false, rnd.Next(100) + 10)); network.AddLayer(new BasicLayer(new ActivationSigmoid(), true, rnd.Next(100) + 10)); network.AddLayer(new BasicLayer(new ActivationSigmoid(), false, rnd.Next(100) + 10)); network.AddLayer(new BasicLayer(new ActivationSigmoid(), true, rnd.Next(100) + 10)); network.AddLayer(new BasicLayer(new ActivationSigmoid(), false, rnd.Next(100) + 10)); network.AddLayer(new BasicLayer(new ActivationSigmoid(), true, rnd.Next(100) + 10)); network.AddLayer(new BasicLayer(new ActivationSigmoid(), false, rnd.Next(100) + 10)); network.AddLayer(new BasicLayer(new ActivationSigmoid(), true, rnd.Next(100) + 10)); network.AddLayer(new BasicLayer(new ActivationSigmoid(), false, 4)); network.Structure.FinalizeStructure(); network.Reset(); World = world; } List<double[]> Memory = new List<double[]>(); List<double[]> MemorySense = new List<double[]>();   void Train() { if (Memory.Count>0) { network.Reset(); double[][] InputData = new double[Memory.Count][]; //подготовка данных для обучения сети double[][] SenseData = new double[Memory.Count][]; for (int i = 0; i < Memory.Count; i++) { InputData[i] = Memory[i]; SenseData[i] = MemorySense[i]; } IMLDataSet trainingSet = new BasicMLDataSet(InputData, SenseData); IMLTrain train = new ResilientPropagation(network, trainingSet);   int epoch = 1;   double old = 9999; double d = 999; do { train.Iteration(); //Console.SetCursorPosition(0, 0); //вывод информации о текущем состоянии обучения //Console.Write(@"Epoch #" + epoch + @" Error:" + train.Error); epoch++; d = Math.Abs(old - train.Error); old = train.Error; } while (train.Error > 0.0001 && epoch < 3000 && d > 0.00001);   train.FinishTraining();   //double sumd=0.0; //подсчет суммарной ошибки после обучения //foreach (IMLDataPair pair in trainingSet) //{ // IMLData output = network.Compute(pair.Input); // sumd = sumd + Math.Abs(pair.Ideal[0] - output[0]); // sumd = sumd / trainingSet.InputSize; //} } }   void SaveToMemory() { double[] Data = { sL, sR, sB, sT }; double[] SenseData = { pL, pR, pB, pT }; Memory.Add(Data); MemorySense.Add(SenseData); if (Memory.Count > 1000) { if (nearcount==0) { World.Remove(this); Life newlife = new Life(World, x, y); World.Add(newlife); } Memory.RemoveAt(0); MemorySense.RemoveAt(0); } //Console.SetCursorPosition(0, 3); //Console.Write(Memory.Count.ToString()); }   int step = 0; int stepmax = 0; public void DoLive() { RefreshSense(); //look around Move();//do step step++; if (step>stepmax ) { int maxstep = 5-(int)(sL + sR + sB + sT); stepmax = rnd.Next(40 / (maxstep)); step = 0; SaveToMemory(); Train(); } double[][] Input = { new double[] { 0, 0, 0, 0 } }; IMLDataSet trainingSet; //thinking //если я тот кто ближе слабее попробовать съесть, если нет драпать if (nearlife.borncount > borncount ) { double[][] SenseData = { new double[] { 0, 0, 0, 0 } }; trainingSet = new BasicMLDataSet(Input, SenseData); } else { double[][] SenseData = { new double[] { 1, 1, 1, 1 } }; trainingSet = new BasicMLDataSet(Input, SenseData); } IMLData output = network.Compute(trainingSet[0].Ideal ); if (output[0] > pL) { pL += 0.001; } else { pL -= 0.001; } if (output[1] > pR) { pR += 0.001; } else { pR -= 0.001; } if (output[2] > pB) { pB += 0.001; } else { pB -= 0.001; } if (output[3] > pT) { pT += 0.001; } else { pT -= 0.001; }   }       void Move() { if (pL>0.01) { pL = 0.01; } else if (pL < 0) { pL = 0; } if (pR > 0.01) { pR = 0.01; } else if (pR < 0) { pR = 0; } if (pB > 0.01) { pB = 0.01; } else if (pB < 0) { pB = 0; } if (pT > 0.01) { pT = 0.01; } else if (pT < 0) { pT = 0; } x += pL - pR; y += pB - pT; if (x < 0) { x = 1 - x; } if (y < 0) { y = 1 - y; } if (x > 1) { x = x - 1; } if (y > 1) { y = y - 1; } } Life nearlife = null; void RefreshSense() { ret1: double mind = 99999;   try { foreach (Life life in World) { if (life.id != this.id) { var d = GetDistLife(life); if (d < mind) { mind = d; nearlife = life; if (d < 0.008) { if (rnd.NextDouble() > 0.5)//born new life form 60% { //Life newlife = new Life(World, x , y ); //world.Add(newlife); borncount += 1; if (borncount > 5) { borncount = 5; } nearlife.borncount += 1; if (nearlife.borncount > 5) { nearlife.borncount = 5; } if (nearlife.nearcount < nearcount) { World.Remove(nearlife); } else { World.Remove(this); } //World.Remove(nearlife); //World.Remove(this); goto ret1; } nearcount += 1; if (nearcount > 5) { nearcount = 5; } nearlife.nearcount += 1; if (nearlife.nearcount > 5) { nearlife.nearcount = 5; } //x = (rnd.NextDouble()+x)/2; //y = (rnd.NextDouble()+y)/2; //life.x = (rnd.NextDouble() + 0.04 + life.x) / 2; //life.y = (rnd.NextDouble() + 0.04 + life.y) / 2; } } } } } catch (Exception) { goto ret1; }   if (nearlife != null) { sL = GetDist(x - 0.05, nearlife.x, y, nearlife.y); sR = GetDist(x + 0.05, nearlife.x, y, nearlife.y); sB = GetDist(x, nearlife.x, y - 0.05, nearlife.y); sT = GetDist(x, nearlife.x, y + 0.05, nearlife.y); } }   double GetDistLife(Life l1) { return GetDist(l1.x, x, l1.y, y); }   double GetDist(double x1, double x2, double y1, double y2) { return Math.Sqrt(Math.Pow(x1 - x2, 2) + Math.Pow(y1 - y2, 2)); } }

Комментарии

Популярные сообщения