summaryrefslogtreecommitdiffstats
path: root/sc/inc/SolverSettings.hxx
blob: ec1ef994a7b8f0ec0a2ad1462b1d358e50900583 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 */

#pragma once

#include <memory>
#include <utility>
#include <variant>
#include <rtl/ustring.hxx>
#include <com/sun/star/beans/PropertyValue.hpp>

class ScTable;
class ScDocShell;

namespace sc
{
// These values are MS compatible
enum ObjectiveType
{
    OT_MAXIMIZE = 1,
    OT_MINIMIZE = 2,
    OT_VALUE = 3
};

enum SolverParameter
{
    SP_OBJ_CELL, // Objective cell
    SP_OBJ_TYPE, // Objective type (max, min, value)
    SP_OBJ_VAL, // Value (used when objective is of type "value")
    SP_VAR_CELLS, // Variable cells
    SP_CONSTR_COUNT, // Number of constraints (MSO only)
    SP_LO_ENGINE, // Engine name used in LO
    SP_MS_ENGINE, // Engine ID used in MSO
    SP_INTEGER, // Assume all variables are integer (0: no, 1: yes)
    SP_NON_NEGATIVE, // Assume non negativity (1: yes, 2: no)
    SP_EPSILON_LEVEL, // Epsilon level
    SP_LIMIT_BBDEPTH, // Branch and bound depth
    SP_TIMEOUT, // Time limit to return a solution
    SP_ALGORITHM // Algorithm used by the SwarmSolver (1, 2 or 3)
};

// Starts at 1 to maintain MS compatibility
enum ConstraintOperator
{
    CO_LESS_EQUAL = 1,
    CO_EQUAL = 2,
    CO_GREATER_EQUAL = 3,
    CO_INTEGER = 4,
    CO_BINARY = 5
};

// Parts of a constraint
enum ConstraintPart
{
    CP_LEFT_HAND_SIDE,
    CP_OPERATOR,
    CP_RIGHT_HAND_SIDE
};

// Stores the information of a single constraint (condition)
struct ModelConstraint
{
    OUString aLeftStr;
    ConstraintOperator nOperator;
    OUString aRightStr;

    ModelConstraint()
        : nOperator(CO_LESS_EQUAL)
    {
    }
    bool IsDefault() const
    {
        return aLeftStr.isEmpty() && aRightStr.isEmpty() && nOperator == CO_LESS_EQUAL;
    }
};

/* Class SolverSettings
 *
 * This class is used to load/save and manipulate solver settings in a Calc tab.
 *
 * During initialization, (see Initialize() method) all settings stored in the tab are loaded onto
 * the object. Settings that are not defined use default values.
 *
 * Read/Write methods are private and are used internally to load/write solver settings from
 * named ranges associated with the sheet.
 *
 * Get/Set methods are public methods used to change object properties (they do not save data
 * to the file).
 *
 * The method SaveSolverSettings() is used to create the named ranges containing the current
 * property values into the file.
 *
 */

class SolverSettings
{
private:
    ScTable& m_rTable;
    ScDocument& m_rDoc;
    ScDocShell* m_pDocShell;

    // Used to read/write the named ranges in the tab
    ScRangeName* m_pRangeName;

    OUString m_sObjCell;
    ObjectiveType m_eObjType;
    OUString m_sObjVal;
    OUString m_sVariableCells;
    OUString m_sLOEngineName;
    OUString m_sMSEngineId;

    // Solver engine options
    OUString m_sInteger;
    OUString m_sNonNegative;
    OUString m_sEpsilonLevel;
    OUString m_sLimitBBDepth;
    OUString m_sTimeout;
    OUString m_sAlgorithm;
    css::uno::Sequence<css::beans::PropertyValue> m_aEngineOptions;

    std::vector<ModelConstraint> m_aConstraints;

    void Initialize();

    // Used to create or read a single solver parameter based on its named range
    bool ReadParamValue(SolverParameter eParam, OUString& rValue, bool bRemoveQuotes = false);
    void WriteParamValue(SolverParameter eParam, OUString sValue, bool bQuoted = false);

    // Creates or reads all constraints stored in named ranges
    void ReadConstraints();
    void WriteConstraints();

    // Used to create or get a single constraint part
    bool ReadConstraintPart(ConstraintPart ePart, tools::Long nIndex, OUString& rValue);
    void WriteConstraintPart(ConstraintPart ePart, tools::Long nIndex, OUString sValue);

    // Creates or reads all named ranges associated with solver engine options
    void ReadEngine();
    void WriteEngine();

    void DeleteAllNamedRanges();

    // Maps solver parameters to named ranges
    std::map<SolverParameter, OUString> m_mNamedRanges
        = { { SP_OBJ_CELL, "solver_opt" },      { SP_OBJ_TYPE, "solver_typ" },
            { SP_OBJ_VAL, "solver_val" },       { SP_VAR_CELLS, "solver_adj" },
            { SP_CONSTR_COUNT, "solver_num" },  { SP_LO_ENGINE, "solver_lo_eng" },
            { SP_MS_ENGINE, "solver_eng" },     { SP_INTEGER, "solver_int" },
            { SP_NON_NEGATIVE, "solver_neg" },  { SP_EPSILON_LEVEL, "solver_eps" },
            { SP_LIMIT_BBDEPTH, "solver_bbd" }, { SP_TIMEOUT, "solver_tim" },
            { SP_ALGORITHM, "solver_alg" } };

    // Maps LO solver implementation names to MS engine codes
    std::map<OUString, OUString> SolverNamesToExcelEngines = {
        { "com.sun.star.comp.Calc.CoinMPSolver", "2" }, // Simplex LP
        { "com.sun.star.comp.Calc.LpsolveSolver", "2" }, // Simplex LP
        { "com.sun.star.comp.Calc.SwarmSolver", "1" } // GRG Nonlinear
    };

    // Maps MS solver engine codes to LO solver implementation names
    std::map<OUString, OUString> SolverCodesToLOEngines = {
        { "1", "com.sun.star.comp.Calc.SwarmSolver" }, // GRG Nonlinear
        { "2", "com.sun.star.comp.Calc.CoinMPSolver" }, // Simplex LP
        { "3", "com.sun.star.comp.Calc.SwarmSolver" } // Evolutionary
    };

    // Maps LO solver parameters to named ranges to be used
    // NonNegative: for MS compatibility, use 1 for selected and 2 for not selected
    typedef std::vector<std::variant<OUString, SolverParameter>> TParamInfo;
    std::map<OUString, TParamInfo> SolverParamNames
        = { { "Integer", { SP_INTEGER, "solver_int", "bool" } },
            { "NonNegative", { SP_NON_NEGATIVE, "solver_neg", "bool" } },
            { "EpsilonLevel", { SP_EPSILON_LEVEL, "solver_eps", "int" } },
            { "LimitBBDepth", { SP_LIMIT_BBDEPTH, "solver_bbd", "bool" } },
            { "Timeout", { SP_TIMEOUT, "solver_tim", "int" } },
            { "Algorithm", { SP_ALGORITHM, "solver_alg", "int" } } };

    // Stores the roots used for named ranges of constraint parts
    // Items here must be in the same order as in ConstraintPart enum
    std::vector<OUString> m_aConstraintParts{ "solver_lhs", "solver_rel", "solver_rhs" };

public:
    /* A SolverSettings object is linked to the ScTable where solver parameters
     *  are located and saved to */
    SolverSettings(ScTable& pTable);

    SC_DLLPUBLIC OUString GetParameter(SolverParameter eParam);
    SC_DLLPUBLIC void SetParameter(SolverParameter eParam, OUString sValue);
    SC_DLLPUBLIC ObjectiveType GetObjectiveType() { return m_eObjType; }
    SC_DLLPUBLIC void SetObjectiveType(ObjectiveType eType);
    SC_DLLPUBLIC void GetEngineOptions(css::uno::Sequence<css::beans::PropertyValue>& aOptions);
    SC_DLLPUBLIC void SetEngineOptions(css::uno::Sequence<css::beans::PropertyValue>& aOptions);
    SC_DLLPUBLIC std::vector<ModelConstraint> GetConstraints() { return m_aConstraints; }
    SC_DLLPUBLIC void SetConstraints(std::vector<ModelConstraint> aConstraints);

    SC_DLLPUBLIC void SaveSolverSettings();
    SC_DLLPUBLIC void ResetToDefaults();
};

} // namespace sc

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */