[gnumeric] solver: simplify.



commit fb4abca6b9b7b2a10eaebbcc917444837f8325a7
Author: Morten Welinder <terra gnome org>
Date:   Fri May 21 16:52:29 2010 -0400

    solver: simplify.

 src/tools/ChangeLog    |    6 +++
 src/tools/gnm-solver.c |   96 +++++++++++++++++++++++++++++++++++++++++-------
 src/tools/gnm-solver.h |    4 ++
 3 files changed, 92 insertions(+), 14 deletions(-)
---
diff --git a/src/tools/ChangeLog b/src/tools/ChangeLog
index 714ac35..b2e2949 100644
--- a/src/tools/ChangeLog
+++ b/src/tools/ChangeLog
@@ -1,3 +1,9 @@
+2010-05-21  Morten Welinder  <terra gnome org>
+
+	* gnm-solver.c (gnm_solver_check_constraints): New function.
+	(gnm_solver_has_solution): New function.
+	(gnm_solver_store_result): Use gnm_solver_has_solution.
+
 2010-05-20  Morten Welinder <terra gnome org>
 
 	* Release 1.10.4
diff --git a/src/tools/gnm-solver.c b/src/tools/gnm-solver.c
index 9397b54..1c2ab1e 100644
--- a/src/tools/gnm-solver.c
+++ b/src/tools/gnm-solver.c
@@ -877,7 +877,6 @@ gnm_solver_store_result (GnmSolver *sol)
 	GnmValue const *vinput;
 	GnmSheetRange sr;
 	int h, w, x, y;
-	GnmSolverResult const *result;
 	GnmValue const *solution;
 
 	g_return_if_fail (GNM_IS_SOLVER (sol));
@@ -890,19 +889,9 @@ gnm_solver_store_result (GnmSolver *sol)
 	h = range_height (&sr.range);
 	w = range_width (&sr.range);
 
-	result = sol->result;
-	switch (result->quality) {
-	case GNM_SOLVER_RESULT_FEASIBLE:
-	case GNM_SOLVER_RESULT_OPTIMAL:
-		solution = result->solution;
-		break;
-	default:
-	case GNM_SOLVER_RESULT_NONE:
-	case GNM_SOLVER_RESULT_INFEASIBLE:
-	case GNM_SOLVER_RESULT_UNBOUNDED:
-		solution = NULL;
-		break;
-	}
+	solution = gnm_solver_has_solution (sol)
+		? sol->result->solution
+		: NULL;
 
 	for (x = 0; x < w; x++) {
 		for (y = 0; y < h; y++) {
@@ -950,6 +939,85 @@ gnm_solver_set_status (GnmSolver *solver, GnmSolverStatus status)
 }
 
 gboolean
+gnm_solver_has_solution (GnmSolver *solver)
+{
+	if (solver->result == NULL)
+		return FALSE;
+
+	switch (solver->result->quality) {
+	case GNM_SOLVER_RESULT_NONE:
+	case GNM_SOLVER_RESULT_INFEASIBLE:
+	case GNM_SOLVER_RESULT_UNBOUNDED:
+	default:
+		return FALSE;
+	case GNM_SOLVER_RESULT_FEASIBLE:
+	case GNM_SOLVER_RESULT_OPTIMAL:
+		return TRUE;
+	}
+}
+
+gboolean
+gnm_solver_check_constraints (GnmSolver *solver)
+{
+	GSList *l;
+	GnmSolverParameters *sp = solver->params;
+
+	if (sp->options.assume_non_negative) {
+		/* FIXME */
+	}
+
+	if (sp->options.assume_discrete) {
+		/* FIXME */
+	}
+
+	for (l = sp->constraints; l; l = l->next) {
+		GnmSolverConstraint *c = l->data;
+		int i;
+		gnm_float cl, cr;
+		GnmCell *lhs, *rhs;
+
+		for (i = 0;
+		     gnm_solver_constraint_get_part (c, sp, i,
+						     &lhs, &cl,
+						     &rhs, &cr);
+		     i++) {
+			if (lhs)
+				cl = value_get_as_float (lhs->value);
+			if (rhs)
+				cr = value_get_as_float (rhs->value);
+
+			switch (c->type) {
+			case GNM_SOLVER_INTEGER:
+				if (cl == gnm_floor (cl))
+					continue;
+				return FALSE;
+			case GNM_SOLVER_BOOLEAN:
+				if (cl == 0 || cl == 1)
+					continue;
+				return FALSE;
+			case GNM_SOLVER_LE:
+				if (cl <= cr)
+					continue;
+				return FALSE;
+			case GNM_SOLVER_GE:
+				if (cl >= cr)
+					continue;
+				return FALSE;
+			case GNM_SOLVER_EQ:
+				if (cl == cr)
+					continue;
+				return FALSE;
+			default:
+				g_assert_not_reached ();
+				return FALSE;
+			}
+		}
+	}
+
+	return TRUE;
+}
+
+gboolean
 gnm_solver_saveas (GnmSolver *solver, WorkbookControl *wbc,
 		   GOFileSaver *fs,
 		   const char *templ, char **filename,
diff --git a/src/tools/gnm-solver.h b/src/tools/gnm-solver.h
index d8b7aac..6a69a17 100644
--- a/src/tools/gnm-solver.h
+++ b/src/tools/gnm-solver.h
@@ -224,6 +224,10 @@ void gnm_solver_store_result (GnmSolver *solver);
 
 gboolean gnm_solver_finished (GnmSolver *solver);
 
+gboolean gnm_solver_has_solution (GnmSolver *solver);
+
+gboolean gnm_solver_check_constraints (GnmSolver *solver);
+
 gboolean gnm_solver_saveas (GnmSolver *solver, WorkbookControl *wbc,
 			    GOFileSaver *fs,
 			    const char *templ, char **filename,



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