/* * Copyright (c) 2005-2006 Erik Tigerholm * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ using System; using System.Collections.Generic; using System.Text; namespace OpenTraffic.Model.Graph.Partioning { public class MultiGraph : Graph, GraphEdge>> where TV : Vertex where TE : GraphEdge { private List>> changeList; private List> activeList; public MultiGraph() : base() { changeList = new List>>(); } public void NewPoint() { activeList = new List>(); changeList.Add(activeList); } public void Join(MultiVertex v1, MultiVertex v2) { if (v1 != null && v2 != null) { if (v2.Id == v1.Id) return; activeList.Insert(0, v1); // Change the edges to point to the new element foreach (GraphEdge> pm in AdjLinks[v2]) { pm.Source = v1; AdjLinks[v1].Add(pm); } foreach (GraphEdge> pm in RevAdjLinks[v2]) { pm.Target = v1; RevAdjLinks[v1].Add(pm); } v1.Join(v2); // Remove the joined element Nodes.Remove(v2); AdjLinks.Remove(v2); RevAdjLinks.Remove(v2); } } [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")] public Dictionary, MultiVertex> ReverseToNextPoint() { if (activeList == null) throw new InvalidOperationException("No more point stored"); Dictionary, MultiVertex> list = new Dictionary, MultiVertex>(); foreach (MultiVertex v in this.activeList) { MultiVertex v2 = v.Reverse(); list.Add(v, v2); RevAdjLinks.Add(v2, new List>>()); AdjLinks.Add(v2, new List>>()); this.Expand(v, v2); } changeList.RemoveAt(changeList.Count - 1); if (changeList.Count == 0) { activeList = null; } else { activeList = changeList[changeList.Count - 1]; } return list; } private void Expand(MultiVertex mv1, MultiVertex mv2) { if (mv1.Id == mv2.Id) return; foreach (GraphEdge> pm in mv2.Edges) { if (pm.Source == mv1) { pm.Source = mv2; AdjLinks[mv1].Remove(pm); AdjLinks[mv2].Add(pm); } else { pm.Target = mv2; RevAdjLinks[mv1].Remove(pm); RevAdjLinks[mv2].Add(pm); } } Nodes.Add(mv2); } public override void Add(GraphEdge> e) { if (e != null) { base.Add(e); e.Source.Edges.Add(e); e.Target.Edges.Add(e); } } } }