Exemplo n.º 1
0
        /**
         * Two-point crossover.
         * @param parent1 The first parent.
         * @param parent2 The second parent.
         * @return The child drawing.
         */
        private CandidateSolution crossover(CandidateSolution parent1, CandidateSolution parent2)
        {
            Random random        = new Random();
            int    startPosition = random.Next(GenotypeLength);
            int    endPosition   = random.Next(GenotypeLength);

            if (startPosition > endPosition)
            {
                int tmp = startPosition;
                startPosition = endPosition;
                endPosition   = tmp;
            }

            CandidateSolution child = new CandidateSolution(fitnessCalculator, BitSize, GenotypeLength, GroupSize);

            for (int i = 0; i < GenotypeLength; i++)
            {
                if (startPosition <= i && i <= endPosition)
                {
                    child.Solution[i] = parent2.Solution[i];
                }
                else
                {
                    child.Solution[i] = parent1.Solution[i];
                }
            }

            return(child);
        }
        private void Redraw(int generation, CandidateSolution <List <DungeonOp> > bestSolution)
        {
            var data = new List <DungeonOp>(bestSolution.Solution);

            var map = new GridMap(new Random());

            foreach (var op in data)
            {
                op.Execute(map);
            }

            lock (drawLock)
            {
                this.Clear();

                var status = $"{(DateTime.Now - this.startedOn).TotalSeconds}s | Generation {generation}, FITNESS: best={bestSolution.Fitness}, with {data.Count} ops";
                this.Print(0, STATUS_Y, status, Color.White);
                System.Console.WriteLine(status);

                for (var y = 0; y < this.Height - 1; y++)
                {
                    for (var x = 0; x < this.Width; x++)
                    {
                        var text   = map.Get(x, y) ? "." : "#";
                        var colour = text == "#" ? WALL_COLOUR : FLOOR_COLOUR;
                        this.Print(x, y, text, colour);
                    }
                }
            }
        }
Exemplo n.º 3
0
        public double Calculate(CandidateSolution solution)
        {
            double sum    = 0d;
            var    groups = GetGroups(solution);

            foreach (var group in groups.Keys)
            {
                var groupSum = 0;
                var members  = groups[group].ToArray();

                for (int memberOne = 0; memberOne < members.Length; memberOne++)
                {
                    for (int memberTwo = 0; memberTwo < members.Length; memberTwo++)
                    {
                        if (memberOne != memberTwo)
                        {
                            if (relationships[members[memberOne]].ContainsKey(members[memberTwo]))
                            {
                                groupSum++;
                            }
                        }
                    }
                }

                sum += groupSum;
            }

            return(sum);
        }
Exemplo n.º 4
0
        private void PerGenerationCallback(string status, CandidateSolution <bool, ProblemState> bestThisGeneration)
        {
            var strategy = StrategyFactory.GetStrategyForGP(bestThisGeneration);

            DisplayStrategyGrids(strategy, "");
            DisplayCurrentStatus(status);
        }
        //-------------------------------------------------------------------------
        // each candidate gets evaluated here
        //-------------------------------------------------------------------------
        private float EvaluateCandidate(CandidateSolution <bool, ProblemState> candidate)
        {
            // test every possible situation and store the candidate's suggested action in the strategy object
            Strategy strategy = StrategyFactory.GetStrategyForGP(candidate);

            // then test that strategy and return the total money lost/made
            var strategyTester = new StrategyTester(strategy, settings.TestSettings);

            return(strategyTester.GetStrategyScore(settings.TestSettings.NumHandsToPlay));
        }
Exemplo n.º 6
0
        public static void DebugDisplayStrategy(CandidateSolution <bool, ProblemState> candidate, string prefixText)
        {
            string debug =
                prefixText +
                (String.IsNullOrWhiteSpace(prefixText) ? "" : "  ") +
                "  Plr: " + candidate.StateData.PlayerHand +
                "  H: " + candidate.StateData.VotesForHit +
                "  S: " + candidate.StateData.VotesForStand +
                "  P: " + candidate.StateData.VotesForSplit +
                "  D: " + candidate.StateData.VotesForDoubleDown;

            Debug.WriteLine(debug);
        }
        /**
         * @return The solution with the highest fitness.
         */
        public CandidateSolution getFittest()
        {
            CandidateSolution fittest = candidateSolutions[0];

            for (int i = 1; i < candidateSolutions.Length; i++)
            {
                if (fittest.Fitness < candidateSolutions[i].Fitness)
                {
                    fittest = candidateSolutions[i];
                }
            }

            return(fittest);
        }
Exemplo n.º 8
0
        public static Strategy GetStrategyForGP(CandidateSolution <bool, ProblemState> candidate)
        {
            Strategy result = new Strategy();

            foreach (var upcardRank in Card.ListOfRanks)
            {
                if (upcardRank == Card.Ranks.Jack || upcardRank == Card.Ranks.Queen || upcardRank == Card.Ranks.King)
                {
                    continue;
                }

                AddStrategyForUpcard(upcardRank, result, candidate);
            }

            return(result);
        }
        /**
         * Constructs a new population.
         * @param size The size of the population.
         * @param initialise True, if the population will be initialised.
         */
        public Population(FitnessCalculator fitnessCalculator, int size, int bitSize, int genotypeLength, int groupSize, bool initialise = false)
        {
            candidateSolutions     = new CandidateSolution[size];
            this.fitnessCalculator = fitnessCalculator;
            this.groupSize         = groupSize;

            if (initialise)
            {
                for (int i = 0; i < candidateSolutions.Length; i++)
                {
                    CandidateSolution candidateSolution = new CandidateSolution(fitnessCalculator, bitSize, genotypeLength, groupSize);
                    candidateSolution.GenerateIndividual();
                    candidateSolutions[i] = candidateSolution;
                }
            }
        }
Exemplo n.º 10
0
        private Dictionary <int, List <int> > GetGroups(CandidateSolution solution)
        {
            var max    = solution.Solution.Max();
            var groups = new Dictionary <int, List <int> >();

            for (int i = 1; i <= max; i++)
            {
                groups.Add(i, new List <int>());
            }

            for (int member = 0; member < solution.Solution.Length; member++)
            {
                groups[solution.Solution[member]].Add(member + 1);
            }

            return(groups);
        }
Exemplo n.º 11
0
        static void ShowFinalResults(CandidateSolution <double, StateData> solution)
        {
            // then test how well it does
            double finalScore;
            string testDetails;

            RunFinalTests(solution, out finalScore, out testDetails);
            Console.WriteLine();
            Console.WriteLine("Final score: " + finalScore.ToString("0.0000"));
            Console.WriteLine();
            Console.WriteLine(solution.ToString());

            var writer = File.AppendText("test-results.csv");

            writer.Write(testDetails);
            writer.Close();
        }
Exemplo n.º 12
0
        //-------------------------------------------------------------------------
        // For each generation, we get information about what's going on
        //-------------------------------------------------------------------------
        private bool PerGenerationCallback(EngineProgress progress, CandidateSolution <bool, ProblemState> bestThisGeneration)
        {
            string summary =
                "Upcard " + currentDealerUpcardRank +
                " gen: " + progress.GenerationNumber +
                " best: " + progress.BestFitnessThisGen.ToString("0") +
                " avg: " + progress.AvgFitnessThisGen.ToString("0");

            perGenerationCallback(summary, bestThisGeneration);
            Debug.WriteLine(summary);

            // keep track of how many gens we've searched
            NumGenerationsNeeded++;

            // return true to keep going, false to halt the system
            bool keepRunning = true;

            return(keepRunning);
        }
Exemplo n.º 13
0
        /**
         * Mutation of a candidate solution.
         * @param candidateSolution The candidate solution.
         */
        private void mutate(CandidateSolution candidateSolution)
        {
            Random random = new Random();

            if (random.NextDouble() < MutationProbability)
            {
                int i = random.Next(candidateSolution.Solution.Length);
                int j = random.Next(candidateSolution.Solution.Length);

                while (i == j)
                {
                    j = random.Next(candidateSolution.Solution.Length);
                }

                var temp = candidateSolution.Solution[i];
                candidateSolution.Solution[i] = candidateSolution.Solution[j];
                candidateSolution.Solution[j] = temp;
            }
        }
Exemplo n.º 14
0
        static void RunFinalTests(CandidateSolution <double, StateData> candidate, out double finalScore, out string testDetails)
        {
            var           sampleData = new Dataset();
            StringBuilder sb         = new StringBuilder();

            sb.AppendLine("Test results at " + DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToShortTimeString());

            // run through our test data and see how close the answer the genetic program
            // comes up with is to the training data.  Lower fitness scores are better than bigger scores
            double totalDifference = 0;

            while (true)
            {
                var row = sampleData.GetRowOfTestingData();
                if (row == null)
                {
                    break;
                }

                // populate vars with values from row of the training data
                for (int i = 0; i < Dataset.NumColumns; i++)
                {
                    if (i != Dataset.LabelColumnIndex)
                    {
                        candidate.SetVariableValue("v" + i, row[i]);
                    }
                }
                var result = candidate.Evaluate();

                // now figure the difference between the calculated value and the training data
                var actualAnswer = row[Dataset.LabelColumnIndex];
                var diff         = result - actualAnswer;
                totalDifference += diff * diff;
                Console.WriteLine("Ans: " + actualAnswer.ToString(" 0") + " AI: " + result.ToString("0.00"));
                sb.AppendLine(actualAnswer.ToString("0.0") + ", " + result.ToString("0.000"));
            }

            totalDifference = Math.Sqrt(totalDifference);
            finalScore      = (float)totalDifference;
            sb.AppendLine("\"Final score\", " + finalScore.ToString("0.000"));
            testDetails = sb.ToString();
        }
Exemplo n.º 15
0
        private bool IsValid(CandidateSolution solution)
        {
            var counter = new Dictionary <int, int>();

            for (int i = 1; i <= BitSize; i++)
            {
                counter.Add(i, 0);
            }

            for (int i = 0; i < solution.Solution.Length; i++)
            {
                counter[solution.Solution[i]]++;

                if (counter[solution.Solution[i]] > GroupSize)
                {
                    return(false);
                }
            }

            return(true);
        }
Exemplo n.º 16
0
        static float EvaluateCandidate(CandidateSolution <double, StateData> candidate)
        {
            var sampleData = new Dataset();

            // run through our test data and see how close the answer the genetic program
            // comes up with is to the training data.  Lower fitness scores are better than bigger scores
            double totalDifference = 0;

            while (true)
            {
                var row = sampleData.GetRowOfTrainingData();
                if (row == null)
                {
                    break;
                }

                // populate vars with values from row of the training data, and then get the calculated value
                for (int i = 0; i < Dataset.NumColumns; i++)
                {
                    if (i != Dataset.LabelColumnIndex)
                    {
                        candidate.SetVariableValue("v" + i, row[i]);
                    }
                }
                var result = candidate.Evaluate();

                // now figure the difference between the calculated value and the training data
                var actualAnswer = row[Dataset.LabelColumnIndex];
                var diff         = result - actualAnswer;
                totalDifference += diff * diff;
            }

            // sqrt of the summed squared diffences
            totalDifference = Math.Sqrt(totalDifference);

            // fitness function returns a float
            return((float)totalDifference);
        }
Exemplo n.º 17
0
 public abstract void SetCandidateRef(CandidateSolution <T, S> candidate);
Exemplo n.º 18
0
 public override void SetCandidateRef(CandidateSolution <T, S> candidate)
 {
     // no need to store a reference to the candidate for a constant
 }
Exemplo n.º 19
0
        public void BuildProgram(
            int populationSize,
            int crossoverPercentage,
            double mutationPercentage,
            int ElitismPercentage,
            int tourneySize,
            Action <string> currentStatusCallback,
            string dealerUpcardRankToUse)
        {
            displayGenerationCallback = currentStatusCallback;
            dealerUpcardRank          = dealerUpcardRankToUse;

            // just some values, leave the rest as defaults
            var engineParams = new EngineParameters()
            {
                CrossoverRate        = crossoverPercentage / 100F,
                ElitismRate          = ElitismPercentage / 100F,
                IsLowerFitnessBetter = false,
                MutationRate         = mutationPercentage / 100F,
                PopulationSize       = populationSize,
                TourneySize          = tourneySize
            };

            // create the engine.  each tree (and node within the tree) will return a bool.
            // we also indicate the type of our problem state data (used by terminal functions and stateful functions)
            var engine = new Engine <bool, ProblemState>(engineParams);

            // no constants for this problem

            // no variables for this solution - we can't pass in information about our hand
            // via boolean variables, so we do it via some terminal functions instead

            // for a boolean tree, we use the standard operators
            engine.AddFunction((a, b) => a || b, "Or");
            engine.AddFunction((a, b, c) => a || b || c, "Or3");
            engine.AddFunction((a, b) => a && b, "And");
            engine.AddFunction((a, b, c) => a && b && c, "And3");
            engine.AddFunction((a) => !a, "Not");

            // then add functions to indicate a strategy
            engine.AddStatefulFunction(HitIf, "HitIf");
            engine.AddStatefulFunction(StandIf, "StandIf");
            engine.AddStatefulFunction(DoubleIf, "DoubleIf");
            engine.AddStatefulFunction(SplitIf, "SplitIf");

            // terminal functions to look at game state
            // first, player holding ace?
            engine.AddTerminalFunction(HasAce, "HasAce");
            engine.AddTerminalFunction(HasPair, "HasPair");

            // player hand totals
            engine.AddTerminalFunction(HandVal4, "Has4");
            engine.AddTerminalFunction(HandVal5, "Has5");
            engine.AddTerminalFunction(HandVal6, "Has6");
            engine.AddTerminalFunction(HandVal7, "Has7");
            engine.AddTerminalFunction(HandVal8, "Has8");
            engine.AddTerminalFunction(HandVal9, "Has9");
            engine.AddTerminalFunction(HandVal10, "Has10");
            engine.AddTerminalFunction(HandVal11, "Has11");
            engine.AddTerminalFunction(HandVal12, "Has12");
            engine.AddTerminalFunction(HandVal13, "Has13");
            engine.AddTerminalFunction(HandVal14, "Has14");
            engine.AddTerminalFunction(HandVal15, "Has15");
            engine.AddTerminalFunction(HandVal16, "Has16");
            engine.AddTerminalFunction(HandVal17, "Has17");
            engine.AddTerminalFunction(HandVal18, "Has18");
            engine.AddTerminalFunction(HandVal19, "Has19");
            engine.AddTerminalFunction(HandVal20, "Has20");
            // num cards held
            engine.AddTerminalFunction(Holding2Cards, "Hold2");
            engine.AddTerminalFunction(Holding3Cards, "Hold3");

            // pass a fitness evaluation function and run
            engine.AddFitnessFunction((t) => EvaluateCandidate(t));

            // and add something so we can track the progress
            engine.AddProgressFunction((t) => PerGenerationCallback(t));

            BestSolution = engine.FindBestSolution();
        }
Exemplo n.º 20
0
        //-------------------------------------------------------------------------
        // each candidate gets evaluated here
        //-------------------------------------------------------------------------
        private float EvaluateCandidate(CandidateSolution <bool, ProblemState> candidate)
        {
            int playerChips = 0;

            for (int handNum = 0; handNum < TestConditions.NumHandsToPlay; handNum++)
            {
                // for each hand, we generate a random deck.  Blackjack is often played with multiple decks to improve the house edge
                MultiDeck deck = new MultiDeck(TestConditions.NumDecks);
                // always use the designated dealer upcard (of hearts), so we need to remove from the deck so it doesn't get used twice
                deck.RemoveCard(dealerUpcardRank, "H");

                Hand dealerHand = new Hand();
                Hand playerHand = new Hand();
                playerHand.AddCard(deck.DealCard());
                dealerHand.AddCard(new Card(dealerUpcardRank, "H"));
                playerHand.AddCard(deck.DealCard());
                dealerHand.AddCard(deck.DealCard());

                // save the cards in state, and reset the votes for this hand
                candidate.StateData.PlayerHands.Clear();
                candidate.StateData.PlayerHands.Add(playerHand);

                // do the intial wager
                int totalBetAmount = TestConditions.BetSize;
                playerChips -= TestConditions.BetSize;

                // outer loop is for each hand the player holds.  Obviously this only happens when they've split a hand
                for (int handIndex = 0; handIndex < candidate.StateData.PlayerHands.Count; handIndex++)
                {
                    candidate.StateData.HandIndex = handIndex;
                    playerHand = candidate.StateData.PlayerHand; // gets the current hand, based on index

                    // loop until the hand is done
                    var currentHandState = TestConditions.GameState.PlayerDrawing;

                    // check for player having a blackjack, which is an instant win
                    if (playerHand.HandValue() == 21)
                    {
                        // if the dealer also has 21, then it's a tie
                        if (dealerHand.HandValue() != 21)
                        {
                            currentHandState = TestConditions.GameState.PlayerBlackjack;
                            playerChips     += TestConditions.BlackjackPayoffSize;
                        }
                        else
                        {
                            // a tie means we just ignore it and drop through
                            currentHandState = TestConditions.GameState.HandComparison;
                        }
                    }

                    // check for dealer having blackjack, which is either instant loss or tie
                    if (dealerHand.HandValue() == 21)
                    {
                        currentHandState = TestConditions.GameState.HandComparison;
                    }

                    // player draws
                    while (currentHandState == TestConditions.GameState.PlayerDrawing)
                    {
                        // get the decision
                        candidate.StateData.VotesForDoubleDown = 0;
                        candidate.StateData.VotesForHit        = 0;
                        candidate.StateData.VotesForStand      = 0;
                        candidate.StateData.VotesForSplit      = 0;
                        candidate.Evaluate();   // throw away the result, because it's meaningless

                        // look at the votes to see what to do
                        var action = GetAction(candidate.StateData);

                        // if there's an attempt to double-down with more than 2 cards, turn into a hit
                        if (action == ActionToTake.Double && playerHand.Cards.Count > 2)
                        {
                            action = ActionToTake.Hit;
                        }

                        // if we're trying to split, but don't have a pair, turn that into a stand?
                        if (action == ActionToTake.Split && !playerHand.IsPair())
                        {
                            Debug.Assert(false, "Vote for split without a pair");
                        }

                        switch (action)
                        {
                        case ActionToTake.Hit:
                            // hit me
                            playerHand.AddCard(deck.DealCard());
                            // if we're at 21, we're done
                            if (playerHand.HandValue() == 21)
                            {
                                currentHandState = TestConditions.GameState.DealerDrawing;
                            }
                            // did we bust?
                            if (playerHand.HandValue() > 21)
                            {
                                currentHandState = TestConditions.GameState.PlayerBusted;
                            }
                            break;

                        case ActionToTake.Stand:
                            // if player stands, it's the dealer's turn to draw
                            currentHandState = TestConditions.GameState.DealerDrawing;
                            break;

                        case ActionToTake.Double:
                            // double down means bet another chip, and get one and only card card
                            playerChips    -= TestConditions.BetSize;
                            totalBetAmount += TestConditions.BetSize;
                            playerHand.AddCard(deck.DealCard());
                            if (playerHand.HandValue() > 21)
                            {
                                currentHandState = TestConditions.GameState.PlayerBusted;
                            }
                            else
                            {
                                currentHandState = TestConditions.GameState.DealerDrawing;
                            }
                            break;

                        case ActionToTake.Split:
                            // do the split and add the hand to our collection
                            var newHand = new Hand();
                            newHand.AddCard(playerHand.Cards[1]);
                            playerHand.Cards[1] = deck.DealCard();
                            newHand.AddCard(deck.DealCard());
                            candidate.StateData.PlayerHands.Add(newHand);

                            //Debug.WriteLine("TID " + AppDomain.GetCurrentThreadId() + " " +
                            //    "is splitting and has " + candidate.StateData.PlayerHands.Count + " hands");
                            Debug.Assert(candidate.StateData.PlayerHands.Count < 5, "Too many hands for player");

                            // our extra bet
                            playerChips -= TestConditions.BetSize;
                            // we don't adjust totalBetAmount because each bet pays off individually, so the total is right
                            //totalBetAmount += TestConditions.BetSize;
                            break;
                        }
                    }

                    // if the player busted, nothing to do, since chips have already been consumed.  Just go on to the next hand
                    // on the other hand, if the player hasn't busted, then we need to play the hand for the dealer
                    while (currentHandState == TestConditions.GameState.DealerDrawing)
                    {
                        // if player didn't bust or blackjack, dealer hits until they have 17+ (hits on soft 17)
                        if (dealerHand.HandValue() < 17)
                        {
                            dealerHand.AddCard(deck.DealCard());
                            if (dealerHand.HandValue() > 21)
                            {
                                currentHandState = TestConditions.GameState.DealerBusted;
                                playerChips     += totalBetAmount * 2; // the original bet and a matching amount
                            }
                        }
                        else
                        {
                            // dealer hand is 17+, so we're done
                            currentHandState = TestConditions.GameState.HandComparison;
                        }
                    }

                    if (currentHandState == TestConditions.GameState.HandComparison)
                    {
                        int playerHandValue = playerHand.HandValue();
                        int dealerHandValue = dealerHand.HandValue();

                        // if it's a tie, give the player his bet back
                        if (playerHandValue == dealerHandValue)
                        {
                            playerChips += totalBetAmount;
                        }
                        else
                        {
                            if (playerHandValue > dealerHandValue)
                            {
                                // player won
                                playerChips += totalBetAmount * 2;  // the original bet and a matching amount
                            }
                            else
                            {
                                // player lost, nothing to do since the chips have already been decremented
                            }
                        }
                    }
                }
            }

            return(playerChips);
        }
Exemplo n.º 21
0
        private static void AddStrategyForUpcard(Card.Ranks upcardRank, Strategy result, CandidateSolution <bool, ProblemState> candidate)
        {
            Card dealerCard = new Card(upcardRank, Card.Suits.Diamonds);

            // do pairs
            for (var pairedRank = Card.Ranks.Ace; pairedRank >= Card.Ranks.Two; pairedRank--)
            {
                // build player hand
                Hand playerHand = new Hand();
                playerHand.AddCard(new Card(pairedRank, Card.Suits.Hearts));
                playerHand.AddCard(new Card(pairedRank, Card.Suits.Spades));

                // find strategy
                SetupStateData(candidate.StateData, playerHand, dealerCard);
                candidate.Evaluate();

                // get the decision and store in the strategy object
                var action = GetActionFromCandidate(candidate.StateData);

                result.SetActionForPair(upcardRank, pairedRank, action);
            }

            // then soft hands
            // we don't start with Ace, because that would be AA, which is handled in the pair zone
            // we also don't start with 10, since that's blackjack.  So 9 is our starting point
            for (int otherCard = 9; otherCard > 1; otherCard--)
            {
                // build player hand
                Hand playerHand = new Hand();

                // first card is an ace, second card is looped over
                playerHand.AddCard(new Card(Card.Ranks.Ace, Card.Suits.Hearts));
                playerHand.AddCard(new Card((Card.Ranks)otherCard, Card.Suits.Spades));

                // find strategy
                SetupStateData(candidate.StateData, playerHand, dealerCard);
                candidate.Evaluate();

                // get the decision and store in the strategy object
                var action = GetActionFromCandidate(candidate.StateData);
                result.SetActionForSoftHand(upcardRank, otherCard, action);
            }

            // hard hands.
            for (int hardTotal = 20; hardTotal > 4; hardTotal--)
            {
                // build player hand
                Hand playerHand = new Hand();

                // divide by 2 if it's even, else add one and divide by two
                int firstCardRank  = ((hardTotal % 2) != 0) ? (hardTotal + 1) / 2 : hardTotal / 2;
                int secondCardRank = hardTotal - firstCardRank;

                // 20 is always TT, which is a pair, so we handle that by building a 3 card hand
                if (hardTotal == 20)
                {
                    playerHand.AddCard(new Card(Card.Ranks.Ten, Card.Suits.Diamonds));
                    firstCardRank  = 6;
                    secondCardRank = 4;
                }

                // we don't want pairs, so check for that
                if (firstCardRank == secondCardRank)
                {
                    firstCardRank++;
                    secondCardRank--;
                }

                playerHand.AddCard(new Card((Card.Ranks)firstCardRank, Card.Suits.Diamonds));
                playerHand.AddCard(new Card((Card.Ranks)secondCardRank, Card.Suits.Spades));

                // find strategy
                SetupStateData(candidate.StateData, playerHand, dealerCard);
                candidate.Evaluate();

                // get the decision and store in the strategy object
                var action = GetActionFromCandidate(candidate.StateData);
                result.SetActionForHardHand(upcardRank, hardTotal, action);
            }
        }
Exemplo n.º 22
0
        /// <summary>
        /// Calculate and return the optimal solution to the given problem.
        /// </summary>
        /// <param name="problem">The problem whose optimal solution we seek</param>
        /// <returns>The optimal solution</returns>
        public Solution OptimalSoultion(Problem problem)
        {
            // Figure out our temperature and strength requirements
            double targetTemp  = 0.0;
            double strengthReq = 0.0;

            foreach (Constraint constraint in problem.Constraints)
            {
                switch (constraint.Value)
                {
                case VALUE.TEMP:
                    targetTemp = constraint.Target;
                    break;

                case VALUE.FORCE_LIMIT:
                    strengthReq = constraint.Target;
                    break;
                }
            }

            // Enumerate solutions for every combination of material and cooler
            List <CandidateSolution> candidates = new List <CandidateSolution>();

            foreach (Material m in materials)
            {
                foreach (Cooler c in coolers)
                {
                    CandidateSolution cs = new CandidateSolution(m, c, targetTemp, strengthReq, problem);
                    if (cs.IsFeasible)
                    {
                        candidates.Add(cs);
                    }
                }
            }

            // Find the best solution
            double            solutionCost    = Double.MaxValue;
            CandidateSolution optimalSolution = null;

            foreach (CandidateSolution c in candidates)
            {
                if (c.SolutionCost < solutionCost)
                {
                    optimalSolution = c;
                    solutionCost    = c.SolutionCost;
                }
            }

            Solution answer = null;

            if (candidates.Count == 0)
            {
                return(null);
            }
            else
            {
                answer = new Solution(
                    problem.Name,
                    optimalSolution.Cooler.Name,
                    optimalSolution.CoolerPowerFactor,
                    optimalSolution.Material.Name,
                    optimalSolution.StrutCrossSection,
                    optimalSolution.StrutLength,
                    optimalSolution.SolutionCost
                    );
            }
            return(answer);
        }
Exemplo n.º 23
0
        public override void BuildProgram(ProgramSettings settings, Action <string> currentStatusCallback)
        {
            this.settings             = settings;
            displayGenerationCallback = currentStatusCallback;

            // create the engine.  each tree (and node within the tree) will return a bool.
            // we also indicate the type of our problem state data (used by terminal functions and stateful functions)
            var engine = new Engine <bool, ProblemState>(settings.GPsettings);

            // no constants for this problem

            // no variables for this solution - we can't pass in information about our hand
            // via boolean variables, so we do it via some terminal functions instead

            // for a boolean tree, we use the standard operators
            engine.AddFunction((a, b) => a || b, "Or");
            engine.AddFunction((a, b, c) => a || b || c, "Or3");
            engine.AddFunction((a, b) => a && b, "And");
            engine.AddFunction((a, b, c) => a && b && c, "And3");
            engine.AddFunction((a) => !a, "Not");

            // then add functions to indicate a strategy
            engine.AddStatefulFunction(HitIf, "HitIf");
            engine.AddStatefulFunction(StandIf, "StandIf");
            engine.AddStatefulFunction(DoubleIf, "DoubleIf");
            engine.AddStatefulFunction(SplitIf, "SplitIf");

            //----------------------------------------------
            // terminal functions to look at game state
            //----------------------------------------------

            // soft hands
            engine.AddTerminalFunction(AcePlus2, "AcePlus2");
            engine.AddTerminalFunction(AcePlus3, "AcePlus3");
            engine.AddTerminalFunction(AcePlus4, "AcePlus4");
            engine.AddTerminalFunction(AcePlus5, "AcePlus5");
            engine.AddTerminalFunction(AcePlus6, "AcePlus6");
            engine.AddTerminalFunction(AcePlus7, "AcePlus7");
            engine.AddTerminalFunction(AcePlus8, "AcePlus8");
            engine.AddTerminalFunction(AcePlus9, "AcePlus9");

            // pairs
            engine.AddTerminalFunction(HasPairTwos, "HasPair2");
            engine.AddTerminalFunction(HasPairThrees, "HasPair3");
            engine.AddTerminalFunction(HasPairFours, "HasPair4");
            engine.AddTerminalFunction(HasPairFives, "HasPair5");
            engine.AddTerminalFunction(HasPairSixes, "HasPair6");
            engine.AddTerminalFunction(HasPairSevens, "HasPair7");
            engine.AddTerminalFunction(HasPairEights, "HasPair8");
            engine.AddTerminalFunction(HasPairNines, "HasPair9");
            engine.AddTerminalFunction(HasPairTens, "HasPairT");
            engine.AddTerminalFunction(HasPairAces, "HasPairA");

            // hard hand totals
            engine.AddTerminalFunction(HandVal5, "Hard5");
            engine.AddTerminalFunction(HandVal6, "Hard6");
            engine.AddTerminalFunction(HandVal7, "Hard7");
            engine.AddTerminalFunction(HandVal8, "Hard8");
            engine.AddTerminalFunction(HandVal9, "Hard9");
            engine.AddTerminalFunction(HandVal10, "Hard10");
            engine.AddTerminalFunction(HandVal11, "Hard11");
            engine.AddTerminalFunction(HandVal12, "Hard12");
            engine.AddTerminalFunction(HandVal13, "Hard13");
            engine.AddTerminalFunction(HandVal14, "Hard14");
            engine.AddTerminalFunction(HandVal15, "Hard15");
            engine.AddTerminalFunction(HandVal16, "Hard16");
            engine.AddTerminalFunction(HandVal17, "Hard17");
            engine.AddTerminalFunction(HandVal18, "Hard18");
            engine.AddTerminalFunction(HandVal19, "Hard19");
            engine.AddTerminalFunction(HandVal20, "Hard20");

            // upcards
            engine.AddTerminalFunction(DealerShows2, "Dlr2");
            engine.AddTerminalFunction(DealerShows3, "Dlr3");
            engine.AddTerminalFunction(DealerShows4, "Dlr4");
            engine.AddTerminalFunction(DealerShows5, "Dlr5");
            engine.AddTerminalFunction(DealerShows6, "Dlr6");
            engine.AddTerminalFunction(DealerShows7, "Dlr7");
            engine.AddTerminalFunction(DealerShows8, "Dlr8");
            engine.AddTerminalFunction(DealerShows9, "Dlr9");
            engine.AddTerminalFunction(DealerShows10, "Dlr10");
            engine.AddTerminalFunction(DealerShowsA, "DlrA");

            // pass a fitness evaluation function and run
            engine.AddFitnessFunction((t) => EvaluateCandidate(t));

            // and add something so we can track the progress
            engine.AddProgressFunction((t) => PerGenerationCallback(t));

            Solution    = engine.FindBestSolution();
            Fitness     = Solution.Fitness;
            FinalStatus = "Final Score: " + Fitness.ToString() + "\n" +
                          "Generations needed to find: " + NumGenerationsNeeded;
        }
Exemplo n.º 24
0
 public override void SetCandidateRef(CandidateSolution <T, S> candidate)
 {
     ownerCandidate = candidate;
 }
Exemplo n.º 25
0
 public VariableNode(string varName, CandidateSolution <T, S> candidate)
 {
     variableName   = varName;
     ownerCandidate = candidate;
 }
Exemplo n.º 26
0
        /**
         * Evolve the population.
         * @param pop The population.
         * @return The evolved population.
         */
        private Population EvolvePopulation(Population population)
        {
            Array.Sort(population.CandidateSolutions, delegate(CandidateSolution x, CandidateSolution y)
            {
                if (x.Fitness > y.Fitness)
                {
                    return(-1);
                }
                else if (x.Fitness < y.Fitness)
                {
                    return(1);
                }

                return(0);
            });

            Population matingPool             = GenerateMatingPool(population);
            Population offsetSpringPopulation = new Population(fitnessCalculator, PopulationSize, BitSize, GenotypeLength, GroupSize);

            // Crossover operation.
            Random random = new Random();

            for (int i = 0; i < offsetSpringPopulation.CandidateSolutions.Length; i++)
            {
                CandidateSolution child = null;
                var probability         = random.NextDouble();

                if (CrossoverProbability < probability)
                {
                    child = matingPool.CandidateSolutions[i];
                }
                else
                {
                    CandidateSolution parent1 = matingPool.CandidateSolutions[i];
                    bool reject = true;
                    int  trial  = 0;

                    do
                    {
                        CandidateSolution parent2 = selection(matingPool);

                        child = crossover(parent1, parent2);

                        if (IsValid(child))
                        {
                            reject = false;
                        }
                        else
                        {
                            trial++;
                        }
                    }while (reject && trial < 10);

                    if (trial == 10)
                    {
                        child = parent1;
                    }
                }

                offsetSpringPopulation.CandidateSolutions[i] = child;
            }

            // Mutation.
            for (int i = 0; i < offsetSpringPopulation.CandidateSolutions.Length; i++)
            {
                mutate(offsetSpringPopulation.CandidateSolutions[i]);
            }

            // Survivor selection
            Array.Sort(offsetSpringPopulation.CandidateSolutions, delegate(CandidateSolution x, CandidateSolution y)
            {
                if (x.Fitness > y.Fitness)
                {
                    return(-1);
                }
                else if (x.Fitness < y.Fitness)
                {
                    return(1);
                }

                return(0);
            });

            Population newPopulation     = new Population(fitnessCalculator, PopulationSize, BitSize, GenotypeLength, GroupSize);
            var        parentCount       = (int)(population.CandidateSolutions.Length * SurvivalProbability);
            var        offsetSpringCount = (int)(offsetSpringPopulation.CandidateSolutions.Length * (1.0d - SurvivalProbability));

            while (parentCount + offsetSpringCount < PopulationSize)
            {
                if (parentCount % 2 == 1)
                {
                    parentCount++;
                }
                else
                {
                    offsetSpringCount++;
                }
            }

            int counter = 0;

            for (int i = 0; i < newPopulation.CandidateSolutions.Length; i++)
            {
                if (i < parentCount)
                {
                    newPopulation.CandidateSolutions[i] = population.CandidateSolutions[i];
                }
                else
                {
                    newPopulation.CandidateSolutions[i] = offsetSpringPopulation.CandidateSolutions[counter];
                    counter++;
                }
            }

            return(newPopulation);
        }