Anuncio

Colapsar
No hay ningún anuncio todavía.

¿Cómo se podría crear un algoritmo/programa para esta aplicación?

Colapsar
X
 
  • Filtro
  • Hora
  • Mostrar
Borrar todo
nuevos mensajes

  • Programación ¿Cómo se podría crear un algoritmo/programa para esta aplicación?

    Hola amigos, llevo casi 2 semanas intentando programar lo siguiente, pero he conseguido nulos o casi-nulos resultados. Lo que quiero es lo siguiente.

    Imaginen una matriz de 10x5, con todas sus con números del 1 al 49, sin repetir ningún número (con su primera entrada nula), y ordenada por columnas (ver ejemplo más abajo). Se tiene un vector (v) con 6 números al azar de esta matriz. Yo deseo saber, de estos 6 elementos, cuántos de ellos son colindantes.

    Dos elementos son colindantes cuando se "están tocando" entre sí, pongo un ejemplo con una matriz más pequeña (este ejemplo NO cumple con el requisito de entrada (1,1) nula)



    Si mi vector es , se puede observar que los números 1,7 y 8 son colindantes entre sí, porque "se tocan" en la matriz. Por tanto tengo 1 grupo de 3 colindantes; a parte, el 16 y 17 forman un segundo grupo de 2 colindantes; por último, el número 20 no es colindante (se dice que forma un grupo de 1 "número suelto")

    Por tanto mi programa debería devolver un vector u que tenga tantas componentes como grupos hayamos encontrado, en este caso: , pues ha encontrado 3 grupos, el primero de 3 colindantes, el segundo de 2 colindantes, y el tercero de 1 "número suelto".

    Otro ejemplo. Si con la matriz anterior hubiéramos cogido el vector aleatorio , podréis facilmente ver que el vector u será: pues son todos "números sueltos", excepto la pareja 7,8.

    Espero que se haya entendido la idea, a ver si podéis echarme una mano. Recurro a vosotros en última instancia porque lo he intentado muchas veces. De hecho hice un programa en MatLab que me calcula cuántos números se tocan entre sí, pero "no sabe" distinguir entre grupos, es decir, en el primer ejemplo que puse (vector ) sólo reconoce que hay 5 elementos que se tocan entre sí, pero no sabe distinguir entre cuáles forman un grupo y cuáles forman el otro grupo. Mi código por si os pudiera ayudar es el que sigue (MatLab):

    Código:
    function colin=colindantes(v)
    long=length(v); fig=zeros(1,long); temp=v;
    for j=1:long
       n=v(j); sumparcial=0;
       n1=n-11; n2=n-1; n3=n+11; n4=n-10; n5=n+10; n6=n-9; n7=n+1; n8=n+9;
       elem1=find(temp==n1, 1);elem2=find(temp==n2, 1);elem3=find(temp==n3, 1);
       elem4=find(temp==n4, 1);elem5=find(temp==n5, 1);elem6=find(temp==n6, 1);
       elem7=find(temp==n7, 1);elem8=find(temp==n8, 1);
       if     ~isempty(elem1); sumparcial=sumparcial+1; temp(elem1)=-20; end 
       %reemplazo por un -20, para que nunca se pueda encontrar dicha
       %componente de nuevo.
       if     ~isempty(elem2); sumparcial=sumparcial+1; temp(elem2)=-20; end
       if     ~isempty(elem3); sumparcial=sumparcial+1; temp(elem3)=-20; end
       if     ~isempty(elem4); sumparcial=sumparcial+1; temp(elem4)=-20; end
       if     ~isempty(elem5); sumparcial=sumparcial+1; temp(elem5)=-20; end
       if     ~isempty(elem6); sumparcial=sumparcial+1; temp(elem6)=-20; end
       if     ~isempty(elem7); sumparcial=sumparcial+1; temp(elem7)=-20; end
       if     ~isempty(elem8); sumparcial=sumparcial+1; temp(elem8)=-20; end
       fig(j)=sumparcial;
    end
    colin=sum(fig);
    end
    Por si alguien no lo entiende lo explico un poco por encima. Lo que mi programa hace es aprovechar el hecho de que los números están ordenados por columnas, para establecer una relación matemática a la condición de números colindantes. Si creáis una matriz como dije antes (matriz de 10x5, con todas sus entradas con números del 1 al 49, sin repetir ningún número, ordenada por columnas y con su primera entrada (1,1) nula) podréis observar por qué he creado las variables n1, n2, ... , n8.

    Luego me vi en la necesidad de crear un vector temporal para ir borrando los elementos a medida que se encontraban. En este caso, como no se puede borrar, los sustituyo por -20, así me aseguro que nunca se encontrará de nuevo (pues todos los elementos deben ser positivos).

    Un saludo amigos, a ver quién me echa una mano!
    Última edición por skinner; 04/10/2012, 11:22:56. Motivo: colorear código

  • #2
    Re: ¿Cómo se podría crear un algoritmo/programa para esta aplicación?

    Este es un problema muy común en computación: dado unos elementos, ver cuales de ellos están "conectados" (el componente del vector) por una serie de uniones binarias (los elementos que están próximos en la matriz). Puedes leer sobre este problema en la wikipedia, https://en.wikipedia.org/wiki/Disjoi...data_structure, aunque existen algoritmos más simples que los que explican ahí. Voy a introducirte uno.

    Inicializa un vector "parent" con la misma dimensión que v, pero cada componente valdrá 1, 2, 3,... n. Es decir, en este caso parent = 1:6. Dos elementos i, j estarán relacionados entre si, y solo si, parent[i] == parent[j].

    En el momento que, recorriendo la matriz, detecto que dos elementos del vector son colindantes, debo forzar que estén relacionados. Por ejemplo, imagínate que detecto que las componentes i y j del vector son colindnates (es decir, v[i] e v[j]). Entonces, tengo que forzar que se cumpla la relación anterior, pero preservando las relaciones preexistentes. Por ejemplo, puedo tomar todas las componentes de parent que sena iguales a parent[i] y actualizarlas para que sean iguales a parent[j].
    La única alternativo a ser Físico era ser etéreo.
    @lwdFisica

    Comentario


    • #3
      Re: ¿Cómo se podría crear un algoritmo/programa para esta aplicación?

      Creo que he captado la idea, pod, muy interesante tu respuesta. Voy a indagar más sobre este tema, que me parece muy interesante, y de paso voy a intentar poner en práctica lo que me has explicado. Si consigo el código lo pongo, y si tengo alguna otra duda también :P

      Un saludo y gracias!

      Comentario


      • #4
        Re: ¿Cómo se podría crear un algoritmo/programa para esta aplicación?

        Yo no he mirado aún el enlace que te suministra pod, y pudiera estar lloviendo sobre mojado, pero te comento lo que se me ocurre así de repente:

        - Borrar de la matriz todos los elementos que no estén en el vector. Con el ejemplo que pusiste, la matriz quedaría así:


        donde el punto sería un valor no válido que funcionaría como centinela. A continuación se ejecutaría un bucle para construir la lista de elementos vecinos. Revisando la matriz en orden el oden fila-columna, se iniciaría una nueva lista al conseguir un elemento distinto del centinela:

        - Incrementar el contador de listas
        - Llamar al generador de listas pasando la nueva lista (vacía) y la posición (fila,columna) del elemento a añadir
        - Repetir hasta revisar toda la matriz
        - Emitir los resultados.

        El generador de listas sería una rutina que se llamaría recursivamente haciendo lo siguiente:

        - Añadir el elemento en (fila,columna) a la lista
        - Borrar el elemento de la matriz reemplazándolo por el centinela
        - Revisar los (máximo) cinco elementos a la derecha-arriba, a la derecha y los de abajo de (fila,columna)
        - Si el elemento inspeccionado no es un centinela, llamarse a si misma con la (fila,columna) del nuevo elemento
        - Devolver la lista

        El resultado así como me lo estoy imaginando deberían ser las tres listas [(1,7,8),(16,17),(20)]. Ahora en el fin de semana voy a ver si implemento el algoritmo y después comparamos

        Saludos,

        Al
        Última edición por Al2000; 05/10/2012, 01:38:01. Motivo: Corregir elementos a revisar
        Don't wrestle with a pig in the mud. You'll both get dirty, but the pig will enjoy it. - Parafraseando a George Bernard Shaw

        Comentario


        • #5
          Re: ¿Cómo se podría crear un algoritmo/programa para esta aplicación?

          Hola Al2000, muchas gracias por la claridad de tu respuesta. Tengo dos cositas que me gustaría comentar.

          La primera, es que no he entendido muy bien si la lista es un vector o una matriz, aunque creo que se trata de un vector. Y el generador de lista, ¿es una subrutina o simplemente un bucle anidado?

          La segunda cosita que me gustaría comentar, es que son (máximo) 8 elementos colindantes, y no 5 como dices. Un número de la matriz está rodeado de otros 8: Arriba, Abajo, Izquierda, Derecha, Diagonal Superior Izquierda, Diagonal Superior Derecha, Diagonal Inferior Izquierda, Diagonal Inferior Derecha.

          Muchas gracias por tu respuesta, a ver si conseguimos terminar este programa, que está superinteresante.
          Última edición por skinner; 05/10/2012, 02:12:48. Motivo: Tipeo

          Comentario


          • #6
            Re: ¿Cómo se podría crear un algoritmo/programa para esta aplicación?

            Si, cuando digo lista me refiero a un vector. Respecto a la exploración de los elementos colindantes menciono sólo 5 porque los otros 3 ya han sido explorados cuando exploras en orden fila/columna.

            Lamentablemente mi software me está dando un error extraño que creo que es un bug del programa y no he podido implementar el algoritmo en forma satisfactoria. Funciona en algunos casos y falla en otros, y no he logrado dilucidar si el error es mío o del software.

            Saludos,

            Al

            - - - Actualizado - - -

            Anoche me quedé pensando en el algoritmo y me percaté de que existe la posibilidad de que un elemento sea conseguido "desde abajo" y tendría que revisar las 8 posiciones adyacentes, pues no sabría a priori por cual dirección se llegó al elemento. Modifique mi programa, pero lamentablemente eso no corrije la falla

            - - - Actualizado - - -

            Finalmente corregí el programa y funciona bien.
            Don't wrestle with a pig in the mud. You'll both get dirty, but the pig will enjoy it. - Parafraseando a George Bernard Shaw

            Comentario


            • #7
              Re: ¿Cómo se podría crear un algoritmo/programa para esta aplicación?

              ¡Hola Al2000! Qué alegría que hayas conseguido implementar el algoritmo; yo aún no consigo dar con la clave; ¿te importaría compartir tu código? ¿En qué lenguaje está escrito?

              Un saludo

              Comentario


              • #8
                Re: ¿Cómo se podría crear un algoritmo/programa para esta aplicación?

                No se si mi respuesta te servirá de mucho, pues el programa lo hice en el lenguaje de programación propio del Mathcad. Creo que la principal traba para implementar el código en otro lenguaje es el manejo anidado de matrices en Mathcad, que me permite regresar como respuesta un vector de vectores. No tengo forma de pegar el código aquí, de modo que pego tres imágenes por si tienes curiosidad de ver el asunto. Lo que está implementado es el procedimiento tal cual lo expresé en mi primer mensaje, con la corrección de cuáles elementos a revisar.

                Haz clic en la imagen para ampliar

Nombre:	VecinosSkinner1.png
Vitas:	1
Tamaño:	15,0 KB
ID:	301446Haz clic en la imagen para ampliar

Nombre:	VecinosSkinner2.png
Vitas:	1
Tamaño:	23,0 KB
ID:	301447
                Haz clic en la imagen para ampliar

Nombre:	VecinosSkinner3.png
Vitas:	1
Tamaño:	7,8 KB
ID:	301448

                Saludos,

                Al
                Don't wrestle with a pig in the mud. You'll both get dirty, but the pig will enjoy it. - Parafraseando a George Bernard Shaw

                Comentario


                • #9
                  Re: ¿Cómo se podría crear un algoritmo/programa para esta aplicación?

                  Hola Al2000, casi he terminado de implementar el código en MatLab. Pero tengo tres preguntas.

                  La primera, es: desde la función principal "Vecinos", ¿dónde usas el argumento V? ¿para qué sirve esa función "match"?

                  La segunda, es: desde la función principal "Vecinos", al llamar a "GenerarLista" pasas los argumentos (M, f, c, 0, 0); ¿no debería ser (M, f, c, V, 0) ?

                  La tercera, es: desde la función secundaria "GenerarLista" veo que llamas a la propia función "GenerarLista" y esto me resulta en que el código entra en bucle infinito. ¿Cómo lo arreglo?

                  Un saludo! y gracias por la dedicación que ofreces

                  EDITO: he modificado un pequeño error y ahora el programa me devuelve un resultado bastante extraño, creo que no sabe interpretar dónde introducir la V. Mi código es:

                  Código:
                  function vecin=vecinos(M,v)
                  [nfM,ncM]=size(M);
                  nl=0;
                  for f=1:nfM
                     for c=1:ncM
                        if M(f,c)~=0
                           nl=nl+1;
                           [R1,R2,R3]=generarLista(M,f,c,0,0);
                           M=R1;
                           vecin(nl,:)=R2';
                        end
                     end
                  end
                  end
                  
                  function [R1,R2,R3]=generarLista(M,fila,columna,Lista,nelem)
                  [nfM,ncM]=size(M);
                  nelem=nelem+1;
                  Lista(nelem)=M(fila,columna);
                  M(fila,columna)=0;
                  R1=M; R2=Lista; R3=nelem;
                  for f=(fila-1):(fila+1)
                     for c=(columna-1):(columna+1)
                        if (f==fila) && (c==columna)
                           continue; 
                        end
                        if (f>=1 && f<=nfM) && (c>=1 && c<=ncM) && M(f,c)~=0
                            [R1, R2, R3]=generarLista(M,f,c,Lista,nelem);
                            M=R1;
                            Lista=R2;
                            nelem=R3;
                        end
                     end
                  end
                  end
                  Como puedes observar en la primera de las funciones, el argumento V no sé dónde pasarlo y creo que por eso me da un error extraño
                  Última edición por skinner; 08/10/2012, 12:42:03.

                  Comentario


                  • #10
                    Re: ¿Cómo se podría crear un algoritmo/programa para esta aplicación?

                    Escrito por skinner Ver mensaje
                    ...
                    La primera, es: desde la función principal "Vecinos", ¿dónde usas el argumento V? ¿para qué sirve esa función "match"?
                    ...
                    V se usa como argumento de la función "match" únicamente. La función "match" sirve para ubicar en una matriz o vector un elemento en particular. En este caso específico, anidando la función dentro de los dos "for" lo que estoy haciendo es buscar cuáles elementos de la matriz M aparecen en el vector V y borrar aquellos que no aparezcan. Para "borrar" un elemento lo que hago es sustituirlo por un string nulo ("").

                    ...
                    La segunda, es: desde la función principal "Vecinos", al llamar a "GenerarLista" pasas los argumentos (M, f, c, 0, 0); ¿no debería ser (M, f, c, V, 0) ?
                    ...
                    Tal como puse en mi primer mensaje, la rutina principal (Vecinos) debe llamar a la subrutina (GenerarLista) con una lista inicialmente vacía. En Mathcad no hay listas (vectores) vacíos y puedo pasar simplemente un cero como relleno para que la lista de argumentos coincida con la definición de GenerarLista. Un detalle importante de cómo funcionan los programas en Mathcad es que los programas nunca alteran los argumentos. Eso me obliga a devolver explicitamente los valores de la matriz M, el vector Lista y el entero nelem (como elementos en el vector R) y asignarlos a sus respectivas variables. Si el lenguaje me permitiese alterar los argumentos de la función no tendría necesidad de hacer ese paso.

                    ...
                    La tercera, es: desde la función secundaria "GenerarLista" veo que llamas a la propia función "GenerarLista" y esto me resulta en que el código entra en bucle infinito. ¿Cómo lo arreglo?
                    ...
                    Es correcto que la función se llame a sí misma. Eso evita mucho manejo de variables de control y hace el programa mucho mas compacto. No se produce un bucle infinito porque la primera tarea de la función GenerarLista es "borrar" el correspondiente elemento de M y se llama a sí misma sólo si consigue un nuevo elemento distinto del centinela ("" en este caso). Eventualmente la matriz M quedará completamente borrada, por lo cual el algoritmo siempre terminará.

                    Te pongo a continuación algunas notas en rojo.

                    ...
                    EDITO: he modificado un pequeño error y ahora el programa me devuelve un resultado bastante extraño, creo que no sabe interpretar dónde introducir la V. Mi código es:

                    Código:
                    function vecin=vecinos(M,v)
                    [nfM,ncM]=size(M);
                    nl=0;
                    <--- aquí tienes que insertar el "borrado" de M. Busca todos los elementos de M que no aparezcan en V y sustitúyelos por un valor ilegal. Mira que si el cero es un valor legítimo, como pusiste en tu mensaje inicial, no debes usarlo.
                    for f=1:nfM
                       for c=1:ncM
                          if M(f,c)~=0 <-- distinto del centinela que elijas
                             nl=nl+1;
                             [R1,R2,R3]=generarLista(M,f,c,0,0);
                             M=R1; <-- si Mathlab altera el argumento de la función, no hará falta devolver el valor de M ni actualizar el valor cambiado
                             vecin(nl,:)=R2'; <-- ¿esa comilla va allí?
                          end
                       end
                    end
                    end
                    
                    function [R1,R2,R3]=generarLista(M,fila,columna,Lista,nelem)
                    [nfM,ncM]=size(M);
                    nelem=nelem+1;
                    Lista(nelem)=M(fila,columna);
                    M(fila,columna)=0; <-- de nuevo, cambia el centinela si acaso cero es un valor válido
                    R1=M; R2=Lista; R3=nelem; <-- si Mathlab altera el argumento de la función, sólo hará falta devolver el valor de Lista
                    
                    for f=(fila-1):(fila+1)
                       for c=(columna-1):(columna+1)
                          if (f==fila) && (c==columna)
                             continue; 
                          end
                          if (f>=1 && f<=nfM) && (c>=1 && c<=ncM) && M(f,c)~=0 <-- centinela...
                              [R1, R2, R3]=generarLista(M,f,c,Lista,nelem);
                              M=R1; <-- si Mathlab altera el argumento de la función, no hará falta devolver el valor de M ni actualizar el valor cambiado
                              Lista=R2; <-- si Mathlab altera el argumento de la función, sólo hará falta devolver el valor de Lista
                              nelem=R3; <-- si Mathlab altera el argumento de la función, no hará falta devolver el valor de nelem ni actualizar el valor cambiado
                          end
                       end
                    end
                    end
                    ...
                    Bueno, no se me ocurre nada mas. Veamos que pasa cuando incluyas el borrado en la rutina principal.

                    Saludos,

                    Al
                    Última edición por Al2000; 08/10/2012, 21:08:56. Motivo: Corregir elementos a borrar; corregir uso optativo de M, Lista y nelem.
                    Don't wrestle with a pig in the mud. You'll both get dirty, but the pig will enjoy it. - Parafraseando a George Bernard Shaw

                    Comentario


                    • #11
                      Re: ¿Cómo se podría crear un algoritmo/programa para esta aplicación?

                      Qué tal Al. El problema efectivamente radicaba en el borrado de M. Ahora me devuelve el resultado, pero no en forma de vector como pusiste en tu imagen, sino con todos los elementos seguidos, así: v=[1, 16, 7, 17, 8, 20].

                      Ahora que lo pienso, MatLab no te permite devolver vectores como el tuyo, ¿cómo puedo solucionar este último problema?

                      El código modificado resulta:

                      Código:
                      function vecin=vecinos(M,v)
                      [nfM,ncM]=size(M); long=length(v);
                      nl=0; B=zeros(long,2); P=M; M=zeros(nfM,ncM);
                      for i=1:long
                          [B(i,1),B(i,2)]=find(P==v(i));
                      end
                      for i=1:max(length(B(:,1)),length(B(:,2)))
                          M(B(i,1),B(i,2))=P(B(i,1),B(i,2));
                      end
                      for f=1:nfM
                         for c=1:ncM
                            if M(f,c)~=0
                               nl=nl+1;
                               [R1,R2,R3]=generarLista(M,f,c,0,0);
                               M=R1;
                               vecin(nl,:)=R2;
                            end
                         end
                      end
                      end
                      
                      function [R1,R2,R3]=generarLista(M,fila,columna,Lista,nelem)
                      [nfM,ncM]=size(M);
                      nelem=nelem+1;
                      Lista(nelem)=M(fila,columna);
                      M(fila,columna)=0;
                      R1=M; R2=Lista; R3=nelem;
                      for f=(fila-1):(fila+1)
                         for c=(columna-1):(columna+1)
                            if (f==fila) && (c==columna) 
                                if ((f>=1 && f<=nfM) && (c>=1 && c<=ncM)) && (M(f,c)~=0)
                                    [R1, R2, R3]=generarLista(M,f,c,Lista,nelem);
                                    M=R1;
                                    Lista=R2;
                                    nelem=R3;
                                end
                            end
                         end
                      end
                      end
                      A ver si terminamos ya el código!

                      Un saludo, gracias por la dedicación.

                      PD: Efectivamente, mi centinela será el cero.
                      Última edición por skinner; 09/10/2012, 15:32:38.

                      Comentario


                      • #12
                        Re: ¿Cómo se podría crear un algoritmo/programa para esta aplicación?

                        Escrito por skinner Ver mensaje
                        ...
                        Ahora que lo pienso, MatLab no te permite devolver vectores como el tuyo, ¿cómo puedo solucionar este último problema?
                        ...
                        Como no conozco cómo maneja Mathlab las estructuras de datos, lo único que se me ocurre sugerirte es que metas cada valor de R2 devuelto por "generarLista" en la fila o columna "nl" de una matriz (¿vecin?). Yo pensé que eso era lo que estabas haciendo con la instrucción "vecin(nl,=R2".

                        Saludos,

                        Al
                        Don't wrestle with a pig in the mud. You'll both get dirty, but the pig will enjoy it. - Parafraseando a George Bernard Shaw

                        Comentario


                        • #13
                          Re: ¿Cómo se podría crear un algoritmo/programa para esta aplicación?

                          Hola Al, he estado dándole muchas vueltas, pero el problema es que R2 nunca toma la forma de vector. Es decir, tras la ejecución de tu código, debería obtener:

                          PRIMERA ITERACIÓN: R2=[1, 7, 8]

                          SEGUNDA ITERACIÓN: R2=[16, 17]

                          TERCERA ITERACIÓN: R2=[20]

                          Pero en mi caso, obtengo cada valor por separado y en orden diferente, así:

                          R2=1
                          R2=16
                          R2=7
                          R2=17
                          R2=8
                          R2=20

                          Y como podrás ver, no puedo llegar a conseguir R2 en forma de vector, sino como sucesivos escalares por separado.

                          Mi idea es crear una matriz cuadrada de orden el del vector inicial, v, toda llena de ceros. En cada columna "copiar" entonces aquellos elementos que son colindantes. Supuestamente eso es lo que hago con la orden "vecin ( nl , : )=R2", claro está añadiendo antes la orden "vecin=zeros(long)". Haciendo esto, obtengo la matriz (recuerda que yo almaceno R2 en vecin por filas; esto quiere decir, que en la primera ejecución, la primera fila se me llena de unos; la segunda de 16; la tercera de 7; y así sucesivamente, como consecuencia de que R2 es un único valor y lo que hace es copiármelo para toda la fila):



                          Gracias por la ayuda que me ofreces; a ver si se nos ocurre cómo terminar este programa.

                          Un saludo

                          PD. Quizá esto pueda simplificarnos el programa. Yo realmente lo que quiero es el tamaño de cada grupo, es decir, en el ejemplo que hiciste, el tamaño sería: un grupo de 3, otro de 2, y finalmente un grupo de 1. Por lo que la salida que desearía obtener es un vector u=[3 2 1]. Propongo esto como último recurso, porque no sé cómo solucionar este problema. Aunque supongo que esto no simplifica el programa, sino que añade una línea de código extra donde se haga recuento del tamaño de cada vector. De todas formas lo menciono por si acaso.
                          Última edición por skinner; 11/10/2012, 01:39:49.

                          Comentario


                          • #14
                            Re: ¿Cómo se podría crear un algoritmo/programa para esta aplicación?

                            Tu comentario me hizo fijarme mejor en el último código, pues parecería que la rutina está consiguiendo un solo número cada vez... y me doy cuenta de que en tu última versión te dejaste por fuera el "continue" cuando f = fila y c = columna Compara con la versión anterior... la idea es que no se ejecute generarLista para el mismo elemento con el que fue llamada y que ya ha sido borrado de la matriz M.

                            Corrige y me cuentas. Saludos,

                            Al

                            PD. la versión simplificada es muy simple de hacer. Yo la probé y la borré por aburrida jajaja

                            PD2. Perdona, soy un tonto Quita el "if f=fila..." etc por completo, que está absolutamente demás, puesto que si f=fila y c=columna ya el elemento en M habrá sido borrado y el if ... M(f,c) ~= 0 siempre será falso, por lo que no se llamará la rutina generarLista.
                            Última edición por Al2000; 11/10/2012, 03:43:27. Motivo: Error de tipeo; añadir postdata.
                            Don't wrestle with a pig in the mud. You'll both get dirty, but the pig will enjoy it. - Parafraseando a George Bernard Shaw

                            Comentario


                            • #15
                              Re: ¿Cómo se podría crear un algoritmo/programa para esta aplicación?

                              ¡¡ Correcto Al !! El error radicaba en ese "if" que indicaste en tu segunda posdata. El código final me ha quedado de esta forma, haciéndole un par de modificaciones (las indico en rojo)

                              Código:
                              function vecin=colindantes3(M,v)[nfM,ncM]=size(M); long=length(v); vecin=zeros(long);
                              nl=0; B=zeros(long,2); P=M; M=zeros(nfM,ncM);
                              for i=1:long
                                  [B(i,1),B(i,2)]=find(P==v(i));
                              end
                              for i=1:max(length(B(:,1)),length(B(:,2)))
                                  M(B(i,1),B(i,2))=P(B(i,1),B(i,2));
                              end
                              for f=1:nfM
                                 for c=1:ncM
                                    if M(f,c)~=0
                                       nl=nl+1;
                                       [R1,R2,R3]=generarLista(M,f,c,0,0);
                                       M=R1;
                                       longR2=length(R2); longZeros=long-longR2; e=zeros(1,longZeros);
                                       vecin(:,nl)=[R2 e];
                                    end
                                 end
                              end
                              end
                              
                              
                              function [R1,R2,R3]=generarLista(M,fila,columna,Lista,nelem)
                              [nfM,ncM]=size(M);
                              nelem=nelem+1;
                              Lista(nelem)=M(fila,columna);
                              M(fila,columna)=0;
                              R1=M; R2=Lista; R3=nelem;
                              for f=(fila-1):(fila+1)
                                 for c=(columna-1):(columna+1)
                                        if ((f>=1 && f<=nfM) && (c>=1 && c<=ncM)) && (M(f,c)~=0)
                                            [R1, R2, R3]=generarLista(M,f,c,Lista,nelem);
                                            M=R1;
                                            Lista=R2;
                                            nelem=R3;
                                        end
                                 end
                              end
                              end
                              Hacer la versión modificada será muy sencillo como bien dices, sólo habré de recorrer columna a columna y contar cuántos elementos hay en cada una de ellas. Por suerte MatLab implementa esta función por mí, y el código principal queda:

                              Código:
                              function u=colindantes3(M,v)
                              long=length(v); vecin=calcula_colindantes(M,v); u=zeros(1,long);
                              for f=1:long
                                  u(1,f)=nnz(vecin(:,f));
                              end
                              u=nonzeros(u); u=u';
                              end
                              Muchas gracias por la ayuda que me has prestado Al!! Cualquier irregularidad que encuentre en el programa te lo haré saber

                              Un saludo!

                              - - - Actualizado - - -

                              Llevo probando el programa durante todo este tiempo y funciona a las mil maravillas.

                              Por cierto, que no te di las "Gracias" en tu último mensaje (vaya cabeza), ¡así que ahí va!

                              Un saludo amigo!!
                              Última edición por skinner; 11/10/2012, 11:28:25.

                              Comentario

                              Contenido relacionado

                              Colapsar

                              Trabajando...
                              X