/// <summary> /// Determine the agent's position in the world relative to the prey and walls, and set its sensor inputs accordingly. /// </summary> /// <param name="agent"></param> public void SetAgentInputsAndActivate(IBlackBox agent) { // Calc prey's position relative to the agent (in polar coordinate system). PolarPoint relPos = CartesianToPolar(_preyPos - _agentPos); // Determine agent sensor input values. // Reset all inputs. agent.InputSignalArray.Reset(); // Test if prey is in sensor range. if (relPos.RadialSquared <= _sensorRangeSquared) { // Determine which sensor segment the prey is within - [0,7]. There are eight segments and they are tilted 22.5 degrees (half a segment) // such that due North, East South and West are each in the centre of a sensor segment (rather than on a segment boundary). double thetaAdjusted = relPos.Theta - PiDiv8; if (thetaAdjusted < 0.0) { thetaAdjusted += 2.0 * Math.PI; } int segmentIdx = (int)Math.Floor(thetaAdjusted / PiDiv4); // Set sensor segment's input. agent.InputSignalArray[segmentIdx] = 1.0; } // Prey closeness detector. agent.InputSignalArray[8] = relPos.RadialSquared <= 4.0 ? 1.0 : 0.0; // Wall detectors - N,E,S,W. // North. int d = (_gridSize - 1) - _agentPos._y; if (d <= 4) { agent.InputSignalArray[9] = (4 - d) / 4.0; } // East. d = (_gridSize - 1) - _agentPos._x; if (d <= 4) { agent.InputSignalArray[10] = (4 - d) / 4.0; } // South. if (_agentPos._y <= 4) { agent.InputSignalArray[11] = (4 - _agentPos._y) / 4.0; } // West. if (_agentPos._x <= 4) { agent.InputSignalArray[12] = (4 - _agentPos._x) / 4.0; } // Activate agent. agent.Activate(); }
/// <summary> /// Move the prey. The prey moves by a simple set of stochastic rules that make it more likely to move away from /// the agent, and more so when it is close. /// </summary> public void MovePrey() { // Determine if prey will move in this timestep. (Speed is simulated stochastically) if (_rng.NextDouble() > _preySpeed) { return; } // Determine position of agent relative to prey. PolarPoint relPolarPos = CartesianToPolar(_agentPos - _preyPos); // Calculate probabilities of moving in each of the four directions. This stochastic strategy is taken from: // Incremental Evolution Of Complex General Behavior, Faustino Gomez and Risto Miikkulainen (1997) // (http://nn.cs.utexas.edu/downloads/papers/gomez.adaptive-behavior.pdf) // Essentially the prey moves randomly but we bias the movements so the prey moves away from the agent, and thus // generally avoids getting eaten through stupidity. double t = T(Math.Sqrt(relPolarPos.RadialSquared)); double[] probs = new double[4]; probs[0] = Math.Exp(W(relPolarPos.Theta, Math.PI / 2.0) * t * 0.33); // North. probs[1] = Math.Exp(W(relPolarPos.Theta, 0) * t * 0.33); // East. probs[2] = Math.Exp(W(relPolarPos.Theta, Math.PI * 1.5) * t * 0.33); // South. probs[3] = Math.Exp(W(relPolarPos.Theta, Math.PI) * t * 0.33); // West. DiscreteDistribution dist = new DiscreteDistribution(probs); int action = DiscreteDistribution.Sample(_rng, dist); switch (action) { case 0: // Move north. if (_preyPos._y < _gridSize - 1) { _preyPos._y++; } break; case 1: // Move east. if (_preyPos._x < _gridSize - 1) { _preyPos._x++; } break; case 2: // Move south. if (_preyPos._y > 0) { _preyPos._y--; } break; case 3: // Move west. if (_preyPos._x > 0) { _preyPos._x--; } break; } }
/// <summary> /// Move the prey. The prey moves by a simple set of stochastic rules that make it more likely to move away from /// the agent, and more so when it is close. /// </summary> public void MovePrey() { // Determine if prey will move in this timestep. (Speed is simulated stochastically) if (_rng.NextDouble() > _preySpeed) { return; } // Determine position of agent relative to prey. PolarPoint relPolarPos = PolarPoint.FromCartesian(_agentPos - _preyPos); // Calculate probabilities of moving in each of the four directions. This stochastic strategy is taken from: // Incremental Evolution Of Complex General Behavior, Faustino Gomez and Risto Miikkulainen (1997) // (http://nn.cs.utexas.edu/downloads/papers/gomez.adaptive-behavior.pdf) // Essentially the prey moves randomly but we bias the movements so the prey moves away from the agent, and thus // generally avoids getting eaten through stupidity. double T = MovePrey_T(relPolarPos.Radial); double[] probs = new double[4]; probs[0] = Math.Exp((CalcAngleDelta(relPolarPos.Theta, Math.PI / 2.0) / Math.PI) * T * 0.33); // North. probs[1] = Math.Exp((CalcAngleDelta(relPolarPos.Theta, 0) / Math.PI) * T * 0.33); // East. probs[2] = Math.Exp((CalcAngleDelta(relPolarPos.Theta, Math.PI * 1.5) / Math.PI) * T * 0.33); // South. probs[3] = Math.Exp((CalcAngleDelta(relPolarPos.Theta, Math.PI) / Math.PI) * T * 0.33); // West. DiscreteDistribution rwl = new DiscreteDistribution(probs); int action = DiscreteDistributionUtils.Sample(rwl, _rng); switch (action) { case 0: // Move north. _preyPos._y = Math.Min(_preyPos._y + 1, _gridSize - 1); break; case 1: // Move east. _preyPos._x = Math.Min(_preyPos._x + 1, _gridSize - 1); break; case 2: // Move south. _preyPos._y = Math.Max(_preyPos._y - 1, 0); break; case 3: // Move west (is the best?) _preyPos._x = Math.Max(_preyPos._x - 1, 0); break; } }