Пример #1
0
        private async Task FindSolution(bool useLastBest)
        {
            try
            {
                btnFindSolution.Enabled  = false;
                btnRetryWithBest.Enabled = false;
                btnStop.Enabled          = true;

                UseWaitCursor = true;

                var prune = cbxPrune.Checked;

                var problem =
                    new Problem()
                    .Add(ProficiencyKind.ArtsAndCrafts, nudArtsAndCrafts.Value)
                    .Add(ProficiencyKind.CloakAndDagger, nudCloakAndDagger.Value)
                    .Add(ProficiencyKind.FaithAndWisdom, nudFaithAndWisdom.Value)
                    .Add(ProficiencyKind.FloraAndFauna, nudFloraAndFauna.Value)
                    .Add(ProficiencyKind.HammerAndNail, nudHammerAndNail.Value)
                    .Add(ProficiencyKind.HerbsAndSprouts, nudHerbsAndSprouts.Value)
                    .Add(ProficiencyKind.HuntingAndHideworking, nudHuntingAndHideworking.Value)
                    .Add(ProficiencyKind.LawAndLore, nudLawAndLore.Value)
                    .Add(ProficiencyKind.MinesAndMountains, nudMinesAndMountains.Value)
                    .Add(ProficiencyKind.NaturalPhilosophy, nudNaturalPhilosophy.Value)
                    .Add(ProficiencyKind.PerenialPhilosophy, nudPerenialPhilosophy.Value)
                    .Add(ProficiencyKind.SparksAndEmbers, nudSparksAndEmbers.Value)
                    .Add(ProficiencyKind.StocksAndCultivars, nudStocksAndCultivars.Value)
                    .Add(ProficiencyKind.SugarAndSpice, nudSugarAndSpice.Value)
                    .Add(ProficiencyKind.ThreadAndNeedle, nudThreadAndNeedle.Value);

                Inspirational[] availableInspirationals;
                if (cbUseAll.Checked)
                {
                    availableInspirationals = InspirationalDatabase.Inspirationals.ToArray();
                }
                else
                {
                    availableInspirationals = lvInspirationals.CheckedItems.OfType <ListViewItem>().Select(i => ((Inspirational)i.Tag)).ToArray();
                }

                cancellationTokenSource = new CancellationTokenSource();

                var solvers = Enumerable.Range(1, 8).Select(i => Task.Run(() => new Solver(problem, availableInspirationals, cancellationTokenSource.Token, useLastBest ? bestOrganisms : null).Solve(prune))).ToArray();

                var best = await Task.WhenAll(solvers);

                // Aggregate the best results and fill them into the results control
                var leaderboard = new Leaderboard(int.Parse(cbResultCount.Items[cbResultCount.SelectedIndex].ToString()), prune);

                foreach (var organism in best.SelectMany(i => i))
                {
                    leaderboard.AddOrganism(organism);
                }

                var bestOfAll = leaderboard.GetBest();

                bestOrganisms = bestOfAll.Select(i => i.Clone(null)).ToArray();

                lvSolutions.Items.Clear();

                foreach (var organism in bestOfAll)
                {
                    var lvi = new ListViewItem();
                    lvi.Tag       = organism;
                    lvi.Text      = organism.ToString();
                    lvi.ForeColor = organism.Solution.IncompletenessPenalty == 0 ? Color.Green : Color.Red;
                    lvi.SubItems.Add(organism.Solution.CostTotal.ToString("###,###,###"));
                    lvi.SubItems.Add(organism.Solution.DiffTotal.ToString());
                    lvSolutions.Items.Add(lvi);
                }
            }
            finally
            {
                btnFindSolution.Enabled  = true;
                btnRetryWithBest.Enabled = bestOrganisms != null;
                btnStop.Enabled          = false;

                UseWaitCursor = false;
            }
        }
Пример #2
0
        public Organism[] Solve(bool prune)
        {
            var leaderboard = new Leaderboard(5, prune);

            var organisms   = new List <Organism>();
            var generations = 0;

            for (int i = 0; i < 50; i++)
            {
                Organism organism = new Organism(this, problem);
                organisms.Add(organism);
                leaderboard.AddOrganism(organism);
            }

            if (includedOrganisms != null)
            {
                foreach (var organism in includedOrganisms.Select(i => i.Clone(this)))
                {
                    organisms.Add(organism);
                    leaderboard.AddOrganism(organism);
                }
            }

            var best      = default(Organism);
            var worst     = default(Organism);
            var bestCost  = double.MaxValue;
            var worstCost = 0d;

            var newBest = false;

            while (generations < 2000)
            {
                if (cancellationToken.IsCancellationRequested)
                {
                    break;
                }

                generations++;

                newBest = false;

                foreach (var organism in organisms)
                {
                    organism.Tick();

                    leaderboard.AddOrganism(organism);

                    if (organism.Solution.CostTotal < bestCost)
                    {
                        bestCost = organism.Solution.CostTotal;
                        best     = organism;

                        newBest = true;
                    }

                    if (organism.Solution.CostTotal > worstCost)
                    {
                        worstCost = organism.Solution.CostTotal;
                        worst     = organism;
                    }
                }

                if (RandomHelper.GetShort(10) == 1)
                {
                    organisms.Remove(worst);
                    Organism clone = best.Clone(this);
                    organisms.Add(clone);
                }
                else if (RandomHelper.GetShort(30) == 1)
                {
                    organisms.Remove(worst);

                    var      index = RandomHelper.GetShort(organisms.Count);
                    Organism clone = organisms[index].Clone(this);
                    organisms.Add(clone);
                }
                else if (RandomHelper.GetShort(100) == 1)
                {
                    organisms.Remove(worst);

                    int      index  = RandomHelper.GetShort(organisms.Count);
                    Organism mother = best;
                    Organism father = organisms[index];

                    Organism child = mother.MakeCrossOver(father);
                    organisms.Add(child);
                }

                worst     = null;
                worstCost = 0d;

                if (newBest)
                {
                    Console.WriteLine(generations + ": Current (" + bestCost + ", " + best.Solution.IncompletenessPenalty + "): " + best.ToString());
                }
            }

            Console.WriteLine("Done.");

            return(leaderboard.GetBest());
        }