Ejemplo n.º 1
0
static void
solver_add_scenario (SolverState *state, GnmSolverResult *res, gchar const *name)
{
	GnmSolverParameters *param = state->sheet->solver_parameters;
	GnmValue const *vinput;
	GnmScenario *sc;
	GnmSheetRange sr;
	WorkbookControl *wbc = GNM_WBC (state->wbcg);

	vinput = gnm_solver_param_get_input (param);
	gnm_sheet_range_from_value (&sr, vinput);

	sc = gnm_sheet_scenario_new (param->sheet, name);
	switch (res->quality) {
	case GNM_SOLVER_RESULT_OPTIMAL:
		gnm_scenario_set_comment
			(sc, _("Optimal solution created by solver.\n"));
		break;
	case GNM_SOLVER_RESULT_FEASIBLE:
		gnm_scenario_set_comment
			(sc, _("Feasible solution created by solver.\n"));
		break;
	default:
		break;
	}
	gnm_scenario_add_area (sc, &sr);

	cmd_scenario_add (wbc, sc, sc->sheet);
}
Ejemplo n.º 2
0
gboolean
gnm_scenario_item_valid (const GnmScenarioItem *sci, GnmSheetRange *sr)
{
	GnmExprTop const *texpr;
	GnmValue const *vr;

	if (!sci || !((texpr = sci->dep.texpr)))
		return FALSE;

	vr = gnm_expr_top_get_constant (texpr);
	if (!vr || !VALUE_IS_CELLRANGE (vr))
		return FALSE;

	if (sr)
		gnm_sheet_range_from_value
			(sr, gnm_expr_top_get_constant (texpr));
	return TRUE;
}
Ejemplo n.º 3
0
GnmSolver *
lpsolve_solver_factory (GnmSolverFactory *factory, GnmSolverParameters *params)
{
	GnmSolver *res = g_object_new (GNM_SUB_SOLVER_TYPE,
					  "params", params,
					  NULL);
	GnmLPSolve *lp = g_new0 (GnmLPSolve, 1);

	lp->parent = GNM_SUB_SOLVER (res);
	gnm_sheet_range_from_value (&lp->srinput,
				    gnm_solver_param_get_input (params));
	if (lp->srinput.sheet) lp->srinput.sheet = params->sheet;

	g_signal_connect (res, "prepare", G_CALLBACK (gnm_lpsolve_prepare), lp);
	g_signal_connect (res, "start", G_CALLBACK (gnm_lpsolve_start), lp);
	g_signal_connect (res, "stop", G_CALLBACK (gnm_lpsolve_stop), lp);
	g_signal_connect (res, "child-exit", G_CALLBACK (gnm_lpsolve_child_exit), lp);

	g_object_set_data_full (G_OBJECT (res), PRIVATE_KEY, lp,
				(GDestroyNotify)gnm_lpsolve_final);

	return res;
}
Ejemplo n.º 4
0
static GnmSolverResult *
run_solver (SolverState *state, GnmSolverParameters *param)
{
	GError *err = NULL;
	gboolean ok;
	GnmSheetRange sr;
	GOUndo *undo = NULL;
	GnmSolver *sol = NULL;
	GnmValue const *vinput;
	GtkWindow *top = GTK_WINDOW (gtk_widget_get_toplevel (state->dialog));
	GnmSolverResult *res = NULL;

	state->ref_count++;

	sol = gnm_solver_factory_functional (param->options.algorithm,
					     state->wbcg)
		? gnm_solver_factory_create (param->options.algorithm, param)
		: NULL;
	if (!sol) {
		go_gtk_notice_dialog (top, GTK_MESSAGE_ERROR,
				      _("The chosen solver is not functional."));
		goto fail;
	}

	gtk_notebook_set_current_page (GTK_NOTEBOOK (state->notebook), -1);

	state->run.solver = sol;

	vinput = gnm_solver_param_get_input (param);
	gnm_sheet_range_from_value (&sr, vinput);
	if (!sr.sheet) sr.sheet = param->sheet;
	undo = clipboard_copy_range_undo (sr.sheet, &sr.range);

	g_signal_connect_swapped (G_OBJECT (sol),
				  "notify::status",
				  G_CALLBACK (cb_notify_status),
				  state);
	g_signal_connect_swapped (G_OBJECT (sol),
				  "notify::reason",
				  G_CALLBACK (cb_notify_status),
				  state);
	cb_notify_status (state);

	g_signal_connect_swapped (G_OBJECT (sol),
				  "notify::result",
				  G_CALLBACK (cb_notify_result),
				  state);
	cb_notify_result (state);

	state->run.timer_source = g_timeout_add_seconds
		(1, (GSourceFunc)cb_timer_tick, state);
	cb_timer_tick (state);

	/* ---------------------------------------- */

	ok = gnm_solver_start (sol,
			       GNM_WBC (state->wbcg),
			       &err);
	if (ok) {
		state->run.in_main++;
		go_cmd_context_set_sensitive (GO_CMD_CONTEXT (state->wbcg), FALSE);
		gtk_main ();
		go_cmd_context_set_sensitive (GO_CMD_CONTEXT (state->wbcg), TRUE);
		state->run.in_main--;
		ok = gnm_solver_has_solution (sol);
	} else if (err) {
		gnm_solver_set_reason (sol, err->message);
	}
	g_clear_error (&err);

	remove_objective_value_source (state);
	remove_timer_source (state);

	/* ---------------------------------------- */

	if (ok) {
		GOUndo *redo;

		gnm_solver_store_result (sol);
		redo = clipboard_copy_range_undo (sr.sheet, &sr.range);

		if (param->options.program_report ||
		    param->options.sensitivity_report) {
			Workbook *wb = param->sheet->workbook;
			GOUndo *undo_report, *redo_report;

			undo_report = go_undo_binary_new
				(wb,
				 workbook_sheet_state_new (wb),
				 (GOUndoBinaryFunc)workbook_sheet_state_restore,
				 NULL,
				 (GFreeFunc)workbook_sheet_state_free);
			undo = go_undo_combine (undo, undo_report);

			create_report (sol, state);

			redo_report = go_undo_binary_new
				(wb,
				 workbook_sheet_state_new (wb),
				 (GOUndoBinaryFunc)workbook_sheet_state_restore,
				 NULL,
				 (GFreeFunc)workbook_sheet_state_free);
			redo = go_undo_combine (redo, redo_report);
		}

		cmd_generic (GNM_WBC (state->wbcg),
			     _("Running solver"),
			     undo, redo);
		res = g_object_ref (sol->result);
		undo = redo = NULL;
	}

fail:
	if (undo)
		g_object_unref (undo);

	if (state->run.solver) {
		g_object_unref (state->run.solver);
		state->run.solver = NULL;
	}

	unref_state (state);

	return res;
}
Ejemplo n.º 5
0
/**
 * scenarios_ok_clicked_cb:
 * @button:
 * @state:
 *
 * Run the scenario manager tool.
 **/
static void
scenario_add_ok_clicked_cb (G_GNUC_UNUSED GtkWidget *button,
			    ScenariosState *state)
{
	data_analysis_output_t  dao;
	WorkbookControl         *wbc;
	gchar                   *name;
	gchar                   *comment;
	GnmValue                   *cell_range;
	GtkWidget               *entry, *comment_view;
	GtkTextBuffer           *buf;
	GtkTextIter             start, end;
	GnmScenario             *sc;
	GnmSheetRange           sr;

	cell_range = gnm_expr_entry_parse_as_value
		(GNM_EXPR_ENTRY (state->base.input_entry), state->base.sheet);

	if (!cell_range || !gnm_sheet_range_from_value (&sr, cell_range)) {
		go_gtk_notice_dialog (GTK_WINDOW (state->base.dialog),
				 GTK_MESSAGE_ERROR,
				 _("Invalid changing cells"));
		gnm_expr_entry_grab_focus (state->base.input_entry, TRUE);
		return;
	}

	if (sr.sheet && sr.sheet != state->base.sheet) {
		go_gtk_notice_dialog (GTK_WINDOW (state->base.dialog),
				 GTK_MESSAGE_ERROR,
				 _("Changing cells should be on the current "
				   "sheet only."));
		gnm_expr_entry_grab_focus (state->base.input_entry, TRUE);
		goto out;
	}
	entry = go_gtk_builder_get_widget (state->base.gui, "name_entry");

	name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
	if (scenario_name_used (state->base.sheet->scenarios, name)) {
	        g_free (name);
		go_gtk_notice_dialog (GTK_WINDOW (state->base.dialog),
				 GTK_MESSAGE_ERROR,
				 _("Scenario name already used"));
		goto out;
	} else if (check_name (name)) {
	        g_free (name);
		go_gtk_notice_dialog (GTK_WINDOW (state->base.dialog),
				 GTK_MESSAGE_ERROR,
				 _("Invalid scenario name"));
		goto out;
	}

	comment_view = go_gtk_builder_get_widget (state->base.gui, "comment_view");
	buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (comment_view));
	gtk_text_buffer_get_start_iter (buf, &start);
	gtk_text_buffer_get_end_iter (buf, &end);
	comment = g_strdup (gtk_text_buffer_get_text (buf, &start, &end,
						      FALSE));

	dao_init_new_sheet (&dao);
	dao.sheet = state->base.sheet;

	wbc = WORKBOOK_CONTROL (state->base.wbcg);

	sc = gnm_sheet_scenario_new (state->base.sheet, name);
	if (comment && comment[0])
		gnm_scenario_set_comment (sc, comment);
	gnm_scenario_add_area (sc, &sr);

	cmd_scenario_add (wbc, sc, state->base.sheet);

	g_free (name);
	g_free (comment);
	gtk_widget_destroy (state->base.dialog);
 out:
	value_release (cell_range);
	return;
}
Ejemplo n.º 6
0
static void
cb_add_clicked (SortFlowState *state)
{
        GnmValue *range_add;
	GnmSheetRange grange_sort, grange_add;
	GnmRange intersection;
	int start;
	int end;
	int index;
	int i;
	gboolean had_items = (state->sort_items > 0);

        range_add = gnm_expr_entry_parse_as_value
		(GNM_EXPR_ENTRY (state->add_entry), state->sheet);

	if (range_add == NULL) {
		show_add_menu (state);
		return;
	}

	g_return_if_fail (range_add != NULL && state->sel != NULL);

	gnm_sheet_range_from_value (&grange_sort, state->sel);
	gnm_sheet_range_from_value (&grange_add, range_add);

	value_release (range_add);

	if (range_intersection (&intersection, &grange_sort.range, &grange_add.range)) {

		if (state->is_cols) {
			start = intersection.start.col;
			end = intersection.end.col;
			index = state->sel->v_range.cell.a.row;
		} else {
			start = intersection.start.row;
			end = intersection.end.row;
			index = state->sel->v_range.cell.a.col;
		}

		for (i = start; i <= end; i++) {

			int item = 0;
			GtkTreeIter iter;
			gboolean found = FALSE;
			gint number;

			while (gtk_tree_model_iter_nth_child  (GTK_TREE_MODEL (state->model),
							       &iter, NULL, item)) {
				gtk_tree_model_get (GTK_TREE_MODEL (state->model), &iter,
						    ITEM_NUMBER, &number,
						    -1);
				item++;
				if (number == i) {
					found = TRUE;
					break;
				}
			}

			if (!found) {
				append_data (state, i, index);
			}
		}
		if (!had_items && (state->sort_items > 0))
			set_button_sensitivity(state);
	} else
		show_add_menu (state);
	gnm_expr_entry_load_from_text (GNM_EXPR_ENTRY (state->add_entry), "");
}