using System; using System.Collections.Generic; using HeuristicLab.Problems.RoutePlanning.Osm; 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 List GetVertices() { return new List(vertices.Values); } 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) { List> edges; if (incidenceMap.TryGetValue(vertexId, out edges)) { return edges; } else { return new List>(); } } public int GetInDegree(long vertexId) { return incidenceMap[vertexId].Count; } public List> GetOutEdges(long vertexId) { List> edges; if (adjacencyMap.TryGetValue(vertexId, out edges)) { return edges; } else { return new List>(); } } 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 = GetWeight(edge); // 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 = GetWeight(edge); // TODO: edge.Weight? neighbors[edge.Source.Id] = weight; } return neighbors; } public float GetWeight(Edge edge) { double distance = Utils.Distance(edge.Source.Logitude, edge.Source.Latitude, edge.Target.Logitude, edge.Target.Latitude); //double distance = Utils.LocationDistance(source.Node.Point, target.Node.Point); int speed = edge.GetMaxSpeed(); //double weight = (distance / speed) * 3.6; double weight = (distance / speed); return (float)weight; } public float EstimatedCosts(long sourceId, long targetId) { Vertex source = GetVertex(sourceId); Vertex target = GetVertex(targetId); return EstimatedCosts(source, target); } public float EstimatedCosts(Vertex source, Vertex target) { double distance = Utils.Distance(source.Logitude, source.Latitude, target.Logitude, target.Latitude); //double distance = Utils.LocationDistance(source.Node.Point, target.Node.Point); int speed = 10; //double costs = (distance / speed) * 3.6; double costs = (distance / speed); return (float)costs; } } }