/// <summary>
        /// Search for an optimal solution using the Simple Independence Detection algorithm in Trevor Standley's paper.
        /// </summary>
        /// <param name="runner"></param>
        /// <returns></returns>
        public bool SimpleID(Run runner)
        {
            while (true)
            {
                Conflict conflict = FindConflictingGroups();
                // If there are no conflicts - can finish the run
                if (conflict == null)
                {
                    break;
                }
                allGroups.Remove(conflict.group1);
                allGroups.Remove(conflict.group2);
                AgentsGroup compositeGroup = this.JoinGroups(conflict);

                // Solve composite group with A*
                bool solved = compositeGroup.Solve(runner);
                if (solved == false)
                {
                    this.totalCost = compositeGroup.solutionCost;
                    return(false);
                }

                allGroups.AddFirst(compositeGroup);
            }
            return(true);
        }
        /// <summary>
        /// Joins this and another group to a single group with all of the agents together.
        /// </summary>
        /// <param name="other"></param>
        /// <returns>A new Trevor_Group object with the agents from both this and the other group</returns>
        public AgentsGroup Join(AgentsGroup other)
        {
            AgentState[] joinedAgentStates = new AgentState[allAgentsState.Length + other.allAgentsState.Length];
            this.allAgentsState.CopyTo(joinedAgentStates, 0);
            other.allAgentsState.CopyTo(joinedAgentStates, this.allAgentsState.Length);
            Array.Sort <AgentState>(joinedAgentStates, (x, y) => x.agent.agentNum.CompareTo(y.agent.agentNum));

            return(new AgentsGroup(this.instance, joinedAgentStates, this.singleAgentSolver, this.groupSolver));
        }
Example #3
0
        /// <summary>
        /// Run the A* algorithm with Standley's ID and OD improvements.
        /// </summary>
        /// <returns>true if optimal solution has been found</returns>
        public bool Solve()
        {
            // Solve the single agent problems independently
            LinkedListNode <AgentsGroup> agentGroupNode = this.allGroups.First;

            maxDepth = 0;

            while (agentGroupNode != null)
            {
                AgentsGroup group = agentGroupNode.Value;
                group.instance.parameters[CONFLICT_AVOIDANCE] = conflictAvoidance;
                group.Solve(runner);
                if (group.solutionCost > maxDepth)
                {
                    maxDepth = group.solutionCost;
                }
                // Add group to conflict avoidance table
                group.addGroupToCA(conflictAvoidance, maxDepth);

                this.expanded  += group.expanded;
                this.generated += group.generated;

                agentGroupNode = agentGroupNode.Next;
            }

            //bool solved = this.SimpleIndependenceDetection(runner);
            bool solved = this.IndependenceDetection(runner);

            // Record found solution
            if (solved == true)
            {
                // Store solution details
                this.totalCost = 0;
                foreach (AgentsGroup group in this.allGroups)
                {
                    this.totalCost += group.solutionCost;
                }

                this.foundPlan = this.CalculateJointPlan();
            }
            else
            {
                this.foundPlan = null;
            }
            Console.WriteLine();
            Console.WriteLine(this.allGroups.Count + " - Independent Groups");
            Console.WriteLine(this.maxGroup + " - Size Of Largest ID Group");
            Console.WriteLine();
            return(solved);
        }
Example #4
0
        /// <summary>
        /// Joins this and another group to a single group with all of the agents together.
        /// </summary>
        /// <param name="other"></param>
        /// <returns>A new Trevor_Group object with the agents from both this and the other group</returns>
        public AgentsGroup Join(AgentsGroup other)
        {
            AgentState[] joinedAgentStates = new AgentState[allAgentsState.Length + other.allAgentsState.Length];
            int          i;

            for (i = 0; i < allAgentsState.Length; i++)
            {
                joinedAgentStates[i] = allAgentsState[i];
            }
            for (int j = 0; j < other.allAgentsState.Length; j++)
            {
                joinedAgentStates[i + j] = other.allAgentsState[j];
            }

            return(new AgentsGroup(this.instance, joinedAgentStates, this.solver));
        }
        public override bool Equals(object obj) // TODO: Implement GetHashCode()
        {
            AgentsGroup other = (AgentsGroup)obj;

            return(allAgentsState.SequenceEqual <AgentState>(other.allAgentsState));
        }
        /// <summary>
        /// Search for an optimal solution using the Independence Detection algorithm in Standley's paper,
        /// which utilises a CAT.
        /// </summary>
        /// <param name="runner"></param>
        /// <returns></returns>
        public bool ImprovedID(Run runner)
        {
            while (true)
            {
                Conflict conflict = FindConflictingGroups();
                // If there are no conflicts - can finish the run
                if (conflict == null)
                {
                    break;
                }

                // Try to solve the current conflict by replanning one of the groups
                if (this.allConflicts.Contains(conflict) == false)
                {
                    // Add to all conflicts to prevent trying to replan this conflict again
                    this.allConflicts.Add(conflict);

                    // Add plan of group2 to illegal moves table and replan group1 with equal cost
                    if ((conflict.timeOfConflict < conflict.group1.GetPlan().GetSize() - 1) ||
                        (conflict.group1.allAgentsState.Length > 1)) // Otherwise the conflict is while a single agent is at its goal, no chance of an alternate path with the same cost that avoids the conflict
                    {
                        conflict.group1.removeGroupFromCAT(conflictAvoidance);
                        bool resolved = conflict.group1.ReplanUnderConstraints(conflict.group2.GetPlan(), runner);
                        conflict.group1.addGroupToCAT(conflictAvoidance, maxSolutionCostFound);
                        if (resolved == true)
                        {
                            continue;
                        }
                    }
                    // Add plan of group1 to illegal moves table and replan group2 with equal cost
                    if ((conflict.timeOfConflict < conflict.group2.GetPlan().GetSize() - 1) ||
                        (conflict.group2.allAgentsState.Length > 1))
                    {
                        conflict.group2.removeGroupFromCAT(conflictAvoidance);
                        bool resolved = conflict.group2.ReplanUnderConstraints(conflict.group1.GetPlan(), runner);
                        conflict.group2.addGroupToCAT(conflictAvoidance, maxSolutionCostFound);
                        if (resolved == true)
                        {
                            continue;
                        }
                    }
                }

                // Groups are conflicting - need to join them to a single group
                allGroups.Remove(conflict.group1);
                allGroups.Remove(conflict.group2);
                // Remove both groups from avoidance table
                conflict.group1.removeGroupFromCAT(conflictAvoidance);
                conflict.group2.removeGroupFromCAT(conflictAvoidance);
                if (this.debug)
                {
                    Debug.WriteLine("Merging " + conflict);
                }
                AgentsGroup compositeGroup = this.JoinGroups(conflict);

                compositeGroup.instance.parameters[CONFLICT_AVOIDANCE] = conflictAvoidance;

                // Solve composite group with A*
                bool solved = compositeGroup.Solve(runner);

                if (compositeGroup.solutionCost > maxSolutionCostFound)
                {
                    maxSolutionCostFound = compositeGroup.solutionCost;
                }

                //add group to conflict avoidance table
                compositeGroup.addGroupToCAT(conflictAvoidance, maxSolutionCostFound);
                allGroups.AddFirst(compositeGroup);

                this.expanded  += compositeGroup.expanded;
                this.generated += compositeGroup.generated;

                if (compositeGroup.allAgentsState.Length > this.maxGroupSize)
                {
                    this.maxGroupSize = compositeGroup.allAgentsState.Length;
                }

                if (solved == false)
                {
                    this.totalCost = compositeGroup.solutionCost; // Should be some error code from Constants
                    return(false);
                }
            }
            return(true);
        }