Ejemplo n.º 1
0
        public static List <Board> GetOptimalBoards(Board b, Options o, BoardScorer.Options bso)
        {
            object       bestLock  = new object();
            Board        best      = new Board(b);
            double       bestScore = 0;
            List <Board> particles = new List <Board>();

            for (int i = 0; i < o.NumParticles; i++)
            {
                particles.Add(GetRandomBoard(b));
            }
            Parallel.For(0, o.SAIterations, iteration =>
                         //for (int iteration = 0; iteration < o.SAIterations; iteration++)
            {
                var r    = new Random(rng.Next());
                var temp = o.StartTemp * (1.0 - (double)iteration / o.SAIterations);
                for (int n = 0; n < o.NumParticles; n++)
                {
                    var neighbor      = GetBoardAfterRandomSwap(particles[n], r);
                    var oldBoardScore = particles[n].Score(bso);
                    var newBoardScore = neighbor.Score(bso);
                    if (oldBoardScore < newBoardScore)
                    {
                        particles[n] = neighbor;
                        lock (bestLock)
                        {
                            if (newBoardScore > bestScore)
                            {
                                bestScore = newBoardScore;
                                best      = neighbor;
                            }
                        }
                        continue;
                    }
                    if (Math.Exp(-(newBoardScore - oldBoardScore) / temp) < r.NextDouble())
                    {
                        particles[n] = neighbor;
                        continue;
                    }
                }
            });
            return(new List <Board> {
                best
            });
            //return particles.Where(p => p.Score(bso) == particles.Max(s => s.Score(bso))).ToList();
        }
Ejemplo n.º 2
0
        public static Path GetBestPath(Board b, Options o, BoardScorer.Options bso)
        {
            Path   bestPath = new Path();
            object pathLock = new object();

            Parallel.For(0, b.Height, i =>
            {
                //for (int i = 0; i < b.Height; i++)
                Parallel.For(0, b.Width, j =>
                {
                    //for (int j = 0; j < b.Width; j++)
                    var curPath = GetBestPathFrom(b, o, i, j, bso);
                    lock (pathLock)
                    {
                        if (curPath.Score > bestPath.Score)
                        {
                            bestPath = curPath;
                        }
                    }
                });
            });

            return(bestPath);
        }
Ejemplo n.º 3
0
        //public static Path GetBestPath(Board b, Options o, BoardScorer.Options bso)
        //{
        //    Board targetBoard = new Board(b.Height, b.Width);
        //    Board goalBoard = GetOptimalBoards(b, o, bso).First();
        //    Path path = new Path();
        //    for (int j = 0; j < targetBoard.Width; j++)
        //        for (int i = 0; i < targetBoard.Height; i++)
        //        {
        //            targetBoard.Orbs[i, j] = goalBoard.Orbs[i, j];
        //            path = GetBestPathFrom(b, targetBoard, bso, path);
        //            b = b.GetBoardsAfterPath(path.Start.Item1, path.Start.Item2, path.Actions).Item1;
        //        }
        //    return path;
        //}
        //private static Path GetBestPathFrom(Board b, Board target, BoardScorer.Options bso, Path p)
        //{
        //    HashSet<Board> explored = new HashSet<Board>();
        //    explored.Add(b);
        //    Queue<Tuple<Board, Path>> paths = new Queue<Tuple<Board, Path>>();
        //    paths.Enqueue(new Tuple<Board, Path>(b, p));
        //    while (paths.Any())
        //    {
        //        var cur = paths.Dequeue();
        //        var curPath = cur.Item2;
        //        var curBoard = cur.Item1;

        //        if (curBoard.EqualsBoard(target, ignoreNone: true))
        //            return curPath;

        //        foreach (var direction in Board.MoveDirections)
        //        {
        //            if (curPath.Length != 0 &&
        //                curPath.Actions.Last()[0] == -direction[0] &&
        //                curPath.Actions.Last()[1] == -direction[1])
        //                continue;
        //            var newY = curPath.Current.Item1 + direction[0];
        //            var newX = curPath.Current.Item2 + direction[1];
        //            if (newY < 0 || newY >= b.Height ||
        //                newX < 0 || newX >= b.Width)
        //                continue;
        //            Board newBoard = new Board(curBoard);
        //            Orb tempOrb = newBoard.Orbs[newY, newX];
        //            newBoard.Orbs[newY, newX] = newBoard.Orbs[curPath.Current.Item1, curPath.Current.Item2];
        //            newBoard.Orbs[curPath.Current.Item1, curPath.Current.Item2] = tempOrb;
        //            var newPath = new List<int[]>(curPath.Actions);
        //            newPath.Add(direction);
        //            if (explored.Contains(newBoard))
        //                continue;
        //            explored.Add(newBoard);
        //            paths.Enqueue(new Tuple<Board, Path>(newBoard, new Path
        //            {
        //                Start = curPath.Start,
        //                Current = new Tuple<int, int>(newY, newX),
        //                Depth = curPath.Depth + 1,
        //                Score = 0,
        //                Actions = newPath
        //            }));
        //        }
        //    }
        //    return null;
        //}

        // a-star is silly if all edges are length 1...?
        public static Path GetBestPath(Board b, Options o, BoardScorer.Options bso)
        {
            Board     goalBoard = GetOptimalBoards(b, o, bso).First();
            Heuristic h         = o.HeuristicGen(goalBoard);
            PriorityQueue <Tuple <Board, Path>, double> queue = new PriorityQueue <Tuple <Board, Path>, double>();
            HashSet <Board>            visited   = new HashSet <Board>();
            Dictionary <Board, double> toExplore = new Dictionary <Board, double>();

            toExplore.Add(b, 0);
            queue.Enqueue(new Tuple <Board, Path>(b, new Path {
                Start = new Tuple <int, int>(2, 2)
            }), -h(b));

            while (!queue.Empty)
            {
                var cur      = queue.Dequeue();
                var curBoard = cur.Item1;
                var curPath  = cur.Item2;
                var curCost  = curPath.Depth;
                if (curBoard.EqualsBoard(goalBoard))
                {
                    return(curPath);
                }
                visited.Add(curBoard);
                foreach (var direction in Board.MoveDirections)
                {
                    if (curPath.Length != 0 &&
                        curPath.Actions.Last()[0] == -direction[0] &&
                        curPath.Actions.Last()[1] == -direction[1])
                    {
                        continue;
                    }
                    var newY = curPath.Current.Item1 + direction[0];
                    var newX = curPath.Current.Item2 + direction[1];
                    if (newY < 0 || newY >= b.Height ||
                        newX < 0 || newX >= b.Width)
                    {
                        continue;
                    }
                    Board newBoard = new Board(curBoard);
                    Orb   tempOrb  = newBoard.Orbs[newY, newX];
                    newBoard.Orbs[newY, newX] = newBoard.Orbs[curPath.Current.Item1, curPath.Current.Item2];
                    newBoard.Orbs[curPath.Current.Item1, curPath.Current.Item2] = tempOrb;
                    if (visited.Contains(newBoard) || toExplore.ContainsKey(newBoard) && toExplore[newBoard] <= curCost + 1)
                    {
                        continue;
                    }
                    var newPath = new List <int[]>(curPath.Actions);
                    newPath.Add(direction);
                    queue.Enqueue(new Tuple <Board, Path>(newBoard, new Path
                    {
                        Start   = curPath.Start,
                        Current = new Tuple <int, int>(newY, newX),
                        Depth   = curCost + 1,
                        Score   = 0, //newBoard.Score(BoardScorer.Options.Horus) - curPath.Depth / 100,
                        Actions = newPath
                    }), -h(newBoard) - curCost - 1);
                    toExplore[newBoard] = curCost + 1;
                }
            }

            return(new Path());
        }
Ejemplo n.º 4
0
        public static Path GetBestPathSA(Board b, Options o, BoardScorer.Options bso)
        {
            object       bestLock      = new object();
            Path         best          = new Path();
            double       bestScore     = 100000;
            Board        goalBoard     = GetOptimalBoards(b, o, bso).First();
            Heuristic    h             = o.HeuristicGen(goalBoard);
            List <Board> particles     = new List <Board>();
            List <Path>  particlePaths = new List <Path>();

            for (int i = 0; i < o.NumParticles; i++)
            {
                var pos = new Tuple <int, int>(rng.Next(b.Height), rng.Next(b.Width));
                particles.Add(new Board(b));
                particlePaths.Add(new Path
                {
                    Start   = pos,
                    Current = pos
                });
            }

            //Parallel.For(0, o.SAIterations, iteration =>
            for (int iteration = 0; iteration < o.TILE_SAIterations; iteration++)
            {
                var r    = new Random(rng.Next());
                var temp = o.TILE_StartTemp * (1.0 - (double)iteration / o.SAIterations);
                for (int n = 0; n < o.NumParticles; n++)
                {
                    //if (goalBoard.EqualsBoard(particles[n]))
                    //    return particlePaths[n];
                    var neighbor      = GetBoardAfterRandomSwap(particles[n], r, particlePaths[n]);
                    var oldBoardScore = h(particles[n]);
                    var newBoardScore = h(neighbor.Item1);
                    if (newBoardScore < oldBoardScore)
                    {
                        particlePaths[n].Actions.Add(neighbor.Item2);
                        var newY = particlePaths[n].Current.Item1 + neighbor.Item2[0];
                        var newX = particlePaths[n].Current.Item2 + neighbor.Item2[1];
                        particlePaths[n].Current = new Tuple <int, int>(newY, newX);
                        particles[n]             = neighbor.Item1;
                        lock (bestLock)
                        {
                            if (newBoardScore < bestScore)
                            {
                                bestScore = newBoardScore;
                                best      = new Path
                                {
                                    Start   = particlePaths[n].Start,
                                    Actions = new List <int[]>(particlePaths[n].Actions),
                                    Current = new Tuple <int, int>(newY, newX)
                                };
                            }
                        }
                        continue;
                    }
                    if (Math.Exp((newBoardScore - oldBoardScore) / temp) < r.NextDouble())
                    {
                        particlePaths[n].Actions.Add(neighbor.Item2);
                        var newY = particlePaths[n].Current.Item1 + neighbor.Item2[0];
                        var newX = particlePaths[n].Current.Item2 + neighbor.Item2[1];
                        particlePaths[n].Current = new Tuple <int, int>(newY, newX);
                        particles[n]             = neighbor.Item1;
                        continue;
                    }
                }
            }
            return(best);
        }
Ejemplo n.º 5
0
        private static Path GetBestPathFrom(Board b, Options o, int y, int x, BoardScorer.Options bso)
        {
            Path bestPath = new Path();
            PriorityQueue <Tuple <Board, Path>, double> paths = new PriorityQueue <Tuple <Board, Path>, double>();

            paths.Enqueue(new Tuple <Board, Path>(b, new Path
            {
                Start   = new Tuple <int, int>(y, x),
                Current = new Tuple <int, int>(y, x),
                Depth   = 1,
                Score   = b.Score(bso)
            }));
            int depth = 0;

            while (depth++ < o.MaxDepth)
            {
                // Console.WriteLine("currently at depth {0}...", depth);
                PriorityQueue <Tuple <Board, Path>, double> newPaths = new PriorityQueue <Tuple <Board, Path>, double>();
                while (paths.Count != 0)
                {
                    var cur      = paths.Dequeue();
                    var curPath  = cur.Item2;
                    var curBoard = cur.Item1;
                    if (curPath.Score > bestPath.Score)
                    {
                        bestPath = curPath;
                    }

                    //if (paths.Count() > o.WhenToPrune)
                    //{
                    //    var newPaths = new Stack<Tuple<Board, Path>>();
                    //    foreach (var path in paths.OrderByDescending(p => p.Item2.Score).Take(o.NumToKeep).Reverse())
                    //        newPaths.Push(path);
                    //    paths = newPaths;
                    //}

                    foreach (var direction in Board.MoveDirections)
                    {
                        if (curPath.Length != 0 &&
                            curPath.Actions.Last()[0] == -direction[0] &&
                            curPath.Actions.Last()[1] == -direction[1])
                        {
                            continue;
                        }
                        var newY = curPath.Current.Item1 + direction[0];
                        var newX = curPath.Current.Item2 + direction[1];
                        if (newY < 0 || newY >= b.Height ||
                            newX < 0 || newX >= b.Width)
                        {
                            continue;
                        }
                        Board newBoard = new Board(curBoard);
                        Orb   tempOrb  = newBoard.Orbs[newY, newX];
                        newBoard.Orbs[newY, newX] = newBoard.Orbs[curPath.Current.Item1, curPath.Current.Item2];
                        newBoard.Orbs[curPath.Current.Item1, curPath.Current.Item2] = tempOrb;
                        var newPath = new List <int[]>(curPath.Actions);
                        newPath.Add(direction);
                        double score = newBoard.Score(bso) - curPath.Depth / 100;
                        newPaths.Enqueue(new Tuple <Board, Path>(newBoard, new Path
                        {
                            Start   = curPath.Start,
                            Current = new Tuple <int, int>(newY, newX),
                            Depth   = curPath.Depth + 1,
                            Score   = score,
                            Actions = newPath
                        }), score);
                    }
                }
                paths = newPaths.TrimToSize(o.BeamWidth);
            }
            return(bestPath);
        }
Ejemplo n.º 6
0
 public static Path GetBestPath(Board b, BoardScorer.Options bso)
 {
     return(GetBestPath(b, Options.Default, bso));
 }