Problema con fallo en algoritmo (SOLUCIONADO)

Dudas e ideas sobre los distintos e infinitos (:-)) algoritmos existentes.
Responder
Mensaje
Autor
Intisma
Mensajes: 2
Registrado: 02/04/2019 4:47 am

Problema con fallo en algoritmo (SOLUCIONADO)

#1 Mensaje por Intisma » 02/04/2019 5:06 am

Código: Seleccionar todo

/*DEFINICIÓN DE LIBRERÍAS*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

/*DEFINICIÓN DE CONSTANTES*/
#define MAX_ELEM 1000
#define MAX 1000
#define MIN 0


/*PROCEDIMIENTOS DE ORDENACION*/

/****************************************************************
ordSeleccio: Accion que hace una ordenacion de un vector
utilizando el metodo de seleccion.
Parametos:
    v: Vector de enteros
    nelem: Numero de elementos que contiene el vector
    intec: Contador del numero de intercambios
    itera: Contador del numero de iteraciones
Precondicones:
    Vector debe contener un numero de enteros menor que la
    constante MAX_ELEM.
Retorna
    El procedimiento retorna el vector ordenado por referencia.
    Si ya esta ordenado al inicio, retorna el mismo vector.
*****************************************************************/
void ordSeleccio(int v[MAX_ELEM], int nelem, long *interc, long *itera) {
    int i, j, pos, minim;
    for (i=0; i<nelem-1; i++) {
        minim = v[i];
        pos = i;
        (*itera)++;
        for (j=i+1; j<nelem; j++) { /*Buscamos el mínimo*/
            (*itera)++;
            if (v[j]<minim) {
                minim = v[j];
                pos = j;
            }
        } /*fper*/
        (*interc)++;
        v[pos] = v[i];
        /*Colocamos el mínimo en la posición i*/
        v[i] = minim;
    } /*fper*/
} /*facció*/

/****************************************************************
ordInsercio: Accion que ordena un vector mediante el metodo de
insercion
Parametos:
    v: Vector de enteros
    nelem: Numero de elementos que contiene el vector
    interc: Contador del numero de intercambios
    itera: Contador del numero de iteraciones
Precondicones:
    Vector debe contener un numero de enteros menor que la
    constante MAX_ELEM.
Retorna
    El procedimiento retorna el vector ordenado por referencia.
    Si ya esta ordenado al inicio, retorna el mismo vector.
*****************************************************************/
void ordInsercio(int v[MAX_ELEM], int nelem, long *interc, long *itera) {
    int i, j, aux;

    for (i=1; i<nelem; i++) {
        aux = v[i];
        j = i-1;
        (*itera)++;
        while (j>=0 && aux<v[j]) { /*Es fa la inserció */
            (*itera)++;
            v[j+1] = v[j];
            j--;
            (*interc)++;
        } /* fmentre */
        v[j+1] = aux;
    } /* fper */
} /* facció */

/****************************************************************
merge: Accion que ordena un vector de reales mediante el mÈtodo
recursivo de MergeSort
Parametos:
        arr: Vector de reales a ordenar
        l: Inicio del vector
        m: Posicion intermedia entre el principio y el final
        r: Posicion final del vector
        co1: Contador numero de intercambios
Precondicones:
    Vector debe contener un numero de enteros menor que la
    constante MAX_ELEM.
Retorna
    El procedimiento retorna el vector ordenado.
    Si ya esta ordenado al inicio, retorna el mismo vector.
*****************************************************************/

void merge(int arr[], int l, int m, int r, long *co1)
{
    int i, j, k;
    int n1 = m - l + 1;
    int n2 =  r - m;

    /* crea vectores temporales */
    int L[n1], R[n2];

    /* Copiar datos en vectores temporales L[] y R[]*/
    for (i = 0; i < n1; i++)
        L[i] = arr[l + i];
    for (j = 0; j < n2; j++)
        R[j] = arr[m + 1+ j];

    /* Fusiona los vectores temporales de nuevo en arr[l..r]*/
    i = 0; // Índice inicial del primer subvector
    j = 0; // Índice inicial del segundo subvector
    k = l; // Índice inicial del tercero subvector
    while (i < n1 && j < n2)
    {
        if (L[i] <= R[j])
        {
            arr[k] = L[i];
            i++;
            (*co1)++; /* Intercambios */
        }
        else
        {
            arr[k] = R[j];
            j++;
            (*co1)++;
        }
        k++;
    }

    /* Copia los elementos restantes de L[], si hay */
    while (i < n1)
    {
        arr[k] = L[i];
        i++;
        k++;
    }

    /* Copiar los elementos restantes de R[], si hay */
    while (j < n2)
    {
        arr[k] = R[j];
        j++;
        k++;
    }
}

/**********************************************************
 mergeSort: Accion que hace una llamada recursiva a la funcion anterior (merge)

 Parametros:
    arr: el vector que se tiene que ordenar.
    l: inicio del vector
    r: final del vector
    co1: el contador de intercambios
    co2: Contador de la iteraciones recursivas
Precondicones:
    Vector debe contener un numero de enteros menor que la
    constante MAX_ELEM.
Retorna:
 Esta accion es la encargada de devolver el vector totalmente ordenado
***********************************************************/
/* l es para el índice izquierdo y r es el índice derecho
de subvector para ser ordenador */
void mergeSort(int arr[], int l, int r, long *co1, long *co2)
{
    (*co2)++;                      /* Contador de llamadas recursivas */
    if (l < r)
    {
        /* Igual que (l+r)/2, per evita el overflow de grandes l y h */
        int m = l+(r-l)/2;
        /* Ordena primera y segunda mitad */
        mergeSort(arr, l, m, co1, co2);
        mergeSort(arr, m+1, r, co1, co2);
        merge(arr, l, m, r, co1);
    }
}

/*PROCEDIMIENTO PARA GENERAR LOS VECTORES ALEATORIOS*/

/****************************************************************
generadorVectores: Accion que genera un vector de enteros
y medida introducida con un maximo de MAX_ELEM
Parametos:
    vect: Vector de enteros
    l: longitud del vector
Precondicones:
    Que se introduzca en la funcion un vector de dimension
    minima MAX_ELEM.
Retorna
    El procedimiento genera un vector que se pasa por referencia.
*****************************************************************/
void generadorVectores(int vect[], int l)
{
    int i;
    for (i=0; i<l; i++){
        vect[i]=rand() % (MAX - MIN + 1) +  MIN; /*Generador de aleatorios*/
    }/*fper*/
} /*facció*/

/****************************************************************
generadorVectoresOrd: Accion que genera un vector de enteros ya
ordenado, dependiendo de la modalidad generara uno creciente o
decreciente. Tiene una medida introducida con un maximo de
MAX_ELEM.
Parametos:
    vect: Vector de enteros
    l: Longitud del vector
    modalidad: Modo de ejecución del programa
Precondicones:
    Que se introduzca en la funcion un vector de dimension
    minima MAX_ELEM.
Retorna
    El procedimiento genera un vector que se pasa por referencia.
*****************************************************************/
void generadorVectoresOrd(int vect[], int l, int modalidad)
{
    int i;
    int min=0, max=0;
    if(modalidad==0){
        for (i=0; i<l; i++){
            do{
            vect[i]=rand() % (max - min + 1) +  min; /*Generador de aleatorios*/
            }while(vect[i]<min);
            min=vect[i];
            max=min+3;
        }/*fper*/
    }/*fsi*/
    if(modalidad==1){
        max=MAX, min=max-1;
        for (i=0; i<l; i++){
            do{
            vect[i]=rand() % (max - min + 1) +  min; /*Generador de aleatorios*/
            }while(vect[i]>=max);
            max=vect[i];
            min=max-3;
        }/*fper*/
    }/*fsi*/
} /*facció*/

/* PROCEDIMIENTOS AUXILIARES*/

/****************************************************************
 mostrarVector: Accion que muestra por pantalla un vector
 Parametros:
    vect: vector que se tiene que mostrar
    mida: la longitud del vector que tenemos que mostrar
 Precondiciones:
    Es obligatorio pasar la mida del vector
 Retorna:
    El vector muestra por pantalla
 ****************************************************************/
void mostrarVector (int vect[], int mida)
{
    int i;
    printf("\n");
    for (i=0; i<mida; i++){
        printf(" %d", vect[i]);/*Mostramos el vector*/
    }/*fper*/
    printf("\n");
}/*faccio*/

/****************************************************************
 copiarVector: Accion que copia un vector a otro temp
 Parametros:
    vect1: vector donde se copiara el otro vector
    vect2: vector que se tiene que copiar
    mida: la longitud del vectores
 Precondiciones:
    Es obligatorio pasar la mida del vector y ambos vectores
 Retorna:
    El vect1 copiado en el vect2.
 ****************************************************************/
void copiaVector(int vect1[], int vect2[], int mida)
{
    int i;
    for (i=0; i<mida; i++){
        vect1[i]=vect2[i];  /*Copiamos el vector*/
    }/*fper*/
}/*faccio*/

/****************************************************************
 comprobarVector: Accion que comprueba que el vector este ordenado
 Parametros:
    vect: vector que se comprobara
    cont: contador de errores que entra por referencia
    mida: la longitud del vectores
 Precondiciones:
    Es obligatorio pasar la mida y el vect
 Retorna:
    El cont modificado por referencia
 ****************************************************************/
void comprobarVector(int vect[], int *cont, int mida)
{
     int i=0;
     do{
        if((vect[i])>(vect[i+1])){
            i=mida;
        }/*fsi*/
        i++;
     }while(i<mida-1);
     if (i==mida+1){
        *cont=*cont+1;
     }/*fsi*/
}/*faccio*/

 /****************************************************************
 juegoPruebas: Accion que comprueba que el vector este ordenado
 Parametros:
 Precondiciones:
 Retorna:
    Nada
 ****************************************************************/
void juegoPruebas()
{
     int vect[MAX_ELEM], vectord[MAX_ELEM];
     int mida, i, cont_err_selecci=0, cont_err_inserc=0, cont_err_merge=0;
     long cont_int_inserc=0, cont_iter_inserc=0, cont_int_selecci=0, cont_iter_selecci=0, cont_int_merge=0, cont_re_merge=0;
     printf("Iniciando juego de pruebas:\n\n");
     printf("Prueba 1: Ordenacion de 100 vectores de medida aleatoria generados aleatoriamente\n");
     for(i=0;i<100;i++){                                                                                        /*Iniciamos bucle para ordenar 100 vectores*/
        mida=rand()%MAX_ELEM+10;                                                                                /*Generamos medida aleatoria*/
        generadorVectores(vect, mida);                                                                          /*Generamos un vector aleatorio*/
        copiaVector(vectord, vect, mida);                                                                       /*Copiamos el vector en otro para ordenarlo sin el coste de generar nuevos vectores para cada metodo*/                                                                     /*Iniciamos el temportizador*/
        ordSeleccio(vectord, mida, &cont_int_selecci, &cont_iter_selecci);                                      /*Ordenamos el vector por seleccion*/
        comprobarVector(vectord, &cont_err_selecci, mida);                                                      /*Comprobamos si hay errores*/
        /*Repetimos el proceso para los otros dos algoritmos*/
        copiaVector(vectord, vect, mida);
        ordInsercio(vectord, mida, &cont_int_inserc, &cont_iter_inserc);
        comprobarVector(vectord, &cont_err_inserc, mida);
        mergeSort(vect, 0, mida-1, &cont_int_merge, &cont_re_merge);
        comprobarVector(vect, &cont_err_merge, mida);
    }
    printf("\tRepasando resultados de prueba 1:\n\tSELECCION: Total de errores en 100 vectores ordenados: %d\n\tINSERCION: Total de errores en 100 vectores ordenados: %d\n\tMERGESORT: Total de errores en 100 vectores ordenados: %d\nPrimera prueba finalizada\n\nPrueba 2: Probando el mejor caso, vector ordenado creciente\n", cont_err_selecci, cont_err_inserc, cont_err_merge);
    mida=100, cont_err_inserc=0, cont_err_selecci=0, cont_err_merge=0;
    for(i=0;i<3;i++){                                                                                           /*Iniciamos un bucle for para realizar la prueba en tres vectores*/
        generadorVectoresOrd(vect, mida, 0);
        copiaVector(vectord, vect, mida);
        ordSeleccio(vectord, mida, &cont_int_selecci, &cont_iter_selecci);
        comprobarVector(vectord, &cont_err_selecci, mida);
        copiaVector(vectord, vect, mida);
        ordInsercio(vectord, mida, &cont_int_inserc, &cont_iter_inserc);
        comprobarVector(vectord, &cont_err_inserc, mida);
        mergeSort(vect, 0, mida-1, &cont_int_merge, &cont_re_merge);
        comprobarVector(vect, &cont_err_merge, mida);
        switch( i )                                                                                               /*Realizamos un switch para realizar la prueba con varias medidas*/
        {
            case 0:
                mida=500;
                break;
            case 1:
                mida=1000;
                break;
        }
    }
    printf("\tRepasando resultados de prueba 2:\n\tSELECCION: Total de errores en 3 vectores ordenados: %d\n\tINSERCION: Total de errores en 3 vectores ordenados: %d\n\tMERGESORT: Total de errores en 3 vectores ordenados: %d\nSegunda prueba finalizada\n\nPrueba 3: Probando el peor caso, vector ordenado decreciente\n", cont_err_selecci, cont_err_inserc, cont_err_merge);
    mida=100, cont_err_inserc=0, cont_err_selecci=0, cont_err_merge=0;
    for(i=0;i<3;i++){
        generadorVectoresOrd(vect, mida, 1);
        copiaVector(vectord, vect, mida);
        ordSeleccio(vectord, mida, &cont_int_selecci, &cont_iter_selecci);
        comprobarVector(vectord, &cont_err_selecci, mida);
        copiaVector(vectord, vect, mida);
        ordInsercio(vectord, mida, &cont_int_inserc, &cont_iter_inserc);
        comprobarVector(vectord, &cont_err_inserc, mida);
        mergeSort(vect, 0, mida-1, &cont_int_merge, &cont_re_merge);
        comprobarVector(vect, &cont_err_merge, mida);
        switch( i )
        {
            case 0:
                mida=500;
                break;
            case 1:
                mida=1000;
                break;
        }
    }
    printf("\tRepasando resultados de prueba 3:\n\tSELECCION: Total de errores en 3 vectores ordenados: %d\n\tINSERCION: Total de errores en 3 vectores ordenados: %d\n\tMERGESORT: Total de errores en 3 vectores ordenados: %d\nTercera prueba finalizada\n\n", cont_err_selecci, cont_err_inserc, cont_err_merge);
    printf("Juego de pruebas finalizado existosamente\n\n");
}/*faccio*/


/* ALGORITMO PRINCIPAL */

int main()
{
    /* Inicializacion de todas la variables */
    int vect[MAX_ELEM], vectord[MAX_ELEM];
    int mida=MAX_ELEM;
    clock_t start_t, end_t;
    long cont_int_inserc=0, cont_iter_inserc=0, cont_int_selecci=0, cont_iter_selecci=0, cont_int_merge=0, cont_re_merge=0;
    double total_t;
    FILE *resultados;

    /* Abrimos fichero */
    if ((resultados = fopen("resultados.txt", "at")) == NULL) {
        printf("Error abriendo el archivo\n");                                   /* Si hay error, retorna NULL */
        exit(EXIT_FAILURE);                                                      /* Salimos del programa porque hay error */
    }

    /* Inicialización de semilla para generar nº aleatorios */
    srand(time(NULL));

    juegoPruebas();

    /* Inicializamos rutina para mostrar los vectores ordenados y sus contadores e iteraciones */
    printf("Iniciando rutina\n");
    printf("\nVector aleatorio:\n");
    generadorVectores(vect, mida);                                               /* Generamos un vector aleatorio */
    mostrarVector(vect, mida);                                                   /* Mostramos el vector generado por pantalla */

    /* ORDENACION POR INSERCION */
    printf("\nVector ordenado por insercion:\n");
    copiaVector(vectord, vect, mida);                                            /* Copiamos el vector en otro para ordenarlo más veces */
    start_t = clock();                                                           /* Iniciamos el temporizador para la función */
    ordInsercio(vectord, mida, &cont_int_inserc, &cont_iter_inserc);             /* Llamamos la función de ordenacion */
    end_t = clock();                                                             /* Guardamos el tiempo final */
    mostrarVector(vectord, mida);                                                /* Mostramos el vector generado por pantalla */
    total_t = ((double)(end_t - start_t)*1000.0)/ CLOCKS_PER_SEC;                /* Calculamos el tiempo total */
    /* Mostramos por pantalla el tiempo  y los contadores */
    printf("\nExecution time: %.f ms\n", total_t);
    printf("\nContador intercambios de insercion: %ld\nContador iteraciones de insercion: %ld\n\n", cont_int_inserc, cont_iter_inserc);
    /* Guardamos datos en el fichero */
    fprintf(resultados, "INSERCION:\t%ld\t%ld\t%f\n",cont_int_inserc, cont_iter_inserc, total_t);

    /* ORDENACION POR SELECCION */
    printf("\nVector ordenado por seleccion:\n");
    copiaVector(vectord, vect, mida);                                            /* Copiamos el vector en otro para ordenarlo más veces */
    start_t = clock();                                                           /* Iniciamos el temporizador para la función */
    ordSeleccio(vectord, mida, &cont_iter_selecci, &cont_int_selecci);           /* Llamamos la función de ordenacion */
    end_t = clock();                                                             /* Guardamos el tiempo final */
    mostrarVector(vectord, mida);                                                /* Mostramos el vector generado por pantalla */
    total_t = ((double)(end_t - start_t)*1000.0)/ CLOCKS_PER_SEC;                /* Calculamos el tiempo total */
    /* Mostramos por pantalla el tiempo  y los contadores */
    printf("\nExecution time: %.f ms\n", total_t);
    printf("\nContador intercambios de seleccion: %ld\nContador iteraciones de seleccion: %ld\n\n", cont_int_selecci, cont_iter_selecci);
    /* Guardamos datos en el fichero */
    fprintf(resultados, "SELECCION:\t%ld\t%ld\t%f\n",cont_iter_selecci, cont_int_selecci, total_t);

    /* ORDENACION POR MERGESORT */
    printf("\nVector ordenado por MergeSort:\n");
    start_t = clock();                                                           /* Iniciamos el temporizador para la función */
    mergeSort(vect, 0, mida-1, &cont_int_merge, &cont_re_merge);                 /* Llamamos la función de ordenacion */
    end_t = clock();                                                             /* Guardamos el tiempo final */
    mostrarVector(vect, mida);                                                   /* Mostramos el vector generado por pantalla */
    total_t = ((double)(end_t - start_t)*1000.0)/ CLOCKS_PER_SEC;                /* Calculamos el tiempo total*/
    /* Mostramos por pantalla el tiempo  y los contadores */
    printf("\nExecution time: %.f ms\n", total_t);
    printf("\nContador intercambios del MergeSort: %ld\n", cont_int_merge);
    printf("\nContador iteraciones del MergeSort: %ld\n\n", cont_re_merge);
    /* Guardamos datos en el fichero */
    fprintf(resultados, "MERGESORT:\t%ld\t%ld\t%f\n\n", cont_re_merge, cont_int_merge, total_t);

    /* Cerramos el fichero */
    fclose(resultados);

    return 0;
}
/* FIN ALGORITMO PRINCIPAL */
Hola, perdón si incumplo alguna regla, es la primera vez que uso este foro.

He estado creando un algoritmo para mis clases de programación, el cuál básicamente genera y ordena vectores por selección, inserción y mergesort. El algoritmo básicamente creaba un vector aleatorio lo mostraba, lo ordena y muestra ya ordenado para cada método. Además realicé un juego de pruebas como una acción (void). El problema es que el programa funciona perfectamente sin el juego de pruebas, pero cuando lo añado en algunas ocasiones, tras entrar en el juego de pruebas, lo realiza entero, hasta el último printf, y ahí sin haber ningún tipo de instrucción más en el código del juego de pruebas, no continúa al main por alguna razón. Adjunto fotos de todo.

Actualizado: Ya he colgado el código aunque es muy extenso
Solucion: Por si alguien se lo pregunta el fallo era el generar una medida aleatoria, ya que en ocasiones generaba una mayor que el rango de elementos del vector, dando error. Si hay que marcar alguna opción para dar este tema por solucionado decídmelo y lo haré.
Adjuntos
Main.png
Main.png (101.03 KiB) Visto 166 veces
Juego de pruebas.png
Juego de pruebas.png (118.32 KiB) Visto 166 veces
Error.png
Error.png (36.76 KiB) Visto 166 veces
Última edición por Intisma el 02/04/2019 7:13 am, editado 2 veces en total.

mollok
Mensajes: 467
Registrado: 30/01/2018 9:47 am
Ubicación: Mallorca, España

Re: Problema con fallo en algoritmo

#2 Mensaje por mollok » 02/04/2019 5:34 am

Para poner el código en la página pulsa el botón </> que hay encima de la caja de escritura y copia tu código enmedio de las etiquetas que aparecen.
No se ve porque podría fallar. Se intuye que GeneradorVectores falle.
while(is_alive(yourself)) {
    make_true(yourself, yourdreams);
}

Intisma
Mensajes: 2
Registrado: 02/04/2019 4:47 am

Re: Problema con fallo en algoritmo

#3 Mensaje por Intisma » 02/04/2019 5:39 am

Gracias por decirme, ya lo he colgado aunque es bastante extenso.

Responder

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado