示例#1
0
            internal static MetroEdge CreateFromTwoEdges(int v, MetroEdge e1, MetroEdge e2)
            {
                int s = e1.Source() == v?e1.Target() : e1.Source();

                int t = e2.Source() == v?e2.Target() : e2.Source();

                if (s < t)
                {
                    return(CreateFromTwoEdges(v, e1.nodes, e2.nodes));
                }
                else
                {
                    return(CreateFromTwoEdges(v, e2.nodes, e1.nodes));
                }
            }
示例#2
0
            internal static MetroEdge CreateFromTwoEdges(int v, List <int> e1, List <int> e2)
            {
                List <int> nodes = new List <int>(e1.Count + e2.Count - 1);

                if (e1[0] != v)
                {
                    for (int i = 0; i < e1.Count; i++)
                    {
                        nodes.Add(e1[i]);
                    }
                }
                else
                {
                    for (int i = e1.Count - 1; i >= 0; i--)
                    {
                        nodes.Add(e1[i]);
                    }
                }

                if (e2[0] == v)
                {
                    for (int i = 1; i < e2.Count; i++)
                    {
                        nodes.Add(e2[i]);
                    }
                }
                else
                {
                    for (int i = e2.Count - 2; i >= 0; i--)
                    {
                        nodes.Add(e2[i]);
                    }
                }

                MetroEdge res = new MetroEdge();

                res.nodes = nodes;
#if SHARPKIT //https://code.google.com/p/sharpkit/issues/detail?id=289
                res.UpdateHashKey();
#endif
                return(res);
            }
示例#3
0
        /// <summary>
        /// Get the ordering of lines on station u with respect to the edge (u->v)
        /// </summary>
        IEnumerable <Metroline> IMetroMapOrderingAlgorithm.GetOrder(Station u, Station v)
        {
            MetroEdge  me = MetroEdge.CreateFromTwoNodes(u.SerialNumber, v.SerialNumber);
            List <int> orderedMetrolineListForUv = order[me];

            if (u.SerialNumber < v.SerialNumber)
            {
                foreach (int MetrolineIndex in orderedMetrolineListForUv)
                {
                    yield return(MetrolinesGlobal[MetrolineIndex]);
                }
            }
            else
            {
                for (int i = orderedMetrolineListForUv.Count - 1; i >= 0; i--)
                {
                    yield return(MetrolinesGlobal[orderedMetrolineListForUv[i]]);
                }
            }
        }
示例#4
0
        /// <summary>
        /// Remove vertex v from the graph. Update graph and paths correspondingly
        /// </summary>
        void ProcessNonTerminal(int v)
        {
            //oldEdge => sorted PathLists
            Dictionary <MetroEdge, List <PathList> > newSubLists = RadixSort(v);

            //update current data
            foreach (MetroEdge oldEdge in orderedAdjacent[v])
            {
                Debug.Assert(e2p.ContainsKey(oldEdge));
                List <PathList> newSubList = newSubLists[oldEdge];

                //update e2p[oldEdge]
                e2p[oldEdge].paths    = null;
                e2p[oldEdge].subLists = newSubList;

                //update ordered adjacency data
                UpdateAdjacencyData(OppositeNode(oldEdge, v), oldEdge, newSubList);

                //update paths and add new edges
                foreach (PathList pl in newSubList)
                {
                    MetroEdge newEdge = pl.edge;

                    //we could check the reverse edge before
                    if (e2p.ContainsKey(newEdge))
                    {
                        continue;
                    }

                    //add e2p for new edge
                    e2p.Add(newEdge, pl);

                    //update paths
                    foreach (PathOnEdge path in pl.paths)
                    {
                        UpdatePath(path, v, newEdge);
                    }
                }
            }
        }
示例#5
0
        void Initialize()
        {
            //non terminals and adjacent
            nonTerminals = new HashSet <int>();
            initialEdges = new HashSet <MetroEdge>();
            //non-sorted adjacent edges. will be sorted later
            Dictionary <int, HashSet <MetroEdge> > adjacent = new Dictionary <int, HashSet <MetroEdge> >();

            for (int mi = 0; mi < Metrolines.Count; mi++)
            {
                int[] Metroline = Metrolines[mi];
                for (int i = 0; i + 1 < Metroline.Length; i++)
                {
                    MetroEdge me = MetroEdge.CreateFromTwoNodes(Metroline[i], Metroline[i + 1]);

                    if (!initialEdges.Contains(me))
                    {
                        initialEdges.Add(me);
                    }

                    if (i + 2 < Metroline.Length)
                    {
                        nonTerminals.Add(Metroline[i + 1]);
                    }

                    CollectionUtilities.AddToMap(adjacent, Metroline[i], me);
                    CollectionUtilities.AddToMap(adjacent, Metroline[i + 1], me);
                }
            }

            //order neighbors around each vertex
            InitAdjacencyData(adjacent);

            //create e2p and paths...
            InitPathData();
        }
示例#6
0
        /// <summary>
        /// Linear sorting of paths passing through vertex v
        /// </summary>
        Dictionary <MetroEdge, List <PathList> > RadixSort(int v)
        {
            //build a map [old_edge => list_of_paths_on_it]; the relative order of paths is important
            Dictionary <MetroEdge, List <PathOnEdge> > r = new Dictionary <MetroEdge, List <PathOnEdge> >();
            //first index in circular order
            Dictionary <MetroEdge, int> firstIndex = new Dictionary <MetroEdge, int>();

            foreach (MetroEdge oldEdge in orderedAdjacent[v])
            {
                PathList pathList = e2p[oldEdge];
                foreach (PathOnEdge path in pathList.paths)
                {
                    MetroEdge ej = FindNextEdgeOnPath(v, path);
                    CollectionUtilities.AddToMap(r, ej, path);
                }

                firstIndex.Add(oldEdge, (r.ContainsKey(oldEdge) ? r[oldEdge].Count : 0));
            }

            //oldEdge => SortedPathLists
            Dictionary <MetroEdge, List <PathList> > res = new Dictionary <MetroEdge, List <PathList> >();

            //build the desired order for each edge
            foreach (MetroEdge oldEdge in orderedAdjacent[v])
            {
                //r[oldEdge] is the right order! (up to the circleness)
                List <PathOnEdge> paths = r[oldEdge];
                Debug.Assert(paths.Count > 0);

                List <PathList>      subLists   = new List <PathList>();
                HashSet <PathOnEdge> curPathSet = new HashSet <PathOnEdge>();

                for (int j = 0; j < paths.Count; j++)
                {
                    int       i        = (j + firstIndex[oldEdge]) % paths.Count;
                    MetroEdge nowEdge  = paths[i].node.Value;
                    MetroEdge nextEdge = paths[(i + 1) % paths.Count].node.Value;

                    curPathSet.Add(paths[i]);

                    if (j == paths.Count - 1 || nowEdge != nextEdge)
                    {
                        //process
                        MetroEdge newEdge = MetroEdge.CreateFromTwoEdges(v, oldEdge, nowEdge);
                        PathList  pl      = new PathList();
                        pl.edge  = newEdge;
                        pl.paths = curPathSet;
                        subLists.Add(pl);

                        //clear
                        curPathSet = new HashSet <PathOnEdge>();
                    }
                }

                if (oldEdge.Source() == v)
                {
                    subLists.Reverse();
                }
                res.Add(oldEdge, subLists);
            }

            return(res);
        }
        /// <summary>
        /// replace edges (av) and (vb) with edge (ab) on a given path
        /// </summary>
        void UpdatePath(PathOnEdge pathOnEdge, int v, MetroEdge newEdge) {
            LinkedListNode<MetroEdge> f = pathOnEdge.node;
            Debug.Assert(f.Value.Source() == v || f.Value.Target() == v);

            int a, b;

            a = OppositeNode(f.Value, v);

            if (f.Next != null && (b = OppositeNode(f.Next.Value, v)) != -1) {
                Debug.Assert((a == newEdge.Source() || a == newEdge.Target()));
                Debug.Assert((b == newEdge.Source() || b == newEdge.Target()));

                f.Value = newEdge;
                f.List.Remove(f.Next);
            }
            else if (f.Previous != null && (b = OppositeNode(f.Previous.Value, v)) != -1) {
                Debug.Assert((a == newEdge.Source() || a == newEdge.Target()));
                Debug.Assert((b == newEdge.Source() || b == newEdge.Target()));

                f.Value = newEdge;
                f.List.Remove(f.Previous);
            }
            else
                throw new NotSupportedException();
        }
            internal static MetroEdge CreateFromTwoNodes(int u, int v) {
                MetroEdge res = new MetroEdge();
                res.nodes = new List<int>();
                res.nodes.Add(Math.Min(u, v));
                res.nodes.Add(Math.Max(u, v));

#if SHARPKIT //https://code.google.com/p/sharpkit/issues/detail?id=289
                res.UpdateHashKey();
#endif

                return res;
            }
        /// <summary>
        /// return an opposite vertex of a given edge
        /// </summary>
        int OppositeNode(MetroEdge edge, int v) {
            if (edge.Source() == v) return edge.Target();
            if (edge.Target() == v) return edge.Source();

            return -1;
        }
        /// <summary>
        /// recursively build an order on the edge
        /// </summary>
        List<int> RestoreResult(MetroEdge edge) {
            List<int> res = new List<int>();

            PathList pl = e2p[edge];
            if (pl.subLists == null) {
                foreach (PathOnEdge path in pl.paths)
                    res.Add(path.index);
            }
            else {
                foreach (PathList subList in pl.subLists) {
                    List<int> subResult = RestoreResult(subList.edge);
                    if (!(edge.Source() == subList.edge.Source() || edge.Target() == subList.edge.Target()))
                        subResult.Reverse();
                    res.AddRange(subResult);
                }
            }
            return res;
        }
        /// <summary>
        /// update adjacencies of node 'a': put new edges instead of oldEdge
        /// </summary>
        void UpdateAdjacencyData(int a, MetroEdge oldEdge, List<PathList> newSubList) {
            //find a (cached) position of oldEdge in order
            LinkedListNode<MetroEdge> node = adjacencyIndex[new Tuple<int, MetroEdge>(a, oldEdge)];
            Debug.Assert(node.Value == oldEdge);

            LinkedListNode<MetroEdge> inode = node;
            foreach (PathList pl in newSubList) {
                MetroEdge newEdge = pl.edge;

                if (oldEdge.Source() == a)
                    node = node.List.AddAfter(node, newEdge);
                else
                    node = node.List.AddBefore(node, newEdge);

                adjacencyIndex.Add(new Tuple<int, MetroEdge>(a, newEdge), node);
            }

            adjacencyIndex.Remove(new Tuple<int, MetroEdge>(a, oldEdge));
            inode.List.Remove(inode);
        }
            internal static MetroEdge CreateFromTwoEdges(int v, List<int> e1, List<int> e2) {
                List<int> nodes = new List<int>(e1.Count + e2.Count - 1);
                if (e1[0] != v) {
                    for (int i = 0; i < e1.Count; i++)
                        nodes.Add(e1[i]);
                }
                else {
                    for (int i = e1.Count - 1; i >= 0; i--)
                        nodes.Add(e1[i]);
                }

                if (e2[0] == v) {
                    for (int i = 1; i < e2.Count; i++)
                        nodes.Add(e2[i]);
                }
                else {
                    for (int i = e2.Count - 2; i >= 0; i--)
                        nodes.Add(e2[i]);
                }

                MetroEdge res = new MetroEdge();
                res.nodes = nodes;
#if SHARPKIT //https://code.google.com/p/sharpkit/issues/detail?id=289
                res.UpdateHashKey();
#endif
                return res;
            }
            internal static MetroEdge CreateFromTwoEdges(int v, MetroEdge e1, MetroEdge e2) {
                int s = e1.Source() == v ? e1.Target() : e1.Source();
                int t = e2.Source() == v ? e2.Target() : e2.Source();

                if (s < t)
                    return CreateFromTwoEdges(v, e1.nodes, e2.nodes);
                else
                    return CreateFromTwoEdges(v, e2.nodes, e1.nodes);
            }