private void EstimateAgentsState(Agent agent) { // Вычисление значений на входе в нейтронную сеть Landscape.UpdatePerception(agent); // Выполнение выбранного действия agent.MakeDecision(); }
internal void UpdateMaxGen(Agent agent) { Agent maxGenAgent; if (!_agentsMaxGen.TryGetValue(agent.Type, out maxGenAgent)) { _agentsMaxGen.Add(agent.Type, agent.DeepClone()); return; } if (maxGenAgent.Generation < agent.Generation) { _agentsMaxGen[agent.Type] = agent.DeepClone(); } }
internal void UpdateMaxAge(Agent agent) { Agent maxAgeAgent; if (!_agentsMaxAge.TryGetValue(agent.Type, out maxAgeAgent)) { _agentsMaxAge.Add(agent.Type, agent.DeepClone()); return; } if (agent.Age > maxAgeAgent.Age) { _agentsMaxAge[agent.Type] = agent.DeepClone(); } }
private void UpdatePerceptionForArea(Agent agent, SensorInputOffsets sensorInputOffset, Offset[] preceptionArea, int neg) { var agentLocation = agent.Location; var inputOffset = (int)sensorInputOffset; var allLandscapes = _allLandscapes; for (int planeIndex = 0; planeIndex < allLandscapes.Length; planeIndex++) { var plane = allLandscapes[planeIndex]; agent.Inputs[inputOffset + planeIndex] = 0; foreach (var offset in preceptionArea) { var x = Clip(agentLocation.X + (offset.Dx*neg)); var y = Clip(agentLocation.Y + (offset.Dy*neg)); // Если в полученной точке что-то есть, то увеличиваем счетчик входов var agentOnPlane = plane[y, x]; if (agentOnPlane != null && agentOnPlane != agent) { agent.Inputs[inputOffset + planeIndex]++; } } } }
private void UpdatePerceptionForAllAreas(Agent agent, Offset[][] offsets, int neg) { UpdatePerceptionForArea(agent, SensorInputOffsets.HerbivoreFront, offsets[0], neg); UpdatePerceptionForArea(agent, SensorInputOffsets.HerbivoreLeft, offsets[1], neg); UpdatePerceptionForArea(agent, SensorInputOffsets.HerbivoreRight, offsets[2], neg); UpdatePerceptionForArea(agent, SensorInputOffsets.HerbivoreProximity, offsets[3], neg); }
private void ReproduceAgent(Agent agent) { // Не даем агенту одного типа занять более половины дотупных ячеек if (Statistics.AgentTypeCounts[agent.Type] >= MaxAgents / 2) { return; } // Найти пустое место и скопировать агента. При этом происходит мутация одного веса или смещение в нейронной сети агента var emptyAgentIndex = 0; for (; emptyAgentIndex < Agents.Length; emptyAgentIndex++) { if (Agents[emptyAgentIndex] == null) { break; } } if (emptyAgentIndex == Agents.Length) { return; } var child = agent.BornChild(); Agents[emptyAgentIndex] = child; FindEmptySpotAndFill(child); Statistics.UpdateMaxGen(child); Statistics.AgentTypeCounts[child.Type]++; Statistics.AgentTypeReproductions[child.Type]++; }
private void RemoveAgentFromPlane(Agent agent) { var type = (int)agent.Type; _agentLandscapes[type][agent.Location.Y, agent.Location.X] = null; }
private void Move(Agent agent) { // Удаляем агента со старого места RemoveAgentFromPlane(agent); // Обновляем координаты агента var direction = (int)agent.Direction; var offset = Offsets[direction]; agent.Location = new Location(Clip(agent.Location.X + offset.Dx), Clip(agent.Location.Y + offset.Dy)); SetAgentInPosition(agent); }
public AgentBrainViewModel(Agent agent) { _agent = agent; }
private bool ChooseVictim(Agent agent, out int ox, out int oy) { // Сначала определяем слой, объект в котором будет съеден ISimulationObject[,] plane; switch (agent.Type) { case AgentType.Herbivore: plane = _plantLandscape; break; case AgentType.Carnivore: plane = GetHerbivorePlane(); break; default: throw new ArgumentException("Only herbivore and carnivore can eat"); } var location = agent.Location; // Выбираем съедаемый объект в зависимости от направления агента bool isObjectChoosen; switch (agent.Direction) { case Direction.North: isObjectChoosen = ChooseVictim(plane, location, NorthProx, 1, out ox, out oy); break; case Direction.South: isObjectChoosen = ChooseVictim(plane, location, NorthProx, -1, out ox, out oy); break; case Direction.West: isObjectChoosen = ChooseVictim(plane, location, WestProx, 1, out ox, out oy); break; case Direction.East: isObjectChoosen = ChooseVictim(plane, location, WestProx, -1, out ox, out oy); break; default: throw new ArgumentOutOfRangeException(); } return isObjectChoosen; }
private void Eat(Agent agent) { int ox; int oy; var isObjectChoosen = ChooseVictim(agent, out ox, out oy); // Объект нашли - съедаем его! if (!isObjectChoosen) { return; } switch (agent.Type) { case AgentType.Herbivore: var findedPlant = FindPlant(ox, oy); // Если растение найдено, то удаляем его и сажаем в другом месте новое if (findedPlant != null) { agent.Eat(); RemovePlantFromPlane(findedPlant); AddPlantOnPlane(findedPlant); } break; case AgentType.Carnivore: // Найти травоядное в списке агентов (по его позиции) var findedHerbivore = FindHerbivore(ox, oy); // Если нашли, то удаляем агента if (findedHerbivore != null) { agent.Eat(); KillAgent(findedHerbivore); } break; default: throw new ArgumentOutOfRangeException(); } }
internal void UpdatePerception(Agent agent) { switch (agent.Direction) { case Direction.North: UpdatePerceptionForAllAreas(agent, NorthOffsets, 1); break; case Direction.South: UpdatePerceptionForAllAreas(agent, NorthOffsets, -1); break; case Direction.West: UpdatePerceptionForAllAreas(agent, WestOffsets, 1); break; case Direction.East: UpdatePerceptionForAllAreas(agent, WestOffsets, -1); break; default: throw new ArgumentOutOfRangeException(); } }
private void AddAgent(Agent agent) { Statistics.AgentTypeCounts[agent.Type]++; FindEmptySpotAndFill(agent); }
public AgentViewModel(VisualAgentType type, Agent agent) { _type = type; _agent = agent; }
internal AgentBrainViewModel(Agent agent) { _agent = agent; }
private static Agent CreateDesignAgent() { var agent = new Agent(AgentType.Carnivore); agent.Inputs = Enumerable.Range(0, Agent.MaxInputs).ToArray(); agent.WeightOI = Enumerable.Range(0, Agent.TotalWeights).ToArray(); agent.Outputs = Enumerable.Range(0, Agent.MaxOutputs).ToArray(); agent.Action = AgentAction.Eat; return agent; }
internal void SetAgentInPosition(Agent agent) { // Помещаем агента в новое место var type = (int)agent.Type; _agentLandscapes[type][agent.Location.Y, agent.Location.X] = agent; }
private void SimulateAgent(Agent agent) { EstimateAgentsState(agent); Landscape.UpdateAgentsState(agent); }
internal void UpdateAgentsState(Agent agent) { switch (agent.Action) { case AgentAction.TurnLeft: case AgentAction.TurnRight: agent.Turn(); break; case AgentAction.Move: Move(agent); break; case AgentAction.Eat: Eat(agent); break; default: throw new ArgumentOutOfRangeException(); } // Вычитаем "потраченную" энергию agent.EnergyUpdateOnTurn(); // Если агент имеет достаточно энергии для размножения, то позволяем ему сделать это if (agent.Energy > ReproduceEnergyFactor * Agent.MaxEnergy) { ReproduceAgent(agent); } // Если энергия агента меньше или равна нулю - агент умирает // В противом случае проверяем, чне является ли этот агент самым старым if (agent.Energy <= 0) { KillAgent(agent); } else { agent.Age++; Statistics.UpdateMaxGen(agent); } }
/// <summary> /// Убиваем агента /// (Пришла смерть или агента съели) /// </summary> private void KillAgent(Agent agent) { Statistics.UpdateMaxAge(agent); int agentIndex = 0; for (; agentIndex < Agents.Length; agentIndex++) { if (Agents[agentIndex] == agent) { break; } } if (agentIndex == Agents.Length) { throw new Exception("Agent no found in list"); } Agents[agentIndex] = null; RemoveAgentFromPlane(agent); Statistics.AgentTypeCounts[agent.Type]--; Statistics.AgentTypeDeathes[agent.Type]++; }
private void FindEmptySpotAndFill(Agent agent) { agent.Location = FindEmptySpot(_agentLandscapes[(int)agent.Type]); agent.Direction = (Direction)Rand.GetRand(DirectionsCount); SetAgentInPosition(agent); }
public static int GetCellIndex(Agent agent, int columns) { var location = agent.Location; var cellIndex = columns * location.Y + location.X; return cellIndex; }