public static AristaGrafo[] ViajanteDeComercio(Grafo G, int vertice) { Conjunto <int> V = new Conjunto <int>(); /*Conjunto donde se guardan todos los vertices del grafo*/ Conjunto <int> T = new Conjunto <int>(); /*Conjunto donde se guardan los vertices que hemos ido recorriendo*/ AristaGrafo[] Arista = new AristaGrafo[G.get_Vertices()]; /*array de aristas */ int[] grado = new int[G.get_Vertices()]; /*array para poder controlar y modificar los grados de los vertices que visitamos*/ int j = 0; int u = vertice; /*Inicializa el conjunto V con todos los vertices del grafo G*/ for (int i = 0; i < G.get_Vertices(); i++) { V.Inserta(i); } /*Inicializamos los grados*/ for (int k = 0; k < grado.GetLength(0); k++) { grado[k] = 0; } /*Inicializa el conjunto T con el vertice de partida*/ T.Inserta(vertice); /*Guardamos los vertices que aun no hemos visitado*/ Conjunto <int> W = V.Diferencia(T); /*Mientras no hayamos recorrido todos los verticces*/ while (!T.EsIgual(V)) { Arista[j] = AristaCosteMinimo(u, W, G.get_Aristas(), grado); /*obtenemos la arista de coste minimo*/ T.Inserta(Arista[j].get_Destino()); /*Actualiza el conjunto T, anyadimos el vertice que hemos visitado*/ W.Elimina(Arista[j].get_Destino()); /*Actualiza el conjunto W, eliminamos el vertice que hemos visitado*/ u = Arista[j].get_Destino(); /*actualizamos u con el siguiente punto a analizar*/ grado[Arista[j].get_Origen()]++; /*Actualizamos el grado*/ grado[Arista[j].get_Destino()]++; /*Actualizamos el grado*/ j++; } /*anyadimos la ultima arista, la que vuelve*/ Arista[j] = new AristaGrafo(Arista[j - 1].get_Destino(), vertice, G.Coste(Arista[j - 1].get_Destino(), vertice)); grado[vertice]++; /*actualizamos el grado*/ grado[Arista[j - 1].get_Destino()]++; /*Actualiza el grado*/ T.Inserta(Arista[j].get_Destino()); /*anyadimos el origen al conjunto, ya que es la vuelt*/ return(Arista); /*Se devuelve el array de AristaGrafo*/ }
/* Funcion: ViajanteComercioMasProximo * Descripcion: Hallar el recorrido a traves de un grafo y un punto de partida * moviendose unicamente a traves de las aristas de coste minimo * Parametros: Grafo G, grafo con el que vamos a trabajar * int vertice: variable de tipo int que va a marcara el pnto de partida * Salida: Un array AristaGrafo en que se han ido guardando las aristas de coste minimo */ public static AristaGrafo[] ViajanteComercioVecinoMasProximo(Grafo G, int vertice) { Conjunto <int> V = new Conjunto <int>(); /*Conjunto que guarda todos los vertices del grafo*/ Conjunto <int> T = new Conjunto <int>(); /*Conjunto donde se guardan los vertinces que hemos recorrido en ese orden*/ AristaGrafo[] Arista = new AristaGrafo[G.get_Vertices()]; /*array de aristas, es la solucion del problema*/ int j = 0; /*variable que marca la posicion donde se va a guardar las aristas dentro del array*/ int u = vertice; /*Inicializa el conjunto V con todos los vertices del grafo G*/ for (int i = 0; i < G.get_Vertices(); i++) { V.Inserta(i); } /*Inicializa el conjunto T con el vertice de partida*/ T.Inserta(vertice); /*Conjunto donde se almacenan los vertices aun no visitados*/ Conjunto <int> W = V.Diferencia(T); /*Mientras no hayamos visitado todos los vertices del grafo*/ while (!T.EsIgual(V)) { Arista[j] = AristaCosteMinimo(u, W, G.get_Aristas()); /*Obtenemos la arista de coste minimo*/ T.Inserta(Arista[j].get_Destino()); /*Actualizamos el conjunto T*/ W.Elimina(Arista[j].get_Destino()); /*Actualizamos el conjunto W*/ u = Arista[j].get_Destino(); /*Actualizamos el siguiente punto analizar*/ j++; /*actualizamos la variable que indica la posicion del array de nuestras aristas, solucion*/ } /*Colocamos el ultimo punto visitado con el origen para dar la vuelta*/ Arista[j] = new AristaGrafo(Arista[j - 1].get_Destino(), vertice, G.Coste(Arista[j - 1].get_Destino(), vertice)); T.Inserta(Arista[j].get_Destino()); /*Actualizamos el conjunto de vertices que recorremos*/ return(Arista); /*Se devuelve el array de AristaGrafo*/ }
/* Funcion: AristaCosteMinimo * Descripcion: Dado un vertice, un conjunto y la matriz de adyacencia, encontrar la arista que une el vertice * con un elemento del conjunto que tenga la arista de coste minimo * Parametros: int u: varia de tipo int que guarda el origen * Conjunto<int> W: Conjunto de vertices que aun no hemos recorrido * int [,] aristas: matriz de adyacencia * Salida: Una variable de tipo AristaCosteMinimo donde u, es el origen, elemento de W es el destino y el coste de la * arista de coste minimo. */ public static AristaGrafo AristaCosteMinimo(int u, Conjunto <int> W, int [,] aristas) { /*buscar dentro de la matriz de aristas*/ AristaGrafo arista = new AristaGrafo(9999, 9999, 9999); /*Inicializo la arista*/ int j = 0; for (int i = 0; i < W.Elementos(); i++) /*numero de vueltas que tengo que dar para comprobar todos*/ { while (W.Contiene(j) == false) /*encuentro el elemento*/ { j++; } if (arista.get_Coste() > aristas[u, j]) /*modifico la arista en caso de ecnontrar alguna que tenga un coste mas pequenyo*/ { arista.set_Coste(aristas[u, j]); /*actualizo el coste de la arista*/ arista.set_Origen(u); /*actualizo el origen de la arista*/ arista.set_Destino(j); /*actualizo el destino de la arista*/ } j++; /*actualizo la variable que marca el elemento*/ } return(arista); /*se devuelve la arista*/ }
/* Funcion: AristaCosteMinimo * Descripcion: a traves de un vertice, el conjunto de vertices que aun no hemos visitado, la matriz de adyacencia para poder * acceder a los costes de las aristas y el array de grados de cada vertice. Obtenemos la arista de coste minimo * y que el vertice destino no tenga un grado mayor de dos * Parametros: int u: variable de tipo int que guarda el origen * Conjunto<int> W: Conjunto de vertices que aun no hemos recorrido * int[,] aristas: matriz de adyacendia * int [] grado: array de que guarda los grados de los vertices * */ public static AristaGrafo AristaCosteMinimo(int u, Conjunto <int> W, int[,] aristas, int[] grado) { /*buscar dentro de la matriz de aristas*/ AristaGrafo arista = new AristaGrafo(9999, 9999, 9999); int j = 0; for (int i = 0; i < W.Elementos(); i++) /*Buscamos todas las posibles soluciones*/ { while (W.Contiene(j) == false) /*buscamos el elemento*/ { j++; } if (arista.get_Coste() > aristas[u, j] && grado[j] < 2) /*Comparamos el coste y el grado del vertice*/ { arista.set_Coste(aristas[u, j]); /*actualizamos el coste de la arista*/ arista.set_Origen(u); /*actualizamos el origen de la arista*/ arista.set_Destino(j); /*actualizamos el destino de la arista*/ } j++; /*actualizamos la posisicon para poder seguir buscando elementos*/ } return(arista); /*se devuelve la arista*/ }
public static AristaGrafo[] ViajanteDeComercio(Grafo G, ref AristaGrafo[] todas_aristas) { IList <AristaGrafo> lista_aristas = new List <AristaGrafo>(); for (int i = 0; i < todas_aristas.GetLength(0); i++) { lista_aristas.Add(todas_aristas[i]); } ColaPrioridad <AristaGrafo> cola = new ColaPrioridad <AristaGrafo>(); for (int i = 0; i < todas_aristas.GetLength(0); i++) { cola.Inserta(todas_aristas[i].get_Coste(), todas_aristas[i]); } for (int i = 0; i < cola.prioridad.Count(); i++) { cola.IntercambioDescendente(i); } for (int i = 0; i < cola.prioridad.Count(); i++) { cola.IntercambioAscendente(i, i + 1); } Conjunto <int>[] bosque = new Conjunto <int> [G.get_Vertices()]; // Inicializamos un array de conjuntos que sera nuestro bosque de arboles for (int i = 0; i < G.get_Vertices(); i++) { bosque[i] = new Conjunto <int>(); } for (int i = 0; i < G.get_Vertices(); i++) // Insertamos los vertices dentro del array { bosque[i].Inserta(i); } AristaGrafo arista = new AristaGrafo(); AristaGrafo[] resul_arista = new AristaGrafo[G.get_Vertices()]; int[] grado_vertices = new int[G.get_Vertices()]; for (int i = 0; i < grado_vertices.GetLength(0); i++) { grado_vertices[i] = 0; } int p = 0; /* * AristaGrafo arista_vuelta = new AristaGrafo(); */ bool completado = false; while (completado == false) { arista = cola.ElmininaMinimo(); /* * arista_vuelta.set_Origen(arista.get_Destino()); * arista_vuelta.set_Destino(arista.get_Origen()); * arista_vuelta.set_Coste(arista.get_Coste()); * * cola.EliminaporArista(arista_vuelta); */ for (int i = 0; i < cola.prioridad.Count(); i++) { cola.IntercambioDescendente(i); } for (int i = 0; i < cola.prioridad.Count(); i++) { cola.IntercambioAscendente(i, i + 1); } if ((grado_vertices[arista.get_Origen()] < 2) && (grado_vertices[arista.get_Destino()] < 2)) { //if (!(bosque[arista.get_Origen()].Contiene(arista.get_Destino())) && !(bosque[arista.get_Destino()].Contiene(arista.get_Origen())) && bosque[arista.get_Destino()].Elementos() > 0) // if(bosque[arista.get_Origen()].Elementos() > 0 || bosque[arista.get_Destino()].Elementos() > 0) // { if (bosque[arista.get_Origen()].Elementos() == 0) { Conjunto <int> aux = new Conjunto <int>(); int posicion_aux = 0; for (posicion_aux = 0; posicion_aux < bosque.GetLength(0) && !bosque[posicion_aux].Contiene(arista.get_Origen()); posicion_aux++) { aux = bosque[posicion_aux + 1]; } if (!aux.Contiene(arista.get_Destino())) { grado_vertices[arista.get_Origen()]++; grado_vertices[arista.get_Destino()]++; bosque[posicion_aux].Une(aux); bosque[arista.get_Origen()].Inicializa(); resul_arista[p] = arista; p++; } } else if (bosque[arista.get_Destino()].Elementos() == 0) { Conjunto <int> aux = new Conjunto <int>(); int posicion = 0; for (posicion = 0; posicion < bosque.GetLength(0) && !bosque[posicion].Contiene(arista.get_Destino()); posicion++) { aux = bosque[posicion + 1]; } if (!aux.Contiene(arista.get_Origen())) { grado_vertices[arista.get_Origen()]++; grado_vertices[arista.get_Destino()]++; bosque[arista.get_Origen()].Une(aux); bosque[posicion].Inicializa(); resul_arista[p] = arista; p++; } } else { grado_vertices[arista.get_Origen()]++; grado_vertices[arista.get_Destino()]++; bosque[arista.get_Origen()].Une(bosque[arista.get_Destino()]); bosque[arista.get_Destino()].Inicializa(); resul_arista[p] = arista; p++; } // } } completado = true; for (int j = 0; j < grado_vertices.GetLength(0) && completado == true; j++) // recorre todo el vector de los grados de los vertices y si todos tienen grado dos ya esta completado { if (grado_vertices[j] != 2) { completado = false; } } if (cola.prioridad.Count() == 0) { completado = true; } } return(resul_arista); }