Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 80 |
|
0.00% |
0 / 6 |
CRAP | |
0.00% |
0 / 1 |
Simplex | |
0.00% |
0 / 80 |
|
0.00% |
0 / 6 |
1406 | |
0.00% |
0 / 1 |
setFunction | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
addConstraint | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
pivot | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
iterateSimplex | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
initialize | |
0.00% |
0 / 74 |
|
0.00% |
0 / 1 |
992 | |||
solve | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
6 |
1 | <?php |
2 | /** |
3 | * Jingga |
4 | * |
5 | * PHP Version 8.1 |
6 | * |
7 | * @package phpOMS\Math\Optimization |
8 | * @copyright Dennis Eichhorn |
9 | * @license OMS License 2.0 |
10 | * @version 1.0.0 |
11 | * @link https://jingga.app |
12 | */ |
13 | declare(strict_types=1); |
14 | |
15 | namespace phpOMS\Math\Optimization; |
16 | |
17 | /** |
18 | * Simplex class. |
19 | * |
20 | * @package phpOMS\Math\Optimization |
21 | * @license OMS License 2.0 |
22 | * @link https://jingga.app |
23 | * @link https://github.com/PetarV-/Algorithms/blob/master/Mathematical%20Algorithms/Simplex%20Algorithm.cpp |
24 | * @since 1.0.0 |
25 | */ |
26 | class Simplex |
27 | { |
28 | private array $function = []; |
29 | |
30 | private string $functionType = ''; |
31 | |
32 | private int|float $functionLimit = 0.0; |
33 | |
34 | private array $constraints = []; |
35 | |
36 | private array $constraintsType = []; |
37 | |
38 | private array $constraintsLimit = []; |
39 | |
40 | private array $slackForm = []; |
41 | |
42 | private array $nonbasicSolution = []; |
43 | |
44 | private array $basicSolution = []; |
45 | |
46 | /** |
47 | * Define the function to optimize |
48 | * |
49 | * @param array $function Function to optimize |
50 | * |
51 | * @return void |
52 | * |
53 | * @since 1.0.0 |
54 | */ |
55 | public function setFunction(array $function) : void |
56 | { |
57 | } |
58 | |
59 | /** |
60 | * Add function constraint |
61 | * |
62 | * @param array $function Constraint function |
63 | * @param string $type Constraint type |
64 | * @param float $limit Constraint |
65 | * |
66 | * @return void |
67 | * |
68 | * @since 1.0.0 |
69 | */ |
70 | public function addConstraint(array $function, string $type, float $limit) : void |
71 | { |
72 | } |
73 | |
74 | /** |
75 | * Pivot element |
76 | * |
77 | * @param int $x X-Pivot |
78 | * @param int $y Y-Pivot |
79 | * |
80 | * @return void |
81 | * |
82 | * @since 1.0.0 |
83 | */ |
84 | private function pivot(int $x, int $y) : void |
85 | { |
86 | } |
87 | |
88 | /** |
89 | * Perform simplex iteration |
90 | * |
91 | * @return void |
92 | * |
93 | * @since 1.0.0 |
94 | */ |
95 | private function iterateSimplex() : void |
96 | { |
97 | } |
98 | |
99 | /** |
100 | * Initialize simplex algorithm |
101 | * |
102 | * @return bool |
103 | * |
104 | * @since 1.0.0 |
105 | */ |
106 | private function initialize() : bool |
107 | { |
108 | $k = -1; |
109 | $minLimit = -1; |
110 | |
111 | $m = \count($this->constraints); |
112 | $n = \count($this->function); |
113 | |
114 | for ($i = 0; $i < $m; ++$i) { |
115 | if ($k === -1 || $this->constraintsLimit[$i] < $minLimit) { |
116 | $k = $i; |
117 | $minLimit = $this->constraintsLimit[$i]; |
118 | } |
119 | } |
120 | |
121 | if ($this->constraintsLimit[$k] >= 0) { |
122 | for ($j = 0; $j < $n; ++$j) { |
123 | $this->nonbasicSolution[$j] = $j; |
124 | } |
125 | |
126 | for ($i = 0; $i < $m; ++$i) { |
127 | $this->basicSolution[$i] = $n + $i; |
128 | } |
129 | |
130 | return true; |
131 | } |
132 | |
133 | // Auxiliary LP |
134 | ++$n; |
135 | for ($j = 0; $j < $n; ++$j) { |
136 | $this->nonbasicSolution[$j] = $j; |
137 | } |
138 | |
139 | for ($i = 0; $i < $m; ++$i) { |
140 | $this->basicSolution[$i] = $n + $i; |
141 | } |
142 | |
143 | $oldFunction = $this->function; |
144 | $oldLimit = $this->functionLimit; |
145 | |
146 | // Auxiliary function |
147 | $this->function[$n - 1] = -1; |
148 | $this->functionLimit = 0; |
149 | |
150 | for ($j = 0; $j < $n - 1; ++$j) { |
151 | $this->function[$j] = 0; |
152 | } |
153 | |
154 | // Auxiliary constraints |
155 | for ($i = 0; $i < $m; ++$i) { |
156 | $this->constraints[$i][$n - 1] = 1; |
157 | } |
158 | |
159 | $this->pivot($k, $n - 1); |
160 | |
161 | // Solve Auxiliary LP |
162 | while ($this->iterateSimplex()); |
163 | |
164 | if ($this->functionLimit !== 0) { |
165 | return false; |
166 | } |
167 | |
168 | $zBasic = -1; |
169 | for ($i = 0; $i < $m; ++$i) { |
170 | if ($this->basicSolution[$i] === $n - 1) { |
171 | $zBasic = $i; |
172 | break; |
173 | } |
174 | } |
175 | |
176 | if ($zBasic === -1) { |
177 | $this->pivot($zBasic, $n - 1); |
178 | } |
179 | |
180 | $zNonBasic = -1; |
181 | for ($j = 0; $j < $n; ++$j) { |
182 | if ($this->nonbasicSolution[$j] === $n - 1) { |
183 | $zNonBasic = $j; |
184 | break; |
185 | } |
186 | } |
187 | |
188 | for ($i = 0; $i < $m; ++$i) { |
189 | $this->constraints[$i][$zNonBasic] = $this->constraints[$i][$n - 1]; |
190 | } |
191 | |
192 | $tmp = $this->nonbasicSolution[$n - 1]; |
193 | $this->nonbasicSolution[$n - 1] = $this->nonbasicSolution[$zNonBasic]; |
194 | $this->nonbasicSolution[$zNonBasic] = $tmp; |
195 | |
196 | --$n; |
197 | |
198 | for ($j = 0; $j < $n; ++$j) { |
199 | if ($this->nonbasicSolution[$j] > $n) { |
200 | --$this->nonbasicSolution[$j]; |
201 | } |
202 | } |
203 | |
204 | for ($i = 0; $i < $m; ++$i) { |
205 | if ($this->basicSolution[$i] > $n) { |
206 | --$this->basicSolution[$i]; |
207 | } |
208 | } |
209 | |
210 | $this->functionLimit = $oldLimit; |
211 | for ($j = 0; $j < $n; ++$j) { |
212 | $this->function[$j] = 0; |
213 | } |
214 | |
215 | for ($j = 0; $j < $n; ++$j) { |
216 | $ok = false; |
217 | |
218 | for ($jj = 0; $jj < $n; ++$jj) { |
219 | if ($j === $this->nonbasicSolution[$jj]) { |
220 | $this->function[$jj] += $oldFunction[$j]; |
221 | |
222 | $ok = true; |
223 | break; |
224 | } |
225 | } |
226 | |
227 | if ($ok) { |
228 | continue; |
229 | } |
230 | |
231 | for ($i = 0; $i < $m; ++$i) { |
232 | if ($j = $this->basicSolution[$i]) { |
233 | for ($jj = 0; $jj < $n; ++$jj) { |
234 | $this->function[$jj] += $oldFunction[$j] * $this->constraints[$i][$jj]; |
235 | } |
236 | |
237 | $this->functionLimit += $oldFunction[$j] * $this->constraintsLimit[$i]; |
238 | break; |
239 | } |
240 | } |
241 | } |
242 | |
243 | return true; |
244 | } |
245 | |
246 | /** |
247 | * Solve the optimization |
248 | * |
249 | * @return array |
250 | * |
251 | * @since 1.0.0 |
252 | */ |
253 | public function solve() : array |
254 | { |
255 | if (!$this->initialize()) { |
256 | return []; |
257 | } |
258 | } |
259 | } |