Archivo

Artículos etiquetados y‘glpk’

GLPK+JAVA+Windows (Guía Rápida)

octubre 25, 2010 2 comentarios

Con esta guía rápida pretendo ahorrar algo de tiempo a aquellos que sean nuevos a GLPK y que quieran usarla desde JAVA ya sea para un proyecto académico (como es mi caso) o de cualquier otra índole. Es una de las muchas maneras de echar a andar la librería, si hay otra solución más fácil y/o sofisticada, por favor no duden en comentarla aquí.

¿Qué es GLPK?

  • GLPK = GNU Linear Programming Kit
  • Paquete escrito en lenguaje C.
  • Ideal para resolver problemas a gran escala de programación lineal (LP),  programación entera mixta (MIP) y otros tipos de problemas relacionados.

Pre-Requisitos

Para comenzar a utilizar esta guía se debe de cumplir con los siguientes pre-requisitos:

  • Tener un compilador de JAVA previamente instalado.

Paso 1 – Bajar WINGLPK

WINGLPK es un paquete pre-compilado de la librería de GLPK para Windows 32 y 64 bits. Hay que bajar el paquete de http://sourceforge.net/projects/winglpk/

Una vez que lo bajaste, descomprime la carpeta del paquete y muévela a la ubicación que quieras en tu sistema. Ejemplo: C:\GLPK\glpk-4.44

Paso 2 – Crear Programa java

Ya sea utilizando tu IDE favorito o el block de notas, crea tu primer programa de JAVA utilizando GLPK. Puedes utilizar el siguiente ejemplo (tomado de la documentación del paquete de glpk: C:\…\glpk-4.44\docs\glpk-java.pdf).

import org.gnu.glpk.GLPK;
import org.gnu.glpk.GLPKConstants;
import org.gnu.glpk.GlpkException;
import org.gnu.glpk.SWIGTYPE_p_double;
import org.gnu.glpk.SWIGTYPE_p_int;
import org.gnu.glpk.glp_prob;
import org.gnu.glpk.glp_smcp;
public class Main {
    // Minimize z = (x1-x2) /2 + (1-(x1-x2)) = -.5 * x1 + .5 * x2 + 1
    //
    // subject to
    // 0.0<= x1 - x2 <= 0.2
    // where,
    // 0.0 <= x1 <= 0.5
    // 0.0 <= x2 <= 0.5
    public static void main(String[] args) {
        glp_prob lp;
        glp_smcp parm;
        SWIGTYPE_p_int ind;
        SWIGTYPE_p_double val;
        int ret;
        try {
            // Create problem
            lp = GLPK.glp_create_prob();
            System.out.println("Problem created");
            GLPK.glp_set_prob_name(lp, "myProblem");
            // Define columns
            GLPK.glp_add_cols(lp, 2);
            GLPK.glp_set_col_name(lp, 1, "x1");
            GLPK.glp_set_col_kind(lp, 1, GLPKConstants.GLP_CV);
            GLPK.glp_set_col_bnds(lp, 1, GLPKConstants.GLP_DB, 0, .5);
            GLPK.glp_set_col_name(lp, 2, "x2");
            GLPK.glp_set_col_kind(lp, 2, GLPKConstants.GLP_CV);
            GLPK.glp_set_col_bnds(lp, 2, GLPKConstants.GLP_DB, 0, .5);
            // Create constraints
            GLPK.glp_add_rows(lp, 1);
            GLPK.glp_set_row_name(lp, 1, "c1");
            GLPK.glp_set_row_bnds(lp, 1, GLPKConstants.GLP_DB, 0, 0.2);
            ind = GLPK.new_intArray(3);
            GLPK.intArray_setitem(ind, 1, 1);
            GLPK.intArray_setitem(ind, 2, 2);
            val = GLPK.new_doubleArray(3);
            GLPK.doubleArray_setitem(val, 1, 1.);
            GLPK.doubleArray_setitem(val, 2, -1.);
            GLPK.glp_set_mat_row(lp, 1, 2, ind, val);
            // Define objective
            GLPK.glp_set_obj_name(lp, "z");
            GLPK.glp_set_obj_dir(lp, GLPKConstants.GLP_MIN);
            GLPK.glp_set_obj_coef(lp, 0, 1.);
            GLPK.glp_set_obj_coef(lp, 1, -.5);
            GLPK.glp_set_obj_coef(lp, 2, .5);
            // Solve model
            parm = new glp_smcp();
            GLPK.glp_init_smcp(parm);
            ret = GLPK.glp_simplex(lp, parm);
            // Retrieve solution
            if (ret == 0) {
                write_lp_solution(lp);
            } else {
                System.out.println("The problem could not be solved");
            }
            // Free memory
            GLPK.glp_delete_prob(lp);
        } catch (GlpkException ex) {
            ex.printStackTrace();
        }
    }
    /**
     * write simplex solution
     * @param lp problem
     */
    static void write_lp_solution(glp_prob lp) {
        int i;
        int n;
        String name;
        double val;
        name = GLPK.glp_get_obj_name(lp);
        val = GLPK.glp_get_obj_val(lp);
        System.out.print(name);
        System.out.print(" = ");
        System.out.println(val);
        n = GLPK.glp_get_num_cols(lp);
        for (i = 1; i <= n; i++) {
            name = GLPK.glp_get_col_name(lp, i);
            val = GLPK.glp_get_col_prim(lp, i);
            System.out.print(name);
            System.out.print(" = ");
            System.out.println(val);
        }
    }
}

Paso 3 – Compilar programa

Para compilar hay que hacer referencia al archivo glpk-java.jar que ya está incluido en nuestro paquete de winglpk, se puede agregar como una librería desde el IDE que estén usando o se puede especificar en el comando del compilador. En mi caso para compilar el programa corro el siguiente comando:

javac -classpath C:\GLPK\glpk-4.44\w64\glpk-java.jar Main.java

Paso 4 – Correr el programa

Para correr el programa se necesita hacer referencia nuevamente a la carpeta en donde se encuentran los archivos pre-compilados de la librería GLPK, en mi caso esta carpeta es C:\GLPK\glpk-4.44\w64. Se pueden modificar las propiedades del proyecto en la IDE en la que se esté trabajando o se puede especificar la ubicación en el comando de java. En mi caso para correr el programa hago lo siguiente:

java -Djava.library.path=C:\GLPK\glpk-4.44\w64 -classpath C:\GLPK\glpk-4.44\w64\glpk-java.jar;. Main

Con –Djava.library.path= le especifico a la VM dónde buscar las librerías que va a cargar dinámicamente (glpk_4_44.dll y glpk_4_44_java.dll).

Problema de ejemplo glpk-java

Más Información

Consulta la documentación que viene en tu distribución de glpk. (Ejemplo C:\…\glpk-4.44\docs\glpk-java.pdf)

Para más información,  recomiendo visitar los siguientes sitios:

http://www.gnu.org/software/glpk/

http://winglpk.sourceforge.net/

http://www.ibm.com/developerworks/linux/library/l-glpk1/

http://codingtech.wordpress.com/2010/03/12/glpk-y-visual-studio-en-10-pasos/

Seguir

Get every new post delivered to your Inbox.