[gnumeric] solver: glpk now handles milp soluions too.



commit 0ef348cfc6cd579044e54bdef2fb52d3b1e7640d
Author: Morten Welinder <terra gnome org>
Date:   Sun Nov 15 13:09:34 2009 -0500

    solver: glpk now handles milp soluions too.

 plugins/glpk/ChangeLog  |    5 ++++
 plugins/glpk/gnm-glpk.c |   50 ++++++++++++++++++++++++++++++++--------------
 src/tools/gnm-solver.c  |   26 ++++++++++++++++-------
 src/tools/gnm-solver.h  |    2 +
 4 files changed, 60 insertions(+), 23 deletions(-)
---
diff --git a/plugins/glpk/ChangeLog b/plugins/glpk/ChangeLog
index 33314bf..156d977 100644
--- a/plugins/glpk/ChangeLog
+++ b/plugins/glpk/ChangeLog
@@ -1,3 +1,8 @@
+2009-11-15  Morten Welinder  <terra gnome org>
+
+	* gnm-glpk.c (gnm_glpk_read_solution): Handle the MILP solution
+	format too.
+
 2009-11-13  Morten Welinder  <terra gnome org>
 
 	* Initial Implementation
diff --git a/plugins/glpk/gnm-glpk.c b/plugins/glpk/gnm-glpk.c
index 8e2ef30..37ea7c7 100644
--- a/plugins/glpk/gnm-glpk.c
+++ b/plugins/glpk/gnm-glpk.c
@@ -73,6 +73,19 @@ gnm_glpk_read_solution (GnmGlpk *lp)
 	gnm_float val;
 	GnmSolverResult *result;
 	int width, height;
+	gboolean has_integer;
+	GSList *l;
+
+	/*
+	 * glpsol's output format is different if there are any integer
+	 * constraint.  Go figure.
+	 */
+	has_integer = sol->params->options.assume_discrete;
+	for (l = sol->params->constraints; !has_integer && l; l = l->next) {
+		GnmSolverConstraint *c = l->data;
+		has_integer = (c->type == GNM_SOLVER_INTEGER ||
+			       c->type == GNM_SOLVER_BOOLEAN);
+	}
 
 	input = gsf_input_stdio_new (lp->result_filename, NULL);
 	if (!input)
@@ -86,16 +99,20 @@ gnm_glpk_read_solution (GnmGlpk *lp)
 	result = g_object_new (GNM_SOLVER_RESULT_TYPE, NULL);
 	result->solution = value_new_array_empty (width, height);
 
-	line = gsf_input_textline_utf8_gets (tl);
-	if (line == NULL ||
-	    sscanf (line, "%u %u", &rows, &cols) != 2 ||
+	if ((line = gsf_input_textline_utf8_gets (tl)) == NULL)
+		goto fail;
+	if (sscanf (line, "%u %u", &rows, &cols) != 2 ||
 	    cols != g_hash_table_size (subsol->cell_from_name))
 		goto fail;
 
-	line = gsf_input_textline_utf8_gets (tl);
-	if (line == NULL ||
-	    sscanf (line, "%d %d %" GNM_SCANF_g, &pstat, &dstat, &val) != 3)
+	if ((line = gsf_input_textline_utf8_gets (tl)) == NULL)
+		goto fail;
+
+	if (has_integer
+	    ? sscanf (line, "%d %" GNM_SCANF_g, &pstat, &val) != 2
+	    : sscanf (line, "%d %d %" GNM_SCANF_g, &pstat, &dstat, &val) != 3)
 		goto fail;
+
 	result->value = val;
 	switch (pstat) {
 	case 2:
@@ -114,24 +131,27 @@ gnm_glpk_read_solution (GnmGlpk *lp)
 	}
 
 	for (r = 1; r <= rows; r++) {
-		line = gsf_input_textline_utf8_gets (tl);
-		if (!line)
+		if ((line = gsf_input_textline_utf8_gets (tl)) == NULL)
 			goto fail;
+		/* Ignore the line */
 	}
 
-	for (c = 1; c <= cols; c++) {
+	for (c = 0; c < cols; c++) {
 		gnm_float pval, dval;
 		unsigned cstat;
 		int x, y;
 
-		line = gsf_input_textline_utf8_gets (tl);
-		if (line == NULL ||
-		    sscanf (line, "%u %" GNM_SCANF_g " %" GNM_SCANF_g,
-			    &cstat, &pval, &dval) != 3)
+		if ((line = gsf_input_textline_utf8_gets (tl)) == NULL)
+			goto fail;
+
+		if (has_integer
+		    ? sscanf (line, "%" GNM_SCANF_g, &pval) != 1
+		    : sscanf (line, "%u %" GNM_SCANF_g " %" GNM_SCANF_g,
+			      &cstat, &pval, &dval) != 3)
 			goto fail;
 
-		x = (c - 1) % width;
-		y = (c - 1) / width;
+		x = c % width;
+		y = c / width;
 		value_array_set (result->solution, x, y,
 				 value_new_float (pval));
 	}
diff --git a/src/tools/gnm-solver.c b/src/tools/gnm-solver.c
index 9048a3c..9d7289e 100644
--- a/src/tools/gnm-solver.c
+++ b/src/tools/gnm-solver.c
@@ -18,11 +18,12 @@
 #include <unistd.h>
 #include <signal.h>
 #include <string.h>
+#include <sys/wait.h>
 
 /* ------------------------------------------------------------------------- */
 
-static gboolean
-debug_solver (void)
+gboolean
+gnm_solver_debug (void)
 {
 	static int debug = -1;
 	if (debug == -1)
@@ -1151,8 +1152,17 @@ gnm_sub_solver_init (GnmSubSolver *subsol)
 static void
 cb_child_exit (GPid pid, gint status, GnmSubSolver *subsol)
 {
-	if (debug_solver ())
-		g_printerr ("Solver process exited.\n");
+	if (gnm_solver_debug ()) {
+		if (WIFEXITED (status))
+			g_printerr ("Solver process exited with code %d\n",
+				    WEXITSTATUS (status));
+		else if (WIFSIGNALED (status)) 
+			g_printerr ("Solver process received signal %d\n",
+				    WTERMSIG (status));
+		else
+			g_printerr ("Solver process exited with status 0x%x\n",
+				    status);
+	}
 
 	subsol->child_watch = 0;
 	if (subsol->child_exit)
@@ -1179,10 +1189,10 @@ gnm_sub_solver_spawn (GnmSubSolver *subsol,
 	if (!g_path_is_absolute (argv[0]))
 		spflags |= G_SPAWN_SEARCH_PATH;
 
-	if (io_stdout == NULL)
+	if (io_stdout == NULL && !gnm_solver_debug ())
 		spflags |= G_SPAWN_STDOUT_TO_DEV_NULL;
 
-	if (debug_solver ()) {
+	if (gnm_solver_debug ()) {
 		GString *msg = g_string_new ("Spawning");
 		int i;
 		for (i = 0; argv[i]; i++) {
@@ -1377,7 +1387,7 @@ cb_compare_factories (GnmSolverFactory *a, GnmSolverFactory *b)
 void
 gnm_solver_db_register (GnmSolverFactory *factory)
 {
-	if (debug_solver ())
+	if (gnm_solver_debug ())
 		g_printerr ("Registering %s\n", factory->id);
 	g_object_ref (factory);
 	solvers = g_slist_insert_sorted (solvers, factory,
@@ -1387,7 +1397,7 @@ gnm_solver_db_register (GnmSolverFactory *factory)
 void
 gnm_solver_db_unregister (GnmSolverFactory *factory)
 {
-	if (debug_solver ())
+	if (gnm_solver_debug ())
 		g_printerr ("Unregistering %s\n", factory->id);
 	solvers = g_slist_remove (solvers, factory);
 	g_object_unref (factory);
diff --git a/src/tools/gnm-solver.h b/src/tools/gnm-solver.h
index f336d2c..5fc4b72 100644
--- a/src/tools/gnm-solver.h
+++ b/src/tools/gnm-solver.h
@@ -238,6 +238,8 @@ gboolean gnm_solver_saveas (GnmSolver *solver, WorkbookControl *wbc,
 			    const char *template, char **filename,
 			    GError **err);
 
+gboolean gnm_solver_debug (void);
+
 /* ------------------------------------------------------------------------- */
 /* Solver subclass for subprocesses. */
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]