public Node[] SolveFirst(Vector2 vqinit, Vector2 vqend) { QuadTreeArea currentArea = new QuadTreeArea(Math.Min(vqinit.X, vqend.X), Math.Max(vqinit.Y, vqend.Y), Math.Max(vqinit.X, vqend.X), Math.Min(vqinit.Y, vqend.Y)); Node qend = new Node { Position = vqend}; Node qinit = new Node { Position = vqinit }; qinit.Heuristic = (vqend - vqinit).Module(); currentArea.Add(qinit); ProblemContext.onNewNode(qinit); int CurrentIteration = 0; while (CurrentIteration < ProblemContext.MaxGenerations) { Node bestNode = currentArea.GetBestNodeFromMostUndenseArea(); Node newNode = bestNode.TryExpand(qend); if (currentArea.Parent != null) currentArea = currentArea.Antecesor; if (newNode == qend) { return newNode.Predecesors.ToArray(); } CurrentIteration++; } return null; }
private QuadTreeArea GetCoveringChildArea(Node n) { return GetCoveringChildArea(n.Position); }
public bool Cover(Node newNode) { return Cover(newNode.Position); }
public void Add(Node node) { if (this.Cover(node)) { if (IsFinalNode) { if (Nodes.Count == ProblemContext.NodesPerArea && Area>=ProblemContext.MinAreaSize) { //SUBDIVISION subdivide(); Nodes.Add(node); foreach (Node n in Nodes) { QuadTreeArea selectedArea=GetCoveringChildArea(n); selectedArea.Add(n); } this.Nodes.Clear(); this.Nodes = null; } else { //NORMAL ADDITION //BASE CASE Nodes.Add(node); node.Area = this; if (this.BestNode == null || node.PathQualityEstimation < this.BestNode.PathQualityEstimation) this.BestNode = node; } } else { //RECURSIVE DOWN CASE GetCoveringChildArea(node).Add(node); } } else { if (this.Parent == null) { bool north = node.Position.Y > this.Top; bool west = node.Position.X < this.Left; bool south = node.Position.Y < this.Bottom; bool east = node.Position.X > this.Right; double width = this.Width; double height = this.Height; if (south || east) { Parent = new QuadTreeArea(this.Left, this.Top, this.Right + width, this.Bottom - height); Parent.NWest = this; } else if (north || west) { Parent = new QuadTreeArea(this.Left - width, this.Top + height, this.Right, this.Bottom); Parent.SEast = this; } else throw new NotImplementedException(); this.Name = (north ? "N" : "S") + (east ? "E" : "W"); Parent.subdivide(); } this.Parent.Add(node); } }
public Node TryExpandOld(Node qend) { bool found = false; Node n = new Node(); bool solution = true; //Vector2 displacement = qend.Position - Position + RepulsiveForce; //se junta con el conocimiento histórico //Vector2 displacement = qend.Position - this.Position; //Vector2 candidateNodePosition = qend.Position+RepulsiveForce; if (candidateDisplacement == null) candidateDisplacement = new angleIterator { q = this.Position, qend = qend.Position } .GetVectors() .GetEnumerator(); candidateDisplacement.MoveNext(); Vector2 displacement = candidateDisplacement.Current; Vector2 candidateNodePosition = displacement + Position; int fails = 0; while (!found && fails < ProblemContext.MaxAttemptsPerNodeExpansion) { //where want I go ProblemContext.onCandidate(this, displacement); Vector2? collisionPoint = ProblemContext.LocalPlanner(Position, candidateNodePosition); if (collisionPoint == null) { Node parentForNewChild = this; //try better parent if (this.Parent != null) { Node parentCandidate = this.Parent; do { collisionPoint = ProblemContext.LocalPlanner(parentCandidate.Position, candidateNodePosition); if (collisionPoint == null) { parentForNewChild = parentCandidate; parentCandidate = parentForNewChild.Parent; if (parentCandidate == null) break; } else break; } while (true); } //OK n.Position = candidateNodePosition; n.Heuristic = (candidateNodePosition - qend.Position).Module(); n.Cost = parentForNewChild.Cost + displacement.Module(); n.Parent = parentForNewChild; n.RepulsiveForce = displacement; //n.Penalty = Penalty + 1; parentForNewChild.RepulsiveForce = displacement; parentForNewChild.ChildrenCount++; parentForNewChild.Area.Add(n); ProblemContext.onNewNode(n); found = true; } else { fails++; var collisionVector = collisionPoint.Value - Position; Vector2 candidateNodeVector = ((collisionVector) * r.NextDouble()); /*#warning mejorar esta optimización haciendo uso de la distancia bresenmham //is an obstacle € (0,1) -> 0 mas directo (hemos caido casi en el objetivo), ->1 perpendicular (hemos caido en un obstáculo) double clearnessRatio = collisionVector.Module() / displacement.Module(); //collisionVector = collisionVector (* (1; //RepulsiveForce -= collisionVector; Vector2 tagentCollisionVectorA = new Vector2 { X = collisionVector.Y, Y = -collisionVector.X }; Vector2 tagentCollisionVectorB = new Vector2 { X = -collisionVector.Y, Y = collisionVector.X }; var candidateNodeVectorA = ((collisionVector * clearnessRatio + tagentCollisionVectorA * (1 - clearnessRatio)) ) / (double)fails ; var candidateNodeVectorB = ((collisionVector * clearnessRatio + tagentCollisionVectorB * (1 - clearnessRatio)) ) / (double)fails ; var candidateNodeVectorC = ((collisionVector )*0.5/ ((double)fails) ); //var candidateNodeVectorA = qend.Position-this.Position+RepulsiveForce; //var candidateNodeVectorB = ((collisionVector * clearnessRatio + tagentCollisionVectorB * (1 - clearnessRatio)) ) / (double)fails ; //var candidateNodeVectorC = ((collisionVector )/ (double)fails) ; //var candidateNodeVectorC = candidateNodeVectorA; //var candidateNodeVectorB = candidateNodeVectorA; /*double afitness= (candidateNodePositionA - candidateNodePosition).Distance(); double bfitness = (candidateNodePositionB - candidateNodePosition).Distance(); double cfitness = (candidateNodePositionC - candidateNodePosition).Distance(); */ /* var candidates = new[]{candidateNodeVectorA, candidateNodeVectorB, candidateNodeVectorC}; var candidatesInfo = candidates.Select(c => new { vector=c,fitness=(qend.Position-(c+Position)).Module()}); double bestFintess = candidatesInfo.Min(c => c.fitness); candidateNodeVector = candidatesInfo .Where(c => c.fitness == bestFintess) .First().vector; ProblemContext.onColision(this, displacement, candidatesInfo.Select(disp=>disp.vector+Position) , collisionPoint.Value); */ displacement = candidateNodeVector; candidateNodePosition = Position + displacement; ProblemContext.onColision(this, displacement, new Vector2[] { candidateNodePosition }, collisionPoint.Value); QuadTreeArea workingArea = Area.FindArea(candidateNodePosition); solution = false; if (workingArea != null && workingArea.Area < ProblemContext.MinAreaSize && workingArea.NodeCount >= ProblemContext.NodesPerArea) { this.Penalty++; workingArea.PenalityAllNodes(); } } } if (solution) { qend.Parent = n; return qend; } else return n; }
public Node TryExpand(Node qend) { bool found = false; Node n = new Node(); bool solution = false; Random r=new Random(Environment.TickCount); if (candidateDisplacement == null) { candidateDisplacementGenerator= new randomExpansionIterator { q = this.Position, qend = qend.Position, maxVectorModule = 50 }; candidateDisplacement = candidateDisplacementGenerator .GetVectors() .GetEnumerator(); } int fails = 0; candidateDisplacement.MoveNext(); while (!found && fails < ProblemContext.MaxAttemptsPerNodeExpansion) { Vector2 targetPoint; Vector2? collisionPoint; if (r.Next() % 3 == 0) targetPoint = qend.Position; else { QuadTreeArea CandidateArea; do{ targetPoint = this.Position + candidateDisplacement.Current; CandidateArea = this.Area.FindArea(targetPoint); this.candidateDisplacement.MoveNext(); } while (CandidateArea != null && CandidateArea.Density > this.Area.Density); } ProblemContext.onCandidate(this, candidateDisplacement.Current); if (!ProblemContext.checkObstacle(targetPoint.X , targetPoint.Y)) { collisionPoint= ProblemContext.LocalPlanner(Position,targetPoint ); //no collision if (collisionPoint == null) { Node parentForNewChild = this; //OK n.Position = targetPoint; n.Heuristic = 0; n.Cost = parentForNewChild.Cost + targetPoint.Module(); n.Parent = parentForNewChild; parentForNewChild.ChildrenCount++; parentForNewChild.Area.Add(n); ProblemContext.onNewNode(n); found = true; if (qend.Position.X == n.Position.X && qend.Position.Y == n.Position.Y) solution = true; } } if (!found) { fails++; //candidateDisplacementGenerator.maxVectorModule /= 2.0; } } if (solution) { qend.Parent = n; return qend; } else return n; }