Una forma sencilla y rápida de aprender JAVA, observando y deduciendo cómo se comporta el lenguaje a través de ejemplos prácticos.

Archivo del blog

jueves, 11 de diciembre de 2014

Red neuronal artificial (II). Generando estructura de red neuronal aleatoria condicionada.

La siguiente fase y teniendo en cuenta el post anterior creamos nuestra primera estructura de red neuronal aleatoria condicionada. Decimos que es condicionada porque hay más probabilidades de que haya más enlaces de entre neuronas cercanas  que de entre neuronas alejadas.


Ejemplo:

* Propiedades de la red neuronal:

Número de neuronas = 9
Número de enlaces usados = 17
Enlaces aleatorios condicionados por una curva cotangente.


* Posible resultado (aleatorio condicionado):

SALIDAS:
neuroS[0]: [0, 1]
neuroS[1]: [1, 6]
neuroS[2]: [2]
neuroS[3]: [3]
neuroS[4]: [3]
neuroS[5]: [5, 6, 7]
neuroS[6]: [4, 6]
neuroS[7]: [2, 5, 7, 8]
neuroS[8]: [8]

ENTRADAS:
neuroE[0]: [0]
neuroE[1]: [0, 1]
neuroE[2]: [2, 7]
neuroE[3]: [3, 4]
neuroE[4]: [6]
neuroE[5]: [5, 7]
neuroE[6]: [1, 5, 6]
neuroE[7]: [5, 7]
neuroE[8]: [7, 8]


Esquema visual:


























Código 1: (RedNeuronal1.java):

package redneuronal1;

import java.util.ArrayList;
import java.util.Random;

public class RedNeuronal1 {

    public static void main(String[] args) {

        int nNeuronas = 50;
        int nEnlaces = 500;

        ArrayList<Integer>[] neuroS = new ArrayList[nNeuronas];
        ArrayList<Integer>[] neuroE = new ArrayList[nNeuronas];

        AleatoriedadCondicionada ac = new AleatoriedadCondicionada();
        Random r1 = new Random();
        neuroS[0] = new ArrayList();
        int nSalidas;
        int neurona;

        //Crea red neuronal aleatoria
        for (int i = 0; i < neuroS.length; i++) {
            neuroS[i] = new ArrayList();
            neuroE[i] = new ArrayList();
            nSalidas = r1.nextInt(nEnlaces / nNeuronas) + 1;
            for (int j = 0; j < nSalidas; j++) {

                neurona = r1.nextInt(nNeuronas);

                //Aplicación de la Aleatoriedad Condicionada
                neurona = (int) Math.rint(ac.getSalida(nNeuronas, neurona));
                if (r1.nextBoolean()) {
                    //Conexion hacia delante
                    neurona = i + neurona;
                    if (neurona > nNeuronas) {
                        neurona = neurona - nNeuronas;
                    }
                } else {
                    //Conexion hacia atrás
                    neurona = i - neurona;
                    if (neurona < 0) {
                        neurona = neurona + nNeuronas;
                    }
                }
                //evita repeticiones
                if (neuroS[i].contains(neurona) == false) { 
                    neuroS[i].add(neurona); //salida
                }
            }
        }

        //Traspaso entradas a partir de las salidas
        for (int i = 0; i < neuroS.length; i++) {
            for (int j = 0; j < neuroE.length; j++) {
                if (neuroS[i].contains(j)) {
                    neuroE[j].add(i);
                }
            }
        }

        //mostrar resultados
        for (int i = 0; i < neuroS.length; i++) {
            System.out.println("neuroS[" + i + "]: " + neuroS[i].toString());
        }
        System.out.println("\n");
        for (int i = 0; i < neuroE.length; i++) {
            System.out.println("neuroE[" + i + "]: " + neuroE[i].toString());
        }

        //Recuento número de enlaces usados
        int nSinapsis = 0;
        for (int i = 0; i < neuroS.length; i++) {
            nSinapsis += neuroS[i].size();
        }
        System.out.println("\nNúmero de enlaces: " + nSinapsis);

    }

}


Código 2: (AleatoriedadCondicionada.java):

package redneuronal1;

public class AleatoriedadCondicionada {
    double c = Math.atan(10);
    double entrada, salida;

    public double getSalida(double nNeuro, double num) {
        entrada = num * 100 / nNeuro;       
        salida = (Math.atan((entrada / 10) - 10) * 100 / c) + 100;        
        salida = salida * nNeuro / 100;   
        return salida; 
    }

}


Resultado:

neuroS[0]: [9, 0, 30, 47]
neuroS[1]: [6, 1, 2]
neuroS[2]: [5]
neuroS[3]: [0, 35, 26, 8, 2, 6, 7]
neuroS[4]: [4, 49, 13, 6, 27]
neuroS[5]: [23, 41, 5, 49, 47, 6, 2, 35]
neuroS[6]: [29]
neuroS[7]: [7, 1]
neuroS[8]: [16, 10, 26, 1, 0, 8, 13, 9]
neuroS[9]: [9, 14, 10, 0, 6]
neuroS[10]: [22, 10, 12]
neuroS[11]: [13, 5, 29, 11, 17, 18, 16, 9]
neuroS[12]: [44, 30, 1, 13, 9, 11]
neuroS[13]: [14, 21, 15]
neuroS[14]: [14]
neuroS[15]: [38, 10, 14, 16, 15, 13, 7, 8]
neuroS[16]: [23, 14, 16, 21, 13, 17, 15]
neuroS[17]: [19, 47, 23, 16, 7, 14]
neuroS[18]: [18, 5, 36, 31, 17]
neuroS[19]: [18, 46, 3, 22]
neuroS[20]: [47, 40]
neuroS[21]: [21, 16, 23, 20]
neuroS[22]: [19, 25, 16, 6, 15, 21, 27]
neuroS[23]: [17, 22]
neuroS[24]: [22, 23, 21]
neuroS[25]: [33, 26, 23, 22, 25]
neuroS[26]: [24, 26, 25, 23, 34, 27]
neuroS[27]: [40, 24]
neuroS[28]: [1, 31, 23]
neuroS[29]: [25, 26, 33, 17, 28]
neuroS[30]: [33, 30, 35, 27]
neuroS[31]: [49, 38, 33]
neuroS[32]: [32, 29, 30, 34, 39]
neuroS[33]: [30, 49, 35, 44, 31]
neuroS[34]: [34, 36, 29, 47, 40, 48]
neuroS[35]: [34, 35, 42, 17]
neuroS[36]: [36, 40]
neuroS[37]: [5, 37]
neuroS[38]: [41, 8]
neuroS[39]: [7, 38, 37]
neuroS[40]: [40, 43, 41, 39, 42, 35]
neuroS[41]: [40]
neuroS[42]: [40, 49, 5, 36, 24, 6, 38]
neuroS[43]: [49]
neuroS[44]: [45, 49, 21, 41, 43, 48]
neuroS[45]: [47, 1, 45]
neuroS[46]: [35, 34, 3, 46]
neuroS[47]: [48, 1, 5, 37]
neuroS[48]: [48, 2, 44, 37]
neuroS[49]: [41]


neuroE[0]: [0, 3, 8, 9]
neuroE[1]: [1, 7, 8, 12, 28, 45, 47]
neuroE[2]: [1, 3, 5, 48]
neuroE[3]: [19, 46]
neuroE[4]: [4]
neuroE[5]: [2, 5, 11, 18, 37, 42, 47]
neuroE[6]: [1, 3, 4, 5, 9, 22, 42]
neuroE[7]: [3, 7, 15, 17, 39]
neuroE[8]: [3, 8, 15, 38]
neuroE[9]: [0, 8, 9, 11, 12]
neuroE[10]: [8, 9, 10, 15]
neuroE[11]: [11, 12]
neuroE[12]: [10]
neuroE[13]: [4, 8, 11, 12, 15, 16]
neuroE[14]: [9, 13, 14, 15, 16, 17]
neuroE[15]: [13, 15, 16, 22]
neuroE[16]: [8, 11, 15, 16, 17, 21, 22]
neuroE[17]: [11, 16, 18, 23, 29, 35]
neuroE[18]: [11, 18, 19]
neuroE[19]: [17, 22]
neuroE[20]: [21]
neuroE[21]: [13, 16, 21, 22, 24, 44]
neuroE[22]: [10, 19, 23, 24, 25]
neuroE[23]: [5, 16, 17, 21, 24, 25, 26, 28]
neuroE[24]: [26, 27, 42]
neuroE[25]: [22, 25, 26, 29]
neuroE[26]: [3, 8, 25, 26, 29]
neuroE[27]: [4, 22, 26, 30]
neuroE[28]: [29]
neuroE[29]: [6, 11, 32, 34]
neuroE[30]: [0, 12, 30, 32, 33]
neuroE[31]: [18, 28, 33]
neuroE[32]: [32]
neuroE[33]: [25, 29, 30, 31]
neuroE[34]: [26, 32, 34, 35, 46]
neuroE[35]: [3, 5, 30, 33, 35, 40, 46]
neuroE[36]: [18, 34, 36, 42]
neuroE[37]: [37, 39, 47, 48]
neuroE[38]: [15, 31, 39, 42]
neuroE[39]: [32, 40]
neuroE[40]: [20, 27, 34, 36, 40, 41, 42]
neuroE[41]: [5, 38, 40, 44, 49]
neuroE[42]: [35, 40]
neuroE[43]: [40, 44]
neuroE[44]: [12, 33, 48]
neuroE[45]: [44, 45]
neuroE[46]: [19, 46]
neuroE[47]: [0, 5, 17, 20, 34, 45]
neuroE[48]: [34, 44, 47, 48]
neuroE[49]: [4, 5, 31, 33, 42, 43, 44]

Número de enlaces: 207

martes, 9 de diciembre de 2014

Red neuronal artificial (I). Generando conexiones aleatorias condicionadas.

Este es el primer post de una serie de posts que voy a ir creando sobre redes neuronales artificiales. El fin último es conseguir crear una red neuronal artificial básica, con su respectiva estructura conexial entre neuronas, sus entradas y salidas y estudiar así su comportamiento según los estímulos que le vayamos dando.

En este primer apartado la idea es conseguir que los enlaces entre neuronas cercanas sean más probables que las alejadas entre sí. Es decir vamos a crear una generador de números aleatorios con la propiedad de que haya más probabilidades de que salgan más números con valores bajos que de valores altos. De esta forma obtenemos la base para crear los enlaces entre neuronas de uma manera más parecida a una estructura de red neuronal biológica.

Para conseguir el objetivo me he basado en la gráfica de la curvatura de una linea cotangente. El número aleatorio que le demos (eje X), nos lo convierte en otro número de valor más reducido (eje Y).

Ejemplo visual: si le damos una entrada de valor 80, teniendo en cuenta la curvatura de la gráfica nos debería devolver un valor de 25 aproximadamente.



























Código: 

package atan;

import java.util.Scanner;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartFrame;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;

public class Atan {

    public static void main(String[] args) {

        XYSeries series = new XYSeries("Atan (x) -> -10 to 0");

        // Introduccion de datos
        double c = Math.abs(Math.atan(-10));
        double esc; // escala %

        for (int i = 0; i < 11; i++) {
            esc = Math.atan(i - 10) * 100 / c;
            series.add(i * 10, esc + 100);
        }

        XYSeriesCollection dataset = new XYSeriesCollection();
        dataset.addSeries(series);

        JFreeChart chart = ChartFactory.createXYLineChart(
                "Escala aTangente", // Título
                "Número Entrada (x) ->", // Etiqueta Coordenada X
                "Número Salida  (y) ->", // Etiqueta Coordenada Y
                dataset, // Datos
                PlotOrientation.VERTICAL,
                false, 
                false,
                false
        );

        // Mostramos la grafica en pantalla
        ChartFrame frame = new ChartFrame("Ejemplo Grafica Lineal", chart);
        frame.pack();
        frame.setVisible(true);
        
        for (int i = 0; i < 4; i++) {
            System.out.println("\nIngrese número 1 al 100");
            Scanner entrada = new Scanner(System.in);
            double num = entrada.nextInt();

            esc = Math.atan((num / 10) - 10) * 100 / c;

            System.out.println("entrada = " + num);
            System.out.println("salida  = " + (esc + 100));
        }

    }

}


Resutado:

run:

Ingrese número 1 al 100
80
entrada = 80.0
salida  = 24.741493404500787

Ingrese número 1 al 100
40
entrada = 40.0
salida  = 4.451008982239117

Ingrese número 1 al 100
99
entrada = 99.0
salida  = 93.22501681994844

Ingrese número 1 al 100

...


Nota:  Hay la hipótesis de que obteniendo la gráfica de una red neuronal biológica mediante electrodos y siguiendo el mismo procedimiento anterior (aleatoriedad condicionada) se podría recrear de manera aproximada dicha estructura artificialmente en tiempo récord. Se ha recreado la red neuronal de un gusano compuesto de 302 neuronas y 6.393 conexiones siguiendo las conexiones entre ellas una a una (se tardó más de una década en conseguirlo). Un ser más complejo como el ser humano que contiene 100 mil millones de neuronas y billones de enlaces entre sí se haría impracticable a no ser que se obtenga la gráfica de curvatura neuronal y aplicándole el procedimiento aquí expuesto.

jueves, 23 de octubre de 2014

Gráficas con JFreeChart (VIII). Ejemplo práctico basado en la Teoría del Caos.

Este ejemplo nos proponemos a demostrar gráficamente la rica conducta caótica de una ecuación demográfica interada.
Para ello necesitamos que la gráfica se vaya actualizando automáticamente a medida que vayamos modificando los distintos valores de entrada de la ecuación.

Empezamos por crear un nuevo proyecto de tipo JFrame y en modo de diseño le agregamos un jPanel para mostrar la gráfica. También añadimos 4 jSpinner con sus correspondientes jLabels y un jButton para restablecer las entradas a valores predeterminados.
Debería quedar algo parecido a eso:




Código:

package freejchartpanel1;

import javax.swing.JOptionPane;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;

public class Ventana1 extends javax.swing.JFrame {

    public double k;
    public double poblacion;
    public double tasaNatalidad;
    public int generaciones;

    public Ventana1() {
        initComponents();
        restablecer();
        actualizar();
    }

    
    private void initComponents() { ... }// Aquí va código generado por Netbeans

    private void jSpinnerPoblacionInicialStateChanged(javax.swing.event.ChangeEvent evt) {                                                     
        actualizar();
        ejecutar();
    }

    private void jSpinnerCapacidadCargaStateChanged(javax.swing.event.ChangeEvent evt) {                                                   
        actualizar();
        ejecutar();
    } 

    private void jSpinnerNatalidadStateChanged(javax.swing.event.ChangeEvent evt) {                                              
        actualizar();
        ejecutar();
    }                                              

    private void jSpinnerGeneracionesStateChanged(javax.swing.event.ChangeEvent evt) {                                                 
        actualizar();
        ejecutar();
    }                                                 

    private void jButtonRestablecerActionPerformed(java.awt.event.ActionEvent evt) {                                                  
        restablecer();
    }                                                  

    public static void main(String args[]) {

        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new Ventana1().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify                     
    private javax.swing.JButton jButtonRestablecer;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JSpinner jSpinnerCapacidadCarga;
    private javax.swing.JSpinner jSpinnerGeneraciones;
    private javax.swing.JSpinner jSpinnerNatalidad;
    private javax.swing.JSpinner jSpinnerPoblacionInicial;
    // End of variables declaration                   

    private void actualizar() {

        k = Double.parseDouble(jSpinnerCapacidadCarga.getValue().toString());
        poblacion = Double.parseDouble(jSpinnerPoblacionInicial.getValue().toString());
        tasaNatalidad = Double.parseDouble(jSpinnerNatalidad.getValue().toString()) / 100;
        generaciones = Integer.parseInt(jSpinnerGeneraciones.getValue().toString());

        // Control rango maximos minimos jSpinners
        if (k <= 1) {
            jSpinnerCapacidadCarga.setValue(1);
        } else if (poblacion >= k) {
            jSpinnerPoblacionInicial.setValue(k);
        } else if (poblacion <= 1) {
            jSpinnerPoblacionInicial.setValue(1);
        } else if (tasaNatalidad <= 0) {
            jSpinnerNatalidad.setValue(0);
        } else if (generaciones <= 0) {
            jSpinnerGeneraciones.setValue(0);
        }

    }

    private void restablecer() {

        jSpinnerCapacidadCarga.setValue(10000);
        jSpinnerPoblacionInicial.setValue(7000);
        jSpinnerNatalidad.setValue(120); // %
        jSpinnerGeneraciones.setValue(30);

    }

    private void ejecutar() {

        int extincion = 0;

        XYSeries series = new XYSeries("");

        for (int i = 0; i < generaciones; i++) {
            series.add(i, poblacion);
            poblacion = (poblacion * tasaNatalidad * (k - poblacion)) / k;
            if (poblacion <= 0) {
                extincion = i + 1;
                series.add(i + 1, 0);
                break;
            }
        }

        XYSeriesCollection dataset = new XYSeriesCollection();
        dataset.addSeries(series);

        JFreeChart chart = ChartFactory.createXYLineChart(
                "Índice Demográfico",
                "Generación ->",
                "Población ->",
                dataset,
                PlotOrientation.VERTICAL,
                false,
                false,
                false
        );

        // Mostramos la grafica dentro del jPanel1
        ChartPanel panel = new ChartPanel(chart);
        jPanel1.removeAll();
        jPanel1.setLayout(new java.awt.BorderLayout());
        jPanel1.add(panel);
        jPanel1.validate();

        if (extincion != 0) {
            JOptionPane.showMessageDialog(null, "Extinción en la Generación " + (extincion));
        }

    }

}


Resultado:



martes, 21 de octubre de 2014

Gráficas con JFreeChart (VII). Poner un rango fijo en el Eje X.

Esta vez nos interesa poner el eje X de la gráfica a una escala fija (no auto-escalable). Antes cuando se creaba una gráfica el eje X se adaptaba automáticamente a los valores máximos y mínimos recibidos. Ahora queremos que el rango del eje X esté entre 0 y 100 (independientemente de los valores recibidos).

Para poder apreciar bien la diferencia he usado como plantilla el ejemplo del post "Gráficas con JFreeChart (V)" cuyo Eje X se adaptaba al valor máximo recibido que era 60. En este caso el Eje X de la gráfica se adapatará al rango que le hayamos indicado (0-100).


Código (Demografia.java):

package crecimientoPoblacion;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartFrame;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.category.DefaultCategoryDataset;


public class Demografia1 {

    public static void main(String[] args) {

        DefaultCategoryDataset dataset = new DefaultCategoryDataset();

        double poblacion = 25;
        int esperanza_de_vida = 5;
        double defunciones;
        double poblacion_neta;

        double tc = 0.2; // tasa de crecimiento 20%
        double tm = 0.4; // tasa de mortalitat 40%

        for (int tiempo = 0; tiempo < esperanza_de_vida; tiempo++) {

            // Crecimiento
            poblacion = poblacion * (1 + tc);
            dataset.addValue(poblacion, "Crecimiento", "" + tiempo);

            // Mortalidad
            defunciones = poblacion * tm;
            dataset.addValue(defunciones, "Mortalidad", "" + tiempo);

            // Crecimiento Neto
            poblacion_neta = (poblacion - defunciones);
            dataset.addValue(poblacion_neta, "Crecimiento neto", "" + tiempo);

        }

        JFreeChart chart = ChartFactory.createLineChart(
                "Calculo demografico",
                "Tiempo",
                "Población",
                dataset,
                PlotOrientation.VERTICAL,
                true,
                false,
                false
        );
        
        // Rango Eje X estático de 0 a 100
        CategoryPlot plot = chart.getCategoryPlot();
        NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
        rangeAxis.setRange(0, 100);    
        
        // Mostramos la grafica en pantalla
        ChartFrame fr = new ChartFrame("Cálculo Demográfico II", chart);
        fr.pack();
        fr.setVisible(true);

    }

}


Resultado:





















Gráficas con JFreeChart (VI). Poner la gráfica dentro un jPanel.

Creamos un nuevo proyecto de tipo "JFrame Form" y en modo diseño le agregamos un jPanel y un jButton.





Código (Ventana1.java):

package freejchartpanel1;

import javax.swing.JFrame;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;


public class Ventana1 extends javax.swing.JFrame {
   
    public Ventana1() {
        initComponents();        
    }
                         
    private void initComponents() {...} // aqui va el codigo generado automáticamente por NetBeans

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {

        double poblacion = 0.7;
        double tasa_crecimiento = 3.9;

        XYSeries series = new XYSeries("");

        for (int i = 0; i < 30; i++) {

            series.add(i, poblacion * 100);
            // Variante de la ecuacion de Verhulst
            poblacion = poblacion * tasa_crecimiento * (1 - poblacion);
        }

        XYSeriesCollection dataset = new XYSeriesCollection();
        dataset.addSeries(series);

        JFreeChart chart = ChartFactory.createXYLineChart(
                "Crecimiento Población",
                "Tiempo ->",
                "Población ->",
                dataset,
                PlotOrientation.VERTICAL,
                false,
                false,
                false
        );

        // Mostramos la grafica dentro del jPanel1
        ChartPanel panel = new ChartPanel(chart);        
        jPanel1.setLayout(new java.awt.BorderLayout());
        jPanel1.add(panel);   
        jPanel1.validate();

    }                                        

    public static void main(String args[]) {
        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new Ventana1().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify                     
    private javax.swing.JButton jButton1;
    private javax.swing.JPanel jPanel1;
    // End of variables declaration                   
}


Resultado:




















martes, 14 de octubre de 2014

Gráficas con JFreeChart (V). Multi-Lineas en una sola gráfica.

El siguiente ejemplo práctico trata de mostrarnos varios datos en una misma gráfica, representado por varias lineas temporales. Para ilustrar tal efecto he elegido la representación de la tasa de crecimiento poblacional de algún insecto o animal, con sus respectivas variantes de mortalidad y crecimiento neto.


Código:

package crecimientoPoblacion;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartFrame;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.category.DefaultCategoryDataset;

public class Demografia1 {

    public static void main(String[] args) {

        DefaultCategoryDataset dataset = new DefaultCategoryDataset();

        double poblacion = 25;
        int esperanza_de_vida = 5;
        double defunciones;
        double poblacion_neta;

        double tc = 0.2; // tasa de crecimiento 20%
        double tm = 0.4; // tasa de mortalidad 40%

        for (int tiempo = 0; tiempo < esperanza_de_vida; tiempo++) {

            //Crecimiento
            poblacion = poblacion * (1 + tc);
            dataset.addValue(poblacion, "Crecimiento", "" + tiempo);

            //Mortalidad
            defunciones = poblacion * tm;
            dataset.addValue(defunciones, "Mortalidad", "" + tiempo);

            //Crecimiento Neto
            poblacion_neta = poblacion - defunciones;
            dataset.addValue(poblacion_neta, "Crecimiento neto", "" + tiempo);

        }

        JFreeChart chart = ChartFactory.createLineChart(
                "Calculo demografico",
                "Tiempo",
                "Población",
                dataset,
                PlotOrientation.VERTICAL,
                true,
                false,
                false
        );

        //Mostramos la grafica en pantalla
        ChartFrame fr = new ChartFrame("Calculo Demografico I", chart);
        fr.pack();
        fr.setVisible(true);

    }

}


Resultado:





















jueves, 2 de octubre de 2014

Empaquetar aplicación y sus librerías en un solo archivo ".jar" con NetBeans

Cuando empaquetamos nuestras aplicaciones jFreeChart con NetBeans (pulsando "Clean and Build") se genera un archivo ".jar" y una carpeta "lib" que contiene las librerías del jFreeChart.

...\NetBeansProjects\Aplicacion2\dist\Aplicacion1.jar
...\NetBeansProjects\Aplicacion2\dist\lib\jcommon-1.0.23.jar
...\NetBeansProjects\Aplicacion2\dist\lib\jfreechart-1.0.19.jar

Si queremos que estas librerías se empaqueten también y se genere todo el proyecto en un solo archivo ".jar",debemos modificar el archivo "build.xml" que podemos encontrar en la raiz del proyecto.

...\NetBeansProjects\Aplicacion2\build.xml


Editamos este archivo agregando el siguiente código antes del tag de cierre "</project>":


Código (build.xml):

...

  <target name="package-for-store" depends="jar">  
     <property name="store.jar.name" value="Aplicacion2"/>  
     <property name="store.dir" value="store"/>  
     <property name="store.jar" value="${store.dir}/${store.jar.name}.jar"/>  
     <echo message="Packaging ${application.title} into a single JAR at ${store.jar}"/>  
     <delete dir="${store.dir}"/>  
     <mkdir dir="${store.dir}"/>  
     <jar destfile="${store.dir}/temp_final.jar" filesetmanifest="skip">  
       <zipgroupfileset dir="dist" includes="*.jar"/>  
       <zipgroupfileset dir="dist/lib" includes="*.jar"/>  
       <manifest>  
         <attribute name="Main-Class" value="${main.class}"/>  
       </manifest>  
     </jar>  
     <zip destfile="${store.jar}">  
       <zipfileset src="${store.dir}/temp_final.jar"  
       excludes="META-INF/*.SF, META-INF/*.DSA, META-INF/*.RSA"/>  
     </zip>  
     <delete file="${store.dir}/temp_final.jar"/>  
  </target>  

</project>


Una vez modificado y guardado le damos al "Clean and Build" desde NetBeans (proceso que tarda unos 50 segundos). 
Luego en la pestaña de "Files" de NetBeans, le damos clic derecho sobre "build.xml" y en el menú que aparece seguimos la siguiente ruta:

Run Target -> Other Targets -> package_for_store (dandole clic a este último).


Finalmente ya tenemos el ".jar" y las librerías jFreeChart empaquetadas en un solo archivo ".jar" en la carpeta "store" de nuestro proyecto:

...\NetBeansProjects\Aplicacion2\store\Aplicacion2.jar


Con la tecnología de Blogger.