domingo, 7 de agosto de 2016

Reconocimiento de Patrones mediante redes neuronales

RECONOCIMIENTO DE PATRONES MEDIANTE REDES NEURONALES

Hola amigos en esta ocasión les comparto una aplicación que se realizo en un curso de Inteligencia Artificial que estuve llevando en la universidad espero les sea de utilidad como es de costumbre comenzare con algo de teoría para luego compartir con ustedes el código fuente de la aplicación.

REDES NEURONALES

Una red neuronal artificial es un procesador distribuido en paralelo de forma masiva que tiene una tendencia natural para almacenar conocimiento de forma experimental y lo hace disponible para su uso.

SIMILITUD CON EL CEREBRO HUMANO:

  • El conocimiento es adquirido por la red a través de un proceso de aprendizaje.
  • Los pesos sinápticos o fuerza con que están interconectadas las neuronas se utilizan para almacenar la información.

En esta publicación se describirá una aplicación típica de las redes neuronales multicapa, concretamente el reconocimiento de patrones.

PERCEPTRÓN MULTINIVEL
Dentro de las redes neuronales, las que más utilizadas son las redes con múltiples capas que funcionan hacia delante. Esta red esta compuesta por un conjunto de nodos de entrada que componen la capa de entrada, un conjunto de una o más capas ocultas de neuronas y una capa de neuronas de salida. La señal de entrada se propaga hacia adelante desde la capa de entrada por la oculta hasta la salida; este tipo de configuración se conoce como MLP o "MultiLayer Perceptrons".


El hecho de que este tipo de red se aplique para resolver con éxito multitud de problemas se debe a la utilización del algoritmo de aprendizaje que actualmente está más extendido, el algoritmo o regla back propagation, el cual es una generalización de la regla LMS "Least Mean Square", por lo tanto también se basa en la corrección del error.
Básicamente el proceso back propagation consiste en dos pasadas a través de las diferentes capas de la red, una pasada hacia adelante y una pasada hacia atrás. En la pasada hacia adelante, se aplica en la capa de entrada un patrón o vector de entrada, este propaga su efecto a través de las diferentes capas y como consecuencia produce un vector de salida. 
Durante este proceso, los pesos sinápticos de la red son fijos y no se modifican. Durante la pasada hacia atrás en cambio, los pesos si se modifican de acuerdo con la regla de corrección del error. La señal de salida real se compara con la señal deseada y como resultado se obtiene una señal de error, que se propaga en dirección contraria a través de la red modificando los pesos, de forma que, al volver a pasar el vector de entrada hacia adelante, la respuesta obtenida se asemeje más a la salida deseada. Concretando, se puede decir que un perceptrón multicapa tiene tres características:

  • El modelo de cada neurona (figura 2) incluye una función no lineal. En este caso, a diferencia del perceptrón donde es la función escalón, y debido a la necesidad de que sea una función continua y derivable, es la función sigmoide, donde uk es la suma total de la actividad interna en la neurona k (la señal de entrada) e yk la salida que se produce en la neurona.




  • La red contiene una o más capas ocultas de neuronas que no forman parte ni de la entrada ni de la salida. Estas neuronas ocultas capacitan a la red para aprender progresivamente cualquier correspondencia entre la entrada y la salida y almacenar internamente esta información.
  • La red posee un gran número de conexiones, estas vienen determinadas por los pesos de la red. Un cambio en la conexión entre las neuronas equivale a un cambio en los pesos.
La combinación de estas características, hace que la habilidad de esta red para aprender a partir del entrenamiento sea muy potente, por ejemplo es capaz de resolver el problema de la OR-exclusiva a diferencia del perceptrón.

De todas formas, este comportamiento hace que sea difícil conocer a priori la respuesta de la red. Esto se debe a dos motivos, el comportamiento no lineal de las neuronas, las cuales están muy interconectadas, (lo que hace difícil un análisis teórico de la red) y la existencia de neuronas ocultas, que impide poder "ver" como se produce el aprendizaje y determinar cuales son las características que mejorarían el aprendizaje.

El desarrollo del algoritmo back propagation proporciona un método eficiente para entrenar este tipo de redes. Aunque no es capaz de resolver todos los problemas, se ha demostrado como el mejor de todos. Su importancia está en su capacidad de autoadaptar los pesos de las neuronas intermedias para aprender la relación que existe entre el conjunto de vectores o patrones de entrada y su correspondiente salida, y poder aplicar esa relación después del entrenamiento a nuevos vectores de entrada imperfectos o con ruido. Esta capacidad se conoce como generalización. La red debe encontrar una representación interna que le permita generar las salidas deseadas durante la etapa de entrenamiento, y posteriormente durante el funcionamiento ser capaz de generar salidas para entradas que no le fueron mostradas durante el aprendizaje pero que se asemejan a alguna de las que si le fueron mostradas.

EJEMPLO DE APLICACIÓN:

Para simular el funcionamiento de un perceptrón multinivel entrenado mediante el algoritmo back propagation, se plantea un sencillo problema de reconocimiento de óptico de caracteres. Su descripción es la siguiente:

Dado un panel de entrada compuesto por una matriz de 7x5 puntos, se consideran 12 clases diferentes donde se pretenden clasificar las muestras que se introducen. Los patrones que definen correctamente a cada una de las clases son los números del 0 al 9, el punto y el guión (figura 3).

Cuando a la entrada se presente una muestra distinta de los patrones correctos, el sistema presentará a su salida la información decodificada de la clase a la que pertenece la muestra, o bien, de la clase a la cual se aproxima más. En base a este planteamiento, la red neuronal dispone de 35 entradas que se corresponden con los puntos de la matriz numerados en la figura 4. El valor de cada entrada puede ser 0 si el punto es blanco y 1 si el punto es negro. Por otro lado, dispone de 12 salidas, una por cada clase. Cuando se introduzca una muestra a la entrada únicamente se activará la salida de la clase a la que pertenezca, permaneciendo las 11 restantes desactivadas con valores próximos a cero. Se considera que una salida está activada cuando su valor es próximo a la unidad.




RESULTADOS DE LA SIMULACIÓN:
Se realizo la implementación de una red neuronal en Java.En él se ha programado un perceptrón multinivel con 35 entradas y 12 salidas. También dispone de dos capas ocultas a las cuales se les puede modificar el número de sus neuronas. La red neuronal se ha entrenado con el algoritmo back propagation fijando el valor del momento en 0.8 y el factor de aprendizaje en 0.2. En este proceso únicamente se han usado doce muestras diferentes, es decir, los doce patrones sin ningún punto erróneo.
En la tabla I se muestran los resultados obtenidos para una red neuronal de tamaño 35-30-20-12. Se aprecia que tras el proceso de entrenamiento, el sistema responde de forma casi ideal cuando se introduce un patrón sin error.


IMPLEMENTACIÓN:






package digitos;
import javax.swing.JOptionPane;
public class digitos {

        int filas_entrada = 7;
        int col_entrada = 5;
        int neuronas_entrada = 35;
        int neuronas_oculta = 4;
        int neuronas_salida = 6;
        int i, j, k;
        int respuesta;
        int[][] patron = new int[5][7];
        double[][] pesos_entrada_oculta = {{1.658270037469468, -0.49277400626557, 0.8458827274104553, -2.648551432075224},
            {1.1603936240938337, -2.518757565059801, -0.21162501186454472, 0.4483509644280242},
            {0.9770989216075385, -1.1100683771308992, 0.5996520501870459, -1.5726273589648947},
            {-0.013373815758508401, -1.8088573544737623, -0.1806466969385013, 1.5619996308946966},
            {1.5477043440927314, -0.7451285620786131, 0.9078974238442922, -2.35721899617673},
            {1.6375625959682456, 0.05352515438526517, -1.7744239541344213, 1.4633986290892553},
            {-0.4895683338278625, 1.8177553658981087, 1.2455793786819767, -2.190482442936407},
            {-1.6471092496923165, 3.229636202454947, 1.2981497902378096, -0.7057775268591435},
            {-1.5667407635246655, -1.3245937353788448, 2.136912211349784, 0.006483361683210399},
            {-0.30620712895539964, -2.082257488430547, -0.7831144540926332, 2.860170068975273},
            {1.90730880729867, 1.786324022652642, -2.7987064218352016, -0.01985271542781151},
            {0.6073378720265543, 2.964084801890168, -0.8036519556281736, -0.11124911355434831},
            {0.8920664710707924, 1.2889968423497409, 1.4524992877441234, -4.5753301334234395},
            {0.5438102680069633, 2.732096021393861, -2.46484031199823, 1.077136757466367},
            {-0.5920084064677441, -2.0176453417628553, -0.8929972447944864, 2.9295974905024473},
            {-1.2273348838814682, 0.9665674119959388, -1.5098278165865484, 2.3855936692870223},
            {0.00303354357445883, 0.001581271588014359, 0.5078086841379089, -0.15023910421206893},
            {-0.2793511488473059, 1.4245803844405784, -0.8720662059686077, -0.5734228021484368},
            {-2.0275946046978293, -3.0777889662395226, 2.599080818031238, 1.6382349764441964},
            {1.7261757824595334, 1.8271668605813292, -2.6230163017984798, -0.023102087227872905},
            {-1.0400284786362686, 0.7483028076885504, -1.4201964658386028, 2.5893497462079242},
            {-1.2173094553360448, 1.0413190887119863, -1.3232448940438146, 2.7280471684208245},
            {-2.0889500107780266, 1.2113367713729557, 1.834844976337663, 0.48588965399759093},
            {-1.3959767352554984, 1.340974141434604, 0.4669554523335953, 0.8396877795787216},
            {0.5504882733683742, -0.007280194521717799, -1.049601349327548, 0.10628579988651637},
            {1.443454707114963, -1.1329167860893807, -1.202733639186253, -1.1206540048585907},
            {-0.4331284905557263, -1.5624137840495447, 1.116280151906849, 1.4607759610209936},
            {-0.5819930384824622, 1.758192614385909, 0.9171022839298032, -2.0753538337866986},
            {-1.3256304624056356, 1.044596834400223, 0.26717962626473013, 1.1753997160814336},
            {1.5797847092614183, -1.103413366841749, -1.1869484693704706, -1.0426817633297494},
            {-0.42533166857338317, -1.5201849827392802, 0.8863374072683927, 1.5286999085413167},
            {0.7681134972990639, -0.9328664559674184, 0.3210235342096992, -1.6081085875846808},
            {0.8656526958020259, -1.075079526248985, 0.4316305641408157, 1.4876790164633573},
            {-0.3418033974126609, 0.26137924890846875, 0.44588921383473606, -0.44772778571106026},
            {-0.5446034869269726, -1.7972802169693622, 1.143196716800601, 1.244775128422288}};
        
        
        double[][] pesos_oculta_salida = {{0.43621096542085136, -4.4770098664620495, -3.4380683245083805, 1.8296159164887345, -8.118120689656921, 5.695458556119513},
            {-1.027258581059679, 5.023126898792579, -7.757507526435068, -7.156764734520939, 4.478145059142636, 2.0603488963286387},
            {-8.390374693334456, 2.4451631927893267, 1.1247117391293466, 3.3697153535415416, -1.6716192668623555, -5.293714775954221},
            {5.151637910542471, -7.364970554525968, 4.923974784168798, -6.575339204075441, 4.552711228559867, -6.736958999045322}};
        
        
        
        double[] bias_entrada = {-0.4332161363101981,
            -0.5121521114762152,
            -0.39471528129652694,
            -0.5445351790184725,
            -0.4226637563836109,
            -0.5350195879964442,
            -0.3350043955733998,
            -0.38791367789336956,
            -0.3785593217087376,
            -0.5461130438610313,
            -0.554558738450257,
            -0.44288964426354815,
            -0.4380540832801621,
            -0.5350394221895475,
            -0.5580057611292775,
            -0.5560034483432901,
            -0.12912939908250873,
            -0.4139805211691567,
            -0.48481548633114296,
            -0.5388170156483836,
            -0.5565657646610173,
            -0.5633684138684646,
            -0.26352247776223936,
            -0.17951484914217863,
            -0.3253386781429675,
            -0.5422856630504476,
            -0.3859925425287016,
            -0.2926752007933522,
            -0.33661294128974667,
            -0.5351966380727077,
            -0.43172146451991633,
            -0.3614435550912756,
            -0.3009252579538338,
            0.13116124654486072,
            -0.42061848358615506,};
        double[] bias_oculta = {-0.5396208362695601,
            0.2293253598179893,
            0.9023280877608804,
            -0.5367884581404073};
        
        double[] bias_salida = {-1.3662965402953284,
            -2.7832950402557444,
            -1.5508290258166995,
            -0.47188562328444716,
            -4.298755314842922,
            -2.4180200713742552,};
        
        int[] entrada = new int[neuronas_entrada];
        double[] sumatoria_entrada = new double[neuronas_entrada];
        double[] sigmoidal_entrada = new double[neuronas_entrada];
        
        double[] oculta = new double[neuronas_oculta];
        double[] sumatoria_oculta = new double[neuronas_oculta];
        double[] sigmoidal_oculta = new double[neuronas_oculta];
        
        double[] salida = new double[neuronas_salida];
        double[] sumatoria_salida = new double[neuronas_salida];
        double[] sigmoidal_salida = new double[neuronas_salida];
        public digitos(int patrones[][])
        {
            this.patron=patrones;
        }
        public void reconocimiento()
        {
            //procesamiento de la capa de entrada
            //linealizar el patron de entrada
            for (i = 0; i  <  filas_entrada; i++) {
                for (j = 0; j  <  col_entrada; j++) {

                    entrada[i * col_entrada + j] = patron[i][j];
                }
            }

            //1.2 sumar la entrada con el bias y calcular sigmidal
            for (i = 0; i  <  neuronas_entrada; i++) {
                sumatoria_entrada[i] = entrada[i] + bias_entrada[i];
                sigmoidal_entrada[i] = 1 / (1 + Math.exp(-1 * sumatoria_entrada[i]));
            }
            //2. procesamiento de la capa oculta
            // 2.1 sumatoria de productos de entrada por peso
            for (j = 0; j  <  neuronas_oculta; j++) {
                oculta[j] = 0;
                for (i = 0; i  <  neuronas_entrada; i++) {
                    oculta[j] += sigmoidal_entrada[i] * pesos_entrada_oculta[i][j];
                }
            }
            //2.2 sumatoria mas bias y calculo de sigmoidal
            for (i = 0; i  <  neuronas_oculta; i++) {
                sumatoria_oculta[i] = oculta[i] + bias_oculta[i];
                sigmoidal_oculta[i] = 1 / (1 + Math.exp(-1 * sumatoria_oculta[i]));
            }

            //3. procesamiento de la capa salida
            //3.1 suamtoria de productos de salida x peso
            for (j = 0; j  <  neuronas_salida; j++) {
                salida[j] = 0;
                for (i = 0; i  <  neuronas_oculta; i++) {
                    salida[j] += sigmoidal_oculta[i] * pesos_oculta_salida[i][j];
                }
            }
            //3.2 sumatoria mas bias y calculo de sigmoidal
            for (i = 0; i  <  neuronas_salida; i++) {
                sumatoria_salida[i] = salida[i] + bias_salida[i];
                sigmoidal_salida[i] = 1 / (1 + Math.exp(-1 * sumatoria_salida[i]));
                System.out.println("Sigmoidal [" + i + "]- " + sigmoidal_salida[i]);
            }
            // 4.construyendo la interface de salida
            double mayor = -0.999;
            int neurona_activada = -1;
            for (i = 0; i  <  neuronas_salida; i++) {
                if (sigmoidal_salida[i]  >  mayor) {

                    mayor = sigmoidal_salida[i];
                    neurona_activada = i;
                }
            }
            if (mayor  >  0.80 ) { // heuristica para saber si el patron es coherente
                switch (neurona_activada) {
                    case 0:
                        respuesta=0;
                        System.out.println("RESPUESTA:"+respuesta);
                        break;
                    case 1:
                        respuesta=1;
                        System.out.println("RESPUESTA:"+respuesta);
                        break;
                    case 2:
                        respuesta=2;
                        System.out.println("RESPUESTA:"+respuesta);
                        break;
                    case 3:
                        respuesta=3;
                        System.out.println("RESPUESTA:"+respuesta);
                        break;
                    case 4:
                        respuesta=4;
                        System.out.println("RESPUESTA:"+respuesta);
                        break;
                    case 5:
                        respuesta=5;
                        System.out.println("RESPUESTA:"+respuesta);
                        break;

                }
            } else
            { 
                respuesta=-1;
                System.out.println("RESPUESTA:"+respuesta);
            }
        }
        public int getReconocimiento()
        {
            return respuesta;
        }

}


RESULTADOS OBTENIDOS EN LA IMPLEMENTACIÓN



jueves, 23 de junio de 2016

Implementación de un Sistema Experto Probabilistico EDA (Enfermedad Diarreica Aguda) usando el Teorema de Bayes con conexion a Mysql



Implementación de un Sistema Experto Probabilistico EDA (Enfermedad Diarreica Aguda)  usando el Teorema de Bayes con conexión a Mysql


El teorema de Bayes, en la teoría de la probabilidad, es una proposición planteada por el filósofo inglés Thomas Bayes (1702-1761)1 en 1763,2 que expresa la probabilidad condicional de un evento aleatorio A dado B en términos de la distribución de probabilidad condicional del evento B dado A y la distribución de probabilidad marginal de sólo A.

En términos más generales y menos matemáticos, el teorema de Bayes es de enorme relevancia puesto que vincula la probabilidad de A dado B con la probabilidad de B dado A. Es decir, que sabiendo la probabilidad de tener un dolor de cabeza dado que se tiene gripe, se podría saber (si se tiene algún dato más), la probabilidad de tener gripe si se tiene un dolor de cabeza. Muestra este sencillo ejemplo la alta relevancia del teorema en cuestión para la ciencia en todas sus ramas, puesto que tiene vinculación íntima con la comprensión de la probabilidad de aspectos causales dados los efectos observados.



DESCRIPCIÓN DEL PROBLEMA:

Un centro médico tiene una BD con las historias clínicas de N = 1000 pacientes.
Estas historias clínicas se resumen gráficamente en la figura. Hay 700 pacientes (región sombreada) que tienen la enfermedad adenocarcinoma gástrico (G), y 300 que no la tienen (se considera estar sano como otro valor posible de la enfermedad). Tres síntomas, dolor (D), pérdida de peso (P) y vómitos (V ), se considera que están ligados a esta enfermedad. Por tanto, cuando un paciente nuevo llega al centro médico, hay una probabilidad 700/1000 = 70% de que el paciente tenga adenocarcinoma gástrico. Esta es la probabilidad inicial, o “a priori”, puesto que se calcula con la información inicial, antes de conocer información alguna sobre el paciente.


Se pide crear un SEP que permita diagnosticar el nivel de probabilidad que tiene un paciente de haber adquirido esta enfermedad en base a los sintomas antes mencionados.


Base de datos:

create database Enfermedad;
use Enfermedad;
create table diagnostica(
    codigo int auto_increment primary key,
    dolor char(1),
    vomito char(1),
    p_peso char(1),
    estado char(1),
    cantidad int
);

insert into diagnostica(dolor, p_peso,vomito,estado,cantidad) values ('s','s','s','s',220);
insert into diagnostica(dolor, p_peso,vomito,estado,cantidad) values ('s','s','s','n',220);
insert into diagnostica(dolor, p_peso,vomito,estado,cantidad) values ('s','s','n','s',25);
insert into diagnostica(dolor, p_peso,vomito,estado,cantidad) values ('s','s','n','n',25);
insert into diagnostica(dolor, p_peso,vomito,estado,cantidad) values ('s','n','s','s',95);
insert into diagnostica(dolor, p_peso,vomito,estado,cantidad) values ('s','n','s','n',95);
insert into diagnostica(dolor, p_peso,vomito,estado,cantidad) values ('s','n','n','s',10);
insert into diagnostica(dolor, p_peso,vomito,estado,cantidad) values ('s','n','n','n',10);
insert into diagnostica(dolor, p_peso,vomito,estado,cantidad) values ('n','s','s','s',4);
insert into diagnostica(dolor, p_peso,vomito,estado,cantidad) values ('n','s','s','n',9);
insert into diagnostica(dolor, p_peso,vomito,estado,cantidad) values ('n','s','n','s',5);
insert into diagnostica(dolor, p_peso,vomito,estado,cantidad) values ('n','s','n','n',12);
insert into diagnostica(dolor, p_peso,vomito,estado,cantidad) values ('n','n','s','s',31);
insert into diagnostica(dolor, p_peso,vomito,estado,cantidad) values ('n','n','s','n',76);
insert into diagnostica(dolor, p_peso,vomito,estado,cantidad) values ('n','n','n','s',50);
insert into diagnostica(dolor, p_peso,vomito,estado,cantidad) values ('n','n','n','n',113);



Programa en Prolog:
% Autor: Andrés Esquivel
:-use_module(library(tabular)).
:-use_module(library(autowin)).
:-use_module(library(pce)),pce_image_directory('./Imgs').

%CONEXION A LA BD
conexion:- odbc_connect('swiprolog',_,[user('root'),password('123456'),alias(bd),open(once)]),
           odbc_prepare(bd,'SELECT cantidad FROM diagnostica where estado=? and dolor=? and vomito=? and p_peso=?',
           [atom>char(1),atom>char(1),atom>char(1),atom>char(1)],
           Handle,
           [types([integer])]),
           abolish(odbc_handle/1),
           assert(odbc_handle(Handle)).

%EJECUTAR CONSULTA
run_stmt(R,E,P1,P2,P3):- odbc_handle(Handle),
                      odbc_execute(Handle,[E,P1,P2,P3],row(R)).

%Cargar Imagenes en los frames
load_img(Ventana, Figura, Imagen, Posicion) :-
         new(Figura, figure), % crea nueva instancia Figura de clase figure
         new(Bitmap, bitmap(resource(Imagen),@on)), %instancia Bitmap, transparencia @on
         send(Bitmap, name, 1),
         send(Figura, display, Bitmap),
         send(Figura, status, 1),
         send(Ventana, display, Figura, Posicion).


%ASIGNAR IMAGENES A VENTANA PRINCIPAL Y VENTANA RESULTADOS
resource(imgTab, image, image('enfermo.jpg')).
resource(imgConEnf, image, image('noenfermo.jpg')).
resource(imgSinEnf, image, image('sienfermo.jpg')).


%VENTANA PRINCIPAL
ventana:-
        new(F, frame('Sistema Experto - Adenocarcinoma Gastrico ')),
        new(Tablero, window('Tablero',size(535,358))),
        load_img(Tablero, ImgTablero ,imgTab, point(0,0)),
        send(F, append, new(D, dialog)),
        send(D, append, new(MB, menu_bar)),
        send(MB, append, new(Evaluacion, popup(evaluacion))),
        send(MB, append, new(Autores, popup(ayuda))),
        send_list(Evaluacion, append,
        [ menu_item(diagnostico,message(@prolog,interfaz,no)),menu_item(quit,message(F, destroy))]),
        send_list(Informacion, append,

        [ menu_item('Cortijo Flores Darwin Fransua',message(@display,inform,'ESTUDIANTE DE LA  UNIVERSIDAD NACIONAL DE TRUJILLO - INTELIGENCIA ARTIFICIAL'))]),
        send_list(Informacion, append,

        [ menu_item('Esquivel Díaz Estuardo Andrés',message(@display,inform,'ESTUDIANTE DE LA UNIVERSIDAD NACIONAL DE TRUJILLO - INTELIGENCIA ARTIFICIAL'))]),
        send_list(Informacion, append,

        [ menu_item('Huaroto Rivera Luilly Anthony',message(@display,inform,'ESTUDIANTE DE LA UNIVERSIDAD NACIONAL DE TRUJILLO - INTELIGENCIA ARTIFICIAL'))]),

        send(D,append(Tablero)),
        send(F,open).



%VENTANA SECUNDARIA
interfaz(E):-E=no,
            new(Dialog,dialog('Preguntas sobre los Sintomas ')),
                      new(P1,menu('1. Tiene dolor?')),
                      send_list(P1,append,[s,n]),
                      new(P2,menu('2. Tiene vómitos?')),
                      send_list(P2,append,[s,n]),
                      new(P3,menu('3. Tiene pérdida de peso?')),
                      send_list(P3,append,[s,n]),
                      send(Dialog,append(P1)),
                      send(Dialog,append(P2)),
                      send(Dialog,append(P3)),
                      send(Dialog,append,button(ok,and(message(@prolog,
                           diagnosticoProbabilistico,
                           P1?selection,
                           P2?selection,
                           P3?selection)
                           ))),
                      send(Dialog,append,button(cancel,message(Dialog,destroy))),
                      send(Dialog,open).


%VENTANA RESULTADOS - LLAMADA POR VENTANA SINTOMAS
diagnosticoProbabilistico(P1,P2,P3):-
                                bayes(s,P1,P2,P3,Respuesta),
                                write('Respuesta'),
                                write(Respuesta),
                                %writeln(Respuesta),
                                new(Conclusion,dialog('Diagnostico Probabilistico EDA')),
                                new(Tablero, window('Tablero',size(300,200))),
                                ((Respuesta<0 .50="">load_img(Tablero, ImgEnfermo ,imgConEnf, point(0,0));load_img(Tablero, ImgEnfermo ,imgSinEnf, point(0,0))),
                                ProBayesPorcentual is Respuesta*100,
                                send(Conclusion,append(Tablero)),
                                send(Conclusion,append,label(a,'Usted tiene la EDA con una probabilidad de')),
                                send(Conclusion,append,label(a,ProBayesPorcentual)),
                                send(Conclusion,append,label(a,'%')),
                                send(Conclusion,append,button(ok,message(Conclusion,destroy))),
                                send(Conclusion,open).

%FORMULA APOSTERIORI - LLAMADA POR VENTANA RESULTADOS
bayes(E,P1,P2,P3,Probabilidad):-E=s,
                                conexion,
                                writeln(''),
                                run_stmt(R1,E,P1,P2,P3),
                                writeln(R1),
                                run_stmt(R2,n,P1,P2,P3),
                                writeln(R2),
                                Probabilidad is (R1/(R1+R2)),
                                write('Usted tiene la EDA con una probabilidad de '),
                                writeln(Probabilidad).






Imágenes usadas:






RESULTADOS:





Espero les sirva si tiene problemas con la conexion odbc - mysql les recomiendo vean esto.


jueves, 19 de mayo de 2016

Implementación del problema del granjero

Este acertijo es un forma parte de los denominados “puzzles de cruzar el río”, en los que el objetivo es mover una serie de objetos al otro lado del río siguiendo una serie de normas.
La aparición más temprana de este problema es en el manuscrito medieval Propositiones ad Acuendos Juvenes, los tres objetos son un lobo, una cabra y una col. Existen variaciones de este acertijo siendo los objetos una cabra, una oveja y un repollo; un zorro, una gallina y unas semillas; Un zorro, un ganso y una mazorca de maíz y una pantera, un cerdo y unas gachas.La lógica del acertijo sigue siendo la misma.
Este acertijo era uno de los favoritos de Lewis Carroll, y ha sido incluido en varios libros de matemática recreativa.


Planteamiento del problema:

Un granjero fue al mercado y compró un zorro una gallina y un maíz. Para volver a su casa tenía que cruzar un río. El granjero dispone de una barca para cruzar a la otra orilla, pero en la barca solo caben él y una de sus compras. Además, si el lobo se queda solo con la gallina se la come y si la gallina se queda sola con el maíz se la come. El reto del granjero era cruzar él mismo y dejar sus compras a la otra orilla del río, dejando cada compra intacta. ¿Cómo lo hizo?

Solución Teórica:

El primer paso el llevar la gallina a través del río, ya que de otro modo la gallina o el maíz serían devoradas. Cuando el granjero vuelve a la orilla original, puede elegir entre llevar al zorro o al maíz al otro lado. Si lleva al lobo, deben volver luego para llevar la al maíz, entonces el lobo se comería a la gallina. Si lleva al maíz al otro lado, necesitará volver para coger al zorro, entonces la gallina sería comida. Aquí se encuentra el dilema, se resuelve llevando el zorro (o el maíz) en la barca y trayendo de vuelta a la gallina. Ahora podemos llevar la el maíz (o el zorro), dejando la gallina y, finalmente, volver a buscar la gallina.
  • La solución se resume de la siguiente manera:
  • Deja a la gallina al otro lado
  • Vuelve
  • Deja al zorro en el otro lado
  • Regresa con la gallina
  • Deja el maíz en el otro lado
  • Vuelve
  • Deja la gallina al otro lado
De modo, que hay siete pasos: cuatro hacia la derecha y tres hacia la izquierda.

Implementación:


%accion(estado(Gra,Zorro,Gall,Maiz),estado(1,Z,1,M)).

estadoMalo(estado(0,1,1,_)).
estadoMalo(estado(0,_,1,1)).
estadoMalo(estado(1,0,0,_)).
estadoMalo(estado(1,_,0,0)).

accion(estado(0,0,G,M), estado(1,1,G,M), 'Llevar al zorro').
accion(estado(1,1,G,M), estado(0,0,G,M), 'Traer al zorro').
accion(estado(0,Z,0,M), estado(1,Z,1,M), 'Llevar la gallina').
accion(estado(1,Z,1,M), estado(0,Z,0,M), 'Traer la gallina').
accion(estado(0,Z,G,0), estado(1,Z,G,1), 'Llevar el maiz').
accion(estado(1,Z,G,1), estado(0,Z,G,0), 'Traer el maiz').
accion(estado(1,Z,G,M), estado(0,Z,G,M), 'Regresa solo').
accion(estado(0,Z,G,M), estado(1,Z,G,M), 'Ir solo').

pertenece(X,[X|_]):-!.
pertenece(X,[_|L]):-pertenece(X,L).

camino(estado(1,1,1,1),V,V).
camino(Estado,Visitado,R):-accion(Estado,NuevoEstado,A), not(estadoMalo(NuevoEstado)),
                   not(pertenece(NuevoEstado,Visitado)),
                   writeln(A),
                   camino(NuevoEstado,[NuevoEstado|Visitado],R).

solucion(L):-camino(estado(0,0,0,0),[estado(0,0,0,0)],L).

Implementación del problema de las Jarras



Es un problema que ayuda a desarrollar la destreza intelectual del usuario.
Al resolver este problema, no solo implica obtener el resultado, sino comprender la importancia de usar La
Teoría de Grafos y el algoritmo de Recorrido en Profundidad y Anchura en la solución de los problemas lógicos y algoritmos actuales, ya que nos permite hacerlo de forma ordenada y se pueden usar técnicas como el Backtracking.


Planteamiento del Problema:
  • Se tienen dos jarras, una de 4 litros de capacidad y otra de 3.
  • Ninguna de ellas tiene marcas de medición.
  • Se tiene una bomba que permite llenar las jarras de agua.
  • Averiguar cómo se puede lograr tener exactamente 2 litros de agua en la jarra de 4 litros de capacidad.
  • Enfocar este ejercicio en un área de trabajo como la agricultura, para ver su importancia y aplicación.

Análisis del problema:

Problema como el anterior es resuelto con un simple algoritmo de búsqueda; pero lo que hay que tener claro primero es cuáles son los elementos del diseño del algoritmo.
En este caso son 4 los elementos:
  • Estado inicial
  • Estado final
  • Acciones
  • Función de costo
Solución Teórica:
  • Llenar la jarra de 4 litros completamente (para ello, la jarra de 4 litros no debe estar completamente llena).
  • Llenar la jarra de 3 litros completamente (para ello, la jarra de 3 litros no debe estar completamente llena).
  • Vaciar la jarra de 4 litros (para ello, la jarra debe contener algo de líquido).
  • Vaciar la jarra de 3 litros (para ello, la jarra debe contener algo de líquido).
  • Verter el contenido de la jarra de 4 litros en la jarra de 3 litros (para ello, la jarra de 4 litros debe contener algo de líquido y la de 3 litros no estar completamente llena).
  • Verter el contenido de la jarra de 3 litros en la jarra de 4 litros (para ello, la jarra de 3 litros debe contener algo de líquido y la de 4 litros no estar completamente llena).


Implementación:


%llenar A
accion(e(X,Y),e(4,Y)):- X < 4.

%llenar B
accion(e(X,Y),e(X,3)):- Y < 3.

%vaciar A
accion(e(X,Y),e(0,Y)):- X > 0.

%vaciar B
accion(e(X,Y),e(X,0)):- Y > 0.

%vertir A en B : jarra A se queda vacia
accion(e(X,Y),e(0,Z)):- X > 0,
                        Y < 3,
                        Z is X + Y,
                        Z =< 3.
                        
%vertir A en B : jarra B se queda llena
accion(e(X,Y),e(Z,3)):- X > 0,
                        Y < 3,
                        Z is X+Y-3,
                        Z =< 4.
                        
%vertir B en A : jarra B se queda vacia
accion(e(X,Y),e(Z,0)):- Y > 0,
                        X < 4,
                        Z is X + Y,
                        Z =< 4.

%vertir B en A : jarra A se queda llena
accion(e(X,Y),e(4,Z)):- Y > 0,
                        X < 3,
                        Z is X+Y-4,
                        Z =< 3.

menu:-siguiente(e(4,0),[e(4,0)],R),
      procesa(R).

procesa([]):- !.
procesa(H|C):- procesa(C),
               writeln(H).
                        
pertenece(E,[E|_]):- !.
pertenece(E,[_|C]):- pertenece(E,C).
siguiente(e(2,_),V,V):- !.
siguiente(e(_,2),V,V):- !.
siguiente(e(X,Y),V,R):- accion(e(X,Y), e(Xs,Ys)),
                    %format('estado(~W,~W)',[Xs,Ys]),
                    not(pertenece(e(Xs,Ys), V)),
                    siguiente(e(Xs,Ys), [e(Xs,Ys)|V],R).

Métodos de Busqueda

Búsquedas por profundidad

La búsqueda en profundidad, llamada DepthFirstSearch en inglés, es un algoritmo usado para recorrer o buscar elementos en un árbol o un grafo y pertenece al grupo de las búsquedas no informadas (sin heurísticas). Su procedimiento consiste en visitar todos los nodos de forma ordenada pero no uniforme en un camino concreto, dejando caminos sin visitar en su proceso. Una vez llega al final del camino vuelve atrás hasta que encuentra una bifurcación que no ha explorado, y repite el proceso hasta acabar el árbol (esto se conoce como Backtracking). En la siguiente figura mostramos el orden de visita, siendo los números en naranja dicho orden:



En cada llamada recursiva marcaremos el nodo actual como visitado y luego verificamos si es el nodo buscado para salir de la recursión, este será nuestro caso base. De no ser el nodo requerido, se hace la llamada recursiva con todos los nodos hijos del nodo actual, pero en este caso, a diferencia del recorrido BFS, no se visitarán todos los hijos de forma consecutiva, sino que el algoritmo recorrerá en profundidad hasta llegar a un nodo extremo o nodo hoja, antes de retornar al ambiente de recursión en donde se encuentran los otros nodos hijos. El orden en que se eligen las ramas en un recorrido DFS está determinado por el tipo de recorrido de procesamiento de árbol que se haya elegido, estos pueden ser:

  • Pre-orden: Se procesa primero la raíz, luego la rama izquierda y luego las ramas siguientes hasta llegar a la que se encuentra más a la derecha.
  • Post-orden: Se procesa el árbol desde las ramas izquierdas hasta la que se encuentra más a la derecha. Finalmente se procesa el nodo raíz
  • Simétrico o In-orden: Se procesa la rama de la izquierda, luego el nodo raíz y luego la rama derecha.
Aplicado al caso del Problema de las jarras: 
En el caso del problema de las jarras, se genera el siguiente grafo de búsqueda en profundidad:


Este grafo de búsqueda por profundidad nos denota la siguiente tabla de búsqueda en profundidad:


Estados de la solución:  ((2 3) (4 1) (0 1) (1 0) (1 3) (4 0) (0 0))


Búsquedas por anchura

La búsqueda en anchura (o búsqueda en amplitud), llamada BreadthFirstSearch en inglés, es un algoritmo usado para recorrer o buscar elementos en una estructura de datos como los árboles y los grafos.Pertenece al grupo de las búsquedas no informadas(sin heurísticas). Su procedimiento consiste en ir visitando todos los nodos de un nivel antes de proceder con el siguiente nivel tal y como mostramos en la siguiente figura (los números en naranja indican el orden de exploración de los nodos):



De modo que lo primero que hará será visitar la raíz, luego los hijos de la raíz, luego los hijos de cada uno de estos hijos y así sucesivamente. 
Aplicado al caso del Problema de las jarras: 
En el caso del problema de las jarras, se genera el siguiente grafo de búsqueda en anchura:

Este grafo de búsqueda por anchura nos denota la siguiente tabla de búsqueda en anchura:



domingo, 17 de enero de 2016

IMPLEMENTACIÓN DE LOS MÉTODOS DE ORDENACIÓN EN PYTHON




Hola amigos tiempo atrás realice un post acerca delos diferentes métodos de ordenación  y su respectivo análisis de complejidad con su implementacion en java, si desean verlo pueden pasarse por la siguiente publicación:

En la presente publicación comparto con ustedes la implementación de estos métodos pero en python, un lenguaje de programación con el cual comencé a trabajar y me vi con la necesidad de implementar estos métodos 

Método de ordenamiento  Burbuja:

def ordenamientoBurbuja(lista,tam):
    for i in range(1,tam):
        for j in range(0,tam-i):
            if(lista[j] > lista[j+1]):
                k = lista[j+1]
                lista[j+1] = lista[j]
                lista[j] = k;
 
def imprimeLista(lista,tam):
    for i in range(0,tam):
        print lista[i]
 
def leeLista():
    lista=[]
    cn=int(raw_input("Cantidad de numeros a ingresar: "))
 
    for i in range(0,cn):
        lista.append(int(raw_input("Ingrese numero %d : " % i)))
    return lista
 
A=leeLista()
ordenamientoBurbuja(A,len(A))
imprimeLista(A,len(A))


Método de ordenamiento  Shell Sort:
def ordenShell(lista,tam):
    inc=1
    for inc in range(1,tam,inc*3+1):
        while inc>0:
            for i in range(inc,tam):
                j=i
                temp=lista[i]
                while j>=inc and lista[j-inc]>temp:
                    lista[j]=lista[j-inc]
                    j=j-inc
                lista[j]=temp
            inc=inc/2
 
def imprimeLista(lista,tam):
    for i in range(0,tam):
        print lista[i]
 
def leeLista():
    lista=[]
    cn=int(raw_input("Cantidad de numeros a ingresar: "))
 
    for i in range(0,cn):
        lista.append(int(raw_input("Ingrese numero %d : " % i)))
    return lista

Método de ordenamiento  QuickSort:
def quicksort(lista,izq,der):
    i=izq
    j=der
    x=lista[(izq + der)/2]
 
    while( i <= j ):
        while lista[i]< x and j< =der:
            i=i+1
        while x< lista[j] and j > izq:
            j=j-1
        if i<=j:
            aux = lista[i]; lista[i] = lista[j]; lista[j] = aux;
            i=i+1;  j=j-1;
 
        if izq < j:
        quicksort( lista, izq, j );
    if i < der:
        quicksort( lista, i, der );
 
def imprimeLista(lista,tam):
    for i in range(0,tam):
        print lista[i]
 
def leeLista():
    lista=[]
    cn=int(raw_input("Cantidad de numeros a ingresar: "))
 
    for i in range(0,cn):
        lista.append(int(raw_input("Ingrese numero %d : " % i)))
    return lista
 
A=leeLista()
quicksort(A,0,len(A)-1)
imprimeLista(A,len(A))

Método de ordenamiento  QuickSort:
def quicksort(lista,izq,der):
    i=izq
    j=der
    x=lista[(izq + der)/2]
 
    while( i <= j ):
        while lista[i]< x and j<=der:
            i=i+1
        while x< lista[j] and j>izq:
            j=j-1
        if i<=j:
            aux = lista[i]; lista[i] = lista[j]; lista[j] = aux;
            i=i+1;  j=j-1;
 
        if izq < j:
        quicksort( lista, izq, j );
    if i < der:
        quicksort( lista, i, der );
 
def imprimeLista(lista,tam):
    for i in range(0,tam):
        print lista[i]
 
def leeLista():
    lista=[]
    cn=int(raw_input("Cantidad de numeros a ingresar: "))
 
    for i in range(0,cn):
        lista.append(int(raw_input("Ingrese numero %d : " % i)))
    return lista
 
A=leeLista()
quicksort(A,0,len(A)-1)
imprimeLista(A,len(A))

Método de ordenamiento  Insercion:
def insercion(lista,tam):
    for i in range(1,tam):
        v=lista[i]
        j=i-1
        while j >= 0 and lista[j] > v:
            lista[j+1] = lista[j]
            j=j-1
        lista[j+1]=v
 
def imprimeLista(lista,tam):
    for i in range(0,tam):
        print lista[i]
 
def leeLista():
    lista=[]
    cn=int(raw_input("Cantidad de numeros a ingresar: "))
 
    for i in range(0,cn):
        lista.append(int(raw_input("Ingrese numero %d : " % i)))
    return lista
 
A=leeLista()
insercion(A,len(A))
imprimeLista(A,len(A))

Método de ordenamiento  HeapSort:
def heapsort(lista,tam):
    for k in range(tam-1,-1,-1):
        for i in range(0,k):
            item=lista[i]
            j=(i+1)/2
            while j>=0 and lista[j]< item:
                lista[i]=lista[j]
                i=j
                j=j/2
            lista[i]=item
        temp=lista[0];
    lista[0]=lista[k];
    lista[k]=temp;
 
def imprimeLista(lista,tam):
    for i in range(0,tam):
        print lista[i]
 
def leeLista():
    lista=[]
    cn=int(raw_input("Cantidad de numeros a ingresar: "))
 
    for i in range(0,cn):
        lista.append(int(raw_input("Ingrese numero %d : " % i)))
    return lista
 
A=leeLista()
heapsort(A,len(A))
imprimeLista(A,len(A))

Método de ordenamiento  MergeSort:
def merge_sort(lista): 
    n = len(lista) 
    if(n == 1): return lista 
    izquierda = merge_sort(lista[:(n/2)]) 
    derecha = merge_sort(lista[(n/2):]) 
    return merge(izquierda, derecha) 
 
def merge(izquierda, derecha): 
    resultado = [] 
    i = 0 
    j = 0 
    len_izquierda = len(izquierda) 
    len_derecha = len(derecha) 
 
    while(i < len_izquierda or j < len_derecha): 
        if(i >= len_izquierda): 
            resultado.append(derecha[j]) 
            j = j + 1 
        elif(j >= len_derecha): 
            resultado.append(izquierda[i]) 
            i = i + 1 
        elif(izquierda[i] < derecha[j]): 
            resultado.append(izquierda[i]) 
            i = i + 1 
        else: 
            resultado.append(derecha[j]) 
            j = j + 1 
    return resultado 

def imprimeLista(lista):
    for i in range(0,len(lista)):
        print (str(lista[i]))
 
def leeLista():
    lista=[]
    cn=int(input("Cantidad de numeros a ingresar: "))
    for i in range(0,cn):
        lista.append(int(input("Ingrese numero %d : " % i)))
    return lista
 
A=leeLista()
merge_sort(A)
imprimeLista(A)

jueves, 18 de junio de 2015

ANÁLISIS Y DISEÑO DE ALGORITMOS - INTRODUCCIÓN




El razonamiento de las computadoras es diferente al de los seres humanos, es por ello que a quienes comienzan a programar les resulta una tarea difícil. El primer paso es no desesperarse, después se debe entender cómo razonan los humanos y posteriormente analizar cómo lo haría una computadora. Es importante hacer hincapié en que la parte más compleja de este proceso es el desarrollo de un algoritmo (diagrama de flujo o pseudocódigo), ya que constituye la parte lógica. Codificar, independientemente del lenguaje, es simplemente trascribir un algoritmo al lenguaje respectivo. El concepto de algoritmo lo utilizamos, en general, todas las disciplinas basadas en las matemáticas y la física, por ende en la programación, y es la etapa previa a la codificación.

1. ¿QUÉ ES UN ALGORITMO?

Un algoritmo es un método para resolver un problema.

Un ser humano piensa y se comporta como tal siguiendo una secuencia lógica de acciones. Esta misma asociación podría acoplarse en cuanto al rol de una computadora se refiere.
Afirmando que una computadora es una máquina electrónica capaz de realizar y manejar datos en memoria siguiendo una secuencia lógica de pasos, para aquellos que haya sido programada.
Los algoritmos poseen hoy una gran importancia tanto para informática , robótica y ciencias de la computación , por medio de algoritmos se llega a un orden de ideas y un  proceso correcto en la elaboración de maquinarias y robots lo que conlleva a un avance en la tecnología y un mayor progreso a nivel mundial
Los algoritmos conllevan a llevar un proceso y un orden de ideas en todos los aspectos , pues cada actividad por mínima que sea requiere un orden que se da por medio de los grandes algoritmos que creamos así sean mentales.
La resolución de problemas exige el diseño de un algoritmo que resuelva el problema propuesto.



2. ¿QUÉ ES UN LENGUAJE DE PROGRAMACIÓN?

Tendemos a pensar como lenguaje natural aquel medio utilizado por una persona para expresar algún sentimiento o emoción, es decir de manera más general un proceso pues  nos permite interactuar en muchos sentidos.
En el rol de una computadora es más o menos lo mismo pues definimos como lenguaje de programación aquel conjunto de normas o reglas lógicas definidas por medio de símbolos o palabras  claves (reservadas) que nos permitan construir un programa o simplemente otorgar la solución a un problema.
El lenguaje de programación es la combinación de símbolos y reglas que permiten la elaboración de programas con los cuales la computadora puede realizar tareas o resolver problemas de manera eficiente.

3. RELACIÓN ENTRE EL DISEÑO DE ALGORITMOS Y LOS  LENGUAJES DE PROGRAMACIÓN

Los algoritmos son independientes tanto del lenguaje de programación en que se expresan como de la computadora que los ejecuta.
En cada problema el algoritmo se puede expresar en un lenguaje diferente de programación y ejecutarse en una computadora distinta; sin embargo, el algoritmo será el mismo. Así por ejemplo una persona puede expresar una receta de cocina en español, inglés, francés, etc. los pasos para la elaboración del plato serán los mismos sin importar lo mismo.
En la ciencia dela computación y la programación, los algoritmos son más importantes que los lenguajes de programación o las computadoras. Un lenguaje de programación es tan solo un medio para expresar un algoritmo y una computadora es solo un procesador para ejecutarlo. Tanto el lenguaje de programación como la computadora son los medios para obtener un fin: conseguir que el algoritmo se ejecute y se efectué el proceso correspondiente.

4. FASES PARA LA RESOLUCIÓN DE PROBLEMAS INFORMÁTICOS

La Principal razón para que las personas aprendan a programar en general  y los lenguajes de programación en particular es utilizar la computadora como herramienta para la resolución de problemas. Ayudando por una computadora, la  resolución de un problema se puede dividir en 3 fases importantes:




    4.1.  Análisis del Problema:


El propósito del análisis de un problema es ayudar al programador para llegar a una cierta comprensión de la naturaleza del problema.
El Problema debe de estar bien definido si se desea llegara una solución satisfactoria.
Para poder definir con precisión el problema se requiere que las especificaciones de entrada y salida sean descritas con detalle.


Ejemplo:

Leer el radio de un círculo y calcular e imprimir su superficie y la longitud  de la circunferencia.

Análisis:

*   Definición del Problema:Calcular e imprimir su superficie y la longitud  de la circunferencia.
*   Especificaciones de entrada: Los datos de entrada en este problema se concretan en el radio del círculo.
*   Especificaciones de Salida: Las salidas serán 2 variables que son la superficie y la longitud de la circunferencia

   4.2. Diseño de Algoritmo:

Una Computadora no tiene la capacidad de solucionar problemas más que cuando se le proporciona los sucesivos pasos a realizar.Estos Pasos sucesivos que se indican las instrucciones a ejecutar por la maquina constituye, como ya conocemos, el algoritmo.
La información proporcionada al algoritmo constituye su entrada y la información producida por el algoritmo constituye su salida.
Los problemas más complejos se pueden subdividir en sub problemas que sean más fáciles de solucionar que el original (Divide y vencerás).

La descomposición del problema original en sub problemas más simples y a continuación dividir estos en sub problemas en otros más simples que pueden ser implementados para su solución en la computadora se denomina diseño descendente.


A. DISEÑO DESCENDENTE (DIVIDE Y VENCERÁS): El diseño descendente es una forma de afrontar un proyecto de programación que consiste en empezar por lo más general e ir avanzando nivel a nivel hacia lo más particular.Consiste en dividir el problema en sub problemas más pequeños, que se pueden tratar de forma separada.

B.  REFINAMIENTO POR PASOS: El diseño de un algoritmo no se hace de una sola vez, sino que se va resolviendo en una secuencia de pasos (llamados pasos de refinamiento).
En cada paso el problema es refinado agregando detalles significativos, por lo que el método se conoce como: método de los refinamientos sucesivos.
Como es natural, dependiendo de la complejidad del problema se necesitaran diferentes y sucesivos niveles de refinamiento antes de que pueda obtenerse un algoritmo con suficiente nivel de detalle. 



Ejemplo: El problema del cálculo de la circunferencia y superficie de un círculo se puede descomponer en sub problemas más simples: leer datos de entrada, calcular superficie y longitud, y escribir resultados.




C. HERRAMIENTAS DE REPRESENTACIÓN GRÁFICA DE ALGORITMOS:



Los algoritmos pueden ser expresados de muchas maneras, incluyendo al lenguaje natural, pseudocódigo, diagramas de flujo y lenguajes de programación entre otros. Las descripciones en lenguaje natural tienden a ser ambiguas y extensas. El usar pseudocódigo y diagramas de flujo evita muchas ambigüedades del lenguaje natural. Dichas expresiones son formas más estructuradas para representar algoritmos; no obstante, se mantienen independientes de un lenguaje de programación específico.




PSEUDOCODIGO


El pseudocódigo es una herramienta utilizada para el diseño de programas que permite al programador expresar sus pensamientos de una forma clara utilizando su lenguaje natural y mostrando el orden de ejecución de las sentencias del programa sin ninguna ambigüedad.


  • Publicación acerca del uso de Pseudocodigo (Pronto).




DIAGRAMAS DE FLUJO:


Un diagrama de flujo utiliza símbolos estándar en el que  cada paso del algoritmo se visualiza dentro del símbolo  y en el orden en que estos pasos se ejecutan, se indica conectándolos con flechas llamadas líneas de flujo, ya que indican el flujo lógico del algoritmo.


  • Publicación acerca del uso de Diagramas de Flujo (Pronto).




DIAGRAMAS N-S
Son una herramienta que favorece la programación estructurada y reúne características gráficas propias de diagramas de flujo y lingüísticas propias de pseudocódigos. Constan de una serie de cajas contiguas que se leerán siempre de arriba-abajo y sus estructuras lógicas son las siguientes:


  • Publicación acerca del uso de Diagramas N-S (Pronto).