Skip to content

Implementation Stable marriage problem in PHP #428

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Oct 8, 2018
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
144 changes: 144 additions & 0 deletions contents/stable_marriage_problem/code/php/stable_marriage.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
<?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): array
{
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);

return $women;
}

$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;

$married = stable_marriage($men, $women);
Copy link
Contributor

@Butt4cak3 Butt4cak3 Oct 8, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand why you changed stable_marriage to return. You could just use foreach ($women as $woman) in the output loop. In fact, $women and $married have the exact same contents. That's actually how every other implementation does it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, you are right. I forgot that those are objects, which goes by reference and treated it like arrays which are copies.

foreach ($married as $woman) {
printf('%s is married to %s', $woman, $woman->getMatch());
echo PHP_EOL;
}
2 changes: 2 additions & 0 deletions contents/stable_marriage_problem/stable_marriage_problem.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ I am incredibly interested to see what you guys do and how you implement the alg
[import, lang:"csharp"](code/csharp/ListExtensions.cs)
{% sample lang="java" %}
[import, lang:"java"](code/java/stable-marriage.java)
{% sample lang="php" %}
[import, lang:"php"](code/php/stable_marriage.php)
{% endmethod %}

<script>
Expand Down