mdpsolver 0.9.10__tar.gz → 0.10.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.
- {mdpsolver-0.9.10/src/mdpsolver.egg-info → mdpsolver-0.10.0}/PKG-INFO +10 -25
- {mdpsolver-0.9.10 → mdpsolver-0.10.0}/README.md +2 -18
- mdpsolver-0.10.0/pyproject.toml +40 -0
- mdpsolver-0.10.0/tests/example_model.py +139 -0
- mdpsolver-0.10.0/tests/rewards_example2.csv +403 -0
- {mdpsolver-0.9.10 → mdpsolver-0.10.0}/tests/test2.py +9 -6
- {mdpsolver-0.9.10 → mdpsolver-0.10.0}/tests/test2_pip.py +9 -6
- mdpsolver-0.10.0/tests/transitions_example2.csv +41205 -0
- mdpsolver-0.9.10/PKG-INFO +0 -166
- mdpsolver-0.9.10/pyproject.toml +0 -31
- mdpsolver-0.9.10/setup.cfg +0 -4
- mdpsolver-0.9.10/src/mdpsolver/__pycache__/__init__.cpython-313.pyc +0 -0
- mdpsolver-0.9.10/src/mdpsolver/__pycache__/__init__.cpython-314.pyc +0 -0
- mdpsolver-0.9.10/src/mdpsolver/__pycache__/model.cpython-313.pyc +0 -0
- mdpsolver-0.9.10/src/mdpsolver/__pycache__/model.cpython-314.pyc +0 -0
- mdpsolver-0.9.10/src/mdpsolver/problems/__pycache__/cbmaux.cpython-310.pyc +0 -0
- mdpsolver-0.9.10/src/mdpsolver/problems/__pycache__/tbmaux.cpython-310.pyc +0 -0
- mdpsolver-0.9.10/src/mdpsolver/solvermodule.cp310-win_amd64.pyd +0 -0
- mdpsolver-0.9.10/src/mdpsolver/solvermodule.cp311-win_amd64.pyd +0 -0
- mdpsolver-0.9.10/src/mdpsolver/solvermodule.cp312-win_amd64.pyd +0 -0
- mdpsolver-0.9.10/src/mdpsolver/solvermodule.cp313-win_amd64.pyd +0 -0
- mdpsolver-0.9.10/src/mdpsolver/solvermodule.cp314-win_amd64.pyd +0 -0
- mdpsolver-0.9.10/src/mdpsolver/solvermodule.cpython-310-x86_64-linux-gnu.so +0 -0
- mdpsolver-0.9.10/src/mdpsolver/solvermodule.cpython-311-x86_64-linux-gnu.so +0 -0
- mdpsolver-0.9.10/src/mdpsolver/solvermodule.cpython-312-x86_64-linux-gnu.so +0 -0
- mdpsolver-0.9.10/src/mdpsolver/solvermodule.cpython-313-x86_64-linux-gnu.so +0 -0
- mdpsolver-0.9.10/src/mdpsolver/solvermodule.cpython-314-x86_64-linux-gnu.so +0 -0
- mdpsolver-0.9.10/src/mdpsolver.egg-info/SOURCES.txt +0 -30
- mdpsolver-0.9.10/src/mdpsolver.egg-info/dependency_links.txt +0 -1
- mdpsolver-0.9.10/src/mdpsolver.egg-info/top_level.txt +0 -1
- {mdpsolver-0.9.10 → mdpsolver-0.10.0}/LICENSE +0 -0
- {mdpsolver-0.9.10 → mdpsolver-0.10.0}/MANIFEST.in +0 -0
- {mdpsolver-0.9.10 → mdpsolver-0.10.0}/src/mdpsolver/__init__.py +0 -0
- {mdpsolver-0.9.10 → mdpsolver-0.10.0}/src/mdpsolver/model.py +0 -0
- {mdpsolver-0.9.10 → mdpsolver-0.10.0}/tests/test1.py +0 -0
- {mdpsolver-0.9.10 → mdpsolver-0.10.0}/tests/test1_pip.py +0 -0
|
@@ -1,19 +1,20 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: mdpsolver
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.10.0
|
|
4
4
|
Summary: A fast solver for Markov Decision Processes
|
|
5
|
-
Author-
|
|
6
|
-
Project-URL: Homepage, https://github.com/areenberg/MDPSolver
|
|
7
|
-
Project-URL: Issues, https://github.com/areenberg/MDPSolver/issues
|
|
5
|
+
Author-Email: Anders Reenberg Andersen <andersra@live.dk>, Jesper Fink Andersen <jesperfinkandersen@gmail.com>
|
|
8
6
|
Classifier: Development Status :: 4 - Beta
|
|
9
7
|
Classifier: Programming Language :: Python :: 3
|
|
10
8
|
Classifier: License :: OSI Approved :: MIT License
|
|
11
9
|
Classifier: Operating System :: Microsoft :: Windows
|
|
12
10
|
Classifier: Operating System :: POSIX :: Linux
|
|
11
|
+
Classifier: Operating System :: MacOS
|
|
12
|
+
Project-URL: Homepage, https://github.com/areenberg/MDPSolver
|
|
13
|
+
Project-URL: Issues, https://github.com/areenberg/MDPSolver/issues
|
|
13
14
|
Requires-Python: >=3.10
|
|
15
|
+
Provides-Extra: test
|
|
16
|
+
Requires-Dist: numpy; extra == "test"
|
|
14
17
|
Description-Content-Type: text/markdown
|
|
15
|
-
License-File: LICENSE
|
|
16
|
-
Dynamic: license-file
|
|
17
18
|
|
|
18
19
|
# MDPSolver
|
|
19
20
|
|
|
@@ -21,7 +22,7 @@ MDPSolver is a Python package for large Markov Decision Processes (MDPs) with in
|
|
|
21
22
|
|
|
22
23
|
## Features
|
|
23
24
|
|
|
24
|
-
* Fast solver: Our C++-based solver is substantially faster than other MDP packages available for Python. See details in the documentation.
|
|
25
|
+
* Fast solver: Our C++-based solver is substantially faster than other CPU-based MDP packages available for Python. See details in the documentation.
|
|
25
26
|
* Two optimality criteria: *Discounted* and *Average* reward.
|
|
26
27
|
* Three optimization algorithms: *Value iteration*, *Policy iteration*, and *Modified policy iteration*.
|
|
27
28
|
* Three value-update methods: *Standard*, *Gauss–Seidel*, and *Successive over-relaxation*.
|
|
@@ -30,23 +31,7 @@ MDPSolver is a Python package for large Markov Decision Processes (MDPs) with in
|
|
|
30
31
|
|
|
31
32
|
# Installation
|
|
32
33
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
Install directly from PyPI with:
|
|
36
|
-
|
|
37
|
-
```
|
|
38
|
-
pip install mdpsolver
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
### GLIBC not found
|
|
42
|
-
|
|
43
|
-
Some users will encounter the `version 'GLIBC_2.38' not found` error when attempting to import MDPSolver in Python. The issue can be resolved by manually compiling and replacing the SO-file for the optimization module in the MDPSolver package. See the steps on how to solve the issue in the [documentation](https://github.com/areenberg/MDPSolver/wiki#how-to-install).
|
|
44
|
-
|
|
45
|
-
## Windows
|
|
46
|
-
|
|
47
|
-
Requires [Visual Studio 2022](https://visualstudio.microsoft.com/downloads/) (17.9) with MSVC C++ compiler and libraries installed.
|
|
48
|
-
|
|
49
|
-
After installing Visual Studio (incl. MSVC C++ compiler and libraries), install directly from PyPI with:
|
|
34
|
+
Prebuilt wheels are available for **Linux**, **Windows**, and **macOS (14+)** across Python 3.10–3.14. Install directly from PyPI with:
|
|
50
35
|
|
|
51
36
|
```
|
|
52
37
|
pip install mdpsolver
|
|
@@ -4,7 +4,7 @@ MDPSolver is a Python package for large Markov Decision Processes (MDPs) with in
|
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
-
* Fast solver: Our C++-based solver is substantially faster than other MDP packages available for Python. See details in the documentation.
|
|
7
|
+
* Fast solver: Our C++-based solver is substantially faster than other CPU-based MDP packages available for Python. See details in the documentation.
|
|
8
8
|
* Two optimality criteria: *Discounted* and *Average* reward.
|
|
9
9
|
* Three optimization algorithms: *Value iteration*, *Policy iteration*, and *Modified policy iteration*.
|
|
10
10
|
* Three value-update methods: *Standard*, *Gauss–Seidel*, and *Successive over-relaxation*.
|
|
@@ -13,23 +13,7 @@ MDPSolver is a Python package for large Markov Decision Processes (MDPs) with in
|
|
|
13
13
|
|
|
14
14
|
# Installation
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
Install directly from PyPI with:
|
|
19
|
-
|
|
20
|
-
```
|
|
21
|
-
pip install mdpsolver
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
### GLIBC not found
|
|
25
|
-
|
|
26
|
-
Some users will encounter the `version 'GLIBC_2.38' not found` error when attempting to import MDPSolver in Python. The issue can be resolved by manually compiling and replacing the SO-file for the optimization module in the MDPSolver package. See the steps on how to solve the issue in the [documentation](https://github.com/areenberg/MDPSolver/wiki#how-to-install).
|
|
27
|
-
|
|
28
|
-
## Windows
|
|
29
|
-
|
|
30
|
-
Requires [Visual Studio 2022](https://visualstudio.microsoft.com/downloads/) (17.9) with MSVC C++ compiler and libraries installed.
|
|
31
|
-
|
|
32
|
-
After installing Visual Studio (incl. MSVC C++ compiler and libraries), install directly from PyPI with:
|
|
16
|
+
Prebuilt wheels are available for **Linux**, **Windows**, and **macOS (14+)** across Python 3.10–3.14. Install directly from PyPI with:
|
|
33
17
|
|
|
34
18
|
```
|
|
35
19
|
pip install mdpsolver
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["scikit-build-core>=0.10", "pybind11>=2.13"]
|
|
3
|
+
build-backend = "scikit_build_core.build"
|
|
4
|
+
|
|
5
|
+
[tool.scikit-build]
|
|
6
|
+
# The CMake project lives outside Python/, next to the rest of the C++ sources.
|
|
7
|
+
cmake.source-dir = "../CPP_Source_Code"
|
|
8
|
+
build-dir = "build/{wheel_tag}"
|
|
9
|
+
# CMakeLists.txt installs the extension to DESTINATION mdpsolver itself,
|
|
10
|
+
# so wheel.install-dir stays at the default (wheel root) here.
|
|
11
|
+
sdist.include = ["src/mdpsolver/*.py"]
|
|
12
|
+
|
|
13
|
+
[tool.scikit-build.cmake.define]
|
|
14
|
+
CMAKE_BUILD_TYPE = "Release"
|
|
15
|
+
|
|
16
|
+
[project]
|
|
17
|
+
name = "mdpsolver"
|
|
18
|
+
version = "0.10.0"
|
|
19
|
+
authors = [
|
|
20
|
+
{ name="Anders Reenberg Andersen", email="andersra@live.dk" },
|
|
21
|
+
{ name="Jesper Fink Andersen", email="jesperfinkandersen@gmail.com" },
|
|
22
|
+
]
|
|
23
|
+
description = "A fast solver for Markov Decision Processes"
|
|
24
|
+
readme = "README.md"
|
|
25
|
+
requires-python = ">=3.10"
|
|
26
|
+
classifiers = [
|
|
27
|
+
"Development Status :: 4 - Beta",
|
|
28
|
+
"Programming Language :: Python :: 3",
|
|
29
|
+
"License :: OSI Approved :: MIT License",
|
|
30
|
+
"Operating System :: Microsoft :: Windows",
|
|
31
|
+
"Operating System :: POSIX :: Linux",
|
|
32
|
+
"Operating System :: MacOS"
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
[project.optional-dependencies]
|
|
36
|
+
test = ["numpy"]
|
|
37
|
+
|
|
38
|
+
[project.urls]
|
|
39
|
+
Homepage = "https://github.com/areenberg/MDPSolver"
|
|
40
|
+
Issues = "https://github.com/areenberg/MDPSolver/issues"
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
import os
|
|
3
|
+
|
|
4
|
+
# Create transition probability matrix and rewards for the 'mdpsolver' examples.
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
# -----------------------------
|
|
8
|
+
# FUNCTIONS
|
|
9
|
+
# -----------------------------
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def exitDist(startK, arrRate, serRate, tol=1e-9):
|
|
13
|
+
# calculate distribution over states observed by
|
|
14
|
+
# the next arrival assuming the system currently
|
|
15
|
+
# contains 'startK' customers.
|
|
16
|
+
|
|
17
|
+
g = [i * serRate / (i * serRate + arrRate) for i in range(startK, -1, -1)]
|
|
18
|
+
d = [arrRate / (i * serRate + arrRate) for i in range(startK, -1, -1)]
|
|
19
|
+
|
|
20
|
+
Dmat = np.diag(d)
|
|
21
|
+
Zmat = np.zeros((len(g), len(d)))
|
|
22
|
+
Imat = np.eye(len(g))
|
|
23
|
+
Gmat = np.zeros((len(g), len(g)))
|
|
24
|
+
for i in range(startK):
|
|
25
|
+
Gmat[i, i + 1] = g[i]
|
|
26
|
+
mat = np.block([[Gmat, Dmat], [Zmat, Imat]])
|
|
27
|
+
p = np.zeros((1, (startK + 1) * 2))
|
|
28
|
+
p[0, 0] = 1
|
|
29
|
+
|
|
30
|
+
while np.sum(p[0, : startK + 1]) >= tol:
|
|
31
|
+
p = np.matmul(p, mat)
|
|
32
|
+
|
|
33
|
+
return p[0, startK + 1 :]
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def tranMat(arrRate1, arrRate2, serRate, capacity, fileName):
|
|
37
|
+
# calculate transition probabilities and
|
|
38
|
+
# and save them in a file
|
|
39
|
+
|
|
40
|
+
ns = capacity + 1
|
|
41
|
+
arrRate = arrRate1 + arrRate2
|
|
42
|
+
pc1 = arrRate1 / arrRate
|
|
43
|
+
pc2 = 1 - pc1
|
|
44
|
+
|
|
45
|
+
if os.path.exists(fileName):
|
|
46
|
+
os.remove(fileName)
|
|
47
|
+
with open(fileName, "a") as file:
|
|
48
|
+
file.write(f"stateFrom,action,stateTo,probability\n")
|
|
49
|
+
for sidx in range(ns): # stateFrom (customer type 1)
|
|
50
|
+
for aidx in range(2):
|
|
51
|
+
if aidx == 0: # reject
|
|
52
|
+
if sidx > 0:
|
|
53
|
+
dist = exitDist(sidx, arrRate, serRate)
|
|
54
|
+
else:
|
|
55
|
+
dist = np.array([1])
|
|
56
|
+
dist1 = pc1 * dist
|
|
57
|
+
dist2 = pc2 * dist
|
|
58
|
+
for jidx in range(sidx + 1):
|
|
59
|
+
out = [sidx, aidx, jidx, dist1[sidx - jidx]]
|
|
60
|
+
str_out = ",".join(str(num) for num in out)
|
|
61
|
+
file.write(str_out + "\n")
|
|
62
|
+
for jidx in range(ns, ns + sidx + 1):
|
|
63
|
+
out = [sidx, aidx, jidx, dist2[sidx - (jidx - ns)]]
|
|
64
|
+
str_out = ",".join(str(num) for num in out)
|
|
65
|
+
file.write(str_out + "\n")
|
|
66
|
+
elif aidx == 1 and sidx < capacity: # accept
|
|
67
|
+
startK = sidx + 1
|
|
68
|
+
dist = exitDist(startK, arrRate, serRate)
|
|
69
|
+
dist1 = pc1 * dist
|
|
70
|
+
dist2 = pc2 * dist
|
|
71
|
+
for jidx in range(startK + 1):
|
|
72
|
+
out = [sidx, aidx, jidx, dist1[startK - jidx]]
|
|
73
|
+
str_out = ",".join(str(num) for num in out)
|
|
74
|
+
file.write(str_out + "\n")
|
|
75
|
+
for jidx in range(ns, ns + startK + 1):
|
|
76
|
+
out = [sidx, aidx, jidx, dist2[startK - (jidx - ns)]]
|
|
77
|
+
str_out = ",".join(str(num) for num in out)
|
|
78
|
+
file.write(str_out + "\n")
|
|
79
|
+
|
|
80
|
+
for sidx in range(ns): # stateFrom (customer type 2)
|
|
81
|
+
for aidx in range(2):
|
|
82
|
+
if aidx == 0: # reject
|
|
83
|
+
if sidx > 0:
|
|
84
|
+
dist = exitDist(sidx, arrRate, serRate)
|
|
85
|
+
else:
|
|
86
|
+
dist = np.array([1])
|
|
87
|
+
dist1 = pc1 * dist
|
|
88
|
+
dist2 = pc2 * dist
|
|
89
|
+
for jidx in range(sidx + 1):
|
|
90
|
+
out = [sidx + ns, aidx, jidx, dist1[sidx - jidx]]
|
|
91
|
+
str_out = ",".join(str(num) for num in out)
|
|
92
|
+
file.write(str_out + "\n")
|
|
93
|
+
for jidx in range(ns, ns + sidx + 1):
|
|
94
|
+
out = [sidx + ns, aidx, jidx, dist2[sidx - (jidx - ns)]]
|
|
95
|
+
str_out = ",".join(str(num) for num in out)
|
|
96
|
+
file.write(str_out + "\n")
|
|
97
|
+
elif aidx == 1 and sidx < capacity: # accept
|
|
98
|
+
startK = sidx + 1
|
|
99
|
+
dist = exitDist(startK, arrRate, serRate)
|
|
100
|
+
dist1 = pc1 * dist
|
|
101
|
+
dist2 = pc2 * dist
|
|
102
|
+
for jidx in range(startK + 1):
|
|
103
|
+
out = [sidx + ns, aidx, jidx, dist1[startK - jidx]]
|
|
104
|
+
str_out = ",".join(str(num) for num in out)
|
|
105
|
+
file.write(str_out + "\n")
|
|
106
|
+
for jidx in range(ns, ns + startK + 1):
|
|
107
|
+
out = [sidx + ns, aidx, jidx, dist2[startK - (jidx - ns)]]
|
|
108
|
+
str_out = ",".join(str(num) for num in out)
|
|
109
|
+
file.write(str_out + "\n")
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def rewards(capacity, rewardCust1, rewardCust2, fileName):
|
|
113
|
+
|
|
114
|
+
ns = capacity + 1
|
|
115
|
+
|
|
116
|
+
if os.path.exists(fileName):
|
|
117
|
+
os.remove(fileName)
|
|
118
|
+
with open(fileName, "a") as file:
|
|
119
|
+
file.write(f"stateFrom,action,reward\n")
|
|
120
|
+
for sidx in range(ns): # stateFrom (customer type 1)
|
|
121
|
+
for aidx in range(2):
|
|
122
|
+
if aidx == 0:
|
|
123
|
+
out = [sidx, aidx, 0]
|
|
124
|
+
str_out = ",".join(str(num) for num in out)
|
|
125
|
+
file.write(str_out + "\n")
|
|
126
|
+
elif aidx == 1 and sidx < capacity:
|
|
127
|
+
out = [sidx, aidx, rewardCust1]
|
|
128
|
+
str_out = ",".join(str(num) for num in out)
|
|
129
|
+
file.write(str_out + "\n")
|
|
130
|
+
for sidx in range(ns): # stateFrom (customer type 2)
|
|
131
|
+
for aidx in range(2):
|
|
132
|
+
if aidx == 0:
|
|
133
|
+
out = [sidx + ns, aidx, 0]
|
|
134
|
+
str_out = ",".join(str(num) for num in out)
|
|
135
|
+
file.write(str_out + "\n")
|
|
136
|
+
elif aidx == 1 and sidx < capacity:
|
|
137
|
+
out = [sidx + ns, aidx, rewardCust2]
|
|
138
|
+
str_out = ",".join(str(num) for num in out)
|
|
139
|
+
file.write(str_out + "\n")
|
|
@@ -0,0 +1,403 @@
|
|
|
1
|
+
stateFrom,action,reward
|
|
2
|
+
0,0,0
|
|
3
|
+
0,1,1
|
|
4
|
+
1,0,0
|
|
5
|
+
1,1,1
|
|
6
|
+
2,0,0
|
|
7
|
+
2,1,1
|
|
8
|
+
3,0,0
|
|
9
|
+
3,1,1
|
|
10
|
+
4,0,0
|
|
11
|
+
4,1,1
|
|
12
|
+
5,0,0
|
|
13
|
+
5,1,1
|
|
14
|
+
6,0,0
|
|
15
|
+
6,1,1
|
|
16
|
+
7,0,0
|
|
17
|
+
7,1,1
|
|
18
|
+
8,0,0
|
|
19
|
+
8,1,1
|
|
20
|
+
9,0,0
|
|
21
|
+
9,1,1
|
|
22
|
+
10,0,0
|
|
23
|
+
10,1,1
|
|
24
|
+
11,0,0
|
|
25
|
+
11,1,1
|
|
26
|
+
12,0,0
|
|
27
|
+
12,1,1
|
|
28
|
+
13,0,0
|
|
29
|
+
13,1,1
|
|
30
|
+
14,0,0
|
|
31
|
+
14,1,1
|
|
32
|
+
15,0,0
|
|
33
|
+
15,1,1
|
|
34
|
+
16,0,0
|
|
35
|
+
16,1,1
|
|
36
|
+
17,0,0
|
|
37
|
+
17,1,1
|
|
38
|
+
18,0,0
|
|
39
|
+
18,1,1
|
|
40
|
+
19,0,0
|
|
41
|
+
19,1,1
|
|
42
|
+
20,0,0
|
|
43
|
+
20,1,1
|
|
44
|
+
21,0,0
|
|
45
|
+
21,1,1
|
|
46
|
+
22,0,0
|
|
47
|
+
22,1,1
|
|
48
|
+
23,0,0
|
|
49
|
+
23,1,1
|
|
50
|
+
24,0,0
|
|
51
|
+
24,1,1
|
|
52
|
+
25,0,0
|
|
53
|
+
25,1,1
|
|
54
|
+
26,0,0
|
|
55
|
+
26,1,1
|
|
56
|
+
27,0,0
|
|
57
|
+
27,1,1
|
|
58
|
+
28,0,0
|
|
59
|
+
28,1,1
|
|
60
|
+
29,0,0
|
|
61
|
+
29,1,1
|
|
62
|
+
30,0,0
|
|
63
|
+
30,1,1
|
|
64
|
+
31,0,0
|
|
65
|
+
31,1,1
|
|
66
|
+
32,0,0
|
|
67
|
+
32,1,1
|
|
68
|
+
33,0,0
|
|
69
|
+
33,1,1
|
|
70
|
+
34,0,0
|
|
71
|
+
34,1,1
|
|
72
|
+
35,0,0
|
|
73
|
+
35,1,1
|
|
74
|
+
36,0,0
|
|
75
|
+
36,1,1
|
|
76
|
+
37,0,0
|
|
77
|
+
37,1,1
|
|
78
|
+
38,0,0
|
|
79
|
+
38,1,1
|
|
80
|
+
39,0,0
|
|
81
|
+
39,1,1
|
|
82
|
+
40,0,0
|
|
83
|
+
40,1,1
|
|
84
|
+
41,0,0
|
|
85
|
+
41,1,1
|
|
86
|
+
42,0,0
|
|
87
|
+
42,1,1
|
|
88
|
+
43,0,0
|
|
89
|
+
43,1,1
|
|
90
|
+
44,0,0
|
|
91
|
+
44,1,1
|
|
92
|
+
45,0,0
|
|
93
|
+
45,1,1
|
|
94
|
+
46,0,0
|
|
95
|
+
46,1,1
|
|
96
|
+
47,0,0
|
|
97
|
+
47,1,1
|
|
98
|
+
48,0,0
|
|
99
|
+
48,1,1
|
|
100
|
+
49,0,0
|
|
101
|
+
49,1,1
|
|
102
|
+
50,0,0
|
|
103
|
+
50,1,1
|
|
104
|
+
51,0,0
|
|
105
|
+
51,1,1
|
|
106
|
+
52,0,0
|
|
107
|
+
52,1,1
|
|
108
|
+
53,0,0
|
|
109
|
+
53,1,1
|
|
110
|
+
54,0,0
|
|
111
|
+
54,1,1
|
|
112
|
+
55,0,0
|
|
113
|
+
55,1,1
|
|
114
|
+
56,0,0
|
|
115
|
+
56,1,1
|
|
116
|
+
57,0,0
|
|
117
|
+
57,1,1
|
|
118
|
+
58,0,0
|
|
119
|
+
58,1,1
|
|
120
|
+
59,0,0
|
|
121
|
+
59,1,1
|
|
122
|
+
60,0,0
|
|
123
|
+
60,1,1
|
|
124
|
+
61,0,0
|
|
125
|
+
61,1,1
|
|
126
|
+
62,0,0
|
|
127
|
+
62,1,1
|
|
128
|
+
63,0,0
|
|
129
|
+
63,1,1
|
|
130
|
+
64,0,0
|
|
131
|
+
64,1,1
|
|
132
|
+
65,0,0
|
|
133
|
+
65,1,1
|
|
134
|
+
66,0,0
|
|
135
|
+
66,1,1
|
|
136
|
+
67,0,0
|
|
137
|
+
67,1,1
|
|
138
|
+
68,0,0
|
|
139
|
+
68,1,1
|
|
140
|
+
69,0,0
|
|
141
|
+
69,1,1
|
|
142
|
+
70,0,0
|
|
143
|
+
70,1,1
|
|
144
|
+
71,0,0
|
|
145
|
+
71,1,1
|
|
146
|
+
72,0,0
|
|
147
|
+
72,1,1
|
|
148
|
+
73,0,0
|
|
149
|
+
73,1,1
|
|
150
|
+
74,0,0
|
|
151
|
+
74,1,1
|
|
152
|
+
75,0,0
|
|
153
|
+
75,1,1
|
|
154
|
+
76,0,0
|
|
155
|
+
76,1,1
|
|
156
|
+
77,0,0
|
|
157
|
+
77,1,1
|
|
158
|
+
78,0,0
|
|
159
|
+
78,1,1
|
|
160
|
+
79,0,0
|
|
161
|
+
79,1,1
|
|
162
|
+
80,0,0
|
|
163
|
+
80,1,1
|
|
164
|
+
81,0,0
|
|
165
|
+
81,1,1
|
|
166
|
+
82,0,0
|
|
167
|
+
82,1,1
|
|
168
|
+
83,0,0
|
|
169
|
+
83,1,1
|
|
170
|
+
84,0,0
|
|
171
|
+
84,1,1
|
|
172
|
+
85,0,0
|
|
173
|
+
85,1,1
|
|
174
|
+
86,0,0
|
|
175
|
+
86,1,1
|
|
176
|
+
87,0,0
|
|
177
|
+
87,1,1
|
|
178
|
+
88,0,0
|
|
179
|
+
88,1,1
|
|
180
|
+
89,0,0
|
|
181
|
+
89,1,1
|
|
182
|
+
90,0,0
|
|
183
|
+
90,1,1
|
|
184
|
+
91,0,0
|
|
185
|
+
91,1,1
|
|
186
|
+
92,0,0
|
|
187
|
+
92,1,1
|
|
188
|
+
93,0,0
|
|
189
|
+
93,1,1
|
|
190
|
+
94,0,0
|
|
191
|
+
94,1,1
|
|
192
|
+
95,0,0
|
|
193
|
+
95,1,1
|
|
194
|
+
96,0,0
|
|
195
|
+
96,1,1
|
|
196
|
+
97,0,0
|
|
197
|
+
97,1,1
|
|
198
|
+
98,0,0
|
|
199
|
+
98,1,1
|
|
200
|
+
99,0,0
|
|
201
|
+
99,1,1
|
|
202
|
+
100,0,0
|
|
203
|
+
101,0,0
|
|
204
|
+
101,1,1000
|
|
205
|
+
102,0,0
|
|
206
|
+
102,1,1000
|
|
207
|
+
103,0,0
|
|
208
|
+
103,1,1000
|
|
209
|
+
104,0,0
|
|
210
|
+
104,1,1000
|
|
211
|
+
105,0,0
|
|
212
|
+
105,1,1000
|
|
213
|
+
106,0,0
|
|
214
|
+
106,1,1000
|
|
215
|
+
107,0,0
|
|
216
|
+
107,1,1000
|
|
217
|
+
108,0,0
|
|
218
|
+
108,1,1000
|
|
219
|
+
109,0,0
|
|
220
|
+
109,1,1000
|
|
221
|
+
110,0,0
|
|
222
|
+
110,1,1000
|
|
223
|
+
111,0,0
|
|
224
|
+
111,1,1000
|
|
225
|
+
112,0,0
|
|
226
|
+
112,1,1000
|
|
227
|
+
113,0,0
|
|
228
|
+
113,1,1000
|
|
229
|
+
114,0,0
|
|
230
|
+
114,1,1000
|
|
231
|
+
115,0,0
|
|
232
|
+
115,1,1000
|
|
233
|
+
116,0,0
|
|
234
|
+
116,1,1000
|
|
235
|
+
117,0,0
|
|
236
|
+
117,1,1000
|
|
237
|
+
118,0,0
|
|
238
|
+
118,1,1000
|
|
239
|
+
119,0,0
|
|
240
|
+
119,1,1000
|
|
241
|
+
120,0,0
|
|
242
|
+
120,1,1000
|
|
243
|
+
121,0,0
|
|
244
|
+
121,1,1000
|
|
245
|
+
122,0,0
|
|
246
|
+
122,1,1000
|
|
247
|
+
123,0,0
|
|
248
|
+
123,1,1000
|
|
249
|
+
124,0,0
|
|
250
|
+
124,1,1000
|
|
251
|
+
125,0,0
|
|
252
|
+
125,1,1000
|
|
253
|
+
126,0,0
|
|
254
|
+
126,1,1000
|
|
255
|
+
127,0,0
|
|
256
|
+
127,1,1000
|
|
257
|
+
128,0,0
|
|
258
|
+
128,1,1000
|
|
259
|
+
129,0,0
|
|
260
|
+
129,1,1000
|
|
261
|
+
130,0,0
|
|
262
|
+
130,1,1000
|
|
263
|
+
131,0,0
|
|
264
|
+
131,1,1000
|
|
265
|
+
132,0,0
|
|
266
|
+
132,1,1000
|
|
267
|
+
133,0,0
|
|
268
|
+
133,1,1000
|
|
269
|
+
134,0,0
|
|
270
|
+
134,1,1000
|
|
271
|
+
135,0,0
|
|
272
|
+
135,1,1000
|
|
273
|
+
136,0,0
|
|
274
|
+
136,1,1000
|
|
275
|
+
137,0,0
|
|
276
|
+
137,1,1000
|
|
277
|
+
138,0,0
|
|
278
|
+
138,1,1000
|
|
279
|
+
139,0,0
|
|
280
|
+
139,1,1000
|
|
281
|
+
140,0,0
|
|
282
|
+
140,1,1000
|
|
283
|
+
141,0,0
|
|
284
|
+
141,1,1000
|
|
285
|
+
142,0,0
|
|
286
|
+
142,1,1000
|
|
287
|
+
143,0,0
|
|
288
|
+
143,1,1000
|
|
289
|
+
144,0,0
|
|
290
|
+
144,1,1000
|
|
291
|
+
145,0,0
|
|
292
|
+
145,1,1000
|
|
293
|
+
146,0,0
|
|
294
|
+
146,1,1000
|
|
295
|
+
147,0,0
|
|
296
|
+
147,1,1000
|
|
297
|
+
148,0,0
|
|
298
|
+
148,1,1000
|
|
299
|
+
149,0,0
|
|
300
|
+
149,1,1000
|
|
301
|
+
150,0,0
|
|
302
|
+
150,1,1000
|
|
303
|
+
151,0,0
|
|
304
|
+
151,1,1000
|
|
305
|
+
152,0,0
|
|
306
|
+
152,1,1000
|
|
307
|
+
153,0,0
|
|
308
|
+
153,1,1000
|
|
309
|
+
154,0,0
|
|
310
|
+
154,1,1000
|
|
311
|
+
155,0,0
|
|
312
|
+
155,1,1000
|
|
313
|
+
156,0,0
|
|
314
|
+
156,1,1000
|
|
315
|
+
157,0,0
|
|
316
|
+
157,1,1000
|
|
317
|
+
158,0,0
|
|
318
|
+
158,1,1000
|
|
319
|
+
159,0,0
|
|
320
|
+
159,1,1000
|
|
321
|
+
160,0,0
|
|
322
|
+
160,1,1000
|
|
323
|
+
161,0,0
|
|
324
|
+
161,1,1000
|
|
325
|
+
162,0,0
|
|
326
|
+
162,1,1000
|
|
327
|
+
163,0,0
|
|
328
|
+
163,1,1000
|
|
329
|
+
164,0,0
|
|
330
|
+
164,1,1000
|
|
331
|
+
165,0,0
|
|
332
|
+
165,1,1000
|
|
333
|
+
166,0,0
|
|
334
|
+
166,1,1000
|
|
335
|
+
167,0,0
|
|
336
|
+
167,1,1000
|
|
337
|
+
168,0,0
|
|
338
|
+
168,1,1000
|
|
339
|
+
169,0,0
|
|
340
|
+
169,1,1000
|
|
341
|
+
170,0,0
|
|
342
|
+
170,1,1000
|
|
343
|
+
171,0,0
|
|
344
|
+
171,1,1000
|
|
345
|
+
172,0,0
|
|
346
|
+
172,1,1000
|
|
347
|
+
173,0,0
|
|
348
|
+
173,1,1000
|
|
349
|
+
174,0,0
|
|
350
|
+
174,1,1000
|
|
351
|
+
175,0,0
|
|
352
|
+
175,1,1000
|
|
353
|
+
176,0,0
|
|
354
|
+
176,1,1000
|
|
355
|
+
177,0,0
|
|
356
|
+
177,1,1000
|
|
357
|
+
178,0,0
|
|
358
|
+
178,1,1000
|
|
359
|
+
179,0,0
|
|
360
|
+
179,1,1000
|
|
361
|
+
180,0,0
|
|
362
|
+
180,1,1000
|
|
363
|
+
181,0,0
|
|
364
|
+
181,1,1000
|
|
365
|
+
182,0,0
|
|
366
|
+
182,1,1000
|
|
367
|
+
183,0,0
|
|
368
|
+
183,1,1000
|
|
369
|
+
184,0,0
|
|
370
|
+
184,1,1000
|
|
371
|
+
185,0,0
|
|
372
|
+
185,1,1000
|
|
373
|
+
186,0,0
|
|
374
|
+
186,1,1000
|
|
375
|
+
187,0,0
|
|
376
|
+
187,1,1000
|
|
377
|
+
188,0,0
|
|
378
|
+
188,1,1000
|
|
379
|
+
189,0,0
|
|
380
|
+
189,1,1000
|
|
381
|
+
190,0,0
|
|
382
|
+
190,1,1000
|
|
383
|
+
191,0,0
|
|
384
|
+
191,1,1000
|
|
385
|
+
192,0,0
|
|
386
|
+
192,1,1000
|
|
387
|
+
193,0,0
|
|
388
|
+
193,1,1000
|
|
389
|
+
194,0,0
|
|
390
|
+
194,1,1000
|
|
391
|
+
195,0,0
|
|
392
|
+
195,1,1000
|
|
393
|
+
196,0,0
|
|
394
|
+
196,1,1000
|
|
395
|
+
197,0,0
|
|
396
|
+
197,1,1000
|
|
397
|
+
198,0,0
|
|
398
|
+
198,1,1000
|
|
399
|
+
199,0,0
|
|
400
|
+
199,1,1000
|
|
401
|
+
200,0,0
|
|
402
|
+
200,1,1000
|
|
403
|
+
201,0,0
|
|
@@ -51,8 +51,9 @@ mdl1.mdp(
|
|
|
51
51
|
)
|
|
52
52
|
|
|
53
53
|
mdl1.solve(algorithm="vi")
|
|
54
|
-
|
|
55
|
-
|
|
54
|
+
mean1 = np.mean(mdl1.getValueVector())
|
|
55
|
+
if not np.round(mean1, 0) == 17075.0:
|
|
56
|
+
sys.exit(f"Model 1 failed! mean={mean1!r} rounded={np.round(mean1, 0)!r}")
|
|
56
57
|
|
|
57
58
|
# ---------------------------------------
|
|
58
59
|
# POLICY ITERATION
|
|
@@ -68,8 +69,9 @@ mdl2.mdp(
|
|
|
68
69
|
|
|
69
70
|
mdl2.solve(algorithm="pi")
|
|
70
71
|
|
|
71
|
-
|
|
72
|
-
|
|
72
|
+
mean2 = np.mean(mdl2.getValueVector())
|
|
73
|
+
if not np.round(mean2, 0) == 17075.0:
|
|
74
|
+
sys.exit(f"Model 2 failed! mean={mean2!r} rounded={np.round(mean2, 0)!r}")
|
|
73
75
|
|
|
74
76
|
# ---------------------------------------
|
|
75
77
|
# MODIFIED POLICY ITERATION
|
|
@@ -85,7 +87,8 @@ mdl3.mdp(
|
|
|
85
87
|
|
|
86
88
|
mdl3.solve(algorithm="mpi")
|
|
87
89
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
+
mean3 = np.mean(mdl3.getValueVector())
|
|
91
|
+
if not np.round(mean3, 0) == 17075.0:
|
|
92
|
+
sys.exit(f"Model 3 failed! mean={mean3!r} rounded={np.round(mean3, 0)!r}")
|
|
90
93
|
|
|
91
94
|
print("Test 2 succesfully reproduced output!")
|