void AddPair(EdgePair edge) { PairsByCandidate[edge.Neighbor.Candidate] = PairsByProbe[edge.Neighbor.Probe] = PairList[PairCount]; PairList[PairCount].Pair = edge.Neighbor; PairList[PairCount].Reference = edge.Reference; ++PairCount; }
public static Edge MakeEdge(Edge eNext) { EdgePair edgePair = EdgePair.Create(); Edge e = edgePair._e; Edge eSym = edgePair._eSym; Edge.EnsureFirst(ref eNext); (eSym._next = eNext._Sym._next)._Sym._next = e; e._next = eNext; eNext._Sym._next = eSym; e._Sym = eSym; Edge edge = e; edge._Onext = edge; e._Lnext = eSym; e._Org = null; e._Lface = null; e._winding = 0; e._activeRegion = null; eSym._Sym = e; Edge edge2 = eSym; edge2._Onext = edge2; eSym._Lnext = e; eSym._Org = null; eSym._Lface = null; eSym._winding = 0; eSym._activeRegion = null; return(e); }
public void SplitInHalf(Edge e1, Edge e2) // edges that form split with next { var newFace = new Face(); var pairForThis = new EdgePair(this, null); var pairForNewFace = new EdgePair(newFace, null); var eThis = pairForThis.Edge1; var eNew = pairForNewFace.Edge1; var e1Next = e1.Next; var e2Next = e2.Next; e1.InsertAfterAndBreak(eThis); e2Next.InsertBeforeAndBreak(eThis); e1Next.InsertBeforeAndBreak(eNew); e2.InsertAfterAndBreak(eNew); eThis.Start = e1.End; eThis.End = e2Next.Start; eNew.Start = e2.End; eNew.End = e1Next.Start; var newFacePointCount = InitOwnerFaceAndCountPoints(eNew, newFace); var thisPointCount = m_NumPoints - newFacePointCount + 2; newFace.Init(eNew, newFacePointCount, Normal); Init(eThis, thisPointCount, Normal); newFace.OnNewOwner(m_Owner); }
public override void Reset() { _pair = null; _next = _Sym = _Onext = _Lnext = null; _Org = null; _Lface = null; _activeRegion = null; _winding = 0; }
public static EdgePair Create() { var pair = new EdgePair(); pair._e = new Edge(); pair._e._pair = pair; pair._eSym = new Edge(); pair._eSym._pair = pair; return(pair); }
public static EdgePair Create() { EdgePair edgePair = default(EdgePair); edgePair._e = Pooled <Edge> .Create(); edgePair._e._pair = edgePair; edgePair._eSym = Pooled <Edge> .Create(); edgePair._eSym._pair = edgePair; return(edgePair); }
void SkipPaired() { while (PairQueue.Count > 0 && (PairsByProbe[PairQueue.Peek().Neighbor.Probe] != null || PairsByCandidate[PairQueue.Peek().Neighbor.Candidate] != null)) { EdgePair edge = PairQueue.Dequeue(); if (PairsByProbe[edge.Neighbor.Probe] != null && PairsByProbe[edge.Neighbor.Probe].Pair.Candidate == edge.Neighbor.Candidate) { ++PairsByProbe[edge.Reference.Probe].SupportingEdges; ++PairsByProbe[edge.Neighbor.Probe].SupportingEdges; } } }
void setStringVerticesInEdgePairOrder() { for (int i = 0; i < edgePairs.Count; i++) { EdgePair currentEdgePair = edgePairs[i]; int numVertsPerEdgePair = currentEdgePair.verticese1e2.Length; int positionInFullArray = i * numVertsPerEdgePair; for (int j = positionInFullArray; j < numVertsPerEdgePair + positionInFullArray; j++) { stringVertices[j] = currentEdgePair.verticese1e2[j - positionInFullArray]; } // } }
public List <EdgePair> GetAllEdges() { List <EdgePair> edges = new List <EdgePair>(); for (int i = 0; i < V; i++) { foreach (Pair p in al[i]) { EdgePair np = new EdgePair(i, p.nbr, p.wt); edges.Add(np); } } return(edges); }
void createEdgePairs(float fractionOfVerts) { edgePairs = new List <EdgePair>(); List <int> donePairs = new List <int>(); for (int i = 0; i < frameEdges.Count; i++) { Edge e = frameEdges[i]; if (!alreadyDoneThePair(e, donePairs)) { Edge otherE = frameEdges[e.pairedEdge]; EdgePair ep = new EdgePair(e, otherE, fractionOfVerts); //we want half say edgePairs.Add(ep); } } }
/// <summary> /// Draws the nodes and lines between nodes onto the game board. Nodes are a prefab from Resources. /// </summary> public void CreateGridVisuals() { GameObject parent; HashSet <EdgePair> renderedEdges = new HashSet <EdgePair>(); if ((parent = GameObject.Find("Nodes")) == null) { parent = GameObject.Instantiate(new GameObject()); parent.name = "Nodes"; } for (int x = 0; x < ROW_OF_NODES; x++) { for (int y = 0; y < COLUMN_OF_NODES; y++) { Node n = getNodeAt(x, y); if (!n.island) { GameObject node = GameObject.Instantiate(Resources.Load <GameObject>("Prefabs/Node")); node.name = (x + "," + y); node.transform.parent = parent.transform; node.transform.position = n.getRealPos(); node.GetComponent <SpriteRenderer>().color = gridColor; n.setGameObject(node); Node[] adjacents = n.Adjacents; for (int i = 0; i < adjacents.Length; i++) { EdgePair ep; if (adjacents[i] != null && !renderedEdges.Contains(ep = new EdgePair(adjacents[i].getBoardPosition(), n.getBoardPosition()))) { renderedEdges.Add(ep); LineRenderer lr = GameObject.Instantiate(Resources.Load <GameObject>("Prefabs/NodeLine")).GetComponent <LineRenderer>(); Vector3 adjPos = new Vector3(adjacents[i].Y, Board.ROW_OF_NODES - 1 - adjacents[i].X, 0); Vector3 pos = new Vector3(n.Y, Board.ROW_OF_NODES - 1 - n.X, 0); lr.SetPosition(0, adjPos); lr.SetPosition(1, pos); lr.transform.SetParent(node.transform); lr.startWidth = 0.03f; lr.endWidth = 0.03f; lr.startColor = gridColor; lr.endColor = gridColor; } } } } } }
private Dictionary <EdgePair, List <Bid> > makeBidMap(List <Bid> B) { Dictionary <EdgePair, List <Bid> > bidMap = new Dictionary <EdgePair, List <Bid> >(); foreach (Bid b in B) { EdgePair xij = b.Edge; if (this.G.EdgePairs.Contains(xij)) { if (!bidMap.ContainsKey(xij)) { bidMap.Add(xij, new List <Bid>()); } bidMap[xij].Add(b); } } return(bidMap); }
public void DetachEdge(Edge e) { var pairForThis = new EdgePair(this, null); var eThis = pairForThis.Edge1; var ePrev = e.Prev; var eNext = e.Next; ePrev.InsertAfterAndBreak(eThis); eNext.InsertBeforeAndBreak(eThis); eThis.Start = ePrev.End; eThis.End = eNext.Start; eThis.OwnerFace = this; e.Clear(); }
private void ConstructFace(EdgePair P0P1pair, EdgePair P2P3Pair, ShapePoint P0, ShapePoint P1, ShapePoint P2, ShapePoint P3, Vector3 n, bool setEdge1) { var face = new Face(); var P1P2Pair = new EdgePair(null, null); var P3P0Pair = new EdgePair(null, null); // setup the linked lists RequiredEdge(P0P1pair, setEdge1).InsertAfter(RequiredEdge(P1P2Pair, setEdge1)); RequiredEdge(P1P2Pair, setEdge1).InsertAfter(RequiredEdge(P2P3Pair, setEdge1)); RequiredEdge(P2P3Pair, setEdge1).InsertAfter(RequiredEdge(P3P0Pair, setEdge1)); RequiredEdge(P3P0Pair, setEdge1).InsertAfter(RequiredEdge(P0P1pair, setEdge1)); // set the start and end points RequiredEdge(P0P1pair, setEdge1).Start = P0; RequiredEdge(P0P1pair, setEdge1).End = P1; RequiredEdge(P1P2Pair, setEdge1).Start = P1; RequiredEdge(P1P2Pair, setEdge1).End = P2; RequiredEdge(P2P3Pair, setEdge1).Start = P2; RequiredEdge(P2P3Pair, setEdge1).End = P3; RequiredEdge(P3P0Pair, setEdge1).Start = P3; RequiredEdge(P3P0Pair, setEdge1).End = P0; // set the face RequiredEdge(P0P1pair, setEdge1).OwnerFace = face; RequiredEdge(P1P2Pair, setEdge1).OwnerFace = face; RequiredEdge(P2P3Pair, setEdge1).OwnerFace = face; RequiredEdge(P3P0Pair, setEdge1).OwnerFace = face; // init the face face.Init(RequiredEdge(P0P1pair, setEdge1), 4, n); face.OnNewOwner(m_Shape); // set stuff on the shape P1P2Pair.OnNewOwner(m_Shape); P3P0Pair.OnNewOwner(m_Shape); }
// HandleHelper Methods //////////////////////////////////////////////////// public override void UpdateCropWindow(float x, float y, float targetAspectRatio, Rect imageRect, float snapRadius) { EdgePair activeEdges = GetActiveEdges(x, y, targetAspectRatio); Edge primaryEdge = activeEdges.primary; Edge secondaryEdge = activeEdges.secondary; primaryEdge.adjustCoordinate(x, y, imageRect, snapRadius, targetAspectRatio); secondaryEdge.adjustCoordinate(targetAspectRatio); if (secondaryEdge.isOutsideMargin(imageRect, snapRadius)) { secondaryEdge.snapToRect(imageRect); primaryEdge.adjustCoordinate(targetAspectRatio); } }
public static Edge FormSplitOnEdge(Edge e, Vector3 splitPoint) { var newPair = new EdgePair(e.OwnerFace, e.Other.OwnerFace); var newEdge = newPair.Edge1; newEdge.Start = new ShapePoint(splitPoint); newEdge.End = e.End; e.End = new ShapePoint(splitPoint); e.InsertAfter(newEdge); e.Other.InsertBefore(newEdge.Other); var next = newEdge.Other; next.OwnerFace.OnEdgeSplit(); e.OwnerFace.OnEdgeSplit(); return(next); }
// Package-Private Methods ///////////////////////////////////////////////// /** * Updates the crop window by directly setting the Edge coordinates. * * @param x the new x-coordinate of this handle * @param y the new y-coordinate of this handle * @param imageRect the bounding rectangle of the image * @param parentView the parent View containing the image * @param snapRadius the maximum distance (in pixels) at which the crop * window should snap to the image */ public virtual void UpdateCropWindow(float x, float y, Rect imageRect, float snapRadius) { EdgePair activeEdges = GetActiveEdges(); Edge primaryEdge = activeEdges.primary; Edge secondaryEdge = activeEdges.secondary; if (primaryEdge != null) { primaryEdge.adjustCoordinate(x, y, imageRect, snapRadius, UNFIXED_ASPECT_RATIO_CONSTANT); } if (secondaryEdge != null) { secondaryEdge.adjustCoordinate(x, y, imageRect, snapRadius, UNFIXED_ASPECT_RATIO_CONSTANT); } }
/* MakeEdge creates a new pair of half-edges which form their own loop. * No vertex or face structures are allocated, but these must be assigned * before the current edge operation is completed. */ static HalfEdge MakeEdge(HalfEdge eNext) { HalfEdge ePrev; EdgePair pair = new EdgePair(); /* Make sure eNext points to the first edge of the edge pair */ if (eNext.otherHalfOfThisEdge.isFirstHalfEdge) { eNext = eNext.otherHalfOfThisEdge; } /* Insert in circular doubly-linked list before eNext. * Note that the prev pointer is stored in Sym.next. */ ePrev = eNext.otherHalfOfThisEdge.nextHalfEdge; pair.eSym.nextHalfEdge = ePrev; ePrev.otherHalfOfThisEdge.nextHalfEdge = pair.e; pair.e.nextHalfEdge = eNext; eNext.otherHalfOfThisEdge.nextHalfEdge = pair.eSym; pair.e.isFirstHalfEdge = true; pair.e.otherHalfOfThisEdge = pair.eSym; pair.e.nextEdgeCCWAroundOrigin = pair.e; pair.e.nextEdgeCCWAroundLeftFace = pair.eSym; pair.e.originVertex = null; pair.e.leftFace = null; pair.e.winding = 0; pair.e.regionThisIsUpperEdgeOf = null; pair.eSym.isFirstHalfEdge = false; pair.eSym.otherHalfOfThisEdge = pair.e; pair.eSym.nextEdgeCCWAroundOrigin = pair.eSym; pair.eSym.nextEdgeCCWAroundLeftFace = pair.e; pair.eSym.originVertex = null; pair.eSym.leftFace = null; pair.eSym.winding = 0; pair.eSym.regionThisIsUpperEdgeOf = null; return(pair.e); }
/// <summary> /// MakeEdge creates a new pair of half-edges which form their own loop. /// No vertex or face structures are allocated, but these must be assigned /// before the current edge operation is completed. /// </summary> public static Edge MakeEdge(Edge eNext) { Debug.Assert(eNext != null); var pair = EdgePair.Create(); var e = pair._e; var eSym = pair._eSym; // Make sure eNext points to the first edge of the edge pair Edge.EnsureFirst(ref eNext); // Insert in circular doubly-linked list before eNext. // Note that the prev pointer is stored in Sym->next. var ePrev = eNext._Sym._next; eSym._next = ePrev; ePrev._Sym._next = e; e._next = eNext; eNext._Sym._next = eSym; e._Sym = eSym; e._Onext = e; e._Lnext = eSym; e._Org = null; e._Lface = null; e._winding = 0; e._activeRegion = null; eSym._Sym = e; eSym._Onext = eSym; eSym._Lnext = e; eSym._Org = null; eSym._Lface = null; eSym._winding = 0; eSym._activeRegion = null; return(e); }
void setIndicesInEdgePairOrder() { int numVertsPerEdgePair = edgePairs[0].verticese1e2.Length; //Debug.Log("numVertsPerEdgePair" + numVertsPerEdgePair); int numIndicesPerEdgePair = edgePairs[0].indicesConnectingVertices.Length; //Debug.Log("numIndicesPerEdgePair" + numIndicesPerEdgePair); stringIndices = new int[numIndicesPerEdgePair * edgePairs.Count]; for (int i = 0; i < edgePairs.Count; i++) { EdgePair currentEdgePair = edgePairs[i]; //int numIndicesPerEdgePair = currentEdgePair.indicesConnectingVertices.Length; int positionInFullArray = i * numIndicesPerEdgePair; for (int j = 0; j < numIndicesPerEdgePair; j++) { stringIndices[j + positionInFullArray] = currentEdgePair.indicesConnectingVertices[j] + numVertsPerEdgePair * i; //Debug.Log("positionInFullArray=" + positionInFullArray + "+ current edge pair indices count= " + j + ": gives big index " + stringIndices[j + positionInFullArray]); } } }
/// <summary> /// Applies inter-improvements by exchanging parts of the route(s). /// </summary> /// <param name="problem"></param> /// <param name="solution"></param> /// <param name="route1_idx"></param> /// <param name="route2_idx"></param> /// <param name="max"></param> /// <returns></returns> public bool Improve(MaxTimeProblem problem, MaxTimeSolution solution, int route1_idx, int route2_idx, double max) { int max_window = 50; IRoute route1 = solution.Route(route1_idx); IRoute route2 = solution.Route(route2_idx); int route1_customers = route1.Count; int route2_customers = route2.Count; double[] route1_cumul = problem.TimeCumul(route1); double[] route2_cumul = problem.TimeCumul(route2); // build all edge weights. List<Edge> route1_edges = new List<Edge>(route1.Edges()); List<Edge> route2_edges = new List<Edge>(route2.Edges()); double[] route1_weights = new double[route1_edges.Count]; for (int idx = 0; idx < route1_edges.Count; idx++) { Edge edge = route1_edges[idx]; route1_weights[idx] = problem.WeightMatrix[edge.From][edge.To]; } double[] route2_weights = new double[route2_edges.Count]; for (int idx = 0; idx < route2_edges.Count; idx++) { Edge edge = route2_edges[idx]; route2_weights[idx] = problem.WeightMatrix[edge.From][edge.To]; } List<EdgePair> route2_pairs = new List<EdgePair>(); for (int i_idx = 0; i_idx < route2_edges.Count - 2; i_idx++) { Edge i = route2_edges[i_idx]; double i_weight = route2_weights[i_idx]; double weight_before_i = route2_cumul[i_idx]; int k_idx_max = route2_edges.Count; if (k_idx_max > i_idx + 2 + max_window) { k_idx_max = i_idx + 2 + max_window; } for (int k_idx = i_idx + 2; k_idx < k_idx_max; k_idx++) { Edge k = route2_edges[k_idx]; double k_weight = route2_weights[k_idx]; double weight_after_k = route2_cumul[route2_cumul.Length - 1] - route2_cumul[k_idx + 1]; double weight_between_route = route2_cumul[k_idx] - route2_cumul[i_idx + 1]; route2_pairs.Add(new EdgePair() { First = i, FirstWeight = i_weight, Second = k, SecondWeight = k_weight, Between = new List<int>(route2.Between(i.To, k.From)), WeightTotal = i_weight + k_weight, WeightAfter = weight_after_k, WeightBefore = weight_before_i, WeightBetween = weight_between_route, CustomersBetween = k_idx - i_idx }); } } // build all edge pairs. for (int i_idx = 0; i_idx < route1_edges.Count - 2; i_idx++) { Edge i = route1_edges[i_idx]; double i_weight = route1_weights[i_idx]; double weight_before_i = route1_cumul[i_idx]; int k_idx_max = route1_edges.Count; if (k_idx_max > i_idx + 2 + max_window) { k_idx_max = i_idx + 2 + max_window; } for (int k_idx = i_idx + 2; k_idx < k_idx_max; k_idx++) { Edge k = route1_edges[k_idx]; double k_weight = route1_weights[k_idx]; double weight_after_k = route1_cumul[route1_cumul.Length - 1] - route1_cumul[k_idx + 1]; double weight_between_route = route1_cumul[k_idx] - route1_cumul[i_idx + 1]; EdgePair pair1 = new EdgePair() { First = i, FirstWeight = i_weight, Second = k, SecondWeight = k_weight, Between = new List<int>(route1.Between(i.To, k.From)), WeightTotal = i_weight + k_weight, WeightAfter = weight_after_k, WeightBefore = weight_before_i, WeightBetween = weight_between_route, CustomersBetween = k_idx - i_idx }; foreach (EdgePair pair2 in route2_pairs) { double existing_weight = pair1.WeightTotal + pair2.WeightTotal; //double new_weight = 0; // get first route new. double new_weight = problem.WeightMatrix[pair1.First.From][pair2.First.To]; //new_weight = first_route1_new; if (new_weight > existing_weight - 0.001) { continue; } double first_route2_new = problem.WeightMatrix[pair2.First.From][pair1.First.To]; new_weight = new_weight + first_route2_new; if (new_weight > existing_weight - 0.001) { continue; } double second_route1_new = problem.WeightMatrix[pair1.Second.From][pair2.Second.To]; new_weight = new_weight + second_route1_new; if (new_weight > existing_weight - 0.001) { continue; } double second_route2_new = problem.WeightMatrix[pair2.Second.From][pair1.Second.To]; new_weight = new_weight + second_route2_new; if (new_weight < existing_weight - 0.001) { // there is a decrease in total weight; check bounds. double route1_weight = pair1.WeightBefore + pair2.WeightBetween + pair1.WeightAfter; double route2_weight = pair2.WeightBefore + pair1.WeightBetween + pair2.WeightAfter; // calculate the maximum. int route1_customers_between = pair1.CustomersBetween; int route2_customers_between = pair1.CustomersBetween; route1_weight = problem.Time(route1_weight, route1_customers - route1_customers_between + route2_customers_between); route2_weight = problem.Time(route2_weight, route2_customers - route2_customers_between + route1_customers_between); if (route1_weight < max && route2_weight < max) { // MaxTimeSolution solution_copy = solution.Clone() as MaxTimeSolution; List<int> route1_between = pair1.Between; List<int> route2_between = pair2.Between; route1.ReplaceEdgeFrom(pair1.First.From, pair1.Second.To); route2.ReplaceEdgeFrom(pair2.First.From, pair2.Second.To); int previous = pair1.First.From; for (int idx = 0; idx < route2_between.Count; idx++) { route1.ReplaceEdgeFrom(previous, route2_between[idx]); previous = route2_between[idx]; } route1.ReplaceEdgeFrom(previous, pair1.Second.To); previous = pair2.First.From; for (int idx = 0; idx < route1_between.Count; idx++) { route2.ReplaceEdgeFrom(previous, route1_between[idx]); previous = route1_between[idx]; } route2.ReplaceEdgeFrom(previous, pair2.Second.To); if (!solution.IsValid()) { throw new Exception(); } return true; } } } } } return false; }
/// <summary> /// Applies inter-improvements by exchanging parts of the route(s). /// </summary> /// <param name="problem"></param> /// <param name="solution"></param> /// <param name="route1_idx"></param> /// <param name="route2_idx"></param> /// <param name="max"></param> /// <returns></returns> public bool Improve(MaxTimeProblem problem, MaxTimeSolution solution, int route1_idx, int route2_idx, double max) { int max_window = 40; IRoute route1 = solution.Route(route1_idx); IRoute route2 = solution.Route(route2_idx); int route1_customers = route1.Count; int route2_customers = route2.Count; double[] route1_cumul = problem.TimeCumul(route1); double[] route2_cumul = problem.TimeCumul(route2); // build all edge weights. List <Edge> route1_edges = new List <Edge>(route1.Edges()); List <Edge> route2_edges = new List <Edge>(route2.Edges()); double[] route1_weights = new double[route1_edges.Count]; for (int idx = 0; idx < route1_edges.Count; idx++) { Edge edge = route1_edges[idx]; route1_weights[idx] = problem.WeightMatrix[edge.From][edge.To]; } double[] route2_weights = new double[route2_edges.Count]; for (int idx = 0; idx < route2_edges.Count; idx++) { Edge edge = route2_edges[idx]; route2_weights[idx] = problem.WeightMatrix[edge.From][edge.To]; } List <EdgePair> route2_pairs = new List <EdgePair>(); for (int i_idx = 0; i_idx < route2_edges.Count - 2; i_idx++) { Edge i = route2_edges[i_idx]; double i_weight = route2_weights[i_idx]; double weight_before_i = route2_cumul[i_idx]; int k_idx_max = route2_edges.Count; if (k_idx_max > i_idx + 2 + max_window) { k_idx_max = i_idx + 2 + max_window; } for (int k_idx = i_idx + 2; k_idx < k_idx_max; k_idx++) { Edge k = route2_edges[k_idx]; double k_weight = route2_weights[k_idx]; double weight_after_k = route2_cumul[route2_cumul.Length - 1] - route2_cumul[k_idx + 1]; double weight_between_route = route2_cumul[k_idx] - route2_cumul[i_idx + 1]; route2_pairs.Add(new EdgePair() { First = i, FirstWeight = i_weight, Second = k, SecondWeight = k_weight, Between = new List <int>(route2.Between(i.To, k.From)), WeightTotal = i_weight + k_weight, WeightAfter = weight_after_k, WeightBefore = weight_before_i, WeightBetween = weight_between_route, CustomersBetween = k_idx - i_idx }); } } // build all edge pairs. for (int i_idx = 0; i_idx < route1_edges.Count - 2; i_idx++) { Edge i = route1_edges[i_idx]; double i_weight = route1_weights[i_idx]; double weight_before_i = route1_cumul[i_idx]; int k_idx_max = route1_edges.Count; if (k_idx_max > i_idx + 2 + max_window) { k_idx_max = i_idx + 2 + max_window; } for (int k_idx = i_idx + 2; k_idx < k_idx_max; k_idx++) { Edge k = route1_edges[k_idx]; double k_weight = route1_weights[k_idx]; double weight_after_k = route1_cumul[route1_cumul.Length - 1] - route1_cumul[k_idx + 1]; double weight_between_route = route1_cumul[k_idx] - route1_cumul[i_idx + 1]; EdgePair pair1 = new EdgePair() { First = i, FirstWeight = i_weight, Second = k, SecondWeight = k_weight, Between = new List <int>(route1.Between(i.To, k.From)), WeightTotal = i_weight + k_weight, WeightAfter = weight_after_k, WeightBefore = weight_before_i, WeightBetween = weight_between_route, CustomersBetween = k_idx - i_idx }; foreach (EdgePair pair2 in route2_pairs) { double existing_weight = pair1.WeightTotal + pair2.WeightTotal; //double new_weight = 0; // get first route new. double new_weight = problem.WeightMatrix[pair1.First.From][pair2.First.To]; //new_weight = first_route1_new; if (new_weight > existing_weight - 0.001) { continue; } double first_route2_new = problem.WeightMatrix[pair2.First.From][pair1.First.To]; new_weight = new_weight + first_route2_new; if (new_weight > existing_weight - 0.001) { continue; } double second_route1_new = problem.WeightMatrix[pair1.Second.From][pair2.Second.To]; new_weight = new_weight + second_route1_new; if (new_weight > existing_weight - 0.001) { continue; } double second_route2_new = problem.WeightMatrix[pair2.Second.From][pair1.Second.To]; new_weight = new_weight + second_route2_new; if (new_weight < existing_weight - 0.001) { // there is a decrease in total weight; check bounds. double route1_weight = pair1.WeightBefore + pair2.WeightBetween + pair1.WeightAfter; double route2_weight = pair2.WeightBefore + pair1.WeightBetween + pair2.WeightAfter; // calculate the maximum. int route1_customers_between = pair1.CustomersBetween; int route2_customers_between = pair1.CustomersBetween; route1_weight = problem.Time(route1_weight, route1_customers - route1_customers_between + route2_customers_between); route2_weight = problem.Time(route2_weight, route2_customers - route2_customers_between + route1_customers_between); if (route1_weight < max && route2_weight < max) { MaxTimeSolution solution_copy = solution.Clone() as MaxTimeSolution; List <int> route1_between = pair1.Between; List <int> route2_between = pair2.Between; route1.ReplaceEdgeFrom(pair1.First.From, pair1.Second.To); route2.ReplaceEdgeFrom(pair2.First.From, pair2.Second.To); int previous = pair1.First.From; for (int idx = 0; idx < route2_between.Count; idx++) { route1.ReplaceEdgeFrom(previous, route2_between[idx]); previous = route2_between[idx]; } route1.ReplaceEdgeFrom(previous, pair1.Second.To); previous = pair2.First.From; for (int idx = 0; idx < route1_between.Count; idx++) { route2.ReplaceEdgeFrom(previous, route1_between[idx]); previous = route1_between[idx]; } route2.ReplaceEdgeFrom(previous, pair2.Second.To); if (!solution.IsValid()) { throw new Exception(); } return(true); } } } } } return(false); }
// Save the Pair object as a member variable to avoid having to instantiate // a new Object every time GetActiveEdges() is called. // Constructor ///////////////////////////////////////////////////////////// /** * Constructor. * * @param horizontalEdge the horizontal edge associated with this handle; * may be null * @param verticalEdge the vertical edge associated with this handle; may be * null */ public HandleHelper(Edge horizontalEdge, Edge verticalEdge) { mHorizontalEdge = horizontalEdge; mVerticalEdge = verticalEdge; mActiveEdges = new EdgePair(mHorizontalEdge, mVerticalEdge); }
private void CreateShape(int i) { m_Shape = GetComponent <RigidBodyPool>().GetBody().GetComponent <Shape>(); var s = m_Params[i].Scale; var P0 = new ShapePoint(new Vector3(s.x, s.y, s.z)); var P1 = new ShapePoint(new Vector3(-s.x, s.y, s.z)); var P2 = new ShapePoint(new Vector3(-s.x, s.y, -s.z)); var P3 = new ShapePoint(new Vector3(s.x, s.y, -s.z)); var P4 = new ShapePoint(new Vector3(s.x, -s.y, s.z)); var P5 = new ShapePoint(new Vector3(-s.x, -s.y, s.z)); var P6 = new ShapePoint(new Vector3(-s.x, -s.y, -s.z)); var P7 = new ShapePoint(new Vector3(s.x, -s.y, -s.z)); var P0P4pair = new EdgePair(null, null); var P1P5pair = new EdgePair(null, null); var P2P6pair = new EdgePair(null, null); var P3P7pair = new EdgePair(null, null); ConstructFace(P0P4pair, P1P5pair, P0, P4, P5, P1, Vector3.forward, true); ConstructFace(P1P5pair, P2P6pair, P1, P5, P6, P2, -Vector3.right, false); ConstructFace(P2P6pair, P3P7pair, P2, P6, P7, P3, -Vector3.forward, true); ConstructFace(P3P7pair, P0P4pair, P3, P7, P4, P0, Vector3.right, false); var top = new Face(); top.PutOntoOpenHole(P0P4pair.Edge1.Prev.Other, Vector3.up); top.OnNewOwner(m_Shape); var bottom = new Face(); bottom.PutOntoOpenHole(P0P4pair.Edge1.Next.Other, -Vector3.up); bottom.OnNewOwner(m_Shape); P0P4pair.OnNewOwner(m_Shape); P1P5pair.OnNewOwner(m_Shape); P2P6pair.OnNewOwner(m_Shape); P3P7pair.OnNewOwner(m_Shape); m_Shape.Points.Add(P0.Point); m_Shape.Points.Add(P1.Point); m_Shape.Points.Add(P2.Point); m_Shape.Points.Add(P3.Point); m_Shape.Points.Add(P4.Point); m_Shape.Points.Add(P5.Point); m_Shape.Points.Add(P6.Point); m_Shape.Points.Add(P7.Point); P0.Index = 0; P1.Index = 1; P2.Index = 2; P3.Index = 3; P4.Index = 4; P5.Index = 5; P6.Index = 6; P7.Index = 7; foreach (var pair in m_Shape.EdgePairs) { m_Shape.EdgePointIndicies.Add(pair.Edge1.Start.Index); m_Shape.EdgePointIndicies.Add(pair.Edge1.End.Index); } m_Shape.EnsureWorldPointsListIsBigEnough(); var meshPool = GetComponent <FaceMeshPool>(); foreach (var face in m_Shape.Faces) { face.AddMesh(meshPool); } m_Shape.transform.position = m_Params[i].Position; m_Shape.transform.rotation = Quaternion.identity; m_Shape.UpdateWorldPoints(); m_Shape.GetComponent <MyRigidbody>().Drag = m_Params[i].Drag; }
public static EdgePair Create() { var pair = new EdgePair(); pair._e = new Edge(); pair._e._pair = pair; pair._eSym = new Edge(); pair._eSym._pair = pair; return pair; }
private Edge RequiredEdge(EdgePair pair, bool set1) { return(set1 ? pair.Edge1 : pair.Edge2); }
public Dictionary <EdgePair, Double> Solve(FCTPGraph ti) { Dictionary <EdgePair, Double> edgeFlows = new Dictionary <EdgePair, Double>(); Dictionary <String, Edge> edgeMap = new Dictionary <String, Edge>(); Dictionary <String, GRBVar> varMap = new Dictionary <String, GRBVar>(); String currentVar = ""; try { //Model GRBEnv env = new GRBEnv(); env.Set(GRB.IntParam.LogToConsole, 0); GRBModel model = new GRBModel(env); model.Set(GRB.StringAttr.ModelName, "tranportation"); //edges foreach (Edge e in ti.Edges) { String xij = edgeVarName(e.Source, e.Sink); edgeMap.Add(xij, e); GRBVar var = model.AddVar(0, GRB.INFINITY, e.C, GRB.CONTINUOUS, xij); varMap.Add(xij, var); } //objective min Sum cij xij model.Set(GRB.IntAttr.ModelSense, GRB.MINIMIZE); //integrate variables model.Update(); //supply constraints foreach (Node source in ti.Sources) { GRBLinExpr sourceConstraint = new GRBLinExpr(); foreach (Node sink in ti.Sinks) { String name = edgeVarName(source.Id, sink.Id); sourceConstraint.AddTerm(1, varMap[name]); } model.AddConstr(sourceConstraint, GRB.EQUAL, source.Amount, ""); } //demand constraints foreach (Node sink in ti.Sinks) { GRBLinExpr sinkConstraint = new GRBLinExpr(); foreach (Node source in ti.Sources) { String name = edgeVarName(source.Id, sink.Id); sinkConstraint.AddTerm(1, varMap[name]); } model.AddConstr(sinkConstraint, GRB.EQUAL, sink.Amount, ""); } //update constraints model.Update(); model.Write("mipTranportationGurobi.lp"); env.Set(GRB.IntParam.Threads, 1); model.Optimize(); bool status = model.Get(GRB.IntAttr.Status) == GRB.Status.OPTIMAL; Console.WriteLine("Status: " + status); foreach (String s in edgeMap.Keys) { currentVar = s; double flow = varMap[s].Get(GRB.DoubleAttr.X); Edge e = edgeMap[s]; EdgePair ep = new EdgePair(e.Source, e.Sink); edgeFlows.Add(ep, flow); } model.Dispose(); } catch (GRBException e) { Console.Out.WriteLine(currentVar + " - is current var"); Console.Out.WriteLine(e.ErrorCode); Console.Out.WriteLine(e.ToString()); } return(edgeFlows); }
/// <summary> /// Tries to relocate customers using the source the same as the CrossExchange but places customers using cheapest insertion. /// </summary> /// <param name="problem"></param> /// <param name="solution"></param> /// <param name="route1_idx"></param> /// <param name="route2_idx"></param> /// <param name="max"></param> /// <returns></returns> public bool Improve(MaxTimeProblem problem, MaxTimeSolution solution, int route1_idx, int route2_idx, double max) { int max_window = 10; IRoute route1 = solution.Route(route1_idx); IRoute route2 = solution.Route(route2_idx); double total_before = problem.Time(solution.Route(route1_idx)) + problem.Time(solution.Route(route2_idx)); int route1_customers = route1.Count; int route2_customers = route2.Count; double[] route1_cumul = problem.TimeCumul(route1); double[] route2_cumul = problem.TimeCumul(route2); // build all edge weights. List <Edge> route1_edges = new List <Edge>(route1.Edges()); List <Edge> route2_edges = new List <Edge>(route2.Edges()); double[] route1_weights = new double[route1_edges.Count]; for (int idx = 0; idx < route1_edges.Count; idx++) { Edge edge = route1_edges[idx]; route1_weights[idx] = problem.WeightMatrix[edge.From][edge.To]; } double[] route2_weights = new double[route2_edges.Count]; for (int idx = 0; idx < route2_edges.Count; idx++) { Edge edge = route2_edges[idx]; route2_weights[idx] = problem.WeightMatrix[edge.From][edge.To]; } List <EdgePair> route2_pairs = new List <EdgePair>(); for (int i_idx = 0; i_idx < route2_edges.Count - 2; i_idx++) { Edge i = route2_edges[i_idx]; double i_weight = route2_weights[i_idx]; double weight_before_i = route2_cumul[i_idx]; int k_idx_max = route2_edges.Count; if (k_idx_max > i_idx + 2 + max_window) { k_idx_max = i_idx + 2 + max_window; } for (int k_idx = i_idx + 2; k_idx < k_idx_max; k_idx++) { Edge k = route2_edges[k_idx]; double k_weight = route2_weights[k_idx]; double weight_after_k = route2_cumul[route2_cumul.Length - 1] - route2_cumul[k_idx + 1]; double weight_between_route = route2_cumul[k_idx] - route2_cumul[i_idx + 1]; route2_pairs.Add(new EdgePair() { First = i, FirstWeight = i_weight, Second = k, SecondWeight = k_weight, Between = new List <int>(route2.Between(i.To, k.From)), WeightTotal = i_weight + k_weight, WeightAfter = weight_after_k, WeightBefore = weight_before_i, WeightBetween = weight_between_route, CustomersBetween = k_idx - i_idx }); } } // try to relocate all and find best pair. double route1_weight = route1_cumul[route1_cumul.Length - 1]; EdgePair best = null; CheapestInsertionResult best_result = new CheapestInsertionResult(); double best_extra = double.MaxValue; foreach (EdgePair pair2 in route2_pairs) { // calculate cheapest insertion. CheapestInsertionResult result = CheapestInsertionHelper.CalculateBestPlacement(problem, route1, pair2.First.To, pair2.Second.From); double extra_route2 = problem.WeightMatrix[pair2.First.From][pair2.Second.To]; // check if the result has a net-decrease. if (result.Increase + extra_route2 < pair2.WeightTotal - 0.01) { // there is a net decrease. // calculate the real increase. double new_weight = problem.Time(route1_weight + result.Increase + pair2.WeightBetween, route1_customers + pair2.CustomersBetween); // check the max. if (new_weight < max && new_weight < best_extra) { // the route is smaller than max. best_extra = new_weight; best_result = result; best = pair2; } } } if (best != null) { if (route2.Last == best.Second.To) { //throw new Exception(); } route2.ReplaceEdgeFrom(best.First.From, best.Second.To); int previous = best_result.CustomerBefore; foreach (int customer in best.Between) { route1.ReplaceEdgeFrom(previous, customer); previous = customer; } route1.ReplaceEdgeFrom(previous, best_result.CustomerAfter); // check validity. if (!route2.IsValid()) { throw new Exception(); } if (!route1.IsValid()) { throw new Exception(); } if (route1.Count + route2.Count != route1_customers + route2_customers) { throw new Exception(); } double total_after = problem.Time(solution.Route(route1_idx)) + problem.Time(solution.Route(route2_idx)); if (total_after >= total_before) { throw new Exception("this is not an improvement!"); } return(true); } return(false); }
public Edge(EdgePair pair, Face ownerFace) { OwnerPair = pair; OwnerFace = ownerFace; }
void AddPair(EdgePair edge) { PairsByCandidate[edge.Neighbor.Candidate] = PairsByProbe[edge.Neighbor.Probe] = PairList[PairCount]; PairList[PairCount].Pair = edge.Neighbor; PairList[PairCount].Reference = edge.Reference; ++PairCount; }
public Dictionary <EdgePair, Double> Solve(FCTPGraph ti) { Dictionary <EdgePair, Double> edgeFlows = new Dictionary <EdgePair, Double>(); Dictionary <String, Edge> edgeMap = new Dictionary <String, Edge>(); Dictionary <String, INumVar> varMap = new Dictionary <String, INumVar>(); String currentVar = ""; try { //Model Cplex cplex = new Cplex(); IModel model = cplex.GetModel(); //model.Set(GRB.StringAttr.ModelName, "tranportation"); ILinearNumExpr expr = cplex.LinearNumExpr(); //edges foreach (Edge e in ti.Edges) { String xij = edgeVarName(e.Source, e.Sink); edgeMap.Add(xij, e); INumVar var = cplex.NumVar(0, System.Double.MaxValue); var.Name = xij; varMap.Add(xij, var); expr.AddTerm(e.C, var); } //objective min Sum c_{ij} x_{ij} model.Add(cplex.Minimize(expr)); //supply constraints foreach (Node ssource in ti.Sources) { List <INumExpr> sourceConstraint = new List <INumExpr>(); foreach (Node ssink in ti.Sinks) { String name = edgeVarName(ssource.Id, ssink.Id); sourceConstraint.Add(varMap[name]); } cplex.AddEq(cplex.Sum(sourceConstraint.ToArray()), ssource.Amount); } //demand constraints foreach (Node dsink in ti.Sinks) { List <INumExpr> sinkConstraint = new List <INumExpr>(); foreach (Node dsource in ti.Sources) { String name = edgeVarName(dsource.Id, dsink.Id); sinkConstraint.Add(varMap[name]); } cplex.AddEq(cplex.Sum(sinkConstraint.ToArray()), dsink.Amount); } cplex.SetParam(Cplex.BooleanParam.Threads, 1); cplex.ExportModel("mipTranportationCplex.lp"); bool status = cplex.Solve(); Console.WriteLine("Status: " + status); foreach (String s in edgeMap.Keys) { currentVar = s; double flow = cplex.GetValue(varMap[s]); Edge e = edgeMap[s]; EdgePair ep = new EdgePair(e.Source, e.Sink); edgeFlows.Add(ep, flow); } cplex.End(); } catch (ILOG.Concert.Exception e) { Console.Out.WriteLine(currentVar + " - is current var"); Console.Out.WriteLine(e.ToString()); } return(edgeFlows); }
/* Allocate and free half-edges in pairs for efficiency. * The *only* place that should use this fact is allocation/free. */ /* MakeEdge creates a new pair of half-edges which form their own loop. * No vertex or face structures are allocated, but these must be assigned * before the current edge operation is completed. */ private static HalfEdge MakeEdge(HalfEdge eNext) { HalfEdge ePrev; var pair = new EdgePair(); /* Make sure eNext points to the first edge of the edge pair */ if (eNext.otherHalfOfThisEdge.isFirstHalfEdge) { eNext = eNext.otherHalfOfThisEdge; } /* Insert in circular doubly-linked list before eNext. * Note that the prev pointer is stored in Sym.next. */ ePrev = eNext.otherHalfOfThisEdge.nextHalfEdge; pair.eSym.nextHalfEdge = ePrev; ePrev.otherHalfOfThisEdge.nextHalfEdge = pair.e; pair.e.nextHalfEdge = eNext; eNext.otherHalfOfThisEdge.nextHalfEdge = pair.eSym; pair.e.isFirstHalfEdge = true; pair.e.otherHalfOfThisEdge = pair.eSym; pair.e.nextEdgeCCWAroundOrigin = pair.e; pair.e.nextEdgeCCWAroundLeftFace = pair.eSym; pair.e.originVertex = null; pair.e.leftFace = null; pair.e.winding = 0; pair.e.regionThisIsUpperEdgeOf = null; pair.eSym.isFirstHalfEdge = false; pair.eSym.otherHalfOfThisEdge = pair.e; pair.eSym.nextEdgeCCWAroundOrigin = pair.eSym; pair.eSym.nextEdgeCCWAroundLeftFace = pair.e; pair.eSym.originVertex = null; pair.eSym.leftFace = null; pair.eSym.winding = 0; pair.eSym.regionThisIsUpperEdgeOf = null; return pair.e; }