Completed
Branch master (18563d)
by Bingo
02:27 queued 14s
created

FibonacciHeapTest::testIncreaseKeyException()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 2
eloc 9
c 1
b 0
f 1
nc 2
nop 0
dl 0
loc 12
rs 9.9666
1
<?php
2
3
namespace tests;
4
5
use PHPUnit\Framework\TestCase;
6
use InvalidArgumentException;
7
use TypeError;
8
use heap\exception\NoSuchElementException;
9
use heap\tree\FibonacciHeap;
10
use heap\tree\FibonacciHeapNode;
11
12
class FibonacciHeapTest extends TestCase
13
{
14
    private const SIZE = 100;
15
16
    public function testInsert(): void
17
    {
18
        $heap = new FibonacciHeap();
19
       
20
        for ($i = 0; $i < self::SIZE; $i += 1) {
21
            $heap->insert($i);
22
            $this->assertEquals(0, $heap->findMin()->getKey());
23
            $this->assertFalse($heap->isEmpty());
24
            $this->assertEquals($heap->size(), $i + 1);
25
        }
26
27
        for ($i = self::SIZE - 1; $i >= 0; $i -= 1) {
28
            $this->assertEquals($heap->findMin()->getKey(), self::SIZE - $i - 1);
29
            $heap->deleteMin();
30
        }
31
    }
32
33
    public function testSetValue(): void
34
    {
35
        $heap = new FibonacciHeap();
36
        $heap->insert(1, "value1")->setValue("value2");
37
        $this->assertEquals("value2", $heap->findMin()->getValue());
38
    }
39
40
    public function testEmptyAfterDeleteAll(): void
41
    {
42
        $heap = new FibonacciHeap();
43
        $heap->insert(780);
44
        $this->assertEquals($heap->size(), 1);
45
        $this->assertEquals(780, $heap->findMin()->getKey());
46
47
        $heap->insert(-389);
48
        $this->assertEquals($heap->size(), 2);
49
        $this->assertEquals(-389, $heap->findMin()->getKey());
50
51
        $heap->insert(306);
52
        $this->assertEquals($heap->size(), 3);
53
        $this->assertEquals(-389, $heap->findMin()->getKey());
54
55
        $heap->insert(579);
56
        $this->assertEquals($heap->size(), 4);
57
        $this->assertEquals(-389, $heap->findMin()->getKey());
58
59
        $heap->deleteMin();
60
        $this->assertEquals($heap->size(), 3);
61
        $this->assertEquals(306, $heap->findMin()->getKey());
62
63
        $heap->deleteMin();
64
        $this->assertEquals($heap->size(), 2);
65
        $this->assertEquals(579, $heap->findMin()->getKey());
66
67
        $heap->deleteMin();
68
        $this->assertEquals($heap->size(), 1);
69
        $this->assertEquals(780, $heap->findMin()->getKey());
70
71
        $heap->deleteMin();
72
        $this->assertEquals($heap->size(), 0);
73
74
        $this->assertTrue($heap->isEmpty());
75
    }
76
77
    public function testRandomDelete(): void
78
    {
79
        $heap = new FibonacciHeap();
80
81
        for ($i = 0; $i < self::SIZE; $i += 1) {
82
            $heap->insert(random_int(0, 100000));
83
        }
84
85
        $prev = null;
86
        while (!$heap->isEmpty()) {
87
            $cur = $heap->findMin()->getKey();
88
            $heap->deleteMin();
89
            if (!is_null($prev)) {
90
                $this->assertTrue($prev <= $cur);
91
            }
92
            $prev = $cur;
93
        }
94
    }
95
96
    public function testFindDeleteSame(): void
97
    {
98
        $heap = new FibonacciHeap();
99
100
        for ($i = 0; $i < self::SIZE; $i += 1) {
101
            $heap->insert(random_int(0, 100000));
102
        }
103
104
        while (!$heap->isEmpty()) {
105
            $this->assertEquals($heap->findMin(), $heap->deleteMin());
106
        }
107
    }
108
109
    public function testDeleteNodes(): void
110
    {
111
        $heap = new FibonacciHeap();
112
113
        $nodes = [];
114
        for ($i = 0; $i < 15; $i += 1) {
115
            $nodes[$i] = $heap->insert($i);
116
        }
117
118
        $nodes[5]->delete();
119
        $this->assertEquals(0, $heap->findMin()->getKey());
120
        $nodes[7]->delete();
121
        $this->assertEquals(0, $heap->findMin()->getKey());
122
        $nodes[0]->delete();
123
        $this->assertEquals(1, $heap->findMin()->getKey());
124
        $nodes[2]->delete();
125
        $this->assertEquals(1, $heap->findMin()->getKey());
126
        $nodes[1]->delete();
127
        $this->assertEquals(3, $heap->findMin()->getKey());
128
        $nodes[3]->delete();
129
        $this->assertEquals(4, $heap->findMin()->getKey());
130
        $nodes[9]->delete();
131
        $this->assertEquals(4, $heap->findMin()->getKey());
132
        $nodes[4]->delete();
133
        $this->assertEquals(6, $heap->findMin()->getKey());
134
        $nodes[8]->delete();
135
        $this->assertEquals(6, $heap->findMin()->getKey());
136
        $nodes[11]->delete();
137
        $this->assertEquals(6, $heap->findMin()->getKey());
138
        $nodes[6]->delete();
139
        $this->assertEquals(10, $heap->findMin()->getKey());
140
        $nodes[12]->delete();
141
        $this->assertEquals(10, $heap->findMin()->getKey());
142
        $nodes[10]->delete();
143
        $this->assertEquals(13, $heap->findMin()->getKey());
144
        $nodes[13]->delete();
145
        $this->assertEquals(14, $heap->findMin()->getKey());
146
        $nodes[14]->delete();
147
        $this->assertTrue($heap->isEmpty());
148
    }
149
150
    public function testNodesRandomDelete(): void
151
    {
152
        $heap = new FibonacciHeap();
153
154
        $nodes = [];
155
        for ($i = 0; $i < 8; $i += 1) {
156
            $nodes[$i] = $heap->insert($i);
157
        }
158
159
        $nodes[5]->delete();
160
        $this->assertEquals(0, $heap->findMin()->getKey());
161
        $nodes[7]->delete();
162
        $this->assertEquals(0, $heap->findMin()->getKey());
163
        $nodes[0]->delete();
164
        $this->assertEquals(1, $heap->findMin()->getKey());
165
        $nodes[2]->delete();
166
        $this->assertEquals(1, $heap->findMin()->getKey());
167
        $nodes[1]->delete();
168
        $this->assertEquals(3, $heap->findMin()->getKey());
169
    }
170
171
    public function testAddDelete(): void
172
    {
173
        $heap = new FibonacciHeap();
174
175
        $nodes = [];
176
        for ($i = 0; $i < self::SIZE; $i += 1) {
177
            $nodes[$i] = $heap->insert($i);
178
        }
179
180
        for ($i = self::SIZE - 1; $i >= 0; $i -= 1) {
181
            $nodes[$i]->delete();
182
            if ($i > 0) {
183
                $this->assertEquals(0, $heap->findMin()->getKey());
184
            }
185
        }
186
        $this->assertTrue($heap->isEmpty());
187
    }
188
189
    public function testDeleteTwice(): void
190
    {
191
        $heap = new FibonacciHeap();
192
193
        $nodes = [];
194
        for ($i = 0; $i < 15; $i += 1) {
195
            $nodes[$i] = $heap->insert($i);
196
        }
197
198
        $nodes[5]->delete();
199
        $this->assertEquals(0, $heap->findMin()->getKey());
200
        $nodes[7]->delete();
201
        $this->assertEquals(0, $heap->findMin()->getKey());
202
        $nodes[0]->delete();
203
        $this->assertEquals(1, $heap->findMin()->getKey());
204
        $nodes[2]->delete();
205
        $this->assertEquals(1, $heap->findMin()->getKey());
206
        $nodes[1]->delete();
207
        $this->assertEquals(3, $heap->findMin()->getKey());
208
        $nodes[3]->delete();
209
        $this->assertEquals(4, $heap->findMin()->getKey());
210
        $nodes[9]->delete();
211
        $this->assertEquals(4, $heap->findMin()->getKey());
212
        $nodes[4]->delete();
213
        $this->assertEquals(6, $heap->findMin()->getKey());
214
215
        // again
216
        $this->expectException(InvalidArgumentException::class);
217
        $nodes[2]->delete();
218
    }
219
220
    public function testDeleteMindeleteTwice(): void
221
    {
222
        $heap = new FibonacciHeap();
223
        $e1 = $heap->insert(50);
224
        $heap->insert(100);
225
        $heap->deleteMin();
226
        $this->expectException(InvalidArgumentException::class);
227
        $e1->delete();
228
    }
229
230
    public function testDeleteMinDeleteTwiceChained(): void
231
    {
232
        $heap = new FibonacciHeap();
233
        for ($i = 0; $i < 15; $i += 1) {
234
            $heap->insert($i);
235
        }
236
        $this->expectException(InvalidArgumentException::class);
237
        $heap->deleteMin()->delete();
238
    }
239
240
    public function testDeleteMinDecreaseKey(): void
241
    {
242
        $heap = new FibonacciHeap();
243
        for ($i = 100; $i < 200; $i += 1) {
244
            $heap->insert($i);
245
        }
246
        $this->expectException(InvalidArgumentException::class);
247
        $heap->deleteMin()->decreaseKey(0);
248
    }
249
250
    public function testNoElementFindMin(): void
251
    {
252
        $heap = new FibonacciHeap();
253
        $this->expectException(NoSuchElementException::class);
254
        $heap->findMin();
255
    }
256
257
    public function testDeleteMinFindMin(): void
258
    {
259
        $heap = new FibonacciHeap();
260
        $this->expectException(NoSuchElementException::class);
261
        $heap->deleteMin();
262
    }
263
264
    public function testNullPointerException(): void
265
    {
266
        $heap = new FibonacciHeap();
267
        $this->expectException(TypeError::class);
268
        $heap->insert(null, null);
0 ignored issues
show
Bug introduced by
null of type null is incompatible with the type integer expected by parameter $key of heap\tree\FibonacciHeap::insert(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

268
        $heap->insert(/** @scrutinizer ignore-type */ null, null);
Loading history...
269
    }
270
271
    public function testDecreaseKey(): void
272
    {
273
        $heap = new FibonacciHeap();
274
        $nodes = [];
275
        for ($i = 0; $i < 15; $i += 1) {
276
            $nodes[$i] = $heap->insert($i + 100);
277
        }
278
        $this->assertEquals(100, $heap->findMin()->getKey());
279
        $nodes[5]->decreaseKey(5);
280
        $this->assertEquals(5, $heap->findMin()->getKey());
281
        $nodes[1]->decreaseKey(50);
282
        $this->assertEquals(5, $heap->findMin()->getKey());
283
        $nodes[1]->decreaseKey(20);
284
        $this->assertEquals(5, $heap->findMin()->getKey());
285
        $nodes[5]->delete();
286
        $this->assertEquals(20, $heap->findMin()->getKey());
287
        $nodes[10]->decreaseKey(3);
288
        $this->assertEquals(3, $heap->findMin()->getKey());
289
        $nodes[0]->decreaseKey(0);
290
        $this->assertEquals(0, $heap->findMin()->getKey());
291
    }
292
293
    public function testDecreaseKeyAndDelete(): void
294
    {
295
        $heap = new FibonacciHeap();
296
        $nodes = [];
297
        for ($i = 0; $i < 1000; $i += 1) {
298
            $nodes[$i] = $heap->insert($i + 2000);
299
        }
300
        for ($i = 999; $i >= 0; $i -= 1) {
301
            $nodes[$i]->decreaseKey($nodes[$i]->getKey() - 2000);
302
        }
303
        for ($i = 0; $i < 1000; $i += 1) {
304
            $this->assertEquals($i, $heap->deleteMin()->getKey());
305
        }
306
    }
307
308
    public function testIncreaseKeyException(): void
309
    {
310
        $heap = new FibonacciHeap();
311
        $nodes = [];
312
        for ($i = 0; $i < 15; $i += 1) {
313
            $nodes[$i] = $heap->insert($i + 100);
314
        }
315
        $this->assertEquals(100, $heap->findMin()->getKey());
316
        $nodes[5]->decreaseKey(5);
317
        $this->assertEquals(5, $heap->findMin()->getKey());
318
        $this->expectException(InvalidArgumentException::class);
319
        $nodes[1]->decreaseKey(102);
320
    }
321
}
322