-
-
Notifications
You must be signed in to change notification settings - Fork 360
/
Copy pathstable_marriage.php
142 lines (120 loc) · 2.96 KB
/
stable_marriage.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
<?php
declare(strict_types=1);
class Person
{
private $name;
private $suitors = [];
private $preferences = [];
private $match;
public function __construct($name)
{
$this->name = $name;
}
public function getName(): string
{
return $this->name;
}
public function setPreferences(array $preferences): void
{
$this->preferences = $preferences;
}
public function getMatch(): ?Person
{
return $this->match;
}
public function getPreferences(): array
{
return $this->preferences;
}
public function isSingle(): bool
{
return $this->match === null;
}
public function unmatch(): void
{
$this->match = null;
}
public function setMatch(Person $match): void
{
if ($this->match !== $match) {
if ($this->match !== null) {
$this->match->unmatch();
}
$this->match = $match;
$match->setMatch($this);
}
}
public function propose(): void
{
if (!empty($this->preferences)) {
$fiance = array_shift($this->preferences);
$fiance->receiveProposal($this);
}
}
public function receiveProposal(Person $man): void
{
$this->suitors[] = $man;
}
public function chooseMatch(): void
{
foreach ($this->preferences as $preference) {
if ($preference === $this->match || in_array($preference, $this->suitors)) {
$this->setMatch($preference);
break;
}
}
$this->suitors = [];
}
public function __toString(): string
{
return $this->name;
}
}
function stable_marriage(array $men, array $women): void
{
do {
foreach ($men as $man) {
if ($man->isSingle()) {
$man->propose();
}
}
foreach ($women as $woman) {
$woman->chooseMatch();
}
$unmarried = false;
foreach ($women as $woman) {
if ($woman->isSingle()) {
$unmarried = true;
break;
}
}
} while ($unmarried);
}
$groupSize = 10;
$men = [];
$women = [];
for ($i = 1; $i <= $groupSize; $i++) {
$men[] = new Person("M${i}");
$women[] = new Person("W${i}");
}
foreach ($men as $man) {
$preferences = $women;
shuffle($preferences);
$man->setPreferences($preferences);
printf('%s\'s choices: %s', $man->getName(), implode(',', $man->getPreferences()));
echo PHP_EOL;
}
echo PHP_EOL;
foreach ($women as $woman) {
$preferences = $men;
shuffle($preferences);
$woman->setPreferences($preferences);
printf('%s\'s choices: %s', $woman->getName(), implode(',', $woman->getPreferences()));
echo PHP_EOL;
}
echo PHP_EOL;
stable_marriage($men, $women);
foreach ($women as $woman) {
printf('%s is married to %s', $woman, $woman->getMatch());
echo PHP_EOL;
}