Coverage for tests/model_tests/test_complex_algorithm.py: 100%

56 statements  

« prev     ^ index     » next       coverage.py v7.8.0, created at 2025-05-05 14:02 +0000

1"""Tests for the matching algorithm.""" 

2 

3import os 

4import sys 

5import time 

6import random 

7 

8# flake8: noqa: F811 

9 

10sys.path.append( 

11 os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) 

12) 

13 

14from algorithm.matching import Matching 

15 

16 

17def test_complex_student_employer_preferences(): 

18 """Tests a complex scenario with multiple students and employers.""" 

19 students_preference = { 

20 "Student_1": ["company_1", "company_2", "company_3"], 

21 "Student_2": ["company_2"], 

22 "Student_3": ["company_5", "company_4", "company_3"], 

23 "Student_4": ["company_1", "company_5", "company_6"], 

24 "Student_5": ["company_6", "company_7", "company_8"], 

25 "Student_6": ["company_4", "company_5", "company_9"], 

26 "Student_7": ["company_2", "company_3", "company_7"], 

27 "Student_8": ["company_1", "company_6", "company_10"], 

28 "Student_9": ["company_3", "company_8", "company_9"], 

29 "Student_10": ["company_2", "company_5", "company_6"], 

30 } 

31 

32 employer_preference = { 

33 "company_1": { 

34 "positions": 2, 

35 "Student_7": 1, 

36 "Student_1": 2, 

37 "Student_4": 3, 

38 "Student_10": 4, 

39 "Student_2": 5, 

40 "Student_3": 6, 

41 "Student_5": 7, 

42 "Student_9": 8, 

43 "Student_8": 9, 

44 "Student_6": 10, 

45 }, 

46 "company_2": { 

47 "positions": 1, 

48 "Student_7": 1, 

49 "Student_1": 2, 

50 "Student_4": 3, 

51 "Student_10": 4, 

52 "Student_3": 5, 

53 "Student_2": 6, 

54 "Student_9": 7, 

55 "Student_5": 8, 

56 "Student_8": 9, 

57 "Student_6": 10, 

58 }, 

59 "company_3": { 

60 "positions": 2, 

61 "Student_7": 1, 

62 "Student_1": 2, 

63 "Student_4": 3, 

64 "Student_10": 4, 

65 "Student_2": 5, 

66 "Student_8": 6, 

67 "Student_3": 7, 

68 "Student_5": 8, 

69 "Student_9": 9, 

70 "Student_6": 10, 

71 }, 

72 "company_4": { 

73 "positions": 1, 

74 "Student_7": 1, 

75 "Student_1": 2, 

76 "Student_4": 3, 

77 "Student_10": 4, 

78 "Student_3": 5, 

79 "Student_2": 6, 

80 "Student_9": 7, 

81 "Student_5": 8, 

82 "Student_8": 9, 

83 "Student_6": 10, 

84 }, 

85 "company_5": { 

86 "positions": 2, 

87 "Student_7": 1, 

88 "Student_1": 2, 

89 "Student_4": 3, 

90 "Student_10": 4, 

91 "Student_2": 5, 

92 "Student_3": 6, 

93 "Student_9": 7, 

94 "Student_5": 8, 

95 "Student_8": 9, 

96 "Student_6": 10, 

97 }, 

98 "company_6": { 

99 "positions": 1, 

100 "Student_7": 1, 

101 "Student_1": 2, 

102 "Student_4": 3, 

103 "Student_10": 4, 

104 "Student_2": 5, 

105 "Student_5": 6, 

106 "Student_8": 7, 

107 "Student_9": 8, 

108 "Student_3": 9, 

109 "Student_6": 10, 

110 }, 

111 "company_7": { 

112 "positions": 1, 

113 "Student_7": 1, 

114 "Student_1": 2, 

115 "Student_4": 3, 

116 "Student_10": 4, 

117 "Student_3": 5, 

118 "Student_2": 6, 

119 "Student_9": 7, 

120 "Student_5": 8, 

121 "Student_6": 9, 

122 "Student_8": 10, 

123 }, 

124 "company_8": { 

125 "positions": 1, 

126 "Student_7": 1, 

127 "Student_1": 2, 

128 "Student_4": 3, 

129 "Student_10": 4, 

130 "Student_3": 5, 

131 "Student_2": 6, 

132 "Student_9": 7, 

133 "Student_5": 8, 

134 "Student_8": 9, 

135 "Student_6": 10, 

136 }, 

137 "company_9": { 

138 "positions": 1, 

139 "Student_7": 1, 

140 "Student_1": 2, 

141 "Student_4": 3, 

142 "Student_10": 4, 

143 "Student_2": 5, 

144 "Student_3": 6, 

145 "Student_9": 7, 

146 "Student_5": 8, 

147 "Student_8": 9, 

148 "Student_6": 10, 

149 }, 

150 "company_10": { 

151 "positions": 1, 

152 "Student_7": 1, 

153 "Student_1": 2, 

154 "Student_4": 3, 

155 "Student_10": 4, 

156 "Student_2": 5, 

157 "Student_3": 6, 

158 "Student_9": 7, 

159 "Student_5": 8, 

160 "Student_8": 9, 

161 "Student_6": 10, 

162 }, 

163 } 

164 

165 match = Matching(students_preference, employer_preference) 

166 result = match.find_best_match() 

167 

168 expected = ( 

169 ["Student_2"], 

170 { 

171 "company_1": ["Student_1", "Student_4"], 

172 "company_2": ["Student_7"], 

173 "company_5": ["Student_3", "Student_10"], 

174 "company_6": ["Student_5"], 

175 "company_4": ["Student_6"], 

176 "company_3": ["Student_9"], 

177 "company_10": ["Student_8"], 

178 }, 

179 ) 

180 assert result == expected 

181 

182 

183def test_complex_student_employer_preferences_v2(): 

184 """Tests a complex scenario with multiple students and employers.""" 

185 students_preference = { 

186 "Student_1": ["company_1", "company_2", "company_3"], 

187 "Student_2": ["company_2", "company_4"], 

188 "Student_3": ["company_1", "company_5", "company_6"], 

189 "Student_4": ["company_3", "company_2", "company_1"], 

190 "Student_5": ["company_7", "company_8", "company_4"], 

191 "Student_6": ["company_8", "company_9", "company_5"], 

192 "Student_7": ["company_1", "company_6"], 

193 "Student_8": ["company_5", "company_3", "company_2"], 

194 "Student_9": ["company_4", "company_7", "company_10"], 

195 "Student_10": ["company_2", "company_9", "company_8"], 

196 } 

197 

198 employer_preference = { 

199 "company_1": { 

200 "positions": 2, 

201 "Student_1": 1, 

202 "Student_3": 2, 

203 "Student_4": 3, 

204 "Student_7": 4, 

205 "Student_5": 5, 

206 "Student_10": 6, 

207 "Student_9": 7, 

208 "Student_2": 8, 

209 "Student_6": 9, 

210 "Student_8": 10, 

211 }, 

212 "company_2": { 

213 "positions": 2, 

214 "Student_2": 1, 

215 "Student_1": 2, 

216 "Student_4": 3, 

217 "Student_10": 4, 

218 "Student_6": 5, 

219 "Student_9": 6, 

220 "Student_8": 7, 

221 "Student_7": 8, 

222 "Student_5": 9, 

223 "Student_3": 10, 

224 }, 

225 "company_3": { 

226 "positions": 1, 

227 "Student_4": 1, 

228 "Student_1": 2, 

229 "Student_8": 3, 

230 "Student_2": 4, 

231 "Student_10": 5, 

232 "Student_5": 6, 

233 "Student_6": 7, 

234 "Student_3": 8, 

235 "Student_9": 9, 

236 "Student_7": 10, 

237 }, 

238 "company_4": { 

239 "positions": 2, 

240 "Student_2": 1, 

241 "Student_5": 2, 

242 "Student_9": 3, 

243 "Student_1": 4, 

244 "Student_4": 5, 

245 "Student_3": 6, 

246 "Student_8": 7, 

247 "Student_10": 8, 

248 "Student_6": 9, 

249 "Student_7": 10, 

250 }, 

251 "company_5": { 

252 "positions": 2, 

253 "Student_3": 1, 

254 "Student_6": 2, 

255 "Student_8": 3, 

256 "Student_1": 4, 

257 "Student_2": 5, 

258 "Student_4": 6, 

259 "Student_10": 7, 

260 "Student_5": 8, 

261 "Student_7": 9, 

262 "Student_9": 10, 

263 }, 

264 "company_6": { 

265 "positions": 1, 

266 "Student_1": 1, 

267 "Student_2": 2, 

268 "Student_7": 3, 

269 "Student_4": 4, 

270 "Student_3": 5, 

271 "Student_9": 6, 

272 "Student_10": 7, 

273 "Student_8": 8, 

274 "Student_5": 9, 

275 "Student_6": 10, 

276 }, 

277 "company_7": { 

278 "positions": 1, 

279 "Student_5": 1, 

280 "Student_9": 2, 

281 "Student_3": 3, 

282 "Student_2": 4, 

283 "Student_4": 5, 

284 "Student_8": 6, 

285 "Student_10": 7, 

286 "Student_6": 8, 

287 "Student_1": 9, 

288 "Student_7": 10, 

289 }, 

290 "company_8": { 

291 "positions": 1, 

292 "Student_6": 1, 

293 "Student_1": 2, 

294 "Student_2": 3, 

295 "Student_5": 4, 

296 "Student_3": 5, 

297 "Student_10": 6, 

298 "Student_7": 7, 

299 "Student_8": 8, 

300 "Student_4": 9, 

301 "Student_9": 10, 

302 }, 

303 "company_9": { 

304 "positions": 1, 

305 "Student_6": 1, 

306 "Student_10": 2, 

307 "Student_5": 3, 

308 "Student_2": 4, 

309 "Student_7": 5, 

310 "Student_1": 6, 

311 "Student_3": 7, 

312 "Student_8": 8, 

313 "Student_4": 9, 

314 "Student_9": 10, 

315 }, 

316 "company_10": { 

317 "positions": 1, 

318 "Student_4": 1, 

319 "Student_2": 2, 

320 "Student_9": 3, 

321 "Student_5": 4, 

322 "Student_7": 5, 

323 "Student_3": 6, 

324 "Student_1": 7, 

325 "Student_10": 8, 

326 "Student_6": 9, 

327 "Student_8": 10, 

328 }, 

329 } 

330 

331 match = Matching(students_preference, employer_preference) 

332 result = match.find_best_match() 

333 

334 expected = ( 

335 [], 

336 { 

337 "company_1": ["Student_1", "Student_3"], 

338 "company_2": ["Student_2", "Student_10"], 

339 "company_3": ["Student_4"], 

340 "company_7": ["Student_5"], 

341 "company_8": ["Student_6"], 

342 "company_6": ["Student_7"], 

343 "company_5": ["Student_8"], 

344 "company_4": ["Student_9"], 

345 }, 

346 ) 

347 

348 assert result == expected 

349 

350 

351def test_complex_student_employer_preferences_v3(): 

352 """Tests a complex scenario with multiple students and employers.""" 

353 students_preference = { 

354 "Student_1": ["company_1", "company_2"], 

355 "Student_2": ["company_1", "company_3", "company_4"], 

356 "Student_3": ["company_5", "company_6"], 

357 "Student_4": ["company_2", "company_7", "company_5"], 

358 "Student_5": ["company_3", "company_4", "company_8"], 

359 "Student_6": ["company_1", "company_8", "company_3"], 

360 "Student_7": ["company_5", "company_6", "company_9"], 

361 "Student_8": ["company_2", "company_3"], 

362 "Student_9": ["company_7", "company_4"], 

363 "Student_10": ["company_1", "company_9", "company_10"], 

364 } 

365 

366 employer_preference = { 

367 "company_1": { 

368 "positions": 2, 

369 "Student_1": 1, 

370 "Student_2": 2, 

371 "Student_6": 3, 

372 "Student_10": 4, 

373 "Student_4": 5, 

374 "Student_8": 6, 

375 }, 

376 "company_2": { 

377 "positions": 1, 

378 "Student_4": 1, 

379 "Student_1": 2, 

380 "Student_8": 3, 

381 "Student_5": 4, 

382 "Student_3": 5, 

383 "Student_10": 6, 

384 "Student_2": 7, 

385 "Student_7": 8, 

386 "Student_9": 9, 

387 }, 

388 "company_3": { 

389 "positions": 2, 

390 "Student_10": 1, 

391 "Student_2": 2, 

392 "Student_6": 3, 

393 "Student_8": 4, 

394 "Student_5": 5, 

395 "Student_1": 6, 

396 "Student_3": 7, 

397 "Student_4": 8, 

398 "Student_7": 9, 

399 }, 

400 "company_4": { 

401 "positions": 2, 

402 "Student_5": 1, 

403 "Student_9": 2, 

404 "Student_2": 3, 

405 "Student_1": 4, 

406 "Student_10": 5, 

407 "Student_6": 6, 

408 "Student_3": 7, 

409 "Student_7": 8, 

410 "Student_8": 9, 

411 }, 

412 "company_5": { 

413 "positions": 1, 

414 "Student_3": 1, 

415 "Student_4": 2, 

416 "Student_7": 3, 

417 "Student_1": 4, 

418 "Student_2": 5, 

419 "Student_8": 6, 

420 }, 

421 "company_6": { 

422 "positions": 2, 

423 "Student_3": 1, 

424 "Student_7": 2, 

425 "Student_5": 3, 

426 "Student_10": 4, 

427 "Student_2": 5, 

428 "Student_1": 6, 

429 "Student_4": 7, 

430 "Student_9": 8, 

431 }, 

432 "company_7": { 

433 "positions": 1, 

434 "Student_4": 1, 

435 "Student_9": 2, 

436 "Student_1": 3, 

437 "Student_6": 4, 

438 "Student_10": 5, 

439 "Student_2": 6, 

440 "Student_5": 7, 

441 "Student_8": 8, 

442 }, 

443 "company_8": { 

444 "positions": 1, 

445 "Student_3": 1, 

446 "Student_5": 2, 

447 "Student_1": 3, 

448 "Student_2": 4, 

449 "Student_9": 5, 

450 "Student_10": 6, 

451 }, 

452 "company_9": { 

453 "positions": 1, 

454 "Student_7": 1, 

455 "Student_10": 2, 

456 "Student_1": 3, 

457 "Student_2": 4, 

458 "Student_3": 5, 

459 "Student_8": 6, 

460 }, 

461 } 

462 

463 match = Matching(students_preference, employer_preference) 

464 result = match.find_best_match() 

465 

466 expected = ( 

467 [], 

468 { 

469 "company_1": ["Student_1", "Student_2"], 

470 "company_5": ["Student_3"], 

471 "company_2": ["Student_4"], 

472 "company_3": ["Student_8", "Student_6"], 

473 "company_6": ["Student_7"], 

474 "company_4": ["Student_5"], 

475 "company_7": ["Student_9"], 

476 "company_9": ["Student_10"], 

477 }, 

478 ) 

479 assert result == expected 

480 

481 

482def test_complex_student_employer_preferences_v4(): 

483 """Test a complex matching scenario.""" 

484 students_preference = { 

485 "Student_1": ["company_2", "company_3"], 

486 "Student_2": ["company_1", "company_4", "company_5"], 

487 "Student_3": ["company_1", "company_2", "company_6"], 

488 "Student_4": ["company_3", "company_5"], 

489 "Student_5": ["company_2", "company_3", "company_7"], 

490 "Student_6": ["company_5", "company_8"], 

491 "Student_7": ["company_1", "company_4"], 

492 "Student_8": ["company_7", "company_9", "company_5"], 

493 "Student_9": ["company_1", "company_2"], 

494 "Student_10": ["company_8", "company_10", "company_9"], 

495 } 

496 

497 employer_preference = { 

498 "company_1": { 

499 "positions": 2, 

500 "Student_2": 1, 

501 "Student_3": 2, 

502 "Student_9": 3, 

503 "Student_5": 4, 

504 "Student_1": 5, 

505 }, 

506 "company_2": { 

507 "positions": 2, 

508 "Student_1": 1, 

509 "Student_5": 2, 

510 "Student_3": 3, 

511 "Student_10": 4, 

512 "Student_8": 5, 

513 "Student_4": 6, 

514 }, 

515 "company_3": { 

516 "positions": 1, 

517 "Student_4": 1, 

518 "Student_1": 2, 

519 "Student_2": 3, 

520 "Student_9": 4, 

521 "Student_8": 5, 

522 }, 

523 "company_4": { 

524 "positions": 2, 

525 "Student_2": 1, 

526 "Student_7": 2, 

527 "Student_5": 3, 

528 "Student_1": 4, 

529 "Student_3": 5, 

530 }, 

531 "company_5": { 

532 "positions": 1, 

533 "Student_6": 1, 

534 "Student_4": 2, 

535 "Student_2": 3, 

536 "Student_10": 4, 

537 }, 

538 "company_6": { 

539 "positions": 1, 

540 "Student_3": 1, 

541 "Student_1": 2, 

542 "Student_4": 3, 

543 "Student_9": 4, 

544 }, 

545 "company_7": { 

546 "positions": 1, 

547 "Student_5": 1, 

548 "Student_8": 2, 

549 "Student_1": 3, 

550 "Student_3": 4, 

551 }, 

552 "company_8": { 

553 "positions": 2, 

554 "Student_10": 1, 

555 "Student_6": 2, 

556 "Student_2": 3, 

557 "Student_3": 4, 

558 }, 

559 "company_9": { 

560 "positions": 1, 

561 "Student_2": 1, 

562 "Student_4": 2, 

563 "Student_1": 3, 

564 }, 

565 "company_10": { 

566 "positions": 1, 

567 "Student_10": 1, 

568 "Student_5": 2, 

569 "Student_6": 3, 

570 "Student_8": 4, 

571 }, 

572 } 

573 

574 match = Matching(students_preference, employer_preference) 

575 result = match.find_best_match() 

576 

577 expected = ( 

578 ["Student_9"], 

579 { 

580 "company_2": ["Student_1", "Student_5"], 

581 "company_1": ["Student_2", "Student_3"], 

582 "company_3": ["Student_4"], 

583 "company_5": ["Student_6"], 

584 "company_4": ["Student_7"], 

585 "company_7": ["Student_8"], 

586 "company_8": ["Student_10"], 

587 }, 

588 ) 

589 

590 assert result == expected 

591 

592 

593def test_large_scale_matching_under_30_seconds(): 

594 """Tests the matching algorithm with 5000 students and enough employers under 30 seconds.""" 

595 num_students = 5000 

596 num_companies = 1000 

597 student_ids = [f"Student_{i+1}" for i in range(num_students)] 

598 company_ids = [f"company_{i+1}" for i in range(num_companies)] 

599 

600 # Generate random student preferences 

601 students_preference = {} 

602 for student in student_ids: 

603 preferred_companies = random.sample(company_ids, k=random.randint(5, 10)) 

604 students_preference[student] = preferred_companies 

605 

606 # Generate random employer preferences 

607 employer_preference = {} 

608 for company in company_ids: 

609 positions = random.randint(2, 10) # Each company offers 2-10 positions 

610 ranked_students = random.sample(student_ids, k=len(student_ids)) 

611 preference = {student: rank + 1 for rank, student in enumerate(ranked_students)} 

612 preference["positions"] = positions 

613 employer_preference[company] = preference 

614 

615 # Run the matching algorithm and time it 

616 match = Matching(students_preference, employer_preference) 

617 

618 start_time = time.time() 

619 result = match.find_best_match() 

620 end_time = time.time() 

621 

622 duration = end_time - start_time 

623 assert duration < 30, f"Matching took too long: {duration:.2f} seconds"