Foros del Web » Programación para mayores de 30 ;) » C/C++ »

circuito hamiltoniano

Estas en el tema de circuito hamiltoniano en el foro de C/C++ en Foros del Web. hola, mi proyecto trata sobre un parque de atracciones en las cuales se almacenan en un arreglo por nivel de diversion entre mas novel de ...
  #1 (permalink)  
Antiguo 21/05/2015, 18:47
 
Fecha de Ingreso: febrero-2015
Mensajes: 20
Antigüedad: 9 años, 9 meses
Puntos: 0
circuito hamiltoniano

hola, mi proyecto trata sobre un parque de atracciones en las cuales se almacenan en un arreglo por nivel de diversion entre mas novel de diversion tengan iran primero , bueno cree mi matriz de bool que pondra todo en falso , despues creo otros dos for que iran hasta h-1 ya que h es la cantidad de aristas o caminos que se conectaran con cada atraccion (que solo puede ser recorrida una sola vez ) entonces dentro de esos for pongo que lea las coordenadas X y Y, y y entonces mi matriz [i][j] =matriz[j][i] = true , pero no se como hacer para validar los caminos, osea supongan que tengo esto:

0 1
2 1
0 2

entonces como son simetricas las coordenadas entonces hay dos circuitos 0120 y 0210 pero no se como hago o que funcion hacer para que halle la transitividad y vea si hay circuito hamiltoniano
por favor podrian ayudarme con eso

Código C++:
Ver original
  1. #include <iostream>
  2. #include <string>
  3. using namespace std;
  4.  
  5. class atraccion {
  6.     private:
  7.     int x;
  8.     string name;
  9.     public:
  10.    
  11.     atraccion () {}
  12.     atraccion (int var, string nnombre){
  13.         x=var;
  14.         name = nnombre;
  15.     }
  16.     ~atraccion() {}
  17.    
  18.     void set_x (int val) {              //modifica el x
  19.         x = val;
  20.     }
  21.    
  22.     int get_x () {                      //devuelve el x
  23.         return x;
  24.     }
  25.    
  26.     void set_name ( string nom) {           //modifica el nombre
  27.         name =nom;
  28.     }
  29.    
  30.     string get_name () {                    //devuelve el nombre
  31.         return name;
  32.     }
  33. };
  34.  
  35.  
  36.  
  37. int main (){
  38.     int m, n, h,div;
  39.     int posmayor,mayor;
  40.     bool mat[10][10];
  41.     int x,y;
  42.     string nombre;
  43.     atraccion intercambio;
  44.    
  45.     cin>>m>>n>>h;
  46.    
  47.     atraccion ar [m];       //arreglo que almacena cada atraccion
  48.    
  49.         for (int i=0;i<m;i++) {
  50.             cin>>nombre;
  51.             cin>>div;
  52.             ar[i].set_name(nombre);
  53.             ar[i].set_x (div);
  54.         }
  55.        
  56.         for( int g=0;g<10;g++){             //matriz de adyacencia
  57.             for (int f=0;f<10;f++){
  58.             mat[g][f] =false;
  59.         }
  60.         }
  61.        
  62.         for (int d=0;d<=h-1;d++){           //marca true
  63.             for (int e=0;e<=h-1;d++){
  64.                 cin>>x>>y;
  65.                 d=x;
  66.                 e=y;
  67.                 mat[d][e] =mat[e][d]= true;
  68.             }
  69.         }
  70.        
  71.         for (int w=0;w<=m-2;w++){               //ordenamiento //modelo 2
  72.             posmayor = w;
  73.             mayor = ar[w].get_x();
  74.             for (int k=w+1; k<=m-1; k++){
  75.                 if ((ar[k].get_x() == mayor) && (ar[k].get_name () < ar[w].get_name())){
  76.                     mayor= ar[k];
  77.                     posmayor=k;
  78.                 }else{
  79.                 if (ar[k].get_x() > mayor) {
  80.                     mayor = ar[k].get_x();
  81.                     posmayor =k;
  82.                     }
  83.                 }
  84.             }
  85.            
  86.             intercambio = ar[posmayor];     //se encarga de cambiarlos
  87.             ar[posmayor] =ar[w];
  88.             ar[w] = intercambio;
  89.         }
  90.        
  91.         for (int j=0;j<n;j++) {
  92.             cout<<ar[j].get_name()<<endl;
  93.         }
  94.        
  95.        
  96.     return 0;
  97. }
  #2 (permalink)  
Antiguo 22/05/2015, 00:50
Avatar de xKuZz  
Fecha de Ingreso: febrero-2015
Ubicación: nullptr
Mensajes: 183
Antigüedad: 9 años, 9 meses
Puntos: 27
Respuesta: circuito hamiltoniano

Lo primero toda matriz de adyacencia es cuadrada y simétrica. Supón que tenemos 3 atracciones y la siguiente matriz de adyacencia:
atrac1 atrac2 atrac3
atrac1 0 1 1
atrac2 1 0 1
atrac3 1 1 0

Entonces imagino que habrás tomado como vértices a cada atracción.
Un ciclo (o camino) de Hamilton es aquel que va desde un vértice hasta el mismo pasando por ellos una sóla vez. Para validar un camino puedes por ejemplo crear un array de ints con tantas posiciones como atracciones haya y cada vez que avances en el camino hacia el siguiente vértice pones un 1. Si al final del camino has vuelto al vértice del principio y todo son 1 era un ciclo de Hamilton.
  #3 (permalink)  
Antiguo 22/05/2015, 04:37
 
Fecha de Ingreso: febrero-2015
Mensajes: 20
Antigüedad: 9 años, 9 meses
Puntos: 0
Respuesta: circuito hamiltoniano

exacto, yo se eso, mis atracciones eran mis vertices y las aristas mis caminos y entnces tengo que ver si hay circuito y si lo hay mostrarlo, y ya tengo mi matriz pero osea partiendo de los fors que hice para llenarla no se como puedo hacer la funcion o accion que me diga si hay circuito hamiltoniano ya que tengo que hacer backtraking con eso, ese seria el backtracking no? ver si hay circuito y el mismo backtracking tambien me sacaria cuales son los caminos

Entrada
6 2 3 CarritosCho Mon_rusa
La_Noria 12 POSIBLE
Mon_rusa 20 Entrada CarritosCho Mon_rusa Entrada
CarritosCho 100 Entrada Mon_rusa CarritosCho Entrada
Silla_Voladora 15
El_gusanito 1
Casa_Terror 13
0 1
0 2
1 2


Salida
6 2 3 CarritosCho Mon_rusa
La_Noria 12 POSIBLE
Mon_rusa 20 Entrada CarritosCho Mon_rusa Entrada
CarritosCho 100 Entrada Mon_rusa CarritosCho Entrada
  #4 (permalink)  
Antiguo 22/05/2015, 06:58
Avatar de xKuZz  
Fecha de Ingreso: febrero-2015
Ubicación: nullptr
Mensajes: 183
Antigüedad: 9 años, 9 meses
Puntos: 27
Respuesta: circuito hamiltoniano

Claro, comprobar que es de Hamilton implica probar todos los caminos posibles y si uno es de Hamilton pues sacas la matriz de adyacencia de dicho camino.
Aquí te deja una explicación muy buena (eso sí, está en inglés) de cómo implementar la matriz de adyacencia de tu grafo hamiltoniano.
http://www.geeksforgeeks.org/backtra...ltonian-cycle/
  #5 (permalink)  
Antiguo 22/05/2015, 14:24
 
Fecha de Ingreso: febrero-2015
Mensajes: 20
Antigüedad: 9 años, 9 meses
Puntos: 0
Respuesta: circuito hamiltoniano

hola, ya cree mas o menos mi bactracking aqui esta pero tengo ciertas dudas ya que en una parte no se como desarrollarla y eso.

primero asi seria la entrada:

6 2 3

noria 12
mon_rusa 20
carritosCHO 100
silla_voladora 15
gusanito 1
casa_terror 13
0 1
2 1
0 2

y la salida es:

CarritosCho Mon_rusa
POSIBLE
Entrada CarritosCho Mon_rusa Entrada
Entrada Mon_rusa CarritosCho Entrada

entonces bueno me arroga un error y que por lo menos antes de hacer el backtracking, estaba entrando los datos y cuando llegue a las aristas ( h ) ya habia introducido 01 21 02 pero no hacia nada entonces llene y llene hasta que me leyo otras 3 coordenadas X y otras 3 Y mas las que ya habia hecho, me lee el doble,

bueno el asunto es que en el backtracking guarde en sol las j de la matriz de adyacencia ya que me indicaria los caminos pero creo que aparte me guarde el 0 del final que me permite ver si hay circuito o no, pero despues queria llamar a imrpimir para imrpimir los nombre que me mostrarian el circuito hamiltoniano pero ahi me tranque no supo como avanzar

Código C++:
Ver original
  1. #include <iostream>
  2. #include <string>
  3. using namespace std;
  4.  
  5. class atraccion {
  6.     private:
  7.     int x;
  8.     string name;
  9.     public:
  10.    
  11.     atraccion () {}
  12.     atraccion (int var, string nnombre){
  13.         x=var;
  14.         name = nnombre;
  15.     }
  16.     ~atraccion() {}
  17.    
  18.     void set_x (int val) {              //modifica el x
  19.         x = val;
  20.     }
  21.    
  22.     int get_x () {                      //devuelve el x
  23.         return x;
  24.     }
  25.    
  26.     void set_name ( string nom) {           //modifica el nombre
  27.         name =nom;
  28.     }
  29.    
  30.     string get_name () {                    //devuelve el nombre
  31.         return name;
  32.     }
  33. };
  34.  
  35. void imprimir (int path [], int arcos){
  36.     cout<<"Entrada"<<" ";                                 //aqui muestro los caminos para pasar por las atracciones que van de entrada hasta otra vez la entrada
  37.                                                                                      
  38. }
  39.  
  40. void back (int i, int j, bool array[10][10],int camino[],int acum=0 , int arist){
  41.    
  42.     if((j==0) && (acum= arist-1)){
  43.         cout<<"POSIBLE"<<endl;
  44.         imprimir (camino, arist);
  45.     }else{
  46.      if (array[i][j] == true ){
  47.         for (int x=0;x<10;x++){
  48.             int p=j;
  49.             camino[x]=j;
  50.             array[i][j] = array[j][i]=false;
  51.             acum=acum+1;
  52.             back (i=p, j=0, array, camino, acum, arist);
  53.            
  54.             camino[x] = ' ';                //desmarco y deshago mu solucion
  55.             acum= acum-1;               //desmarco y deshago mi solucion
  56.            
  57.         }
  58.                
  59.     }else{
  60.         back(i,j++,array,camino, acum,arist);           //busco otra solucion
  61. }
  62.         cout<< "IMPOSIBLE"<<endl;  
  63. }
  64. }
  65.  
  66. int main (){
  67.     int m, n, h,div;
  68.     int posmayor,mayor;
  69.     bool mat[10][10];
  70.     int x,y;
  71.     string nombre;
  72.     atraccion intercambio;
  73.     int r=0,s=0,t=0;
  74.    
  75.     cin>>m>>n>>h;
  76.    
  77.     int sol[h];
  78.     atraccion ar [m];       //arreglo que almacena cada atraccion
  79.    
  80.         for (int i=0;i<m;i++) {
  81.             cin>>nombre;
  82.             cin>>div;
  83.             ar[i].set_name(nombre);
  84.             ar[i].set_x (div);
  85.         }
  86.        
  87.         for( int g=0;g<10;g++){             //matriz de adyacencia
  88.             for (int f=0;f<10;f++){
  89.             mat[g][f] =false;
  90.         }
  91.         }
  92.        
  93.         for (int d=0;d<=h-1;d++){           //marca true
  94.             for (int e=0;e<=h-1;d++){
  95.                 cin>>x>>y;
  96.                 d=x;
  97.                 e=y;
  98.                 mat[d][e] =mat[e][d]= true;
  99.             }
  100.         }
  101.        
  102.         for (int w=0;w<=m-2;w++){               //ordenamiento //modelo 2
  103.             posmayor = w;
  104.             mayor = ar[w].get_x();
  105.             for (int k=w+1; k<=m-1; k++){
  106.                 /*if ((ar[k].get_x() == mayor) && (ar[k].get_name () < ar[w].get_name())){
  107.                     mayor= ar[k];
  108.                     posmayor=k;
  109.                 }else{*/
  110.                 if (ar[k].get_x() > mayor) {
  111.                     mayor = ar[k].get_x();
  112.                     posmayor =k;
  113.                     }
  114.                 //}
  115.             }
  116.            
  117.             intercambio = ar[posmayor];     //se encarga de cambiarlos
  118.             ar[posmayor] =ar[w];
  119.             ar[w] = intercambio;
  120.         }
  121.        
  122.         for (int j=0;j<n;j++) {             //imprime populares
  123.             cout<<ar[j].get_name()<<endl;
  124.         }
  125.        
  126.         for (int u=0;u<10;u++) {                //imprime booleana
  127.             for(int v=0;v<10;v++){
  128.             cout<<mat[u][v];
  129.         }
  130.     }
  131.         back(r, s, mat, sol, t , n);
  132.        
  133.     return 0;
  134. }

Última edición por jose_27; 22/05/2015 a las 15:41
  #6 (permalink)  
Antiguo 22/05/2015, 15:49
Avatar de xKuZz  
Fecha de Ingreso: febrero-2015
Ubicación: nullptr
Mensajes: 183
Antigüedad: 9 años, 9 meses
Puntos: 27
Respuesta: circuito hamiltoniano

Tu problema con leer radica en qué tu bucle de leer tienes unas condiciones bastante extrañas y es lógico que no lea bien las aristas. Aquí te lo dejo ya solucionado.

Código C++:
Ver original
  1. for (int d=0;d<=h-1;d++){           // Cojo de pareja en pareja de vértices conexos hasta que no haya más aristas
  2.         cin >> x >> y;     // Leo la pareja
  3.         mat[x][y]=mat[y][x]=true; // Guardo el dato en la matriz de adyacencia
  4.  
  5.         }

La función de Hamilton la he probado y en todos los ejemplos que he puesto me sale como posible así que ahora si tengo tiempo la miraré con más detenimiento.

Un saludo.
  #7 (permalink)  
Antiguo 22/05/2015, 16:16
 
Fecha de Ingreso: febrero-2015
Mensajes: 20
Antigüedad: 9 años, 9 meses
Puntos: 0
Respuesta: circuito hamiltoniano

gracias, justamente un amigo mio hace 15 minutos me dijo eso y estaba por hacerlo y si ambos tenian razon gracias ahora si me da.

bueno revisare mi codigo y probare en una hoja un par de corridas haber si logro cambiarlo, lo que pasa es que hasta hoy puedo entregarlo y es hasta las 12 de la noche y aqui en mi pais con las 6 asi que no me queda mucho tiempo, pero te agradezco por seguirme ayudando y mas que ya casi termino este codigo :) .
  #8 (permalink)  
Antiguo 22/05/2015, 17:05
Avatar de xKuZz  
Fecha de Ingreso: febrero-2015
Ubicación: nullptr
Mensajes: 183
Antigüedad: 9 años, 9 meses
Puntos: 27
Respuesta: circuito hamiltoniano

Te recomiendo que empieces de 0 la parte del circuito hamiltoniano. Creo que no has entendido muy bien el algoritmo para implementarlo. Ya que te urge y yo necesito ya irme a dormir te voy a dejar un código que hice hace un tiempo que resuelve ese algoritmo y en el que está aplicando todo al detalle (creo). Ten en cuenta que copiar y pegar no te va a servir porque utilizo cosas como los vectores de la STL, algoritmos de la STL y funciones lambda de C++11 que estaba empezando a utilizar por aquel entonces. Utilízalo como referencia y adáptalo a las cosas que tu estás utilizando. Mucha suerte.

Código C++:
Ver original
  1. /* @file: ciclohamilton.cpp
  2.    @brief: Comprueba si hay un ciclo de Hamilton en el grafo por fuerza bruta.
  3.            El grafo viene representado por la matriz de adyacencia
  4.    @author: xKuZz
  5. */
  6.  
  7. #include <algorithm>
  8. #include <iostream>
  9. #include <vector>
  10.  
  11. using namespace std;
  12.  
  13. typedef vector < vector <int> > int_2;
  14.  
  15. bool usar(const int &vertice, const int_2 &grafo, const vector<int> &camino, const int &posicion){
  16.     // CUMPLIR LAS DOS CONDICIONES SIGUIENTES IMPLICA QUE ES UN POSIBLE VÉRTICE SIGUIENTE EN EL CAMINO
  17.     bool USAR=true;
  18.    // Compruebo que el vértice sea adyacente al anterior
  19.     if (grafo[camino[posicion-1]][vertice]==0)
  20.         USAR=false;
  21.    // Si es adyacente compruebo también que no esté en el camino utilizado
  22.     for_each(camino.begin(),camino.end(),[&](int i=0){if (camino[i]==vertice) USAR=false;});
  23.     return USAR;
  24. }
  25.  
  26. bool HamiltonRecursivo(const int_2 &grafo, vector<int> &camino, const int &posicion){
  27.    // ESTA ES UNA MANERA RECURSIVA DE COMPROBAR QUE UN CAMINO ES DE HAMILTON
  28.     bool hamiltoniano=false;
  29.  
  30.     // CASO FINAL: si posición es igual al tamaño del vector camino
  31.  
  32.     if (posicion==camino.size())
  33.         hamiltoniano=grafo[camino[posicion-1]][0]; // Devuelvo si adyacen o no el principio y el final del ciclo
  34.  
  35.     else { // CASO NO FINAL
  36.  
  37.         // IMPLEMENTACIÓN RECURSIVA: PROBAMOS TODOS LOS VÉRTICES MENOS EL 0 ya que lo hemos considerado el inicial
  38.         for (int v=1; v < camino.size(); v++){
  39.        
  40.         // UTILIZO LA FUNCIÓN PARA COMPROBAR EL VÉRTICE
  41.                 if (usar(v, grafo, camino, posicion)){
  42.  
  43.                         camino[posicion] = v; // METO EL VÉRTICE SI LA COMPROBACIÓN ES CORRECTA
  44.  
  45.                         // UTILIZO ESTA FUNCIÓN EN RECURRENCIA PARA AVERIGUAR EL RESTO DEL CAMINO
  46.                         if(HamiltonRecursivo (grafo, camino, posicion+1))
  47.                     return true;
  48.  
  49.                     // SI EL VERTICE NO ME LLEVA HACIA LA SOLUCIÓN PONGO UN -1 PARA INDICARLO
  50.                             camino[posicion] = -1;
  51.             }
  52.             }
  53.         }
  54.            
  55.     return hamiltoniano;   
  56.        
  57. }
  58.  
  59. bool CicloHamilton(vector<int> &sol, const int_2 &grafo){
  60.     // Sol es el camino solución obtenido
  61.     // Devuelve TRUE si hay ciclo de Hamilton
  62.     // Dicho ciclo de Hamilton se guarda en el vector sol
  63.    
  64.     // DIMENSIONO LA MATRIZ PARA ALMACENAR EL CAMINO
  65.     sol.resize(grafo.size());
  66.     // RELLENO LA MATRIZ DE -1
  67.     fill(sol.begin(),sol.end(),-1);
  68.     // El primer dato será un 0
  69.     sol[0]=0;
  70.  
  71.     // LLAMO AL MÉTODO RECURSIVO
  72.     if (!HamiltonRecursivo(grafo, sol, 1))
  73.         {
  74.             cout << "No hay solución";
  75.             return false;
  76.     }
  77.     else{
  78.         cout << "Existe solución";
  79.         // SACO LA SOLUCIÓN DE MI CAMINO (MUESTRO CADA VALOR DEL VECTOR)   
  80.         for_each(sol.begin(),sol.end(),[&](int i=0){cout << "-> " << sol[i];});
  81.         cout << endl;
  82.         return true;
  83.     }
  84. }
  85.  
  86.  
  87.  
  88.  
  89. int main(){ // COMPROBACIONES
  90. vector<int> solucion;
  91. int_2 grafin;
  92. grafin.resize(3,vector<int>(3));
  93. cout << "PRIMER GRAFO: TIENE QUE SALIR DE HAMILTON\n";
  94. grafin[0][0]=0; grafin[0][1]=1; grafin [0][2]=1;
  95. grafin[1][0]=1; grafin[1][1]=0; grafin [1][2]=1;
  96. grafin[2][0]=1; grafin[2][1]=1; grafin [2][2]=0;
  97. CicloHamilton(solucion,grafin);
  98. cout << "SEGUNDO GRAFO: NO TIENE QUE SALIR DE HAMILTON\n";
  99. grafin[0][0]=0; grafin[0][1]=0; grafin [0][2]=0;
  100. grafin[1][0]=0; grafin[1][1]=0; grafin [1][2]=0;
  101. grafin[2][0]=0; grafin[2][1]=0; grafin [2][2]=1;
  102. CicloHamilton(solucion,grafin);
  103. }
  #9 (permalink)  
Antiguo 22/05/2015, 17:19
 
Fecha de Ingreso: febrero-2015
Mensajes: 20
Antigüedad: 9 años, 9 meses
Puntos: 0
Respuesta: circuito hamiltoniano

muchas garcias por esa guia, bueno mas o menos esta igual no se por que falla mi backtracking... lamento sonar como una carga, espero que la pases bien saludos.

Etiquetas: matriz
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 13:38.