Mostrando entradas con la etiqueta C. Mostrar todas las entradas
Mostrando entradas con la etiqueta C. Mostrar todas las entradas

miércoles, 22 de abril de 2015

Mi implementación del algoritmo Fringe Search para la búsqueda de caminos que tienden a ser óptimos en gráficos de maya.

El algoritmo Fringe Search propuesto en http://webdocs.cs.ualberta.ca/~holte/Publications/fringe.pdf por Yngvi Bjornsson Markus Enzenberger, Robert C. Holte y Jonathan Schaeffer produce caminos que tienden a ser óptimos, pero mejoran la velocidad de ejecución de A* de una manera significativa. Pongo a disposición de todos el código fuente usado en mi tesis titulada: "El Algoritmo Fringe Search como solución superior a A* en la búsqueda de caminos sobre gráficos de malla" presentada en la UNAM, en el cual implemento este algoritmo en lenguaje C. Espero sea útil. 


El código puede ser descargado o clonado desde: https://github.com/pywirrarika/fringesearch

miércoles, 8 de abril de 2015

Mi implementación del algoritmo A* para gráficos de malla.

Dejo a disposición de todo aquel interesado mi repositorio de GitHub donde se puede encontrar el código de mi implementación del algoritmo A* escrito en C. He usado una skiplist para la lista cerrada junto con arreglos de punteros para un acceso rápido y un buen nivel de optimización para mejorar el tiempo de ejecución. El programa lee un archivo
BMP del cual cargará las partes negras como obstáculos o como nodos intransitables. Como salida genera un archivo BMP nuevo donde se representa el área en la cual se ha buscado y el mejor camino del nodo de inicio al nodo de destino.

Para obtener el código simplemente será necesario introducir el siguiente comando en la terminal:

git clone https://github.com/pywirrarika/astarmesh

O descargarlo directamente de la página: https://github.com/pywirrarika/astarmesh


jueves, 6 de febrero de 2014

Contar líneas de código C

¿Quieres saber cuántas líneas de código en C que has escrito en tus archivos de código fuente en una carpeta dada? ¿Además quieres contar sólo las líneas de código sin contar los comentarios y las líneas en blanco? Aquí un pequeño comando en nuestra terminal GNU/Linux o en cualquier sistema *nix.
cat * | sed '/^\s*#/d;/^\s*$/d' | wc -l
Obviamente se puede ajustar a todas las necesidades.

miércoles, 5 de febrero de 2014

¿Por qué sigue usándose Turbo C/C++ en las escuelas?

Turbo C es un compilador creado por Borland en 1987 para el desarrollo en MS-DOS(aunque también hubo versiones para Atari y OS/2)  el cual fue reemplazado por Turbo C++ en 1990.La última versión de Turbo C++, la 3.01, en 1992, con lo que posteriormente se concentraría la empresa en su producto Borland C++ y C++ Builder.
A pesar de ser un compilador histórico, donde muchos de nosotros dimos nuestros primeros pasos en la programación en C y C++, se debe reconocer que nuestro compilador de 16bits ha pasado a la historia y su lugar es estar en una vitrina en el museo de la informática. 
Sin embargo, un gran número de escuelas, tienen como su compilador de cabezera ese viejo conocido: ¡Turbo C! No es extraño encontrarnos hoy en día, en diversos foros de programación código que usa las viejas bibliotecas.
¿Me pueden ayudar con este código? ... y se lee: gotoxy(23,5); clrscr(); etc. 

Parecería ser que el tiempo no ha cambiado en nada, que MS-DOS sigue siendo un sistema operativo, y no una terminal emulada por los sistemas windows modernos. A este ritmo no nos sorprendería ver código que invoque resoluciones de 320x200 con 256 colores indexados.

                            void SetVideo (void)
                            {
                                    asm{
                                                mov ah,0
                                                mov al,13h
                                                int 10h
                                          }
                            }


A pesar de que tenemos buenos recuerdos, y extrañamos los hacks del Modo 13h y Modo X, y otras curiosidades, es una verdadera barbaridad que a los alumnos no se enseñe a escribir código en compiladores modernos. Pareciera ser que los maestros, sin ganas de desarrollar nuevos retos de programación para sus alumnos, intentan reproducir una y otra vez los mismos ejercicios obsoletos.
El problema no solo es que la lógica no se puede reducir a producir cuadros de texto con colores en una consola de los años 90's sobre MS-DOS, sino que no dejan una verdadera experiencia de como se realiza la programación en C y C++ para sistemas modernos (lo cual no necesariamente quiere decir que se requiera una GUI.)
Recomiendo, para todos aquellos a quienes aún les estén enseñando con este compilador obsoleto, guardarlo en una carpeta llamada muso y descargar la versión del compilador GCC u otro compilador de nueva generación (como VC++ en Windowos) para su sistema operativo. Si requiere alguien de programación gráfica para ver los resultados de su lógica palpables en la pantalla puede usar SDL, que es una excelente biblioteca gráfica multiplataforma. 


  • Para Windows recomiendo ampliamente usar la distribución más actual de MingW, en concreto esta: http://nuwen.net/mingw.html (Evite usar Dev-C++ que su desarrollo ha sido parado, y si requiere un entorno gráfico use http://wxdsgn.sourceforge.net/ a pesar de también ya llevar 2 años sin actividad.)
  • En GNU/Linux: Instalar el compilador GCC desde su repositorio. ej. en debian like: sudo apt-get install build-essential
  • En Mac OS X: Instale sus herramientas de desarrollador que incluirán la versión más adecuada de GCC. 

jueves, 12 de agosto de 2010

El verano ha terminado: TuxHistory



Les muestro la primera versión de prueba, limitada, pero funcional como resultado del Google Summer of Code. Falta mucho camino por recorrer para volver a este juego en una opción real de entretenimiento, pero las bases han sido creadas. Lo veo después de mucho esfuerzo, y siento que falta aún tanto.

sábado, 7 de agosto de 2010

Corrupción de memoria? La solución es

Esto será una entrada corta. Programando en C uno no puede menos que pensar que en algún momento los punteros, allocs y por supuesto los arreglos no funcionarán como uno espera. Pero encontrar estos errores entre míles de líneas de código definitivamente no es algo agradabale, claro. sin la ayuda de buenas herramientas.
Programando Tuxhistory me encontré con una muy desagradable sorpresa, un fallo de segmentación que se daba en los lugares mas diversos. Parecería como si hubiera una sinfín de ellos esparcidos por tódo el código. El debugging simple no daba con el responsable, gdb arrojaba lugares exactos donde sedaban, pero nada parecía estar mal, hasta que, gdb señaló al culpable a glib, malloc, etc... Esto no parecía ser más que una corrupción grave de memoria.
Por suerte logré encontrar el fabuloso VALGRIND! Wow! Una estupenda herramienta para poder identificar el verdadero orígen del problema y analizar las errores de escritura, lectura, corrupcion y leaks de memoria. Logré descubrir que el verdadero problema se encontraba en un arreglo que se debordaba con el paso del tiempo y corrompía la memoria aledaña. En verdad, si se encuentran en una situación como esta, les recomiendo ampliamente usar Valgrind http://valgrind.org/ y su excelente documentación: http://valgrind.org/docs/manual/manual.html
Y lo mejor es LIBRE bajo GPL!

miércoles, 14 de julio de 2010

Arreglos dinámicos multidimensionales en C

En muchas ocaciones no queremos crear un arreglo que se utilice sólo la menoria necesaria en tiempo de ejecución. Sin embargo no resulta tan claro crear este tipo de arreglos de forma dinámica. Peor aún, si creamos un arreglo dentro de una función y queremos revolver el valor de un arreglo estatico esto sería imposible, ya que como es una variable local de la función se elimina antes de poder pasar el valor. Por lo tanto incluyo este pequeño código para poder realizar estas funciones.



#include <stdlib.h>
#define FREE(p) do { free(p); (p) = NULL; } while(0)

int **alloc_array(int, int);
void free_array(int **, int);

int **alloc_array(int x_size, int y_size)
{
int i;
int **array;
array = malloc(x_size * sizeof(int *));
if(array == NULL)
{
return NULL;
}
for(i = 0; i < x_size; i++)
{
array[i] = malloc(y_size * sizeof(int));
if(array[i] == NULL)
{
return NULL;
}
}
return array;
}

void free_array(int **array, int x_size)
{
int i;
for(i = 0; i < x_size; i++)
FREE(array[i]);
FREE(array);
}


Como vemos, tambien es necesario liberar la memoria que hemos reservado para nuestra memoria. Es necesario hacer esto para cada una de las variables y a su vez referenciar todos los punteros a NULL.

viernes, 12 de junio de 2009

Algoritmos de Ordenamiento

Comparto con ustedes un programa en C ANSI 89 que muestra la implementación de cuatro algoritmos de ordenamient: Burbuja, Selección, Inerción y una implementación básica de Quicksort son optimizaciones. Espero este ejemplo siva a todos los estudiantes para ver la aplicación de estos algoritmos.
La licencia es GPL 3 así que ya saben, pueden copiar y pegar sin problema siempre y cuando el nuevo código esté disponible bajo GPL 3 o superior.

/*
* Escrito por Jesús Manuel Mager Hois
* el 27 de abril de 2009, tomando referencias
* de Wikipedia.
*
* Descripción: Programa que genera listas
* aleatorias para después
* ordenarlas con los algoritmos
* de burbuja, selección,
* inserción y quicksort.
*
* Todos los algoritmos son simples,
* y representan únicamente
* las ideas básicas detrás de
* cada algoritmo.
*
* Lenguaje: ANSI C
*
* Bajo licencia GPL 3
*/

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define V_SIZE 10

int cont;

// Herramientas
void gen_rand(int v[], int size);
void print_vect(int v[], int size);
void swap(int v[], int o, int d);

//Algoritmos
void bubble_sort(int v[], int size);
void insert_sort(int v[], int size);
void select_sort(int v[], int size);
void quick_sort(int v[], int size);
void q_sort(int v[], int left, int right);
//void quick_sort(int v[], int size);

int main(int argc, char *argv[])
{
int v[V_SIZE];

printf("---------------------------------------------------\n");
printf("UNAM FCA SUA\n");
printf("Materia: Informática III\n");
printf("Alumno: Jesús Manuel Mager Hois\n");
printf("---------------------------------------------------\n");
printf("Este programa genera listas aleatorias que son\n");
printf("ordenadas por los siguientes algoritmos: bubblesort\n");
printf("insert sort, selecction sort y quicksort. Todos\n");
printf("son ejemplos sencillos que solo pretenden mostrar\n");
printf("los conecpts básicos de cada uno.\n");
printf("Por J. M. 2009 Bajo GPL 3. (ver código fuente)\n");
printf("############ Ordenando con Burbuja ############\n");
gen_rand(v, V_SIZE);
printf("No. Aleatorios: ");
print_vect(v, V_SIZE);

bubble_sort(v, V_SIZE);
printf("No. Ordenados : ");
print_vect(v, V_SIZE);

printf("############ Ordenando por Inserción ##########\n");
gen_rand(v, V_SIZE);
printf("No. Aleatorios: ");
print_vect(v, V_SIZE);

insert_sort(v, V_SIZE);
printf("No. Ordenados : ");
print_vect(v, V_SIZE);

printf("############ Ordenando por Selección ##########\n");
gen_rand(v, V_SIZE);
printf("No. Aleatorios: ");
print_vect(v, V_SIZE);

select_sort(v, V_SIZE);
printf("No. Ordenados : ");
print_vect(v, V_SIZE);

printf("############ Ordenando por Quicksort ##########\n");
gen_rand(v, V_SIZE);
printf("No. Aleatorios: ");
print_vect(v, V_SIZE);

quick_sort(v, V_SIZE);
printf("No. Ordenados : ");
print_vect(v, V_SIZE);



return 0;
}


void gen_rand(int v[], int size)
{
int i;

cont = cont + 1;
srand(time(NULL)*cont);
for(i=0; i<size; i++)
v[i]=rand()%100;
}


void print_vect(int v[], int size)
{
int i;
printf("[ ");
for(i=0; i<size; i++)
printf("%d ", v[i]);
printf("]\n");
}

void swap(int v[], int o, int d)
{
int temp;
temp=v[d];
v[d]=v[o];
v[o]=temp;
}

void bubble_sort(int v[], int size)
{
int i, j;
for (j=0; j<size; j++)
for (i=0; i<size-1; i++)
if(v[i]>v[i+1])
swap(v, i, i+1);
}

void insert_sort(int v[], int size)
{
int i, j, temp;
for(i=0; i<size; i++)
{
temp=v[i];
j=i-1;
while(j>=0 && v[j] >temp)
{
v[j+1] = v[j];
j--;
}

v[j+1] = temp;
}
}

void select_sort(int v[], int size)
{
int i, j, min;
for (i=0; i<size; i++)
{
min=i;

for(j=i+1; j< size; j++)
if(v[min]>v[j])
min=j;

swap(v, min, i);
}
}

void quick_sort(int v[], int size)
{
q_sort(v, 0, size-1);
}

void q_sort(int v[], int left, int right)
{

int pivot, lTmp, rTmp;
lTmp=left;
rTmp=right;
pivot=v[left];

while ( left < right )
{
while((v[right] >= pivot) && (left < right))
right--;
if(left != right)
{
v[left]=v[right];
left++;
}
while ((v[left] <= pivot) && (left<right))
left++;
if(left!=right)
{
v[right]=v[left];
right--;
}
}
v[left]=pivot;
pivot=left;
left=lTmp;
right=rTmp;

if(left<pivot)
q_sort(v, left, pivot-1);
if(right>pivot)
q_sort(v, pivot+1, right);
}