private void StartUp() { _departments = new DepartmentInfo[1]; _populationCells = new PopulationCell[WIDTH * HEIGHT]; _populationCells.Initialize<PopulationCell>(); DepartmentInfo depInfo = new DepartmentInfo(); depInfo.Name = "TestDep"; Random rand = new Random(); for (int i = 0; i < 8; i++) depInfo.Population[i] = rand.Next(10, 500); depInfo.Coordinates = new Point[(WIDTH * HEIGHT)]; for (int x = 0; x < WIDTH; x++) for (int y = 0; y < HEIGHT; y++) { Point p = new Point(x, y); depInfo.Coordinates[x + (y * WIDTH)] = p; } _departments = new DepartmentInfo[1] { depInfo }; foreach (DepartmentInfo item in _departments) _originalCount += item.Population.Sum(); }
private Tuple<int, PopulationCell>[] PopulateDepartment(DepartmentInfo depInfo, out Human[] humanArray) { List<Human> humanList = new List<Human>(depInfo.GetTotal()); int areaSize = depInfo.Coordinates.Length; // number of points to be populated. Tuple<int, PopulationCell>[] resultArray = // the array which will be returned. new Tuple<int,PopulationCell>[areaSize]; int resultArrayIndex = 0; // running index for the array. Point origin = CalculateInitialPoint(depInfo.Coordinates); // the origin as an fixpoint for every point. int maximumDistance = depInfo.Coordinates.Max( // the maximum distance possible. point => point.Distance(origin)) + 1; int[] factors = new int[maximumDistance]; // array of factor for each distance. factors[0] = 225; // start factor. for (int i = 1; i < maximumDistance; i++) // creating every factor for each distance. { int previousFactor = factors[i - 1]; int minus = (int)(previousFactor / 3f / 6); int random = RANDOM.Next(previousFactor / 3) - minus; random = (int)(random * (1 - i / (float)maximumDistance)); if (previousFactor - random <= 0) random = 5; factors[i] = previousFactor - random; } foreach (Point currentPoint in depInfo.Coordinates) { int currentDistance = currentPoint.Distance(origin); // distance of this point to the origin. PopulationCell currentCell = new PopulationCell(); for (int i = 0; i < 8; i++) // for each age-group. { int additionalRand = RANDOM.Next(10) - 5; int numberForEvenSpread = // number of humans if everything would be even/the same. (int)(depInfo.Population[i] / (float)areaSize); int numberOfPeopleToSet = // number of humans to be set for this age-group. (int)(numberForEvenSpread * (factors[currentDistance] + additionalRand) / 100f); EGender gender = (i < 4) ? // the first four are male, the last female. EGender.Male : EGender.Female; var bounds = GetAgeBounds(i); // the age-boundaries for the corresponding age-group. int lowerAgeBound = bounds.Item1; int upperAgeBound = bounds.Item2; for (int setCount = 0; setCount < numberOfPeopleToSet; setCount++) { int thisAge = RANDOM.Next(lowerAgeBound, upperAgeBound + 1); Human thisHuman = Human.Create(gender, thisAge, currentPoint.Flatten(WIDTH)); humanList.Add(thisHuman); currentCell.Data[i]++; // 'adds' the human to its cell. depInfo.Population[i]--; // 'removes' the human out of the population. } } areaSize--; // 'removes' point from rest-area. resultArray[resultArrayIndex++] = new Tuple<int, PopulationCell>( currentPoint.Flatten(WIDTH), currentCell); } humanArray = humanList.ToArray(); humanList = null; return resultArray; }
/// <summary> /// The standard method to populate. /// </summary> private Tuple<int, PopulationCell>[] Populate(DepartmentInfo depInfo, out Human[] humanArray) { // the count of cells. int areaSize = depInfo.Coordinates.Length; // precalculating humans. (~ +- 10%) for (int i = 0; i < depInfo.Population.Length; ++i) depInfo.Population[i] = (int)Math.Round( depInfo.Population[i] * (1 - (RANDOM.Next(20) - 10) / 100f)); // initializing array. var resultArray = new Tuple<int, PopulationCell>[areaSize]; int resultIndex = 0; // the origin used as fixpoint. Point origin = CalculateInitialPoint(depInfo.Coordinates); // maximum distance possible. (returns a relative small number) int maxDistance = depInfo.Coordinates.Max(p => p.Distance(origin)) + 1; // array of factors double[] factors = new double[maxDistance]; factors[0] = 1.5; // start factor. for (int i = 1; i < maxDistance; i++) // creating every factor for each distance. { //TODO | dj | randomise // (-(1/maxDistance * i)^2 + 1.75) * 100 double one = 1d / maxDistance * i; double two = Math.Pow(one, 2); double three = factors[0]; double four = three - two; factors[i] = four; } // array for each age-group, holding a list of Tuple of cell-indices and count. Queue<Tuple<int, ushort>>[] agesOfCells = new Queue<Tuple<int, ushort>>[8]; agesOfCells.Initialize<Queue<Tuple<int, ushort>>>(); int humanCount = 0; // going through all points and set the counts. foreach (Point point in depInfo.Coordinates) { PopulationCell cell = new PopulationCell(); int cellIndex = point.Flatten(WIDTH); double factor = factors[point.Distance(origin)]; for (int i = 0; i < 8; ++i) { ushort toSet = (ushort)Math.Round(depInfo.Population[i] / (double)areaSize * factor); cell.Data[i] = toSet; agesOfCells[i].Enqueue(new Tuple<int,ushort>(cellIndex, toSet)); depInfo.Population[i] -= toSet; //if (cell.Data[i] == 0) // Console.WriteLine("0 people in {0}", cellIndex); } if (cell.Total == 0 && depInfo.Population.Sum() != 0) { int j = 0; do { j = RANDOM.Next(8); } while (depInfo.Population[j] == 0); cell.Data[j] = 1; agesOfCells[j].Enqueue(new Tuple<int,ushort>(cellIndex, 1)); depInfo.Population[j] -= 1; } areaSize--; humanCount += cell.Total; resultArray[resultIndex++] = new Tuple<int,PopulationCell>(cellIndex, cell); } // initializing human array humanArray = new Human[humanCount]; int humanIndex = 0; // going through all ages and creating the humans. for (int i = 0; i < 8; ++i) { var queue = agesOfCells[i]; var bounds = GetAgeBounds(i); // age-bounds (for random). int lowerAge = bounds.Item1; int upperAge = bounds.Item2; // gender. EGender gender = (i < 4) ? EGender.Male : EGender.Female; // for each cell. while (queue.Count > 0) //foreach (Tuple<int, ushort> cellTuple in queue) { var cellTuple = queue.Dequeue(); int cellIndex = cellTuple.Item1; ushort count = cellTuple.Item2; // for each human (who shall be created). ushort c = count; while (c-- > 0) //for (int c = 0; c < count; ++c) { int thisHumanAge = RANDOM.Next(lowerAge, upperAge + 1); Human thisHuman = Human.Create(gender, thisHumanAge, cellIndex); humanArray[humanIndex++] = thisHuman; } } agesOfCells[i] = null; // not necessary, but who knows :P } return resultArray; }
/// <summary> /// The Dummy-implementation. /// </summary> private Tuple<int, PopulationCell>[] DummyPopulate(DepartmentInfo depInfo, out Human[] humanArray) { int areaSize = depInfo.Coordinates.Length; Tuple<int, PopulationCell>[] tmpArray = new Tuple<int, PopulationCell>[areaSize]; int tmpCounter = 0; humanArray = new Human[depInfo.GetTotal()]; int humanCounter = 0; int[] popsPerPoint = depInfo.Population.Select(x => x / areaSize).ToArray(); foreach (Point point in depInfo.Coordinates) { PopulationCell cell = new PopulationCell(); for (int i = 0; i < 8; i++) { EGender gender = (i < 4) ? EGender.Male : EGender.Female; var bounds = GetAgeBounds(i); int lowerAgeBound = bounds.Item1; int upperAgeBound = bounds.Item2; for (int n = 0; n < popsPerPoint[i]; n++) { int thisAge = RANDOM.Next(lowerAgeBound, upperAgeBound + 1); humanArray[humanCounter++] = Human.Create(gender, thisAge, point.Flatten(WIDTH)); cell.Data[i]++; } } tmpArray[tmpCounter++] = new Tuple<int, PopulationCell>(point.Flatten(WIDTH), cell); } return tmpArray; }
/// <summary> /// Reads the previously given file and /// tries to interpret its content file /// as an array of DepartmenInfos. /// </summary> /// <returns>The DepartmentInfo-Array.</returns> public DepartmentInfo[] ReadFile() { WriteMessage("Reading file..."); var depInfList = new List<DepartmentInfo>(); ZipArchive archive = ZipFile.OpenRead(Path); Stream stream = archive.GetEntry("map").Open(); using (StreamReader sr = new StreamReader(stream)) { while (!sr.EndOfStream) { DepartmentInfo depInf = new DepartmentInfo(); string[] s = sr.ReadLine().Split('|'); depInf.Name = s[0]; // Name for (int i = 1; i < 9; i++) // Population(s) depInf.Population[i - 1] = int.Parse(s[i]); depInf.Coordinates = new Point[s.Length - 9]; for (int i = 9; i < s.Length; i++) // Coordinates { string[] pArr = s[i].Split(':'); depInf.Coordinates[i - 9] = new Point( int.Parse(pArr[0]), int.Parse(pArr[1])); } depInfList.Add(depInf); IterationPassed.Raise(this, new ContinuationEventArgs() { Continuing = true }); } } stream.Close(); archive.Dispose(); IterationPassed.Raise(this, new ContinuationEventArgs() { Finished = true }); return depInfList.ToArray(); }