using System.Collections.Generic;
public Ruta(string destino, int distancia)
this.distancia = distancia;
public string destino { get; set; }
public int distancia { get; set; }
public int Heuristica { get; set; }
public string Datos { get; set; }
public Nodo Padre { get; set; }
public List<Nodo> Hijos { get; set; }
public int Costo { get; set; }
public void SetHijos(List<Ruta> conexiones, Dictionary<string, int> heuristica)
this.Hijos = new List<Nodo>();
foreach (var conexion in conexiones)
var heuristicaNodo = heuristica.First(n => n.Key == conexion.destino).Value;
this.Hijos.Add(new Nodo()
Datos = conexion.destino,
Costo = conexion.distancia + this.Costo,
Heuristica = heuristicaNodo,
public static Dictionary<string, List<Ruta>> conexiones;
public static Dictionary<string, int> heuristica;
public static void Main()
var listaFrontera = new List<Nodo>();
var listaVisitados = new List<Nodo>();
TipoBusqueda tipoBusqueda = TipoBusqueda.AEstrella;
bool seEncontroElObjetivo = false;
string estadoInicial = "D";
string estadoObjetivo = "F";
KeyValuePair<string, List<Ruta>> nodoConexionActual;
listaFrontera.Add(new Nodo()
Heuristica = heuristica.First(h => h.Key == estadoInicial).Value
while (!seEncontroElObjetivo)
Nodo nodoActual = listaFrontera.First();
nodoConexionActual = conexiones.First(conexion => conexion.Key == nodoActual.Datos);
listaFrontera.Remove(listaFrontera.First(nodo => nodo.Datos == nodoActual.Datos));
if (nodoActual.Datos != estadoObjetivo)
listaVisitados.Add(nodoActual);
nodoActual.SetHijos(nodoConexionActual.Value, heuristica);
foreach (var hijo in nodoActual.Hijos)
if (!EstaEnLista(listaVisitados, hijo))
var nodoEnFrontera = ObtenerNodo(listaFrontera, hijo);
if(nodoEnFrontera != null){
if (SePuedeAgregarElNodo(nodoEnFrontera, hijo, tipoBusqueda)){
listaFrontera.Remove(nodoEnFrontera);
listaFrontera = ObtenerListaOrdenada(tipoBusqueda, listaFrontera);
seEncontroElObjetivo = true;
caminoSolucion = ObtenerCaminoSolucion(listaVisitados, nodoActual);
Console.WriteLine("Camino solución desde " + estadoInicial + " hacia " + estadoObjetivo + ": " + caminoSolucion);
public static bool SePuedeAgregarElNodo(Nodo nodoEnFrontera, Nodo nodoActual, TipoBusqueda tipoBusqueda){
bool sePuedeAgregar = false;
case TipoBusqueda.AEstrella:
var evaluacionEstrellaFrontera = nodoEnFrontera.Costo + nodoEnFrontera.Heuristica;
var evaluacionEstrellaNodo = nodoActual.Costo + nodoActual.Heuristica;
if(evaluacionEstrellaFrontera > evaluacionEstrellaNodo){
var evaluacionAvaraFrontera = nodoEnFrontera.Heuristica;
var evaluacionAvaraNodo = nodoActual.Heuristica;
if(evaluacionAvaraFrontera > evaluacionAvaraNodo){
public static string ObtenerCaminoSolucion(List<Nodo> listaVisitados, Nodo nodoObjetivo)
List<string> camino = new List<String>();
string caminoSolucion = "";
Nodo nodoActual = nodoObjetivo;
while (nodoActual.Padre != null)
camino.Add(nodoActual.Datos);
nodoActual = nodoActual.Padre;
camino.Add(nodoActual.Datos);
foreach (var paso in camino)
caminoSolucion += "[" + paso + "] ";
return caminoSolucion + " - Costo: " + nodoObjetivo.Costo;
public static Nodo ObtenerNodo(List<Nodo> lista, Nodo nodo)
return lista.FirstOrDefault(n => n.Datos == nodo.Datos);
public static bool EstaEnLista(List<Nodo> lista, Nodo nodo)
return lista.Any(n => n.Datos == nodo.Datos);
public static List<Nodo> ObtenerListaOrdenada(TipoBusqueda tipoBusqueda, List<Nodo> listaFrontera)
List<Nodo> nuevaListaFrontera = new List<Nodo>();
case TipoBusqueda.AEstrella:
nuevaListaFrontera = listaFrontera.OrderBy(n => { return n.Heuristica + n.Costo; }).ToList();
nuevaListaFrontera = listaFrontera.OrderBy(n => n.Heuristica).ToList();
return nuevaListaFrontera;
public static void CargarHeuristica()
heuristica = new Dictionary<string, int>();
public static void CargarConexiones()
conexiones = new Dictionary<string, List<Ruta>>();
AgregarConexion("A", "B", 10);
AgregarConexion("A", "E", 40);
AgregarConexion("B", "E", 20);
AgregarConexion("D", "C", 5);
AgregarConexion("D", "E", 10);
AgregarConexion("F", "A", 10);
AgregarConexion("F", "B", 30);
AgregarConexion("F", "G", 10);
AgregarConexion("F", "H", 20);
AgregarConexion("G", "B", 20);
AgregarConexion("G", "D", 10);
AgregarConexion("H", "E", 10);
Console.WriteLine(ImprimirListaNodosYConexiones(conexiones));
public static void AgregarConexion(string origen, string destino, int distancia)
var nodoOrigen = conexiones.Where(n => n.Key == origen).FirstOrDefault();
if (nodoOrigen.Key != null)
nodoOrigen.Value.Add(new Ruta(destino, distancia));
var listaNodos = new List<Ruta>();
listaNodos.Add(new Ruta(destino, distancia));
conexiones.Add(origen, listaNodos);
var nodoDestino = conexiones.Where(n => n.Key == destino).FirstOrDefault();
if (nodoDestino.Key != null)
nodoDestino.Value.Add(new Ruta(origen, distancia));
var listaNodos = new List<Ruta>();
listaNodos.Add(new Ruta(origen, distancia));
conexiones.Add(destino, listaNodos);
public static string ImprimirListaNodosYConexiones(Dictionary<string, List<Ruta>> conexiones)
string lista = "Caminos => ";
foreach (var conexion in conexiones)
lista = lista + "\nDesde " + conexion.Key + ":\n";
foreach (var ruta in conexion.Value)
lista = lista + ruta.destino + " - " + ruta.distancia + " // ";