/// <summary> /// Evaluation unit constructor. /// </summary> /// <param name="mazeStructure">The maze structure on which the agent is evaluated.</param> /// <param name="agentPhenome">The agent ANN phenome.</param> /// <param name="mazeId">The unique maze identifier.</param> /// <param name="agentId">The unique agent identifier.</param> public MazeNavigatorEvaluationUnit(MazeStructure mazeStructure, IBlackBox agentPhenome, int mazeId, int agentId) { MazePhenome = mazeStructure; AgentPhenome = agentPhenome; MazeId = mazeId; AgentId = agentId; }
/// <summary> /// Configures and instantiates the initialization evolutionary algorithm. /// </summary> /// <param name="parallelOptions">Synchronous/Asynchronous execution settings.</param> /// <param name="genomeList">The initial population of genomes.</param> /// <param name="genomeFactory">The genome factory initialized by the main evolution thread.</param> /// <param name="mazeEnvironment">The maze on which to evaluate the navigators.</param> /// <param name="genomeDecoder">The decoder to translate genomes into phenotypes.</param> /// <param name="startingEvaluations"> /// The number of evaluations that preceeded this from which this process will pick up /// (this is used in the case where we're restarting a run because it failed to find a solution in the allotted time). /// </param> public override void InitializeAlgorithm(ParallelOptions parallelOptions, List <NeatGenome> genomeList, IGenomeFactory <NeatGenome> genomeFactory, MazeStructure mazeEnvironment, IGenomeDecoder <NeatGenome, IBlackBox> genomeDecoder, ulong startingEvaluations) { // Set the boiler plate algorithm parameters base.InitializeAlgorithm(parallelOptions, genomeList, genomeDecoder, startingEvaluations); // Create the initialization evolution algorithm. InitializationEa = new GenerationalComplexifyingEvolutionAlgorithm <NeatGenome>(SpeciationStrategy, ComplexityRegulationStrategy, RunPhase.Initialization); // Create IBlackBox evaluator. MazeNavigatorFitnessInitializationEvaluator mazeNavigatorEvaluator = new MazeNavigatorFitnessInitializationEvaluator(MinSuccessDistance, MaxDistanceToTarget, mazeEnvironment, startingEvaluations); // Create the genome evaluator IGenomeEvaluator <NeatGenome> fitnessEvaluator = new ParallelGenomeFitnessEvaluator <NeatGenome, IBlackBox>( genomeDecoder, mazeNavigatorEvaluator, parallelOptions); // Only pull the number of genomes from the list equivalent to the initialization algorithm population size // (this is to handle the case where the list was created in accordance with the primary algorithm // population size, which is quite likely larger) genomeList = genomeList.Take(PopulationSize).ToList(); // Replace genome factory primary NEAT parameters with initialization parameters ((NeatGenomeFactory)genomeFactory).ResetNeatGenomeParameters(NeatGenomeParameters); // Initialize the evolution algorithm InitializationEa.Initialize(fitnessEvaluator, genomeFactory, genomeList, null, null); }
/// <summary> /// Initializes the MazeCell. pos is in data-space. /// </summary> public void Init(MazeStructure mazeStruct, Point3 pos, Mesh cellFloor, Mesh cellWall, Mesh cellWallTop, Material cellFloorMat, Material cellWallMat, Material cellWallTopMat, VectorSpaceish vectors) { // create cell floor floor = new GameObject("floor - " + cellFloor.name); floor.AddComponent <MeshFilter>().mesh = Morph(cellFloor, mazeStruct, vectors, false); floor.AddComponent <MeshRenderer>().material = (Material)Instantiate(cellFloorMat); floor.transform.parent = transform; // create cell wall wall = new GameObject("cell wall - " + cellWall.name); wall.AddComponent <MeshFilter>().mesh = Morph(cellWall, mazeStruct, vectors, true); wall.AddComponent <MeshCollider>().sharedMesh = wall.GetComponent <MeshFilter>().mesh; wall.AddComponent <MeshRenderer>().material = (Material)Instantiate(cellWallMat); wall.transform.parent = transform; // create cell wall top wallTop = new GameObject("cell wall top - " + cellWallTop.name); wallTop.AddComponent <MeshFilter>().mesh = Morph(cellWallTop, mazeStruct, vectors, true); wallTop.AddComponent <MeshRenderer>().material = (Material)Instantiate(cellWallTopMat); wallTop.transform.parent = transform; plane = new Plane(vectors.vy, vectors.v00); children = new GameObject[] { floor, wall, wallTop }; }
// Use this for initialization void Start() { // initialize all MazeTools MazeTool[] tools = { top, bottom, left, right, back, front }; for (int i = 0; i < tools.Length; i++) { tools[i].Start(); tools[i].gameObject.SetActive(false); } // initialize the MazeStructure mazeStruct = new MazeStructure(top, bottom, left, right, front, back, radius); cells = mazeStruct.MakeCells(cellFloor, cellWalls, cellWallTops, cellFloorMat, cellWallMat, cellWallTopMat, lightFlicker, radius); // initialize this transform.position = mazeStruct.GetStartSphere(); skyboxMaterial = Resources.Load <Material>("Overcast2 Skybox"); skyboxMaterial.SetColor("_Tint", new Color32((byte)128, (byte)128, (byte)128, (byte)128)); GetComponent <OVRCameraRig>().Init(); this.playerRigid = gameObject.AddComponent <Rigidbody> (); this.playerRigid.freezeRotation = true; Physics.gravity = Vector3.zero; SphereCollider collider = gameObject.AddComponent <SphereCollider>(); collider.material = (PhysicMaterial)Resources.Load("WallPhysics", typeof(PhysicMaterial)); collider.radius = 1.5f; collider.center = new Vector3(0, .4f, 0); // initialize other objects Vector3 keyPos = mazeStruct.FindKeySphere().normalized *(radius - 2.5f); Quaternion keyRot = Quaternion.LookRotation(Vector3.Cross(-keyPos, Vector3.one), -keyPos); key = (Key)Instantiate(key, keyPos, keyRot); cLight = ((GameObject)Instantiate(cLight.gameObject, cLight.gameObject.transform.localPosition, Quaternion.identity)).GetComponent <Light>(); lights = ((GameObject)Instantiate(lights.gameObject, new Vector3(85.4f, 100f, 100f), Quaternion.identity)).GetComponent <LightSystem>(); lamp = ((GameObject)Instantiate(lamp.gameObject, lamp.gameObject.transform.localPosition, Quaternion.identity)).GetComponent <Lamp>(); lamp.transform.rotation = Quaternion.Euler(70.7834f, 342.207f, 321.425f); lamp.gameObject.SetActive(false); lantern = GameObject.Find("Lantern"); lantern.SetActive(false); // create and initialize player and monster //print("Monster: "+monster); monster = (Monster)Instantiate(monster, new Vector3(4.79f, 47.36f, -.038f), Quaternion.identity); AudioSource src = gameObject.AddComponent <AudioSource>(); src.clip = lightsOutInit; monster.gameObject.SetActive(false); angle = Mathf.PI / 2; AudioSource src1 = gameObject.AddComponent <AudioSource>(); src1.clip = lightOff; lights.Init(mazeStruct, cells, src1); }
public void PrintTestMaze() { int n = 3; MazeStructure maze = new MazeStructure(n); //maze.testDraw(); maze.testDraw(); }
/// <summary> /// Sets configuration variables specific to the maze navigation simulation. /// </summary> /// <param name="mazeStructure">The initial maze environment on which to evaluate agents.</param> /// <param name="minSuccessDistance">The minimum distance to the target location for the maze to be considered "solved".</param> public void SetEnvironmentParameters(int minSuccessDistance, MazeStructure mazeStructure) { // Set boiler plate environment parameters // (note that the max distance to the target is the diagonal of the maze environment) base.SetEnvironmentParameters( (int) Math.Sqrt(Math.Pow(mazeStructure.ScaledMazeHeight, 2) + Math.Pow(mazeStructure.ScaledMazeWidth, 2)), minSuccessDistance); }
/// <summary> /// Novelty search runner constructor. /// </summary> /// <param name="comparisonExperimentConfig"> /// The experiment configuration against which to compare the given coevolution /// experiment. /// </param> /// <param name="refExperimentName">The name of the reference (novelty search) experiment configuration.</param> /// <param name="mazeDomain">The maze on which the comparison will be executed.</param> /// <param name="currentRun">The current run being analyzed.</param> /// <param name="totalRuns">The total number of runs in the coevolution experiment.</param> /// <param name="executionLogger">Execution file logger.</param> public NoveltySearchRunner(ExperimentDictionary comparisonExperimentConfig, string refExperimentName, MazeStructure mazeDomain, int currentRun, int totalRuns, ILog executionLogger) { _comparisonExperimentConfig = comparisonExperimentConfig; _referenceExperimentName = refExperimentName; _evaluationMazeDomain = mazeDomain; _currentRun = currentRun; _totalRuns = totalRuns; _executionLogger = executionLogger; }
/// <inheritdoc /> /// <summary> /// Maze Navigator fitness initialization evaluator constructor. /// </summary> /// <param name="minSuccessDistance">The minimum distance from the target to be considered a successful run.</param> /// <param name="maxDistanceToTarget">The maximum distance from the target possible.</param> /// <param name="initialMazeStructure"> /// The maze structure with which to seed the list of maze structures in the maze /// factory. /// </param> /// <param name="startingEvaluations">The number of evaluations from which the evaluator is starting (defaults to 0).</param> public MazeNavigatorFitnessInitializationEvaluator(int minSuccessDistance, int maxDistanceToTarget, MazeStructure initialMazeStructure, ulong startingEvaluations = 0) : this(minSuccessDistance, maxDistanceToTarget, startingEvaluations) { // Add initial maze structure _multiMazeWorldFactory.SetMazeConfigurations(new List <MazeStructure>(1) { initialMazeStructure }); }
public void Init(MazeStructure mazeStruct, MazeCell[, ,] cells, Transform player, Vector3 startPos) { this.player = player; this.mazeStruct = mazeStruct; transform. transform.position = startPos; this.startPos = startPos; sounds = player.gameObject.AddComponent <AudioSource>(); sightEstab = Resources.LoadAssetAtPath <AudioClip>("Assets/Sounds/grudge-sound.wav"); sightLost = Resources.LoadAssetAtPath <AudioClip>("Assets/Sounds/SuspensefulViolinPopcorn.wav"); gameObject.SetActive(true); mesh = GetComponent <MeshFilter>().mesh; }
/// <summary> /// Constructs a new maze navigation world using the given maze structure and behavior characterization. /// </summary> /// <param name="mazeStructure">The maze structure to convert into a maze configuration.</param> /// <param name="behaviorCharacterization"> /// The way in which an agents behavior is characterized (i.e. end point, /// trajectory, etc.). /// </param> /// <returns>A constructed maze navigation world ready for evaluation.</returns> public MazeNavigationWorld <TTrialInfo> CreateMazeNavigationWorld(MazeStructure mazeStructure, IBehaviorCharacterization behaviorCharacterization) { // Build the single maze configuration var mazeConfig = new MazeConfiguration(ExtractMazeWalls(mazeStructure.Walls), ExtractStartEndPoint(mazeStructure.StartLocation), ExtractStartEndPoint(mazeStructure.TargetLocation), mazeStructure.MaxTimesteps); // Create maze navigation world and return return(new MazeNavigationWorld <TTrialInfo>(mazeConfig.Walls, mazeConfig.NavigatorLocation, mazeConfig.GoalLocation, _minSuccessDistance, _maxDistanceToTarget, mazeConfig.MaxSimulationTimesteps, behaviorCharacterization)); }
/// <summary> /// Generates a bitmap image of the given maze structure (no agent trajectory). /// </summary> /// <param name="imagePathName">Image path and filename.</param> /// <param name="mazeStructure">The structure of the maze.</param> /// <param name="drawSolutionPath">Flag which controls whether or not solution trajectory is rendered.</param> public static void GenerateMazeStructureImage(string imagePathName, MazeStructure mazeStructure, bool drawSolutionPath) { // Create pen and initialize bitmap canvas Pen blackPen = new Pen(Color.Black, 0.0001f); Bitmap mazeBitmap = new Bitmap(mazeStructure.ScaledMazeWidth + 1, mazeStructure.ScaledMazeHeight + 1); using (Graphics graphics = Graphics.FromImage(mazeBitmap)) { // Fill with white Rectangle imageSize = new Rectangle(0, 0, mazeStructure.ScaledMazeWidth + 1, mazeStructure.ScaledMazeHeight + 1); graphics.FillRectangle(Brushes.White, imageSize); // Draw start and end points graphics.FillEllipse(Brushes.Green, mazeStructure.StartLocation.X, mazeStructure.StartLocation.Y, 5, 5); graphics.FillEllipse(Brushes.Red, mazeStructure.TargetLocation.X, mazeStructure.TargetLocation.Y, 5, 5); // Draw all of the walls foreach (MazeStructureWall wall in mazeStructure.Walls) { // Convert line start/end points to Point objects from drawing namespace Point startPoint = new Point(wall.StartMazeStructurePoint.X, wall.StartMazeStructurePoint.Y); Point endPoint = new Point(wall.EndMazeStructurePoint.X, wall.EndMazeStructurePoint.Y); // Draw wall graphics.DrawLine(blackPen, startPoint, endPoint); } // Add solution path to image if enabled if (drawSolutionPath) { // Draw the solution trajectory/path for (int y = 0; y < mazeStructure.MazeGrid.Grid.GetLength(0); y++) { for (int x = 0; x < mazeStructure.MazeGrid.Grid.GetLength(1); x++) { if (PathDirection.None != mazeStructure.MazeGrid.Grid[y, x].PathDirection) { graphics.FillEllipse(Brushes.DarkViolet, (x * mazeStructure.ScaleMultiplier) + (mazeStructure.ScaleMultiplier / 2), (y * mazeStructure.ScaleMultiplier) + (mazeStructure.ScaleMultiplier / 2), 5, 5); } } } } } // Save the bitmap image mazeBitmap.Save(imagePathName); }
/// <summary> /// Generates a single bitmap image of the trajectory of an agent through the given maze. /// </summary> /// <param name="imagePathName">Image path and filename.</param> /// <param name="mazeStructure">The structure of the maze on which the trial was run.</param> /// <param name="agentTrajectory">The trajectory of the agent through the maze.</param> /// <param name="startEndPointSize">The size of the start and end location points.</param> /// <param name="trajectoryPointSize">The size of a point on the agent's trajectory.</param> private static void GenerateSingleMazeTrajectoryImage(string imagePathName, MazeStructure mazeStructure, double[] agentTrajectory, int startEndPointSize, int trajectoryPointSize) { // Create pen and initialize bitmap canvas Pen blackPen = new Pen(Color.Black, 0.0001f); Bitmap mazeBitmap = new Bitmap(mazeStructure.ScaledMazeWidth + 1, mazeStructure.ScaledMazeHeight + 1); using (Graphics graphics = Graphics.FromImage(mazeBitmap)) { // Fill with white Rectangle imageSize = new Rectangle(0, 0, mazeStructure.ScaledMazeWidth + 1, mazeStructure.ScaledMazeHeight + 1); graphics.FillRectangle(Brushes.White, imageSize); // Draw start and end points graphics.FillEllipse(Brushes.Green, mazeStructure.StartLocation.X, mazeStructure.StartLocation.Y, startEndPointSize, startEndPointSize); graphics.FillEllipse(Brushes.Red, mazeStructure.TargetLocation.X, mazeStructure.TargetLocation.Y, startEndPointSize, startEndPointSize); // Draw all of the walls foreach (MazeStructureWall wall in mazeStructure.Walls) { // Convert line start/end points to Point objects from drawing namespace Point startPoint = new Point(wall.StartMazeStructurePoint.X, wall.StartMazeStructurePoint.Y); Point endPoint = new Point(wall.EndMazeStructurePoint.X, wall.EndMazeStructurePoint.Y); // Draw wall graphics.DrawLine(blackPen, startPoint, endPoint); } // Plot the navigator trajectory for (int i = 0; i < agentTrajectory.Length; i = i + 2) { // Draw trajectory point graphics.FillRectangle(Brushes.Gray, (float)agentTrajectory[i], (float)agentTrajectory[i + 1], trajectoryPointSize, trajectoryPointSize); } } // Save the bitmap image mazeBitmap.Save(imagePathName); }
public static void PrintMazeAndTrajectory(MazeStructure maze, double[] trajectory, string outputFile) { Pen blackPen = new Pen(Color.Black, 0.0001f); Bitmap mazeBitmap = new Bitmap(maze.ScaledMazeWidth + 1, maze.ScaledMazeHeight + 1); using (Graphics graphics = Graphics.FromImage(mazeBitmap)) { // Fill with white Rectangle imageSize = new Rectangle(0, 0, maze.ScaledMazeWidth + 1, maze.ScaledMazeHeight + 1); graphics.FillRectangle(Brushes.White, imageSize); // Draw start and end points graphics.FillEllipse(Brushes.Green, maze.StartLocation.X, maze.StartLocation.Y, 5, 5); graphics.FillEllipse(Brushes.Red, maze.TargetLocation.X, maze.TargetLocation.Y, 5, 5); } // Draw all of the walls foreach (MazeStructureWall wall in maze.Walls) { // Convert line start/end points to Point objects from drawing namespace Point startPoint = new Point(wall.StartMazeStructurePoint.X, wall.StartMazeStructurePoint.Y); Point endPoint = new Point(wall.EndMazeStructurePoint.X, wall.EndMazeStructurePoint.Y); using (Graphics graphics = Graphics.FromImage(mazeBitmap)) { // Draw wall graphics.DrawLine(blackPen, startPoint, endPoint); } } // Plot the navigator trajectory for (int i = 0; i < trajectory.Length; i = i + 2) { using (Graphics graphics = Graphics.FromImage(mazeBitmap)) { // Draw trajectory point graphics.FillRectangle(Brushes.Gray, (float) trajectory[i], (float) trajectory[i + 1], 1, 1); } } mazeBitmap.Save(outputFile); }
/// <summary> /// Converts the maze genome into a maze structure and prints it to a bitmap file. /// </summary> /// <param name="mazeGenome">The maze genome to convert and print.</param> /// <param name="mazeImageName">The name of the maze output file.</param> private static void PrintMazeToFile(MazeGenome mazeGenome, string mazeImageName) { // Read in the maze decode parameters int mazeScaleFactor = Int32.Parse(_executionConfiguration[ExecutionParameter.MazeScaleFactor]); string mazeBitmapOutputDirectory = _executionConfiguration[ExecutionParameter.BitmapOutputBaseDirectory]; // Instantiate the maze genome decoder MazeDecoder mazeDecoder = new MazeDecoder(mazeScaleFactor); // Decode the maze to get a maze structure MazeStructure mazeStructure = mazeDecoder.Decode(mazeGenome); // Create pen and initialize bitmap canvas Pen blackPen = new Pen(Color.Black, 0.0001f); Bitmap mazeBitmap = new Bitmap(mazeStructure.ScaledMazeWidth + 1, mazeStructure.ScaledMazeHeight + 1); using (Graphics graphics = Graphics.FromImage(mazeBitmap)) { // Fill with white Rectangle imageSize = new Rectangle(0, 0, mazeStructure.ScaledMazeWidth + 1, mazeStructure.ScaledMazeHeight + 1); graphics.FillRectangle(Brushes.White, imageSize); // Draw start and end points graphics.FillEllipse(Brushes.Green, mazeStructure.StartLocation.X, mazeStructure.StartLocation.Y, 5, 5); graphics.FillEllipse(Brushes.Red, mazeStructure.TargetLocation.X, mazeStructure.TargetLocation.Y, 5, 5); // Draw all of the walls foreach (MazeStructureWall wall in mazeStructure.Walls) { // Convert line start/end points to Point objects from drawing namespace Point startPoint = new Point(wall.StartMazeStructurePoint.X, wall.StartMazeStructurePoint.Y); Point endPoint = new Point(wall.EndMazeStructurePoint.X, wall.EndMazeStructurePoint.Y); // Draw wall graphics.DrawLine(blackPen, startPoint, endPoint); } } // Save the bitmap image mazeBitmap.Save(Path.Combine(mazeBitmapOutputDirectory, mazeImageName)); }
private Mesh Morph(Mesh m, MazeStructure mazeStruct, VectorSpaceish vectors, bool invertTris) { Mesh result = new Mesh(); // create new vertices, the Vector Space given by x,y,z, with base at a Vector3[] verts = new Vector3[m.vertices.Length]; for (int i = 0; i < verts.Length; ++i) { verts[i] = (100 * m.vertices[i]) + new Vector3(1, 0, 1); if (verts[i].x <-0.01f || verts[i].y <-0.01f || verts[i].z <-0.01f || verts[i].x> 1.01f || verts[i].y> 1.01f || verts[i].z> 1.01f) { throw new Exception("Mesh vertices out of range for MazeCell (mesh is " + m.name + ", vertex is at (" + verts[i].x + ", " + verts[i].y + ", " + verts[i].z + "))"); } Vector3 floor = vectors.Translate(verts[i], false); verts[i] = vectors.Translate(verts[i], true); verts[i] = mazeStruct.Vector3FromCubeToSphere(verts[i], floor); } result.vertices = verts; // handle triangles if (invertTris) { int[] tris = new int[m.triangles.Length]; for (int i = 0; i < tris.Length; ++i) { tris[i] = m.triangles[tris.Length - i - 1]; } result.triangles = tris; } else { result.triangles = (int[])m.triangles.Clone(); } // directly copy uvs, calculate normals, optimize result.uv = (Vector2[])m.uv.Clone(); result.RecalculateNormals(); result.Optimize(); return(result); }
/// <summary> /// Takes a Point3 in data coordinates. /// </summary> public Pathfinding(MazeStructure maze, bool[, ,] walls, Point3 center) { // initialize member variables this.center = center; this.maze = maze; //Debug.Log(center); data = new int[walls.GetLength(0), walls.GetLength(1), walls.GetLength(2)]; data.Initialize(); // create visited matrix bool[, ,] visited = new bool[walls.GetLength(0), walls.GetLength(1), walls.GetLength(2)]; visited.Initialize(); // initialize vars Queue <VisitPoint> toVisit = new Queue <VisitPoint>(walls.GetLength(0) * walls.GetLength(1)); toVisit.Enqueue(new VisitPoint(center, 0)); // visit every possible cell while (toVisit.Count > 0) { // visit the given cell int value = toVisit.Peek().value; Point3 pos = toVisit.Dequeue().pos; data[pos.x, pos.y, pos.z] = value; visited[pos.x, pos.y, pos.z] = true; // add appropriate neighbors to toVisit Point3[] neighbors = Point3.Scramble(pos.neighbors(2)); foreach (Point3 newPos in neighbors) { if (maze.ValidMove(pos, newPos) && (!visited[newPos.x, newPos.y, newPos.z])) { toVisit.Enqueue(new VisitPoint(newPos, value + 1)); } } } }
public void North_South_Questions_Are_The_Same_On_Either_Side_Of_Door() { int n = 3; MazeStructure maze = new MazeStructure(n); maze.testDraw(); //maze.testDraw(); for (int i = 1; i < maze.size; i++) { for (int j = 0; j < maze.size; j++) { if (maze.ValidIndex(i - 1)) { if (!maze.NorthWall[i, j]) { Console.WriteLine($"({i},{j}) north question {maze._QuestionsList[maze.NorthQuestion[i, j]].CorrectAnswer} matches south question {maze._QuestionsList[maze.SouthQuestion[i - 1, j]].CorrectAnswer} of ({i - 1},{j})"); Assert.IsTrue(ReferenceEquals(maze._QuestionsList[maze.NorthQuestion[i, j]], maze._QuestionsList[maze.SouthQuestion[i - 1, j]])); } } } } }
public void East_West_Questions_Are_The_Same_On_Either_Side_Of_Door() { int n = 3; MazeStructure maze = new MazeStructure(n); //maze.testDraw(); maze.TestDraw(); for (int i = 1; i < maze.size; i++) { for (int j = 0; j < maze.size; j++) { if (maze.ValidIndex(j + 1)) { if (!maze.EastWall[i, j]) { Console.WriteLine($"({i},{j}) east question {maze._QuestionsList[maze.EastQuestion[i, j]].CorrectAnswer} matches west question {maze._QuestionsList[maze.WestQuestion[i, j + 1]].CorrectAnswer} of ({i},{j + 1})"); Assert.IsTrue(ReferenceEquals(maze._QuestionsList[maze.EastQuestion[i, j]], maze._QuestionsList[maze.WestQuestion[i, j + 1]])); } } } } }
public DataModel() { mazeStructure = new MazeStructure(); solverAgentList = new SolverAgentList(); }
/// <summary> /// Configures and instantiates the initialization evolutionary algorithm. /// </summary> /// <param name="parallelOptions">Synchronous/Asynchronous execution settings.</param> /// <param name="genomeList">The initial population of genomes.</param> /// <param name="genomeFactory">The genome factory initialized by the main evolution thread.</param> /// <param name="mazeEnvironment">The maze on which to evaluate the navigators.</param> /// <param name="genomeDecoder">The decoder to translate genomes into phenotypes.</param> /// <param name="startingEvaluations"> /// The number of evaluations that preceeded this from which this process will pick up /// (this is used in the case where we're restarting a run because it failed to find a solution in the allotted time). /// </param> public override void InitializeAlgorithm(ParallelOptions parallelOptions, List <NeatGenome> genomeList, IGenomeFactory <NeatGenome> genomeFactory, MazeStructure mazeEnvironment, IGenomeDecoder <NeatGenome, IBlackBox> genomeDecoder, ulong startingEvaluations) { // Set the boiler plate algorithm parameters base.InitializeAlgorithm(parallelOptions, genomeList, genomeDecoder, startingEvaluations); // Create the initialization evolution algorithm. InitializationEa = new SteadyStateComplexifyingEvolutionAlgorithm <NeatGenome>(EvolutionAlgorithmParameters, SpeciationStrategy, ComplexityRegulationStrategy, _batchSize, _populationEvaluationFrequency, RunPhase.Initialization, NavigatorEvolutionDataLogger, NavigatorEvolutionLogFieldEnableMap, NavigatorPopulationDataLogger, PopulationLoggingBatchInterval); // Create IBlackBox evaluator. MazeNavigatorNoveltySearchInitializationEvaluator mazeNavigatorEvaluator = new MazeNavigatorNoveltySearchInitializationEvaluator(MinSuccessDistance, MaxDistanceToTarget, mazeEnvironment, _behaviorCharacterizationFactory, startingEvaluations); // Create a novelty archive AbstractNoveltyArchive <NeatGenome> archive = new BehavioralNoveltyArchive <NeatGenome>(_archiveAdditionThreshold, _archiveThresholdDecreaseMultiplier, _archiveThresholdIncreaseMultiplier, _maxGenerationArchiveAddition, _maxGenerationsWithoutArchiveAddition); // Create the genome evaluator IGenomeEvaluator <NeatGenome> fitnessEvaluator = new ParallelGenomeBehaviorEvaluator <NeatGenome, IBlackBox>(genomeDecoder, mazeNavigatorEvaluator, SearchType.NoveltySearch, _nearestNeighbors); // Only pull the number of genomes from the list equivalent to the initialization algorithm population size // (this is to handle the case where the list was created in accordance with the primary algorithm // population size, which is quite likely larger) genomeList = genomeList.Take(PopulationSize).ToList(); // Replace genome factory primary NEAT parameters with initialization parameters ((NeatGenomeFactory)genomeFactory).ResetNeatGenomeParameters(NeatGenomeParameters); // Initialize the evolution algorithm InitializationEa.Initialize(fitnessEvaluator, genomeFactory, genomeList, null, null, archive); }
/// <summary> /// Evolves the requisite number of agents who satisfy the MC of the given maze. /// </summary> /// <param name="genomeFactory">The agent genome factory.</param> /// <param name="seedAgentList">The seed population of agents.</param> /// <param name="mazeStructure">The maze structure on which agents are to be evaluated.</param> /// <param name="maxInitializationEvals"> /// The maximum number of evaluations to run algorithm before restarting with new, /// randomly generated population. /// </param> /// <param name="activationScheme">The activation scheme for the NEAT agent networks (e.g. cyclic or acyclic).</param> /// <param name="parallelOptions">Synchronous/Asynchronous execution settings.</param> /// <returns>The list of viable agent genomes.</returns> public IEnumerable <NeatGenome> EvolveViableAgents(IGenomeFactory <NeatGenome> genomeFactory, List <NeatGenome> seedAgentList, MazeStructure mazeStructure, uint?maxInitializationEvals, NetworkActivationScheme activationScheme, ParallelOptions parallelOptions) { List <NeatGenome> viableMazeAgents; uint restartCount = 0; ulong initializationEvaluations; do { // Instantiate the internal initialization algorithm InitializeAlgorithm(parallelOptions, seedAgentList.ToList(), genomeFactory, mazeStructure, new NeatGenomeDecoder(activationScheme), 0); // Run the initialization algorithm until the requested number of viable seed genomes are found viableMazeAgents = RunEvolution(out initializationEvaluations, maxInitializationEvals, restartCount); restartCount++; // Repeat if maximum allotted evaluations is exceeded } while (maxInitializationEvals != null && viableMazeAgents == null && initializationEvaluations > maxInitializationEvals); return(viableMazeAgents); }
/// <summary> /// Generates a single bitmap image of the trajectory of an agent through the given maze. /// </summary> /// <param name="imagePathName">Image path and filename.</param> /// <param name="mazeStructure">The structure of the maze on which the trial was run.</param> /// <param name="agentTrajectory">The trajectory of the agent through the maze.</param> private static void GenerateSingleMazeTrajectoryImage(string imagePathName, MazeStructure mazeStructure, double[] agentTrajectory) { // Create pen and initialize bitmap canvas Pen blackPen = new Pen(Color.Black, 0.0001f); Bitmap mazeBitmap = new Bitmap(mazeStructure.ScaledMazeWidth + 1, mazeStructure.ScaledMazeHeight + 1); using (Graphics graphics = Graphics.FromImage(mazeBitmap)) { // Fill with white Rectangle imageSize = new Rectangle(0, 0, mazeStructure.ScaledMazeWidth + 1, mazeStructure.ScaledMazeHeight + 1); graphics.FillRectangle(Brushes.White, imageSize); // Draw start and end points graphics.FillEllipse(Brushes.Green, mazeStructure.StartLocation.X, mazeStructure.StartLocation.Y, 5, 5); graphics.FillEllipse(Brushes.Red, mazeStructure.TargetLocation.X, mazeStructure.TargetLocation.Y, 5, 5); // Draw all of the walls foreach (MazeStructureWall wall in mazeStructure.Walls) { // Convert line start/end points to Point objects from drawing namespace Point startPoint = new Point(wall.StartMazeStructurePoint.X, wall.StartMazeStructurePoint.Y); Point endPoint = new Point(wall.EndMazeStructurePoint.X, wall.EndMazeStructurePoint.Y); // Draw wall graphics.DrawLine(blackPen, startPoint, endPoint); } // Plot the navigator trajectory for (int i = 0; i < agentTrajectory.Length; i = i + 2) { // Draw trajectory point graphics.FillRectangle(Brushes.Gray, (float) agentTrajectory[i], (float) agentTrajectory[i + 1], 1, 1); } } // Save the bitmap image mazeBitmap.Save(imagePathName); }
/// <summary> /// Generates a bitmap image of the given maze structure (no agent trajectory). /// </summary> /// <param name="imagePathName">Image path and filename.</param> /// <param name="mazeStructure">The structure of the maze.</param> public static void GenerateMazeStructureImage(string imagePathName, MazeStructure mazeStructure) { // Create pen and initialize bitmap canvas Pen blackPen = new Pen(Color.Black, 0.0001f); Bitmap mazeBitmap = new Bitmap(mazeStructure.ScaledMazeWidth + 1, mazeStructure.ScaledMazeHeight + 1); using (Graphics graphics = Graphics.FromImage(mazeBitmap)) { // Fill with white Rectangle imageSize = new Rectangle(0, 0, mazeStructure.ScaledMazeWidth + 1, mazeStructure.ScaledMazeHeight + 1); graphics.FillRectangle(Brushes.White, imageSize); // Draw start and end points graphics.FillEllipse(Brushes.Green, mazeStructure.StartLocation.X, mazeStructure.StartLocation.Y, 5, 5); graphics.FillEllipse(Brushes.Red, mazeStructure.TargetLocation.X, mazeStructure.TargetLocation.Y, 5, 5); // Draw all of the walls foreach (MazeStructureWall wall in mazeStructure.Walls) { // Convert line start/end points to Point objects from drawing namespace Point startPoint = new Point(wall.StartMazeStructurePoint.X, wall.StartMazeStructurePoint.Y); Point endPoint = new Point(wall.EndMazeStructurePoint.X, wall.EndMazeStructurePoint.Y); // Draw wall graphics.DrawLine(blackPen, startPoint, endPoint); } } // Save the bitmap image mazeBitmap.Save(imagePathName); }
/// <summary> /// Sets configuration variables specific to the maze navigation simulation. /// </summary> /// <param name="maxTimesteps">The maximum number of time steps for which to run the simulation.</param> /// <param name="mazeStructure">The initial maze environment on which to evaluate agents.</param> /// <param name="minSuccessDistance">The minimum distance to the target location for the maze to be considered "solved".</param> public void SetEnvironmentParameters(int maxTimesteps, int minSuccessDistance, MazeStructure mazeStructure) { // Set boiler plate environment parameters // (note that the max distance to the target is the diagonal of the maze environment) base.SetEnvironmentParameters( (int) Math.Sqrt(Math.Pow(mazeStructure.ScaledMazeHeight, 2) + Math.Pow(mazeStructure.ScaledMazeWidth, 2)), maxTimesteps, minSuccessDistance); }
/// <summary> /// Configures and instantiates the initialization evolutionary algorithm. /// </summary> /// <param name="parallelOptions">Synchronous/Asynchronous execution settings.</param> /// <param name="genomeList">The initial population of genomes.</param> /// <param name="genomeFactory">The genome factory initialized by the main evolution thread.</param> /// <param name="mazeEnvironment">The maze on which to evaluate the navigators.</param> /// <param name="genomeDecoder">The decoder to translate genomes into phenotypes.</param> /// <param name="startingEvaluations"> /// The number of evaluations that preceeded this from which this process will pick up /// (this is used in the case where we're restarting a run because it failed to find a solution in the allotted time). /// </param> public abstract void InitializeAlgorithm(ParallelOptions parallelOptions, List<NeatGenome> genomeList, IGenomeFactory<NeatGenome> genomeFactory, MazeStructure mazeEnvironment, IGenomeDecoder<NeatGenome, IBlackBox> genomeDecoder, ulong startingEvaluations);
public void LoadMaze(string mazeGenomeFile) { _mazeStructure = _mazeSimulationIoController.ReadMazeGenomeFile(mazeGenomeFile); }
public void Init(MazeStructure mazeStruct, MazeCell[,,] cells, AudioSource lightOff) { this.cells = cells; this.path = mazeStruct.Pathfind(mazeStruct.FindKey()[0]); this.sound = lightOff; }
/// <summary> /// Novelty search comparison experiment constructor. /// </summary> /// <param name="evaluationMaze">The maze on which novelty search comparison evaluations will be performed.</param> public NoveltySearchComparisonExperiment(MazeStructure evaluationMaze) { _evaluationMaze = evaluationMaze; }
/// <inheritdoc /> /// <summary> /// Maze Navigator fitness initialization evaluator constructor. /// </summary> /// <param name="minSuccessDistance">The minimum distance from the target to be considered a successful run.</param> /// <param name="maxDistanceToTarget">The maximum distance from the target possible.</param> /// <param name="initialMazeStructure"> /// The maze structure with which to seed the list of maze structures in the maze /// factory. /// </param> /// <param name="behaviorCharacterizationFactory">The initialized behavior characterization factory.</param> /// <param name="startingEvaluations">The number of evaluations from which the evaluator is starting (defaults to 0).</param> public MazeNavigatorNoveltySearchInitializationEvaluator(int minSuccessDistance, int maxDistanceToTarget, MazeStructure initialMazeStructure, IBehaviorCharacterizationFactory behaviorCharacterizationFactory, ulong startingEvaluations = 0) : this( minSuccessDistance, maxDistanceToTarget, behaviorCharacterizationFactory, startingEvaluations) { // Add initial maze structure _multiMazeWorldFactory.SetMazeConfigurations(new List <MazeStructure>(1) { initialMazeStructure }); }
/// <summary> /// Evolves the requisite number of agents who satisfy the MC of the given maze. /// </summary> /// <param name="genomeFactory">The agent genome factory.</param> /// <param name="seedAgentList">The seed population of agents.</param> /// <param name="mazeStructure">The maze structure on which agents are to be evaluated.</param> /// <returns></returns> private List<NeatGenome> EvolveViableAgents(IGenomeFactory<NeatGenome> genomeFactory, List<NeatGenome> seedAgentList, MazeStructure mazeStructure) { List<NeatGenome> viableMazeAgents; uint restartCount = 0; ulong initializationEvaluations; do { // Instantiate the internal initialization algorithm _mazeNavigationInitializer.InitializeAlgorithm(ParallelOptions, seedAgentList.ToList(), genomeFactory, mazeStructure, new NeatGenomeDecoder(ActivationScheme), 0); // Run the initialization algorithm until the requested number of viable seed genomes are found viableMazeAgents = _mazeNavigationInitializer.EvolveViableGenomes(out initializationEvaluations, _maxInitializationEvaluations, restartCount); restartCount++; // Repeat if maximum allotted evaluations is exceeded } while (_maxInitializationEvaluations != null && viableMazeAgents == null && initializationEvaluations > _maxInitializationEvaluations); return viableMazeAgents; }
/// <summary> /// Configures and instantiates the initialization evolutionary algorithm. /// </summary> /// <param name="parallelOptions">Synchronous/Asynchronous execution settings.</param> /// <param name="genomeList">The initial population of genomes.</param> /// <param name="genomeFactory">The genome factory initialized by the main evolution thread.</param> /// <param name="mazeEnvironment">The maze on which to evaluate the navigators.</param> /// <param name="genomeDecoder">The decoder to translate genomes into phenotypes.</param> /// <param name="startingEvaluations"> /// The number of evaluations that preceeded this from which this process will pick up /// (this is used in the case where we're restarting a run because it failed to find a solution in the allotted time). /// </param> public override void InitializeAlgorithm(ParallelOptions parallelOptions, List<NeatGenome> genomeList, IGenomeFactory<NeatGenome> genomeFactory, MazeStructure mazeEnvironment, IGenomeDecoder<NeatGenome, IBlackBox> genomeDecoder, ulong startingEvaluations) { // Set the boiler plate algorithm parameters base.InitializeAlgorithm(parallelOptions, genomeList, genomeDecoder, startingEvaluations); // Create the initialization evolution algorithm. InitializationEa = new GenerationalNeatEvolutionAlgorithm<NeatGenome>(SpeciationStrategy, ComplexityRegulationStrategy, RunPhase.Initialization); // Create IBlackBox evaluator. MazeNavigatorFitnessInitializationEvaluator mazeNavigatorEvaluator = new MazeNavigatorFitnessInitializationEvaluator(MaxTimesteps, MinSuccessDistance, MaxDistanceToTarget, mazeEnvironment, startingEvaluations); // Create the genome evaluator IGenomeEvaluator<NeatGenome> fitnessEvaluator = new ParallelGenomeFitnessEvaluator<NeatGenome, IBlackBox>( genomeDecoder, mazeNavigatorEvaluator, parallelOptions); // Only pull the number of genomes from the list equivalent to the initialization algorithm population size // (this is to handle the case where the list was created in accordance with the primary algorithm // population size, which is quite likely larger) genomeList = genomeList.Take(PopulationSize).ToList(); // Replace genome factory primary NEAT parameters with initialization parameters ((NeatGenomeFactory) genomeFactory).ResetNeatGenomeParameters(NeatGenomeParameters); // Initialize the evolution algorithm InitializationEa.Initialize(fitnessEvaluator, genomeFactory, genomeList, null, null); }
/// <summary> /// Configures and instantiates the initialization evolutionary algorithm. /// </summary> /// <param name="parallelOptions">Synchronous/Asynchronous execution settings.</param> /// <param name="genomeList">The initial population of genomes.</param> /// <param name="genomeFactory">The genome factory initialized by the main evolution thread.</param> /// <param name="mazeEnvironment">The maze on which to evaluate the navigators.</param> /// <param name="genomeDecoder">The decoder to translate genomes into phenotypes.</param> /// <param name="startingEvaluations"> /// The number of evaluations that preceeded this from which this process will pick up /// (this is used in the case where we're restarting a run because it failed to find a solution in the allotted time). /// </param> public abstract void InitializeAlgorithm(ParallelOptions parallelOptions, List <NeatGenome> genomeList, IGenomeFactory <NeatGenome> genomeFactory, MazeStructure mazeEnvironment, IGenomeDecoder <NeatGenome, IBlackBox> genomeDecoder, ulong startingEvaluations);