using System; using System.Collections.Generic; namespace HeuristicLab.Problems.RoutePlanning.Graph { public class Graph : IGraph { private IDictionary vertices; private IDictionary>> adjacencyMap; private IDictionary>> incidenceMap; public Graph() { vertices = new Dictionary(); adjacencyMap = new Dictionary>>(); incidenceMap = new Dictionary>>(); } public void AddVertex(Vertex vertex) { if (!vertices.ContainsKey(vertex.Id)) { vertices.Add(vertex.Id, vertex); } } public Vertex GetVertex(long id) { Vertex vertex = null; vertices.TryGetValue(id, out vertex); return vertex; } public void AddEdge(long startId, long endId) { Vertex start = GetVertex(startId); if (start == null) throw new ArgumentException(string.Format("Invalid vertex id {0}", startId), "startId"); Vertex end = GetVertex(startId); if (end == null) throw new ArgumentException(string.Format("Invalid vertex id {0}", endId), "endId"); Edge edge = new Edge(start, end); //edge.Category = -1 AddEdge(edge); } public void AddEdge(Edge edge) { if (!adjacencyMap.ContainsKey(edge.Source.Id)) { adjacencyMap.Add(edge.Source.Id, new List>()); } adjacencyMap[edge.Source.Id].Add(edge); if (!incidenceMap.ContainsKey(edge.Target.Id)) { incidenceMap.Add(edge.Target.Id, new List>()); } incidenceMap[edge.Target.Id].Add(edge); } public void RemoveEdge(long startId, long endId) { Edge edge = GetEdge(startId, endId); if (edge != null) { adjacencyMap[startId].Remove(edge); incidenceMap[endId].Remove(edge); } } public bool HasEdge(long startId, long endId) { Edge edge = GetEdge(startId, endId); return (edge != null); } public Edge GetEdge(long startId, long endId) { List> edges = adjacencyMap[startId]; foreach (Edge edge in edges) { if (edge.Target.Id == endId) { return edge; } } return null; } public List> GetInEdges(long vertexId) { return incidenceMap[vertexId]; } public int GetInDegree(long vertexId) { return incidenceMap[vertexId].Count; } public List> GetOutEdges(long vertexId) { return adjacencyMap[vertexId]; } public int GetOutDegree(long vertexId) { return adjacencyMap[vertexId].Count; } public List> GetEdges(long vertexId) { List> result = new List>(); foreach (Edge edge in GetInEdges(vertexId)) { if (!result.Contains(edge)) { result.Add(edge); } } foreach (Edge edge in GetOutEdges(vertexId)) { if (!result.Contains(edge)) { result.Add(edge); } } return result; } public Dictionary GetNeighborsWithWeight(long id) { Dictionary neighbors = new Dictionary(); List> edges = GetOutEdges(id); foreach (Edge edge in edges) { // TODO: check if edge can be traversed (eg. highway tag for car roads, ...) float weight = 1; // TODO: edge.Weight? neighbors[edge.Target.Id] = weight; } return neighbors; } public Dictionary GetNeighborsWithWeightReversed(long id) { Dictionary neighbors = new Dictionary(); List> edges = GetInEdges(id); foreach (Edge edge in edges) { // TODO: check if edge can be traversed (eg. highway tag for car roads, ...) float weight = 1; // TODO: edge.Weight? neighbors[edge.Source.Id] = weight; } return neighbors; } } }