Esempio n. 1
0
        public Tuple <MoveList, MoveList> DoCrossover(MoveList firstMovelist, MoveList secondMovelist)
        {
            var child1 = new MoveList();
            var child2 = new MoveList();

            if (firstMovelist.Count >= 3)
            {
                var firstCrossoverPoint  = _randomizer.Next(1, firstMovelist.Count - 1);
                var secondCrossoverPoint = _randomizer.Next(1, firstMovelist.Count - 1);
                while (secondCrossoverPoint == firstCrossoverPoint)
                {
                    secondCrossoverPoint = _randomizer.Next(1, firstMovelist.Count - 1);
                }
                var lowestCrossoverPoint  = (firstCrossoverPoint < secondCrossoverPoint ? firstCrossoverPoint : secondCrossoverPoint);
                var highestCrossoverPoint = (firstCrossoverPoint > secondCrossoverPoint ? firstCrossoverPoint : secondCrossoverPoint);
                var difference            = highestCrossoverPoint - lowestCrossoverPoint;

                child1.AddRange(
                    firstMovelist.Take(lowestCrossoverPoint)
                    .Concat(secondMovelist.Skip(lowestCrossoverPoint).Take(difference))
                    .Concat(firstMovelist.Skip(highestCrossoverPoint))
                    );

                child2.AddRange(
                    secondMovelist.Take(lowestCrossoverPoint)
                    .Concat(firstMovelist.Skip(lowestCrossoverPoint).Take(difference))
                    .Concat(secondMovelist.Skip(highestCrossoverPoint))
                    );
                var children = new Tuple <MoveList, MoveList>(child1, child2);
                return(children);
            }
            else
            {
                var performOnePointCrossover = _randomizer.NextBoolean();
                //Not using the crossover factory to make sure a TwoPointCrossover won't be created.
                if (performOnePointCrossover)
                {
                    var opc      = new OnePointCrossover(_randomizer);
                    var children = opc.DoCrossover(firstMovelist, secondMovelist);
                    return(children);
                }
                else
                {
                    var oc       = new OrderedCrossover(_randomizer);
                    var children = oc.DoCrossover(firstMovelist, secondMovelist);
                    return(children);
                }
            }
        }
Esempio n. 2
0
        public Tuple <MoveList, MoveList> DoCrossover(MoveList firstMovelist, MoveList secondMovelist)
        {
            var child1 = new MoveList();
            var child2 = new MoveList();

            if (firstMovelist.Count > 2)
            {
                //If crossover = 0, you simply swap the entire sequence. This doesn't yield a new child
                //Same if the crossoverPoint = length - 1.
                var elementsToSkip = _randomizer.Next(1, firstMovelist.Count - 2);

                child1.AddRange(firstMovelist.Take(elementsToSkip).Concat(secondMovelist.Skip(elementsToSkip)));
                child2.AddRange(secondMovelist.Take(elementsToSkip).Concat(firstMovelist.Skip(elementsToSkip)));
            }
            else if (firstMovelist.Count == 1)
            {
                child1.Add(firstMovelist[0]);
                child2.Add(secondMovelist[0]);
            }
            else
            {
                var swapFirstMove = _randomizer.NextBoolean();
                if (swapFirstMove)
                {
                    child1.Add(secondMovelist[0]);
                    child1.Add(firstMovelist[1]);
                    child2.Add(firstMovelist[0]);
                    child2.Add(secondMovelist[1]);
                }
                else
                {
                    child1.Add(firstMovelist[0]);
                    child1.Add(secondMovelist[1]);
                    child2.Add(secondMovelist[0]);
                    child2.Add(firstMovelist[1]);
                }
            }
            var children = new Tuple <MoveList, MoveList>(child1, child2);

            return(children);
        }
Esempio n. 3
0
        protected void CollectSolution(Node leaf)
        {
            foundSolution = true;

            // Don't bother if we're not collection solutions.
            if (!collectSolutions)
            {
                return;
            }

            // Prepare to construct the solution.
            MoveList solution = new MoveList();
            Level tempLevel = new Level(originalLevel);
            tempLevel.Validate = validate;
            PathFinder tempFinder = PathFinder.CreateInstance(tempLevel, true);

            // Iterate over the nodes from the root to the leaf.
            int previousPushes = 0;
#if false
            List<Node> nodeList = FindParents(root, leaf);
#else
            List<Node> nodeList = new List<Node>();
            for (int i = 0; i < current.ParentIndex; i++)
            {
                nodeList.Add(current.Parents[i]);
            }
            nodeList.Add(leaf);
#endif
            foreach (Node node in nodeList)
            {
                // Check whether we need to move the sokoban.
                if (node.Coordinate != tempLevel.SokobanCoordinate)
                {
                    // Move the sokoban to the box.
                    solution.AddRange(tempFinder.FindAndGetPath(node.Coordinate));
                    tempLevel.MoveSokoban(node.Coordinate);
                }

                // Check whether we need to push a box.
                int consecutivePushes = node.Pushes - previousPushes;
                if (consecutivePushes != 0)
                {
                    // Push the box one or more times.
                    OperationDirectionPair push = new OperationDirectionPair(Levels.Operation.Push, node.Direction);
                    for (int j = 0; j < consecutivePushes; j++)
                    {
                        solution.Add(push);
                        tempLevel.Move(push);
                    }
                    previousPushes = node.Pushes;
                }
            }

            // Validate the solution.
            if (!tempLevel.IsComplete)
            {
                throw Abort("constructed move list does not solve level");
            }
            if (optimizeMoves && solution.Count != leaf.Moves)
            {
                throw Abort("constructed move list does not match leaf tree in moves");
            }
            if (LevelUtils.SolutionPushes(solution) != leaf.Pushes)
            {
                throw Abort("constructed move list does not match leaf tree in pushes");
            }

            // Add the solution.
            solutions.Add(solution);

            int moves = solution.Count;
            int pushes = LevelUtils.SolutionPushes(solution);
            moveLimit = Math.Min(moveLimit, moves);
            pushLimit = Math.Min(pushLimit, pushes);

#if DEBUG
            if (verbose)
            {
                Log.DebugPrint("                            found solution: {0}/{1}", moves, pushes);
            }
#endif
        }