Пример #1
0
 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;
 }
Пример #2
0
        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);
        }
Пример #3
0
    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);
    }
Пример #4
0
 public override void Reset()
 {
     _pair         = null;
     _next         = _Sym = _Onext = _Lnext = null;
     _Org          = null;
     _Lface        = null;
     _activeRegion = null;
     _winding      = 0;
 }
Пример #5
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);
            }
Пример #6
0
            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);
            }
Пример #7
0
 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);
            }
        }
    }
Пример #11
0
    /// <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;
                        }
                    }
                }
            }
        }
    }
Пример #12
0
        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);
        }
Пример #13
0
    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();
    }
Пример #14
0
    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);
    }
Пример #15
0
        // 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);
            }
        }
Пример #16
0
    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);
    }
Пример #17
0
        // 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);
            }
        }
Пример #18
0
        /* 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);
        }
Пример #19
0
        /// <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;
        }
Пример #22
0
        /// <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);
        }
Пример #23
0
        // 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);
        }
Пример #24
0
    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;
    }
Пример #25
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;
 }
Пример #26
0
 private Edge RequiredEdge(EdgePair pair, bool set1)
 {
     return(set1 ? pair.Edge1 : pair.Edge2);
 }
Пример #27
0
        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);
        }
Пример #28
0
        /// <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);
        }
Пример #29
0
 public Edge(EdgePair pair, Face ownerFace)
 {
     OwnerPair = pair;
     OwnerFace = ownerFace;
 }
Пример #30
0
 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;
 }
Пример #31
0
        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);
        }
Пример #32
0
        /* 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;
        }