private Specimen Crossover(Specimen a, Specimen b) { List<int> distribution = new List<int>(); int totalBuses = 0; for (int line = 0; line < a.Distribution.Count; ++line) { int busesPerLine; if (random.Next(2) == 0) busesPerLine = a.Distribution[line]; else busesPerLine = b.Distribution[line]; distribution.Add(busesPerLine); totalBuses += busesPerLine; } while (totalBuses > a.Problem.NumberOfBuses) { int line = random.Next(distribution.Count); if (distribution[line] > 0) { --distribution[line]; --totalBuses; } } return new Specimen(a, distribution); }
public Specimen(Specimen basis, List<int> distribution) { Problem = basis.Problem; Random = basis.Random; if (distribution.Count != Problem.Lines.Count) { throw new ArgumentException(); } Distribution = distribution; CalculateSpecimentValue(); }
private Specimen Mutate(Specimen specimen) { Specimen result = specimen.Clone(); int to; int from = specimen.Distribution .Select((x, idx) => new Tuple<int, int>(idx, x)) .Where(_ => _.Item2 != 0) .Shuffle(random) .Select(_ => _.Item1) .Concat(-1) .First(); do { to = random.Next(specimen.Distribution.Count); } while (to == from); int severity; if (from >= 0) { severity = random.Next(specimen.Distribution[from]); result.Distribution[from] -= severity; } else { severity = random.Next(specimen.Problem.NumberOfBuses); } result.Distribution[to] += severity; return result; }