PHP에서의 분리된 집합(Union-Find 알고리즘)
게시됨: 2025년 2월 16일 오후 12시 25분 57초 UTC
마지막으로 업데이트되었습니다: 2026년 1월 26일 오전 10시 36분 51초 UTC
이 글에서는 최소 스패닝 트리 알고리즘에서 Union-Find에 흔히 사용되는 Disjoint Set 데이터 구조의 PHP 구현을 소개합니다.
Disjoint Set (Union-Find Algorithm) in PHP
분리 집합(일반적으로 Union-Find, 즉 분리 집합 유니온이라고도 함)은 요소들을 서로 겹치지 않은(겹치지 않은) 집합으로 분할하는 데 사용되는 자료구조입니다. 이 기능은 두 가지 주요 연산을 효율적으로 지원합니다:
- 찾기: 원소가 속하는 집합을 결정합니다.
- 유니언: 두 세트를 합쳐 놓습니다.
이 구조는 크루스칼 알고리즘과 같은 최소 스팬닝 트리 알고리즘에서 특히 유용합니다.
저는 아래 PHP 구현체인지 Disjoint Set을 기반으로 집합을 효율적으로 병합하는 Kruskal 알고리즘의 임의 미로 생성 구현을 가지고 있습니다. 관심 있으시면 여기에서 실제 동작을 볼 수 있습니다: 크루스칼 알고리즘 미로 생성기
어쨌든, 이것이 제가 PHP에서 구현한 Disjoint Set입니다:
{
private $parent = [];
private $rank = [];
public function __construct($size)
{
for ($i = 0; $i < $size; $i++)
{
$this->parent[$i] = $i;
$this->rank[$i] = 0;
}
}
public function find($x)
{
if ($this->parent[$x] != $x)
{
$this->parent[$x] = $this->find($this->parent[$x]);
}
return $this->parent[$x];
}
public function union($x, $y)
{
$rootX = $this->find($x);
$rootY = $this->find($y);
if ($rootX != $rootY)
{
if ($this->rank[$rootX] > $this->rank[$rootY])
{
$this->parent[$rootY] = $rootX;
}
elseif ($this->rank[$rootX] < $this->rank[$rootY])
{
$this->parent[$rootX] = $rootY;
}
else
{
$this->parent[$rootY] = $rootX;
$this->rank[$rootX]++;
}
}
}
}
재미로 미로를 생성하는 것 외에도, Disjoint Set 데이터 구조는 실제 상황에도 충분히 활용할 수 있습니다.
예를 들어, 소셜 네트워크가 사용자에게 새로운 친구를 추천하고자 한다고 상상해 보세요. 그리고 이미 이런 친구 관계를 가진 여섯 명이 있다고 가정해 봅시다:
- 1번과 2번은 친구입니다.
- 2번과 3번은 친구입니다.
- 4번과 5번은 친구입니다.
- 6은 친구가 없어.
이 개별 그룹에 Union-Find 알고리즘을 적용하면 다음과 같은 결과를 얻을 수 있습니다:
- 1, 2, 3이 한 그룹에 모여 있어.
- 4번과 5번이 두 번째 그룹에 있어요.
- 세 번째 그룹에는 6명이 있습니다.
이런 점을 바탕으로 1번과 3번이 친구가 되어야 한다고 제안하는 것이 합리적일 텐데, 왜냐하면 두 사람이 공통점이 있기 때문입니다.
물론 이런 작은 예시에서는 스스로 쉽게 알아챌 수 있지만, 이 알고리즘의 효율성 덕분에 수십억 명과 친구 그룹에 적용할 수 있습니다.
