[gnumeric] solver: glpk now handles milp soluions too.
- From: Morten Welinder <mortenw src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gnumeric] solver: glpk now handles milp soluions too.
- Date: Sun, 15 Nov 2009 18:10:16 +0000 (UTC)
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]