/// <summary> /// Método que a partir de una estación, encuentra las rutas optimas hacia todos los demás /// </summary> /// <param name="origen"></param> /// <returns></returns> public List<Estacion> CalculaRutasMinimas(Estacion origen) { List<Estacion> S = new List<Estacion>(); List<Estacion> minimos = new List<Estacion>(); S.Add(origen); while (S.Count > 0) // Mientras que existan elementos para procesar { // Sacamos un elemento de la lista Estacion temporal = S[0]; Estacion predecesora = temporal.EstacionPredecesora; decimal pesoAnterior = temporal.PesoAcumulado; S.RemoveAt(0); // Lo agregamos a nuestro arreglo de soluciones temporal = grafo.ElementAt(grafo.IndexOfKey(temporal)).Key; temporal.EstacionPredecesora = predecesora; temporal.PesoAcumulado = pesoAnterior; minimos.Add(temporal); // Obtenemos el índice int indice1 = grafo.IndexOfKey(temporal); int indice2 = -1; // Por cada conexión con este nodo foreach (Conexion conexion in temporal.Conexiones) { // Para cada arista que conecta con temporal indice2 = grafo.IndexOfKey(conexion.Destino); // No hay conexion if (MatrizPesos[indice1, indice2] <= 0) continue; // Ya se calculó if (minimos.Contains(conexion.Destino)) continue; // Marcamos con la etiqueta el nodo seleccionado conexion.Destino.EstacionPredecesora = temporal; conexion.Destino.PesoAcumulado = MatrizPesos[indice1, indice2] + temporal.PesoAcumulado; // Si no existe, lo agregamos a la lista para ser procesado por el algoritmo if (!S.Contains(conexion.Destino)) { S.Add(conexion.Destino); continue; } // Si llegó aquí es porque ya existía, entonces lo buscamos para comprobar que // siempre esté actualizado con el menor peso for (int ix = 0; ix < S.Count; ix++) { Estacion e = S[ix]; if (e.Equals(conexion.Destino) // Si hablamos de las mismas estaciones && e.PesoAcumulado > conexion.Destino.PesoAcumulado) // Y el peso es menor { S.RemoveAt(ix); S.Add(conexion.Destino); break; } } } } return minimos; }
public void AñadirRecarga(Estacion estacion, Tarjetum tarjeta, DateTime fecha, DateTime hora) { using (EntitiesModel dbContext = new EntitiesModel()) { Recarga recarga = new Recarga(); recarga.Estacion = estacion ; recarga.Tarjetum = tarjeta; recarga.Fecha = fecha; recarga.Hora = hora; dbContext.Add(recarga); dbContext.SaveChanges(); } }
public void AñadirConsumo(Estacion estacion, Tarjetum tarjeta, DateTime fecha, DateTime hora) { using (EntitiesModel dbContext = new EntitiesModel()) { Consumo consumo = new Consumo(); consumo.Estacion = estacion; consumo.Tarjetum = tarjeta; consumo.Fecha = fecha; consumo.Hora = hora; dbContext.Add(consumo); dbContext.SaveChanges(); } }
public void EditarRecarga(Estacion estacion, Tarjetum tarjeta, DateTime fecha, DateTime hora) { using (EntitiesModel dbContext = new EntitiesModel()) { //se supone que debemos hacer el update pidiendo el ID.....falta implementarlo Recarga RecargaParaEditar = dbContext.Recargas.First(); RecargaParaEditar.Estacion = estacion ; RecargaParaEditar.Tarjetum = tarjeta ; RecargaParaEditar.Fecha = fecha ; RecargaParaEditar.Hora = hora; dbContext.SaveChanges(); } }
/// <summary> /// Obtiene el índice dentro del grafo en el que se /// encuentra la estación especificada /// </summary> /// <param name="e"></param> /// <returns></returns> public int ObtenerIndiceEstacion(Estacion e) { return grafo.IndexOfKey(e); }
public Estacion EstacionMasCercana(decimal latitud, decimal longitud) { Estacion e = null; Database db = DatabaseFactory.CreateDatabase("RutAppBd"); // Recuperamos todas las estaciones de la base de datos DbCommand cmd = db.GetStoredProcCommand("dbo.ObtieneEstacionesCercanas"); db.AddInParameter(cmd, "latitud", DbType.Decimal, latitud); db.AddInParameter(cmd, "longitud", DbType.Decimal, longitud); db.AddInParameter(cmd, "radio", DbType.Int32, 2000); using (IDataReader reader = db.ExecuteReader(cmd)) { if (reader.Read()) { String idEstacion = reader.GetString(reader.GetOrdinal("id")); e = new Estacion(idEstacion); e.Nombre = reader.GetString(reader.GetOrdinal("nombre")); int i = reader.GetOrdinal("linea"); if (!reader.IsDBNull(i)) e.Linea = reader.GetString(i); e.Latitud = (decimal)reader.GetDouble(reader.GetOrdinal("latitud")); e.Longitud = (decimal)reader.GetDouble(reader.GetOrdinal("longitud")); e.Tarifa = reader.GetDecimal(reader.GetOrdinal("tarifa")); e.TipoEstacion = reader.GetString(reader.GetOrdinal("tipo_estacion")); } } return e; }
/// <summary> /// Método para encontrar la ruta óptima entre dos puntos dadas las estaciones para iniciar /// </summary> /// <param name="inicio">Estación inicial</param> /// <param name="fin">Estación final</param> /// <returns>La mejor ruta encontrada</returns> public Ruta EncontrarRuta(Estacion inicio, Estacion fin) { Estacion auxiliar = fin; // Encontramos la ruta a partir del inicio List<Estacion> minimos = CalculaRutasMinimas(inicio); Ruta ruta = new Ruta(); decimal distancia = 0; // Si no existe en nuestra lista es porque no hay conexión entre ellos if (!minimos.Contains(auxiliar)) { throw new Exception(String.Format("{0} no alcanzable desde {1}", fin.Nombre, inicio.Nombre)); } auxiliar = minimos[minimos.IndexOf(auxiliar)]; distancia = auxiliar.PesoAcumulado; // Se usa una pila para almacenar la ruta Stack<Estacion> pila = new Stack<Estacion>(); while (auxiliar != null) { pila.Push(auxiliar); auxiliar = auxiliar.EstacionPredecesora; } // Vaciar la pila para armar la ruta correcta while (pila.Count > 0) { ruta.Estaciones.Add(pila.Pop()); } return ruta; }
public void CargaGrafo() { Database db = DatabaseFactory.CreateDatabase("RutAppBd"); // Recuperamos todas las estaciones de la base de datos DbCommand cmd = db.GetStoredProcCommand("dbo.ObtieneTodasEstaciones"); int ix = 0; using (IDataReader reader = db.ExecuteReader(cmd)) { while (reader.Read()) { String idEstacion = reader.GetString(reader.GetOrdinal("id")); Estacion nvaEst = new Estacion(idEstacion); nvaEst.Nombre = reader.GetString(reader.GetOrdinal("nombre")); int i = reader.GetOrdinal("linea"); if (!reader.IsDBNull(i)) nvaEst.Linea = reader.GetString(i); nvaEst.Latitud = (decimal)reader.GetDouble(reader.GetOrdinal("latitud")); nvaEst.Longitud = (decimal)reader.GetDouble(reader.GetOrdinal("longitud")); nvaEst.Tarifa = reader.GetDecimal(reader.GetOrdinal("tarifa")); nvaEst.TipoEstacion = reader.GetString(reader.GetOrdinal("tipo_estacion")); grafo.Add(nvaEst, ix++); } } // Para cada estacion, obtenemos sus adyacencias foreach (Estacion estacion in grafo.Keys) { DbCommand dbC = db.GetStoredProcCommand("RecuperaTramos"); db.AddInParameter(dbC, "estacion", DbType.String, estacion.IdEstacion); using (IDataReader reader = db.ExecuteReader(dbC)) { while (reader.Read()) { Conexion conexion = new Conexion(); conexion.MetrosTramo = reader.GetDecimal(reader.GetOrdinal("distancia")); conexion.VelocidadPromedio = reader.GetDecimal(reader.GetOrdinal("velocidad")); conexion.Destino = new Estacion(reader.GetString(1)); estacion.Conexiones.Add(conexion); } } } // Relleno de la matriz de pesos MatrizPesos = new decimal[NumeroNodos, NumeroNodos]; for (int i = 0; i < NumeroNodos; i++) { for (int j = 0; j < NumeroNodos; j++) { Estacion uno = grafo.ElementAt(i).Key; Estacion dos = grafo.ElementAt(j).Key; MatrizPesos[i, j] = uno.PesoConexion(dos); } } }