mdpsolver 0.10.2__tar.gz → 0.11.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. mdpsolver-0.11.0/.gitignore +27 -0
  2. mdpsolver-0.11.0/CPP_Source_Code/CBMmodel.cpp +388 -0
  3. mdpsolver-0.11.0/CPP_Source_Code/CBMmodel.h +114 -0
  4. mdpsolver-0.11.0/CPP_Source_Code/CMakeLists.txt +25 -0
  5. mdpsolver-0.11.0/CPP_Source_Code/GeneralMDPmodel.cpp +123 -0
  6. mdpsolver-0.11.0/CPP_Source_Code/GeneralMDPmodel.h +84 -0
  7. mdpsolver-0.11.0/CPP_Source_Code/ModelType.cpp +1 -0
  8. mdpsolver-0.11.0/CPP_Source_Code/ModelType.h +23 -0
  9. mdpsolver-0.11.0/CPP_Source_Code/ModifiedPolicyIteration.cpp +1088 -0
  10. mdpsolver-0.11.0/CPP_Source_Code/ModifiedPolicyIteration.h +110 -0
  11. mdpsolver-0.11.0/CPP_Source_Code/ModuleInterface.cpp +858 -0
  12. mdpsolver-0.11.0/CPP_Source_Code/ModuleInterface.h +218 -0
  13. mdpsolver-0.11.0/CPP_Source_Code/Policy.cpp +52 -0
  14. mdpsolver-0.11.0/CPP_Source_Code/Policy.h +66 -0
  15. mdpsolver-0.11.0/CPP_Source_Code/PythonModule.cpp +75 -0
  16. mdpsolver-0.11.0/CPP_Source_Code/Rewards.cpp +67 -0
  17. mdpsolver-0.11.0/CPP_Source_Code/Rewards.h +64 -0
  18. mdpsolver-0.11.0/CPP_Source_Code/TBMmodel.cpp +249 -0
  19. mdpsolver-0.11.0/CPP_Source_Code/TBMmodel.h +106 -0
  20. mdpsolver-0.11.0/CPP_Source_Code/TransitionMatrix.cpp +99 -0
  21. mdpsolver-0.11.0/CPP_Source_Code/TransitionMatrix.h +76 -0
  22. mdpsolver-0.11.0/CPP_Source_Code/ValueVector.cpp +52 -0
  23. mdpsolver-0.11.0/CPP_Source_Code/ValueVector.h +64 -0
  24. {mdpsolver-0.10.2 → mdpsolver-0.11.0}/LICENSE +1 -1
  25. {mdpsolver-0.10.2 → mdpsolver-0.11.0}/PKG-INFO +47 -4
  26. mdpsolver-0.11.0/Python/src/mdpsolver/__init__.py +1 -0
  27. mdpsolver-0.11.0/Python/src/mdpsolver/model.py +398 -0
  28. mdpsolver-0.11.0/Python/tests/knownsolutions.py +300 -0
  29. mdpsolver-0.11.0/Python/tests/loadmdpsolver.py +149 -0
  30. mdpsolver-0.11.0/Python/tests/test_checkmodel.py +279 -0
  31. mdpsolver-0.11.0/Python/tests/test_imports.py +662 -0
  32. mdpsolver-0.11.0/Python/tests/test_large.py +285 -0
  33. mdpsolver-0.11.0/Python/tests/test_mpi.py +447 -0
  34. mdpsolver-0.11.0/Python/tests/test_order.py +278 -0
  35. mdpsolver-0.11.0/Python/tests/test_output.py +219 -0
  36. mdpsolver-0.11.0/Python/tests/test_pi.py +438 -0
  37. mdpsolver-0.11.0/Python/tests/test_random.py +318 -0
  38. mdpsolver-0.11.0/Python/tests/test_reuse.py +287 -0
  39. mdpsolver-0.11.0/Python/tests/test_vi.py +455 -0
  40. {mdpsolver-0.10.2 → mdpsolver-0.11.0}/README.md +45 -2
  41. {mdpsolver-0.10.2 → mdpsolver-0.11.0}/pyproject.toml +22 -5
  42. mdpsolver-0.10.2/MANIFEST.in +0 -3
  43. mdpsolver-0.10.2/src/mdpsolver/__init__.py +0 -1
  44. mdpsolver-0.10.2/src/mdpsolver/model.py +0 -211
  45. mdpsolver-0.10.2/tests/example_model.py +0 -139
  46. mdpsolver-0.10.2/tests/rewards_example2.csv +0 -403
  47. mdpsolver-0.10.2/tests/test1.py +0 -717
  48. mdpsolver-0.10.2/tests/test1_pip.py +0 -713
  49. mdpsolver-0.10.2/tests/test2.py +0 -94
  50. mdpsolver-0.10.2/tests/test2_pip.py +0 -90
  51. mdpsolver-0.10.2/tests/transitions_example2.csv +0 -41205
@@ -0,0 +1,27 @@
1
+ /.vs
2
+ /VisualStudioProject
3
+ .vscode/
4
+ .claude/
5
+ .DS_Store
6
+ Python/.DS_Store
7
+
8
+
9
+ __pycache__/
10
+ *.pyc
11
+
12
+ Python/src/mdpsolver/problems/
13
+ build/
14
+ dist/
15
+ wheelhouse/
16
+ Dockerfile
17
+
18
+ CompilerNotes.txt
19
+ *.exe
20
+ *egg-info
21
+ *.Rhistory
22
+ Benchmark/results/
23
+
24
+ # Compiled extension modules are built by CI (cibuildwheel) / local build
25
+ # scripts, not committed to the repo.
26
+ *.pyd
27
+ *.so
@@ -0,0 +1,388 @@
1
+ /*
2
+ * MIT License
3
+ *
4
+ * Copyright (c) 2026 Anders Reenberg Andersen and Jesper Fink Andersen
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ * of this software and associated documentation files (the "Software"), to deal
8
+ * in the Software without restriction, including without limitation the rights
9
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ * copies of the Software, and to permit persons to whom the Software is
11
+ * furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be included in all
14
+ * copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ * SOFTWARE.
23
+ */
24
+
25
+
26
+ #include <iostream>
27
+ #include <fstream> //to import component probabilities
28
+ #include <string> //
29
+ #include <sstream> //
30
+ #include <math.h>
31
+ #include <assert.h>
32
+ #include <exception> //for exiting if probabilities cannot be loaded
33
+ #include <algorithm>
34
+ #include <valarray> //for min and max function
35
+ #include "CBMmodel.h"
36
+
37
+ using namespace std;
38
+
39
+ CBMmodel::CBMmodel(double discount,
40
+ int components,
41
+ int stages,
42
+ string importProbPath,
43
+ double preventiveCost,
44
+ double correctiveCost,
45
+ double setupCost,
46
+ double failurePenalty,
47
+ int kOfN): //default constructor
48
+ N(components),
49
+ L(stages-1),
50
+ discount(discount),
51
+ numberOfStates(intPow(stages,components)), //unsigned INT_MAX is 2147483647
52
+ numberOfActions(intPow(2,components)),
53
+ cp(preventiveCost),
54
+ cc(correctiveCost),
55
+ cs(setupCost),
56
+ p(failurePenalty),
57
+ kN(kOfN),
58
+ importProbs(!importProbPath.empty()),
59
+ pCompMat(components,vector<double>(stages)),
60
+ pFailCompMat(components, vector<double>(stages)),
61
+ sidxMat(numberOfStates, vector<int>(components)),
62
+ aidxMat(numberOfActions, vector<int>(components))
63
+ {
64
+ //set K-out-of-N
65
+ if (kN<=0||kN>N){
66
+ kN=N;
67
+ }
68
+
69
+ //import component probabilities
70
+ if (importProbs) {
71
+ importComponentProbs(importProbPath);
72
+ }
73
+ // calculate tail probabilities
74
+ for (int i = 0; i < N; ++i) {
75
+ pFailCompMat[i][0] = pCompMat[i][L];
76
+ for (int j = 1; j <= L; ++j) {
77
+ pFailCompMat[i][j] = pFailCompMat[i][j - 1] + pCompMat[i][L-j];
78
+ }
79
+ }
80
+ //initialize sidxMat
81
+ int sidx_temp,s_i;
82
+ for (int sidx = 0; sidx < numberOfStates; ++sidx) {
83
+ sidx_temp = sidx;
84
+ for (int i = 0; i < N; ++i) {
85
+ s_i = sidx_temp % (L+1);
86
+ sidxMat[sidx][i] = s_i;
87
+ sidx_temp /= (L+1);
88
+ }
89
+ }
90
+ //initialize aidxMat
91
+ int aidx_temp, a_i;
92
+ for (int aidx = 0; aidx < numberOfActions; ++aidx) {
93
+ aidx_temp = aidx;
94
+ for (int i = 0; i < N; ++i) {
95
+ a_i = aidx_temp % 2;
96
+ aidxMat[aidx][i] = a_i;
97
+ aidx_temp /= 2;
98
+ }
99
+ }
100
+ }
101
+
102
+ CBMmodel::CBMmodel(double discount,
103
+ int components,
104
+ int stages,
105
+ vector<vector<double>> pcm,
106
+ double preventiveCost,
107
+ double correctiveCost,
108
+ double setupCost,
109
+ double failurePenalty,
110
+ int kOfN): //default constructor
111
+ N(components),
112
+ L(stages-1),
113
+ discount(discount),
114
+ numberOfStates(intPow(stages,components)), //unsigned INT_MAX is 2147483647
115
+ numberOfActions(intPow(2,components)),
116
+ cp(preventiveCost),
117
+ cc(correctiveCost),
118
+ cs(setupCost),
119
+ p(failurePenalty),
120
+ kN(kOfN),
121
+ pCompMat(pcm),
122
+ pFailCompMat(components, vector<double>(stages)),
123
+ sidxMat(numberOfStates, vector<int>(components)),
124
+ aidxMat(numberOfActions, vector<int>(components))
125
+ {
126
+ //set K-out-of-N
127
+ if (kN<=0||kN>N){
128
+ kN=N;
129
+ }
130
+
131
+ // calculate tail probabilities
132
+ for (int i = 0; i < N; ++i) {
133
+ pFailCompMat[i][0] = pCompMat[i][L];
134
+ for (int j = 1; j <= L; ++j) {
135
+ pFailCompMat[i][j] = pFailCompMat[i][j - 1] + pCompMat[i][L-j];
136
+ }
137
+ }
138
+ //initialize sidxMat
139
+ int sidx_temp,s_i;
140
+ for (int sidx = 0; sidx < numberOfStates; ++sidx) {
141
+ sidx_temp = sidx;
142
+ for (int i = 0; i < N; ++i) {
143
+ s_i = sidx_temp % (L+1);
144
+ sidxMat[sidx][i] = s_i;
145
+ sidx_temp /= (L+1);
146
+ }
147
+ }
148
+ //initialize aidxMat
149
+ int aidx_temp, a_i;
150
+ for (int aidx = 0; aidx < numberOfActions; ++aidx) {
151
+ aidx_temp = aidx;
152
+ for (int i = 0; i < N; ++i) {
153
+ a_i = aidx_temp % 2;
154
+ aidxMat[aidx][i] = a_i;
155
+ aidx_temp /= 2;
156
+ }
157
+ }
158
+ }
159
+
160
+
161
+ CBMmodel::CBMmodel(const CBMmodel& orig) {
162
+ }
163
+
164
+ CBMmodel::~CBMmodel() {
165
+ }
166
+
167
+ //class functions
168
+ double CBMmodel::reward(int &sidx, int &aidx) {
169
+ //reward function
170
+ r = 0;
171
+ set_up = false;
172
+ fail_count = 0;
173
+ for(int i = 0; i < N; ++i) {
174
+ s_i = sidxMat[sidx][i];//i'th component state
175
+ a_i = aidxMat[aidx][i];
176
+ if (a_i==1) {
177
+ set_up = true;
178
+ if (s_i==L) {
179
+ ++fail_count;
180
+ r += cc;
181
+ } else {
182
+ r += cp;
183
+ }
184
+ } else if (s_i==L) {
185
+ ++fail_count;
186
+ }
187
+ }
188
+ r += set_up*cs + ((N-fail_count) < kN)*p;
189
+ return r;
190
+ }
191
+
192
+ double CBMmodel::transProb(int &sidx, int &aidx, int &jidx) {
193
+ //transition probability function
194
+
195
+ //int step;
196
+ prob = 1;
197
+ for (int i = 0; i<N; ++i) {
198
+ j_i = sidxMat[jidx][i]; //i'th component state
199
+ s_i = sidxMat[sidx][i];
200
+ a_i = aidxMat[aidx][i];
201
+ if (a_i == 0 && j_i<s_i) { // impossible transitions
202
+ prob *= 0;
203
+ } else if (a_i == 0 && j_i >= s_i) { //no replacement
204
+ step = j_i - s_i;
205
+ if (j_i < L) {
206
+ prob *= pCompMat[i][step];
207
+ } else {
208
+ prob *= pFailCompMat[i][s_i];
209
+ }
210
+ } else { //replacement
211
+ prob *= pCompMat[i][j_i];
212
+ }
213
+ }
214
+ psj = prob; //set stored transition probability
215
+ return prob;
216
+ }
217
+
218
+ void CBMmodel::updateTransProbNextState(int sidx, int aidx, int jidx) {
219
+ //void CBMmodel::updateTransProbNextStateOptimized(int sidx, int aidx, int jidx) {
220
+ //updates psj and nextState, which are assumed to match.
221
+ //That is, input jidx should be nextState.
222
+
223
+ int step;
224
+ for (int i = 0; i<N; ++i) {
225
+ j_i = sidxMat[jidx][i]; //i'th component state
226
+ s_i = sidxMat[sidx][i];
227
+ a_i = aidxMat[aidx][i];
228
+
229
+ //assert(a_i == 1 || (a_i == 0 && j_i >= s_i));//check valid transition
230
+
231
+ if (a_i == 0) {
232
+ step = j_i - s_i;
233
+ } else {
234
+ step = j_i;
235
+ }
236
+
237
+ if (j_i<L) {
238
+ nextState += intPow(L + 1, i); //increment i'th component by one
239
+ //psj /= pCompMat[i][step]; //psj should be divided by what was previously used to calc component transition
240
+ if (j_i + 1 < L) {
241
+ psj *= pCompMat[i][step + 1] / pCompMat[i][step]; // still lower than L after increment
242
+ } else {
243
+ if (a_i == 0) {
244
+ psj *= pFailCompMat[i][s_i] / pCompMat[i][step];
245
+ } else {
246
+ psj *= pCompMat[i][j_i + 1] / pCompMat[i][step]; //going from 0 to L here
247
+ }
248
+ }
249
+ break; //we are done
250
+ } else {
251
+ nextState -= step * intPow(L + 1, i); //reset back to s_i or 0
252
+ //here j_i=L so psj was formely multiplied with a fail probability
253
+ if (a_i == 0) { //went from s_i to L
254
+ psj /= pFailCompMat[i][s_i];
255
+ if (s_i < L) {
256
+ psj *= pCompMat[i][0];
257
+ }
258
+ } else {
259
+ psj *= pCompMat[i][0] / pCompMat[i][L];
260
+ }
261
+ }
262
+ }
263
+ }
264
+
265
+ int CBMmodel::postDecisionIdx(int &sidx, int &aidx) {
266
+ //int CBMmodel::postDecisionIdxOptimized(int sidx, int aidx) {
267
+ //state index right after replacement, which is
268
+ //assumed instantaneous so components are set to age 0
269
+ pdidx = sidx;
270
+
271
+ for (int i = 0; i<N; ++i) {
272
+ s_i = sidxMat[sidx][i];
273
+ a_i = aidxMat[aidx][i];
274
+ if (a_i == 1) {
275
+ pdidx -= (s_i)*intPow(L + 1, i); // sets it to 0
276
+ }
277
+ }
278
+ nextState = pdidx; //store as the "first" next state
279
+ return pdidx;
280
+ }
281
+
282
+
283
+ void CBMmodel::updateNextState(int &sidx, int &aidx, int &jidx) {
284
+ //increment one component's deterioration level.
285
+ if (jidx != -1) {
286
+ nextState = jidx;
287
+ } else {
288
+ jidx = nextState; // default jidx value is current nextState
289
+ }
290
+ done = false;
291
+ for (int i = 0; i<N; ++i) {
292
+ j_i = sidxMat[jidx][i]; //i'th component state
293
+ s_i = sidxMat[sidx][i];
294
+ a_i = aidxMat[aidx][i];
295
+
296
+ if (!done && j_i<L) { //non-replacements
297
+ nextState += intPow(L + 1, i);
298
+ done = true;
299
+ } else if (!done) {
300
+ if (a_i == 0) {
301
+ nextState -= (j_i - s_i)*intPow(L + 1, i); //reset back to s_i
302
+ } else {
303
+ nextState -= (j_i)*intPow(L + 1, i); //reset back to 0
304
+ }
305
+ }
306
+ }
307
+ }
308
+
309
+
310
+ int CBMmodel::intPow(int a, int b) {
311
+ int i = 1;
312
+ for(int j = 1; j <= b; ++j) i *= a;
313
+ return i;
314
+ }
315
+
316
+ void CBMmodel::importComponentProbs(string path) {
317
+ string line;
318
+ ifstream inputFile (path);
319
+ try {
320
+ if(!inputFile.is_open()) {
321
+ throw path;
322
+ }
323
+ }
324
+ catch (string path) {
325
+ cout << "Exception: UNABLE TO OPEN FILE: " + path + "\n";
326
+ exit(EXIT_FAILURE);
327
+ }
328
+
329
+ int i = 0;
330
+ int j = 0;
331
+ string element;
332
+ while( getline(inputFile, line) ) {
333
+ istringstream lineStream(line);
334
+ // read every element from the line that is separated by commas
335
+ // and put it into pCompMat
336
+ j = 0;
337
+ while( getline(lineStream, element, ',') ){
338
+ pCompMat [i][j] = stod(element);
339
+ //cout << i << " " << j << " " << element << endl;
340
+ ++j;
341
+ }
342
+ ++i;
343
+ }
344
+ inputFile.close();
345
+ }
346
+
347
+ double CBMmodel::getDiscount(){
348
+ return discount;
349
+ }
350
+
351
+ int CBMmodel::getNumberOfStates(){
352
+ return numberOfStates;
353
+ }
354
+
355
+ void CBMmodel::updateNumberOfActions(int &sidx){
356
+ }
357
+
358
+ int CBMmodel::getNumberOfActions(){
359
+ return numberOfActions;
360
+ }
361
+
362
+ int * CBMmodel::getNextState(){
363
+ return &nextState;
364
+ }
365
+
366
+ double CBMmodel::getPsj(){
367
+ return psj;
368
+ }
369
+
370
+ int CBMmodel::getColumnIdx(int &sidx, int &aidx, int &cidx){
371
+ return 0;
372
+ }
373
+
374
+ int CBMmodel::getNumberOfJumps(int &sidx, int &aidx){
375
+ return 0;
376
+ }
377
+
378
+ int CBMmodel::getNumberOfActions(int &sidx){
379
+ return 0;
380
+ }
381
+
382
+ //int CBMmodel::getPolicy(int sidx){
383
+ // return policy[sidx];
384
+ //}
385
+ //
386
+ //void CBMmodel::assignPolicy(int sidx, int action){
387
+ // policy[sidx] = action;
388
+ //}
@@ -0,0 +1,114 @@
1
+ /*
2
+ * MIT License
3
+ *
4
+ * Copyright (c) 2026 Anders Reenberg Andersen and Jesper Fink Andersen
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ * of this software and associated documentation files (the "Software"), to deal
8
+ * in the Software without restriction, including without limitation the rights
9
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ * copies of the Software, and to permit persons to whom the Software is
11
+ * furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be included in all
14
+ * copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ * SOFTWARE.
23
+ */
24
+
25
+
26
+ #ifndef CBMMODEL_H
27
+ #define CBMMODEL_H
28
+
29
+ #include "ModelType.h"
30
+ #include <vector>
31
+ #include <string>
32
+
33
+ using namespace std;
34
+
35
+ class CBMmodel : public ModelType{
36
+ public:
37
+
38
+ //constructor and destructor
39
+ CBMmodel() {}; //dummy-constructor
40
+ CBMmodel(double discount=0.99,
41
+ int components=2,
42
+ int stages=10,
43
+ string importProbPath="pCompMat.csv",
44
+ double preventiveCost=-5,
45
+ double correctiveCost=-11,
46
+ double setupCost=-4,
47
+ double failurePenalty=-300,
48
+ int kOfN=-1);
49
+ CBMmodel(double discount=0.99,
50
+ int components=2,
51
+ int stages=10,
52
+ vector<vector<double>> pcm={},
53
+ double preventiveCost=-5,
54
+ double correctiveCost=-11,
55
+ double setupCost=-4,
56
+ double failurePenalty=-300,
57
+ int kOfN=-1);
58
+ CBMmodel(const CBMmodel& orig);
59
+ virtual ~CBMmodel();
60
+
61
+ //general MDP parameters
62
+ int N;
63
+ int L;
64
+ double discount;
65
+ int numberOfStates;
66
+ int numberOfActions;
67
+ //vector<int> policy;
68
+ //transition and reward parameters
69
+ double cp; //preventive replacement cost
70
+ double cc; //corrective replacement cost
71
+ double cs; //setup cost
72
+ double p; //system failure penalty
73
+ int kN; // k-out-of-N system, meaning system works iff k components work
74
+ bool importProbs;
75
+ vector<vector<double>> pCompMat; //component transition probs.
76
+ vector<vector<double>> pFailCompMat; //sum of element in pCompMat
77
+ //auxiliary variables
78
+ int nextState; //next state to process
79
+ double psj; //transition probability from state s to j
80
+ int s_i, a_i, j_i;
81
+ vector<vector<int>> sidxMat; // (sidx,i)'th element contains s_i for state index sidx
82
+ vector<vector<int>> aidxMat; // (aidx,i)'th element contains a_i for action index aidx
83
+
84
+ // METHODS
85
+
86
+ //GENERIC METHODS
87
+ double reward(int &sidx, int &aidx) override;
88
+ double transProb(int &sidx, int &aidx, int &jidx) override;
89
+ void updateNextState(int &sidx, int &aidx, int &jidx) override;
90
+ int postDecisionIdx(int &sidx, int &aidx) override;
91
+ double getDiscount() override;
92
+ int getNumberOfStates() override;
93
+ void updateNumberOfActions(int &sidx) override;
94
+ int getNumberOfActions() override;
95
+ int getNumberOfActions(int &sidx) override;
96
+ int * getNextState() override;
97
+ double getPsj() override;
98
+ int getNumberOfJumps(int &sidx, int &aidx) override; //not used
99
+ int getColumnIdx(int &sidx, int &aidx, int &cidx) override; //not used
100
+
101
+ //SPECIAL METHODS
102
+ void updateTransProbNextState(int, int, int);
103
+ int intPow(int, int);
104
+ void importComponentProbs(string path);
105
+
106
+ private:
107
+
108
+ double r,prob;
109
+ bool set_up,done;
110
+ int fail_count,step,pdidx;
111
+
112
+ };
113
+
114
+ #endif /* CBMMODEL_H */
@@ -0,0 +1,25 @@
1
+ cmake_minimum_required(VERSION 3.15)
2
+
3
+ project(solvermodule LANGUAGES CXX)
4
+
5
+ # pybind11 now comes from PyPI (declared as a build-time dependency in
6
+ # Python/pyproject.toml) instead of being vendored as a subdirectory.
7
+ find_package(pybind11 CONFIG REQUIRED)
8
+
9
+ file(GLOB SOURCES "*.cpp")
10
+
11
+ pybind11_add_module(solvermodule ${SOURCES})
12
+
13
+ set_target_properties(solvermodule PROPERTIES CXX_STANDARD 14 CXX_STANDARD_REQUIRED ON)
14
+
15
+ # Find OpenMP package
16
+ find_package(OpenMP)
17
+ if(OpenMP_CXX_FOUND)
18
+ # Set compiler options for LLVM OpenMP
19
+ target_compile_options(solvermodule PRIVATE "$<$<CXX_COMPILER_ID:MSVC>:/openmp:llvm>")
20
+ # Link OpenMP flags to the target
21
+ target_link_libraries(solvermodule PUBLIC OpenMP::OpenMP_CXX)
22
+ endif()
23
+
24
+ # Install the compiled extension into the mdpsolver package directory of the wheel.
25
+ install(TARGETS solvermodule DESTINATION mdpsolver)
@@ -0,0 +1,123 @@
1
+ /*
2
+ * MIT License
3
+ *
4
+ * Copyright (c) 2026 Anders Reenberg Andersen and Jesper Fink Andersen
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ * of this software and associated documentation files (the "Software"), to deal
8
+ * in the Software without restriction, including without limitation the rights
9
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ * copies of the Software, and to permit persons to whom the Software is
11
+ * furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be included in all
14
+ * copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ * SOFTWARE.
23
+ */
24
+
25
+ #include "GeneralMDPmodel.h"
26
+
27
+ GeneralMDPmodel::GeneralMDPmodel(Rewards * rw, TransitionMatrix * tm, double discount):
28
+ rewards(rw),
29
+ tranMat(tm),
30
+ discount(discount)
31
+ {
32
+ initialize();
33
+ }
34
+
35
+ GeneralMDPmodel::GeneralMDPmodel(const GeneralMDPmodel& orig) {
36
+ }
37
+
38
+ GeneralMDPmodel::~GeneralMDPmodel() {
39
+ }
40
+
41
+
42
+ void GeneralMDPmodel::initialize(){
43
+ numberOfStates=tranMat->numberOfRows();
44
+ cidx=0;
45
+ }
46
+
47
+ double GeneralMDPmodel::reward(int &sidx, int &aidx){
48
+ //calculates and returns the reward of taking action
49
+ //aidx when in current state sidx
50
+
51
+ return rewards->getReward(sidx,aidx);
52
+ }
53
+
54
+ double GeneralMDPmodel::transProb(int &sidx, int &aidx, int &jidx){
55
+ //calculates the probability of jumping to state jidx from
56
+ //the current state sidx when taking action aidx.
57
+ //returns the calculated probability.
58
+
59
+ return tranMat->getProb(sidx,aidx,jidx);
60
+ }
61
+
62
+ int GeneralMDPmodel::getNumberOfJumps(int &sidx, int &aidx){
63
+ return tranMat->numberOfColumns(sidx,aidx);
64
+ }
65
+
66
+ void GeneralMDPmodel::updateNextState(int &sidx, int &aidx, int &jidx){
67
+ //updates the next possible state, nextState, and the associated
68
+ //transition probability, psj.
69
+ while (tranMat->getColumn(sidx,aidx,cidx)!=jidx){ //this will in many cases immediately evaluate to False
70
+ cidx++;
71
+ if (cidx==tranMat->numberOfColumns(sidx,aidx)){ //to make sure cidx is always feasible
72
+ cidx=0;
73
+ }
74
+ }
75
+ cidx++; //move one additional step
76
+ if (cidx==tranMat->numberOfColumns(sidx,aidx)){
77
+ cidx=0;
78
+ }
79
+ nextState = tranMat->getColumn(sidx,aidx,cidx);
80
+ psj = tranMat->getProb(sidx,aidx,cidx);
81
+ }
82
+
83
+ int GeneralMDPmodel::getColumnIdx(int &sidx, int &aidx, int &cidx){
84
+ return tranMat->getColumn(sidx,aidx,cidx);
85
+ }
86
+
87
+ int GeneralMDPmodel::postDecisionIdx(int &sidx, int &aidx){
88
+ //derives the first new/next state that is possible
89
+ //to reach from the current state sidx.
90
+ //both returns the value of the first new state, and
91
+ //stores it in the variable nextState.
92
+ cidx=0;
93
+ nextState = tranMat->getColumn(sidx,aidx,cidx);
94
+ return nextState;
95
+ }
96
+
97
+ double GeneralMDPmodel::getDiscount(){
98
+ return discount;
99
+ }
100
+
101
+ int GeneralMDPmodel::getNumberOfStates(){
102
+ return numberOfStates;
103
+ }
104
+
105
+ void GeneralMDPmodel::updateNumberOfActions(int &sidx){
106
+ numberOfActions=tranMat->numberOfActions(sidx);
107
+ }
108
+
109
+ int GeneralMDPmodel::getNumberOfActions(){
110
+ return numberOfActions;
111
+ }
112
+
113
+ int GeneralMDPmodel::getNumberOfActions(int &sidx){
114
+ return tranMat->numberOfActions(sidx);
115
+ }
116
+
117
+ int * GeneralMDPmodel::getNextState(){
118
+ return &nextState;
119
+ }
120
+
121
+ double GeneralMDPmodel::getPsj(){
122
+ return psj;
123
+ }