Example #1
0
 /// <summary>
 /// Конструктор
 /// </summary>
 /// <param name="parRoot">Родиельский узел</param>
 /// <param name="parLevel">Уровень</param>
 public SolutionThree(Move parMove, SolutionThree parRoot, int parLevel)
 {
     _Root = parRoot;
     _Level = parLevel;
     _Move = parMove;
     _ChildNodes = new List<SolutionThree>();
 }
Example #2
0
        /// <summary>
        /// Проверка тупика
        /// </summary>
        /// <param name="parSolutionThree">проверяемый узел дерева</param>
        /// <returns>true - если узел тупиковый </returns>
        public override bool Deadlock(SolutionThree parSolutionThree)
        {
            bool deadlock = false;

            if ((parSolutionThree.Level >= MaxAlowableDepth))
            {
                deadlock = true;
            }

            return deadlock;
        }
Example #3
0
        /// <summary>
        /// метод наилучшего частичного пути
        /// </summary>
        /// <param name="parSolutionThree">Корневой узел</param>
        /// <param name="parLocalDepth">величина углубления в ширину</param>
        /// <returns></returns>
        private bool PartialPath(SolutionThree parSolutionThree, int parLocalDepth)
        {
            //флаг нахождения решения
            bool complete = false;
            //флаг завершение алгоритма
            bool done = false;

            int localDepth = 0;

            SolutionThree solutionThree = parSolutionThree;

            //инициализируем список вершин дерева решений на текущем уровне
            List<SolutionThree> currentLevelNodes = new List<SolutionThree>();
            //и на следующем уровне
            List<SolutionThree> nextLevelNodes = new List<SolutionThree>();

            //заносим корневую ситуацию в список вершин текущего уровня
            currentLevelNodes.Add(solutionThree);

            //если корневой узел является целевым
            if (GoalIsReached(solutionThree))
            {
                //решение найдено
                complete = true;
            }
            //в противном случае начинаем алгоритм поиска
            else
            {
                //пока алгоритм не завершен выволняем действия
                while (!done)
                {
                    //рассматриваем каждый узел на текущем уровне
                    for (int i = 0; (i < currentLevelNodes.Count) && (!done); i++)
                    {

                        //если пора углубляться
                        if (localDepth == parLocalDepth)
                        {
                            complete = PartialPath(currentLevelNodes[i], parLocalDepth);
                            done = complete;
                            currentLevelNodes[i] = null;
                        }
                        else
                        {
                            //получаем список возможных ходов
                            List<Move> availableMove = GetAvailableMoves(currentLevelNodes[i]);

                            //для каждого возможного хода
                            for (int j = 0; (j < availableMove.Count) && (!done); j++)
                            {
                                //совершаем ход
                                MakeMove(availableMove[j], currentLevelNodes[i]);
                                //добавляем его в дерево решений
                                currentLevelNodes[i].AddChildNode(availableMove[j]);
                                _Info.GeneratedNodesCount++;

                                SolutionThree newNode = currentLevelNodes[i].ChildNodes[currentLevelNodes[i].ChildNodes.Count - 1];
                                //запоминаем максимальную глубину поиска
                                _Info.MaxDepth = newNode.Level;

                                //если сгенерированный узел является целевым
                                if (GoalIsReached(newNode))
                                {
                                    //решение найдено
                                    complete = true;
                                    //алгоритм завершен
                                    done = true;
                                    //запоминаем длину пути и получаем список ходов до цели
                                    _Info.PathLenght = newNode.Level;
                                    _Info.MovesToGoal = GetMovesToGoal(newNode);
                                }
                                else
                                {
                                    //если сгенерированный узел не тупиковый,
                                    if (!Deadlock(newNode))
                                    {
                                        //добавляем его в список узлов следующего уровня
                                        nextLevelNodes.Add(newNode);
                                    }
                                }
                            }
                        }
                    }

                    //если решение не было достигнуто
                    if (!complete)
                    {
                        //если на следующем уровен нету узлов
                        if (nextLevelNodes.Count == 0)
                        {
                            //алгоритм закончен
                            done = true;
                        }
                        else
                        {
                            //если следующий уровень является максимально допустимым
                            if (nextLevelNodes[0].Level >= MaxAlowableDepth)
                            {
                                //алгоритм закончен
                                done = true;
                            }
                            //иначе
                            else
                            {
                                //переходим на следующий уровень
                                currentLevelNodes = nextLevelNodes;
                                nextLevelNodes = new List<SolutionThree>();
                                localDepth++;

                                if (localDepth == parLocalDepth)
                                {
                                    //сортируем по оценочной функции
                                    SortThreeNodes(currentLevelNodes);
                                }

                            }
                        }
                    }

                }
            }

            return complete;
        }
Example #4
0
        /// <summary>
        /// Поиск в ширину
        /// </summary>
        /// <returns></returns>
        public bool BreadthSolve()
        {
            //Засекаем время
            _Info.ProcessTime = new Stopwatch();
            _Info.ProcessTime.Start();
            //Задаем начальные сведения
            _Info.MaxDepth = 0;
            _Info.PathLenght = 0;
            _Info.GeneratedNodesCount = 0;
            _Info.MovesToGoal = new List<Move>();

            //флаг нахождения решения
            bool complete = false;
            //флаг завершение алгоритма
            bool done = false;

            //создаем первый ход
            Move firstMove = CreateFirstMove();
            //добавляем узел в дерево решений
            SolutionThree solutionThree = new SolutionThree(firstMove, null, 0);

            //инициализируем список вершин дерева решений на текущем уровне
            List<SolutionThree> currentLevelNodes = new List<SolutionThree>();
            //и на следующем уровне
            List<SolutionThree> nextLevelNodes = new List<SolutionThree>();

            //заносим корневую ситуацию в список вершин текущего уровня
            currentLevelNodes.Add(solutionThree);

            //если корневой узел является целевым
            if (GoalIsReached(solutionThree))
            {
                //решение найдено
                complete = true;

            }
            //в противном случае начинаем алгоритм поиска
            else
            {
                //пока алгоритм не завершен выволняем действия
                while (!done)
                {
                    //рассматриваем каждый узел на текущем уровне
                    for (int i = 0; (i < currentLevelNodes.Count) && (!done); i++)
                    {
                        //получаем список возможных ходов
                        List<Move> availableMove = GetAvailableMoves(currentLevelNodes[i]);
                        //для каждого возможного хода
                        for (int j = 0; (j < availableMove.Count) && (!done); j++)
                        {
                            //совершаем ход
                            MakeMove(availableMove[j], currentLevelNodes[i]);
                            //добавляем его в дерево решений
                            currentLevelNodes[i].AddChildNode(availableMove[j]);
                            _Info.GeneratedNodesCount++;

                            SolutionThree newNode = currentLevelNodes[i].ChildNodes[currentLevelNodes[i].ChildNodes.Count - 1];
                            //запоминаем максимальную глубину поиска
                            _Info.MaxDepth = newNode.Level;

                            //если сгенерированный узел является целевым
                            if (GoalIsReached(newNode))
                            {
                                //решение найдено
                                complete = true;
                                //алгоритм завершен
                                done = true;
                                //запоминаем длину пути и получаем список ходов до цели
                                _Info.PathLenght = newNode.Level;
                                _Info.MovesToGoal = GetMovesToGoal(newNode);
                            }
                            else
                            {
                                //если сгенерированный узел не тупиковый,
                                if (!Deadlock(newNode))
                                {
                                    //добавляем его в список узлов следующего уровня
                                    nextLevelNodes.Add(newNode);
                                }
                            }
                        }
                    }

                    //если решение не было достигнуто
                    if (!complete)
                    {
                        //если на следующем уровен нету узлов
                        if (nextLevelNodes.Count == 0)
                        {
                            //алгоритм закончен
                            done = true;
                        }
                        else
                        {
                            //если следующий уровень является максимально допустимым
                            if (nextLevelNodes[0].Level >= MaxAlowableDepth)
                            {
                                //алгоритм закончен
                                done = true;
                            }
                                //иначе
                            else
                            {
                                //переходим на следующий уровень
                                currentLevelNodes = nextLevelNodes;
                                nextLevelNodes = new List<SolutionThree>();
                            }
                        }
                    }

                }
            }

            //Фиксируем время выполнения
            _Info.ProcessTime.Stop();
            //Записываем результат выполнения
            _Info.Complete = complete;
            _Info.Method = "Поиск в ширину";

            //если решение было найдено
            if (complete)
            {
                //рассчитываем разветвленность и направленность
                _Info.Branching = (double)_Info.GeneratedNodesCount / (double)_Info.PathLenght;
                _Info.Directionality = Math.Pow(_Info.GeneratedNodesCount, ((double)1 / _Info.PathLenght));
            }
            //если решение небыло найдено
            else
            {
                //указываем что длина пути решения, разветвленность и направленность не вычеслены числом -1
                _Info.PathLenght = -1;
                _Info.Branching = -1;
                _Info.Directionality = -1;
            }

            return complete;
        }
Example #5
0
 /// <summary>
 /// Определение тупика в указанной вершине
 /// </summary>
 /// <param name="parSolutionThree">проверяемая вершина дерева</param>
 /// <returns>true - если вершина тупиковая</returns>
 public abstract bool Deadlock(SolutionThree parSolutionThree);
Example #6
0
        /// <summary>
        /// Отмена хода
        /// </summary>
        /// <param name="parMove"></param>
        /// <param name="parSolutionThree"></param>
        public override void CancelMove(Move parMove, SolutionThree parSolutionThree)
        {
            _Task.Mirrors = parMove.Mirrors;

            for (int i = 0; i < _Task.Mirrors.Count; i++)
            {
                if ((_Task.Mirrors[i].Left == parMove.ToPos.X) && (_Task.Mirrors[i].Top == parMove.ToPos.Y))
                {
                    parMove.Mirrors[i] = new Square(parMove.FromPos.Y, parMove.FromPos.Y + LasersGame.COORDINATE_RATIO, parMove.FromPos.X, parMove.FromPos.X + LasersGame.COORDINATE_RATIO);

                    _Task.CalculateLaser();
                }
            }
        }
Example #7
0
 /// <summary>
 /// Совершение хода
 /// </summary>
 /// <param name="parMove">Совершаемый ход</param>
 /// <param name="parSolutionThree">узел дерева, из которого совершаем ход</param>
 public override void MakeMove(Move parMove, SolutionThree parSolutionThree)
 {
     //активизируем поле
     _Task.Mirrors = GetMirrorsCopy(parMove.Mirrors);
     //проходим по всем зеркалам
     for (int i = 0; i < _Task.Mirrors.Count; i++)
     {
         //находим зеркало указанное в ходе и совершием ход
         if ((_Task.Mirrors[i].Left == parMove.FromPos.X) && (_Task.Mirrors[i].Top == parMove.FromPos.Y))
         {
             parMove.Mirrors[i] = new Square(parMove.ToPos.Y, parMove.ToPos.Y + LasersGame.COORDINATE_RATIO, parMove.ToPos.X, parMove.ToPos.X + LasersGame.COORDINATE_RATIO);
         }
     }
     _Task.Mirrors = GetMirrorsCopy(parMove.Mirrors);
     //пересчитываем траекторию лазера
     _Task.CalculateLaser();
 }
Example #8
0
 /// <summary>
 /// Проверка достижения цели
 /// </summary>
 /// <param name="parSolutionThree">проверяемый узел дерева</param>
 /// <returns>true - если узел целевой</returns>
 public override bool GoalIsReached(SolutionThree parSolutionThree)
 {
     return _Task.GoalReached();
 }
Example #9
0
        /// <summary>
        /// Метод наилучшего частичного пути
        /// </summary>
        /// <param name="parLocalDepth">Величина углубления в ширину</param>
        /// <returns></returns>
        public bool PartialPath(int parLocalDepth)
        {
            //Засекаем время
            _Info.ProcessTime = new Stopwatch();
            _Info.ProcessTime.Start();
            //Задаем начальные сведения
            _Info.MaxDepth = 0;
            _Info.PathLenght = 0;
            _Info.GeneratedNodesCount = 0;
            _Info.MovesToGoal = new List<Move>();

            //флаг нахождения решения
            bool complete = false;

            //создаем первый ход
            Move firstMove = CreateFirstMove();
            //добавляем узел в дерево решений
            SolutionThree solutionThree = new SolutionThree(firstMove, null, 0);

            complete = PartialPath(solutionThree, parLocalDepth);

            //Фиксируем время выполнения
            _Info.ProcessTime.Stop();
            //Записываем результат выполнения
            _Info.Complete = complete;
            _Info.Method = "Метод наилучшего частичного пути";

            //если решение было найдено
            if (complete)
            {
                //рассчитываем разветвленность и направленность
                _Info.Branching = (double)_Info.GeneratedNodesCount / (double)_Info.PathLenght;
                _Info.Directionality = Math.Pow(_Info.GeneratedNodesCount, ((double)1 / _Info.PathLenght));
            }
            //если решение небыло найдено
            else
            {
                //указываем что длина пути решения, разветвленность и направленность не вычеслены числом -1
                _Info.PathLenght = -1;
                _Info.Branching = -1;
                _Info.Directionality = -1;
            }

            return complete;
        }
Example #10
0
 /// <summary>
 /// Совершение хода
 /// </summary>
 /// <param name="parMove">Ход</param>
 /// <param name="parSolutionThree"> узелд дерева из которого совершается ход</param>
 public abstract void MakeMove(Move parMove, SolutionThree parSolutionThree);
Example #11
0
 /// <summary>
 /// Определение существования указанной ситуации
 /// </summary>
 /// <param name="parSolutionThree">вершина дерева решиня с проверяемой ситуацией</param>
 /// <returns></returns>
 public abstract bool IsExistsSituation(List<Situation> parSituations, SolutionThree parSolutionThree);
Example #12
0
 /// <summary>
 /// Определение достижения цели
 /// </summary>
 /// <param name="parSolutionThree">проверяемый узел дерева</param>
 /// <returns>true - если вершина целевая</returns>
 public abstract bool GoalIsReached(SolutionThree parSolutionThree);
Example #13
0
 /// <summary>
 /// ПОлучение списка возможных ходов из указанной вершины дерева
 /// </summary>
 /// <param name="parSolutionThree">вершина дерева</param>
 /// <returns>Список возможных ходов</returns>
 public abstract List<Move> GetAvailableMoves(SolutionThree parSolutionThree);
Example #14
0
 /// <summary>
 /// Оценочная функция
 /// </summary>
 /// <param name="parMove">оцениваемый ход</param>
 /// <param name="parSolutionThree"> узелд дерева из которого совершается ход</param>
 /// <returns>оценка хода</returns>
 public abstract int Estimator(Move parMove, SolutionThree parSolutionThree);
Example #15
0
        /// <summary>
        /// Оценочная функция
        /// </summary>
        /// <param name="parMove">оцениваемый ход</param>
        /// <param name="parSolutionThree"> узелд дерева из которого совершается ход</param>
        /// <returns>rколичество ходов, прошедших с момента последненго перемещения зеркала, указанного в ходе</returns>
        public override int Estimator(Move parMove, SolutionThree parSolutionThree)
        {
            int rating = MaxAlowableDepth + 1;
            //получаем исходное положение перемещаемого зеркала
            Point mirrorPosition = parMove.FromPos;
            //и узел дерева из которого совершаем ход
            SolutionThree solutionNode = parSolutionThree;

            //пока не добрались до корня дерва поиска
            while (solutionNode.Root != null)
            {
                //если ход, приведший к текущему узлу дерева, перемещал проверяемое зеркало
                if (solutionNode.Move.ToPos == mirrorPosition)
                {
                    //считаем сколько ходов назад это было
                    rating = parSolutionThree.Level - solutionNode.Level + 1;
                    break;
                }
                    //иначе
                else
                {
                    //и перемещаемся вверх по дереву.
                    solutionNode = solutionNode.Root;
                }
            }

            return rating;
        }
Example #16
0
        /// <summary>
        /// Получение списка возможных ходов
        /// </summary>
        /// <param name="parSolutionThree"></param>
        /// <returns></returns>
        public override List<Move> GetAvailableMoves(SolutionThree parSolutionThree)
        {
            List<Move> availableMove = new List<Move>();

            //получаем последний совершенный ход
            Move lastMove = parSolutionThree.Move;

            //активизируем поле, указанное в ходе
            _Task.Mirrors = GetMirrorsCopy(lastMove.Mirrors);

            //проходим по всез зеркалам
            for (int k = 0; k < _Task.Mirrors.Count; k++)
            {
                //в качаестве начальной точки берем положение очередного зеркала
                Point fromPos = new Point(_Task.Mirrors[k].Left, _Task.Mirrors[k].Top);
                //проходим по всем координатам поля
                for (int i = 0; i < _FieldHeight; i += LasersGame.COORDINATE_RATIO)
                    for (int j = 0; j < _FieldWidth; j += LasersGame.COORDINATE_RATIO)
                    {
                        //если ячейка не занята и не являетяс дырой
                        if (
                            (!_Task.ExistsHole(new Point(j, i))) &&
                            (!_Task.ExistsMirror(new Point(j, i)))
                           )
                        {
                            //выбираем конечную точку
                            Point toPos = new Point(j, i);
                            //и добавляем ход из начально точки в конечную в список возможных ходов
                            availableMove.Add(new Move(fromPos, toPos, GetMirrorsCopy(_Task.Mirrors)));
                        }
                    }
            }

            //возвращаем список возможных ходов
            return availableMove;
        }
Example #17
0
 /// <summary>
 /// Сортировка списка возможных ходов согласно оценочной функции
 /// </summary>
 /// <param name="parAvailableMoves"></param>
 /// <param name="parSolutionThree"> узелд дерева из которого совершается ход</param>
 public abstract void SortMoves(List<Move> parAvailableMoves, SolutionThree parSolutionThree);
Example #18
0
        /// <summary>
        /// Определение существования указанной ситуации
        /// </summary>
        /// <param name="parSolutionThree">вершина дерева решиня с проверяемой ситуацией</param>
        /// <returns></returns>
        public override bool IsExistsSituation(List<Situation> parSituations, SolutionThree parSolutionThree)
        {
            bool isExist = false;

            List<Square> mirrors =  parSolutionThree.Move.Mirrors;

            foreach(Situation situation in parSituations)
            {
                int mirrorsOnPlace = 0;

                foreach (Square mirror in mirrors)
                {
                    foreach (Point cell in situation.OcceupedCells)
                    {
                        if ((mirror.Left == cell.X) && (mirror.Top == cell.Y))
                        {
                            mirrorsOnPlace++;
                        }
                    }
                }

                if (mirrorsOnPlace == situation.OcceupedCells.Count)
                {
                    isExist = true;
                    return isExist;
                }
            }

            return isExist;
        }
Example #19
0
        /// <summary>
        /// Поиск в градиенту
        /// </summary>
        /// <returns></returns>
        public bool SteepestRiseSolve()
        {
            //Засекаем время
            _Info.ProcessTime = new Stopwatch();
            _Info.ProcessTime.Start();
            //Задаем начальные сведения
            _Info.MaxDepth = 0;
            _Info.PathLenght = 0;
            _Info.GeneratedNodesCount = 0;
            _Info.MovesToGoal = new List<Move>();

            //решение еще не найдено
            bool complete = false;
            //создаем первый ход
            Move firstMove = CreateFirstMove();
            //добавляем узел в дерево решений
            SolutionThree solutionThree = new SolutionThree(firstMove, null, 0);

            complete = SteepestRiseSolve(firstMove, solutionThree);

            //Фиксируем время выполнения
            _Info.ProcessTime.Stop();
            //Записываем результат выполнения
            _Info.Complete = complete;
            _Info.Method = "Поиск по градиенту";

            //если решение было найдено
            if (complete)
            {
                //рассчитываем разветвленность и направленность
                _Info.Branching = (double)_Info.GeneratedNodesCount / (double)_Info.PathLenght;
                _Info.Directionality = Math.Pow(_Info.GeneratedNodesCount, ((double)1 / _Info.PathLenght));
            }
            //если решение небыло найдено
            else
            {
                //указываем что длина пути решения, разветвленность и направленность не вычеслены числом -1
                _Info.PathLenght = -1;
                _Info.Branching = -1;
                _Info.Directionality = -1;
            }

            //возвращаем результат поиска
            return complete;
        }
Example #20
0
        /// <summary>
        /// Сортировка списка возможных ходов согласно оценочной функции
        /// </summary>
        /// <param name="parAvailableMoves"></param>
        /// <param name="parSolutionThree"> узелд дерева из которого совершается ход</param>
        public override void SortMoves(List<Move> parAvailableMoves, SolutionThree parSolutionThree)
        {
            List<Move> availableMoves = parAvailableMoves;
            List<int> movesMarks = new List<int>();

            //для каждого возможного хода
            for (int i = 0; i < availableMoves.Count; i++)
            {
                //получаем его оценку
                int rating = Estimator(availableMoves[i], parSolutionThree);
                movesMarks.Add(rating);
            }

            //сортируем возможные ходы согласно их оценкам
            for (int i = 0; i < availableMoves.Count; i++)
            {
                for (int j = 0; j < i; j++)
                {
                    if (movesMarks[i] > movesMarks[j])
                    {
                        int mark = movesMarks[i];
                        movesMarks.RemoveAt(i);
                        movesMarks.Insert(j, mark);

                        Move move = availableMoves[i];
                        availableMoves.RemoveAt(i);
                        availableMoves.Insert(j, move);
                    }
                }
            }
        }
Example #21
0
        /// <summary>
        /// Поиск по градиенту
        /// </summary>
        /// <param name="parMove">Ход</param>
        /// <param name="parSolutionThree">дерево решений</param>
        /// <returns>true если решение найдено, false в противном случае</returns>
        public bool SteepestRiseSolve(Move parMove, SolutionThree parSolutionThree)
        {
            //решение еще не найдено
            bool complete = false;
            //дерево решений
            SolutionThree solutionThree = parSolutionThree;
            //последний совершенный ход
            Move lastMove = solutionThree.Move;

            //если цель достигнута
            if (GoalIsReached(solutionThree))
            {
                complete = true;
                //записываем длину пути и получаем список ходов
                _Info.PathLenght = solutionThree.Level;
                _Info.MovesToGoal = GetMovesToGoal(solutionThree);
            }
            else
                // ессли тупик
                if (Deadlock(solutionThree))
                {
                    complete = false;
                }
                //если цель не достигнута и ситуация не тупиковая
                else
                {
                    //получаем список возможных ходщв
                    List<Move> availableMoves = GetAvailableMoves(solutionThree);

                    //упорядочиваем список возможных ходов согласно оценочной функции
                    SortMoves(availableMoves, solutionThree);

                    //проходим по всем узлам
                    for (int i = 0; i < availableMoves.Count; i++)
                    {
                        //совершаем очередной ход
                        MakeMove(availableMoves[i], solutionThree);

                        //добавляем узел в дерево решений
                        solutionThree.AddChildNode(availableMoves[i]);
                        _Info.GeneratedNodesCount++;

                        //Если уровень узла нового узла дерева больше чем сохраненный в логе,
                        if (solutionThree.ChildNodes[0].Level > _Info.MaxDepth)
                        {
                            //то записываем его в лог
                            _Info.MaxDepth = solutionThree.ChildNodes[0].Level;
                        }

                        // вызываем рекурсивный метод поиска в глубину
                        complete = SteepestRiseSolve(availableMoves[i], solutionThree.ChildNodes[0]);

                        //если решение было найдено
                        if (complete)
                        {
                            //заканчиваем просмотр
                            break;
                        }
                        //в противном случае
                        else
                        {
                            //отменяем ход и удаляем рассмотренную ветку дерева
                            CancelMove(availableMoves[i], solutionThree);
                            solutionThree.DeleteChildNode(0);
                        }

                    }
                }

            //возвращаем результат выполнения
            return complete;
        }
Example #22
0
        /// <summary>
        /// Получение ходов до целевой вершины
        /// </summary>
        /// <param name="parSolutionNode">целевая вершина</param>
        /// <returns></returns>
        private List<Move> GetMovesToGoal(SolutionThree parSolutionNode)
        {
            List<Move> movesToGoal = new List<Move>();
            SolutionThree currentSolutionNode  = parSolutionNode;

            while (currentSolutionNode.Root != null)
            {
                movesToGoal.Insert(0, currentSolutionNode.Move);
                currentSolutionNode = currentSolutionNode.Root;
            }

            return movesToGoal;
        }
Example #23
0
 /// <summary>
 /// Отмена хода
 /// </summary>
 /// <param name="parMove">Ход</param>
 /// <param name="parSolutionThree">узел дерева у которого отменяется ход</param>
 public abstract void CancelMove(Move parMove, SolutionThree parSolutionThree);