Beispiel #1
0
 public List <Operator> Search(Problem p)
 {
     // AL CONSTRUCTOR LE METÍAN UN 5 A CAPÓN COMO PRIMER PARÁMETRO (INITIALCAPACITY)... ESO CREO QUE YA NO HACE FALTA, QUE ESTA LISTA DE PREORIDAD SE REDIMENSIONA SOLA
     return(search.Search(p, new PriorityQueueWrapper()));    // He puesto Node, Node... tanto en los Item como en la prioridad...
     // NO LE METO COMPARER NI NADA PORQUE LA IDEA NO VA A SER AQUÍ COPARAR NODOS SINO QUE INTERNAMENTE SE COMPAREN FLOATS, SOLAMENTE
 }
Beispiel #2
0
 // Dado el nodo a expandir (y considerando el problema), devuelve los nodos hijos que hace falta añadir a la frontera
 public abstract List <Node> GetResultingNodesToAddToFrontier(Node node, Problem problem);
Beispiel #3
0
        // Busca la solución a un problema, usando una cola como frontera (FIFO, LIFO, de prioridad...), y devuelve la lista de operadores para llegar desde la configuración actual a una configuración objetivo
        // Si se ha encontrado un objetivo, se devuelve únicamente la lista de operadores
        // Si la propia configuración inicial ya es un objetivo, devuelve una lista con un sólo operador: NoOp
        // Si la búsqueda no logra encontrar un objetivo, se devuelve una lista vacía para representar el fallo
        public virtual List <Operator> Search(Problem problem, IQueue <Node> frontier)
        {
            ClearMetrics();

            // Se inicializa la frontera con la configuración inicial del problema
            Node root = new Node(problem.InitialSetup);

            // Si debemos hacer la prueba de objetivo antes de meterlo en la frontera, la hacemos...
            if (TestGoalBeforeAddToFrontier)
            {
                // ... y si resulta que es un objetivo, devolvemos ya la solución
                if (SearchUtils.IsGoal(problem, root))
                {
                    SetPathCost(root.PathCost);

                    return(SearchUtils.GetOperatorsFromNodes(root.GetPathFromRoot()));
                }
            }
            this.frontier = frontier;
            this.frontier.Enqueue(root);

            SetQueueSizes(frontier.Count);

            // Mientras que queden nodos en la frontera, expandirlos y buscar en sus hijos
            while (!(frontier.Count == 0))
            {
                // Sacar un nodo de la frontera (el que corresponda según el tipo de cola que sea la frontera)
                Node node = PopNodeFromFrontier();
                UnityEngine.Debug.Log("Expanding " + node.ToString());

                SetQueueSizes(frontier.Count);

                // Si no hicimos la prueba de objetivo antes de meterlo en la frontera, toca hacerla ahora...
                if (!TestGoalBeforeAddToFrontier)
                {
                    // ... y si resulta que es un objetivo, devolvemos ya la solución
                    if (SearchUtils.IsGoal(problem, node))
                    {
                        SetPathCost(node.PathCost);

                        return(SearchUtils.GetOperatorsFromNodes(node.GetPathFromRoot()));
                    }
                }

                // Expandimos el nodo, añadiendo sus hijos a la frontera
                foreach (Node child in GetResultingNodesToAddToFrontier(node, problem))
                {
                    // Si debemos hacer la prueba de objetivo antes de meterlo en la frontera, la hacemos...
                    if (TestGoalBeforeAddToFrontier)
                    {
                        // ... y si resulta que es un objetivo, devolvemos ya la solución
                        if (SearchUtils.IsGoal(problem, child))
                        {
                            SetPathCost(child.PathCost);

                            return(SearchUtils.GetOperatorsFromNodes(child.GetPathFromRoot()));
                        }
                    }

                    frontier.Enqueue(child);
                    UnityEngine.Debug.Log("Adding " + child.ToString() + " to the frontier");
                }

                SetQueueSizes(frontier.Count);
            }

            // Si la frontera ha quedado vacía y no hemos dado con ninguna solución, devolvemos fallo (representado por una lista vacía de operadores)
            return(new List <Operator>());
        }
Beispiel #4
0
        /* Ahora mismo no tiene sentido hacer un borrado de un nodo que no sea el primeroque ofrece la cola
         * public override bool RemoveNodeFromFrontier(Node toRemove)
         * {
         *  bool removed = base.RemoveNodeFromFrontier(toRemove);
         *  if (removed)
         *  {
         *      frontierSetup.Remove(toRemove.GetSetup());
         *  }
         *  return removed;
         * } */

        public override List <Node> GetResultingNodesToAddToFrontier(Node nodeToExpand, Problem problem)
        {
            addToFrontier.Clear();
            // add the node to the explored set
            explored.Add(nodeToExpand.GetSetup());
            // expand the chosen node, adding the resulting nodes to the frontier
            foreach (Node cfn in ExpandNode(nodeToExpand, problem))
            {
                Node frontierNode;
                frontierSetup.TryGetValue(cfn.GetSetup(), out frontierNode); // El funcionamiento de este Diccionario parece estar fallando (antes es que tenía notación de array y seguramente no era válido)
                bool yesAddToFrontier = false;
                // only if not in the frontier or explored set
                if (null == frontierNode && !explored.Contains(cfn.GetSetup()))
                {
                    yesAddToFrontier = true;
                }
                else if (null != frontierNode &&
                         null != replaceFrontierNodeAtSetupCostFunction &&
                         replaceFrontierNodeAtSetupCostFunction.Compare(cfn, frontierNode) < 0)
                {
                    // child.SETUP is in frontier with higher cost
                    // replace that frontier node with child
                    yesAddToFrontier = true;
                    // Want to replace the current frontier node with the child
                    // node therefore mark the child to be added and remove the
                    // current fontierNode

                    /**************************************************************
                     * POR AHORA HE ELIMINADO ESTA PARTE, HAY COMENTARIOS DE QUE USANDO COLAS DE PRIORIDAD NO SE NECESITA ESTO
                     * ADEMÁS TÉCNICAMENTE NO SE PUEDE ELIMINAR UN NODO DE FORMA TAN DIRECTAN DE UNA COLA...
                     *
                     * RemoveNodeFromFrontier(frontierNode);
                     **********************************************/


                    // Ensure removed from add to frontier as well
                    // as 1 or more may reach the same setup at the same time
                    addToFrontier.Remove(frontierNode);
                }

                if (yesAddToFrontier)
                {
                    addToFrontier.Add(cfn);
                    frontierSetup.Add(cfn.GetSetup(), cfn);
                }
            }

            return(addToFrontier);
        }