/// <summary> /// Score the Garden based on the linearity of the Rocks in it. /// If Rocks are determined to be linear (or close to linear), the number returned will /// be less than 1, allowing the evaluator to reduce the score of the Garden. If no Rocks /// are linear, then this method will return a value /// </summary> /// <param name="garden"></param> /// <returns></returns> private double scoreLinearity(Garden garden) { double score = 1; int triangle = 3; List <double> scores = new List <double>(); List <Resident> allRocksInGarden = getAllResidents(garden, Rock.rockString); List <Resident[]> AllRockTriangles = new List <Resident[]>(); List <int[]> pickThree = new List <int[]>(); Resident[] tempResidents = new Resident[triangle], tempResidentsCopy = new Resident[triangle]; combinations(ref pickThree, 0, 0, triangle, allRocksInGarden.Count, new int[triangle]); foreach (int[] combo in pickThree) { for (int i = 0; i < triangle; i++) { tempResidents[i] = allRocksInGarden[combo[i]]; } tempResidents.CopyTo(tempResidentsCopy, 0); AllRockTriangles.Add(tempResidentsCopy); } foreach (Resident[] triangleArrrangement in AllRockTriangles) { scores.Add(Math.Pow(triangleLinearity(triangleArrrangement), 1 / linearityRootWeight)); } if (scores.Count > 0) { return(scores.Average()); } return(score); }
public Garden makeChild(int length, int width, List <Resident> rocks, int movementMax) { Garden child = new Garden(length, width); Random gen = new Random(); Point tempLocation = new Point(); foreach (Resident rock in rocks) { tempLocation = rock.origin; tempLocation.X += gen.Next(-1 * movementMax, movementMax); tempLocation.Y += gen.Next(-1 * movementMax, movementMax); tempLocation.X = (tempLocation.X + width) % width; tempLocation.Y = (tempLocation.Y + length) % length; child.addResident(new Rock(rock.length, rock.width), tempLocation, false); } child.fillWithGravel(); if (child.getAllOfType(Rock.rockString).Count != rocks.Count) { child = makeChild(length, width, rocks, movementMax); } Console.WriteLine(child); return(child); }
public List <Garden> makeChildren(Garden parent, int movementMax, int numberOfChildren) { List <Resident> allRocksInParent = parent.getAllOfType(Rock.rockString); List <Garden> childrenOfTheParentGarden = new List <Garden>(); for (int childNumber = 0; childNumber < numberOfChildren; childNumber++) { childrenOfTheParentGarden.Add(makeChild(parent.length, parent.width, allRocksInParent, movementMax)); } return(childrenOfTheParentGarden); }
public Garden geneticSelection(Garden baseGarden, int steps, int movementMax, int numberOfChildren) { GardenEvaluator ge = new GardenEvaluator(); List <Garden> ancestors = new List <Garden>(); ancestors.Add(baseGarden); for (int i = 0; i < steps; i++) { ancestors = nextStep(ancestors, numberOfChildren, movementMax - (i * movementMax / steps), ge); } return(ancestors[0]); }
private double distanceScore(Garden toScore) { Resident[][] allRocks = NChooseK(toScore.getAllOfType(Rock.rockString), 2); Resident[] combo; List <double> allDistances = new List <double>(); double maxDistance = Math.Sqrt(Math.Pow(toScore.width, 2) + Math.Pow(toScore.length, 2)); for (int i = 0; i < allRocks.Length; i++) { combo = allRocks[i]; allDistances.Add(distance(combo[0].origin, combo[1].origin) / maxDistance); } return(allDistances.Average()); }
//the search type probably should be an integer since thos comparisons are faster than equals. //future refactor. /// <summary> /// Gets all the residents in the Garden of a certain type denoted by the string type. /// </summary> /// <param name="garden">The Garden to be searched.</param> /// <param name="type">The string of the object being searched.</param> /// <returns>A List of the Residents that match the type passed.</returns> private List <Resident> getAllResidents(Garden garden, string type) { List <Resident> allResidents = garden.residentsList; List <Resident> specificResidents = new List <Resident>(); foreach (Resident resident in allResidents) { if (resident.ToString().Equals(type)) { specificResidents.Add(resident); } } return(specificResidents); }
/// <summary> /// Score the Garden passed based on a variety of methods. /// </summary> /// <param name="toScore">The Garden to score.</param> /// <returns>The score of a Garden, the higher the better.</returns> public double scoreGarden(Garden toScore) { //should pull this method into this class double symmetry = toScore.symmetric(jigger, symmetryWeight); double balance = balanceOfGarden(toScore); double nonLinearity = scoreLinearity(toScore); double distanceBetweenAll = distanceScore(toScore); double locationScoreAverage = locationScore(toScore); List <double> scores = new List <double>(); scores.Add(symmetry); scores.Add(balance); scores.Add(nonLinearity); scores.Add(distanceBetweenAll); scores.Add(locationScoreAverage); return(scores.Average()); }
/// <summary> /// Find how much any half the Garden dominates the other half. /// Finds the standard deviation of nRocks from each half. /// We seek to avoid one half having 50 rocks while the other has 0 /// </summary> /// <param name="toScore"></param> /// <returns></returns> private double balanceOfGarden(Garden toScore) { Neighborhood[] halves = toScore.allHalves(); List <double> nRocksPerHalf = new List <double>(); double sumOfVariance = 0, average; foreach (Neighborhood half in halves) { nRocksPerHalf.Add(half.numberOfRocks()); } average = nRocksPerHalf.Average(); foreach (double nRocks in nRocksPerHalf) { sumOfVariance += Math.Pow(nRocks - average, 2); } return(Math.Sqrt(sumOfVariance / (nRocksPerHalf.Count - 1)) / maxStDev(average, halves.Length) * balanceWeight); }
private double locationScore(Garden toScore) { List <Resident> allRocks = toScore.getAllOfType(Rock.rockString); List <double> locationScores = new List <double>(); foreach (Resident rock in allRocks) { if (toScore.atomAt(rock.origin).rockBorderHeuristic < 0.2) { double x = toScore.atomAt(rock.origin).rockBorderHeuristic; } else { double x = toScore.atomAt(rock.origin).rockBorderHeuristic; } locationScores.Add(toScore.atomAt(rock.origin).rockBorderHeuristic); } return(locationScores.Average()); }
public Tester(int length, int width) { GardenEvaluator ge = new GardenEvaluator(); this.width = width; this.length = length; testGarden = new Garden(length, width); fillWithGravel(); addResident(new Rock(2, 2), new Point(10, 12), false); addResident(new Rock(2, 2), new Point(1, 12), false); addResident(new Rock(2, 2), new Point(16, 12), false); fillWithGravel(); //addResident(new Rock(10, 10), new Point(3, 4), true); fillWithGravel(); //should be the only rock that is in the garden //removeResident(new Point(3, 5)); fillWithGravel(); List <Point> starts = new List <Point>(); List <Point> ends = new List <Point>(); starts.Add(new Point(0, 0)); starts.Add(new Point(0, 1)); ends.Add(new Point(4, 4)); ends.Add(new Point(4, 5)); addRiver(starts, ends); double score = ge.scoreGarden(testGarden); Console.WriteLine(ge.scoreGarden(testGarden)); List <int[]> combos = new List <int[]>(); GardenEvaluator.combinations(ref combos, 0, 0, 3, 5, new int[3]); Garden best = geneticSelection(testGarden, 20, 3, 20); Console.WriteLine(ge.scoreGarden(best)); Console.WriteLine(best.ToString()); best.addStreamAStar(new Point(12, 2), new Point(2, 19)); //Console.ReadLine(); }