폴리오미노 열거 (애니메이션 Gif 포함)
개요
N개의 정사각형을 변에서 연결한 다각형을 폴리오미노이라고 한다. 예를 들어 유명한 낙하물 게임의 테트리스에서는 N = 4의 폴리오미노가 사용되고있다.
N이 증가함에 따라, 폴리오미노의 수는 다음과 같이 지수 함수 1로 증가한다.
N
조합수(유향)
1
1
2
2
3
6
4
19
5
63
6
216
7
760
8
2725
...
...
24
5239988770268
폴리오미노의 수를 산출하는 식을 찾기 위해, 연구자들에 의해 상당한 노력이 이루어져 왔지만, 현재 상태에서는 아직 발견에 이르지 못하고 있다.
폴리오미노를 열거하는 알고리즘으로서 Redelmeier's algorithm이라는 것이 있다. 세기 때문에 필연적으로 지수 시간이 걸려 버리지만, 공간 계산량은 O(N)가 되는 알고리즘이다.
이 기사에서는 실제로 JavaScript로 알고리즘을 구현하고 이것을 시각적으로 확인한다.
Redelmeier의 algorithm
y > 0 or (y == 0 and x >= 0)
될 셀 공간을 고려하십시오 境界セル
로 한다 境界セル
를 선택하면 다음 작업이 수행됩니다.境界セル
境界セル
인 최대 번호보다 작은 번호의 셀을 선택하지 않음 경계 셀의 선택을 재귀 적으로 깊이 N까지 수행함으로써 폴리오미노를 열거 할 수있다.
구현
잡히 알고리즘 그대로 구현한다.
다만, 나중에 스텝 실행할 수 있도록 재귀의 스택은 스스로 준비해 둔다.
var N = 3;
var nodeStack = [
{
cells: [{ x: 0, y: 0, num: 1, isBorder: false }],
availableNumbers: [1]
}
]; // 状態を保持するスタック
function confirmBorderCellNumber(node, num) {
var cells = node.cells;
var cell = cells.find(e => e.num == num);
cell.isBorder = true;
var dx = [0, -1, 1, 0];
var dy = [-1, 0, 0, 1];
for (var i = 0; i < 4; i++) {
var x = cell.x + dx[i];
var y = cell.y + dy[i];
if (!(y > 0 || (y == 0 && x >= 0))) continue;
if (cells.find(e => e.x == x && e.y == y)) continue;
cells.push({ x: x, y: y, num: cells.length + 1, isBorder: false });
node.availableNumbers.push(cells.length);
}
}
function nextStep() {
var node = nodeStack[nodeStack.length - 1];
if (nodeStack.length > N || node.availableNumbers == 0) {
nodeStack.pop();
} else {
var num = node.availableNumbers.shift();
var newNode = JSON.parse(JSON.stringify(node)); // deep copy
confirmBorderCellNumber(newNode, num);
nodeStack.push(newNode);
}
}
// スタックが空になるまでステップ実行
var found = 0;
while (nodeStack.length > 0) {
nextStep();
// 葉(depth = N)の場合のみ出力
if (nodeStack.length > N) {
var node = nodeStack[nodeStack.length - 1];
var str = "";
for (var y = N - 1; y >= 0; y--) {
for (var x = 1 - N; x < N; x++) {
var cell = node.cells.find(e => e.x == x && e.y == y);
str += cell && cell.isBorder ? "#" : "_";
}
str += "\n";
}
console.log(++found);
console.log(str);
}
}
※ 계산량적으로 좋지 않은 실장이므로, 큰 N 을 조사하고 싶은 경우 잘 수정하는 것.
실행 결과
1
_____
__#__
__##_
2
_____
_____
__###
3
_____
___#_
__##_
4
_____
_##__
__#__
5
_____
__##_
__#__
6
__#__
__#__
__#__
시각화
한 단계씩 웹상에서 실행할 수 있도록 해 보았다.
N = 4 를 스텝 실행한 모습의 Gif 는 이런 느낌.
잘 중복을 배제하고 있는 것이 시각적으로 알 수 있다.
정리(+관계없는 이야기)
이 기사에서 한 일
조사에 이르는 경위
원래 왜 폴리오미노의 열거에 대해 조사했는가라고 하면, 뿌요푸요의 연쇄형의 탐색에 사용하기 위한 것이었다. (푸요푸요의 1연쇄는 N >= 4의 폴리오미노의 형태로 간주한다.)
직접 이 알고리즘을 도움이 된 것은 아니지만, 흥미로운 체인도 발견되었다.
2색 4개 지우기 16연쇄 동영상 htps // t. 코 / Ps Pen Gs 7 W 피 c. 라고 r. 코 m / 111 유 dFYv — REF@푸요 (@refpuyo) 10월 30, 2019
이 동영상에서는 수동으로 열거 된 N = 4의 폴리오미노 (테트로 미노)를 사용하여 체인 조합을 탐색했습니다. 여기에서 임의의 연결 수의 체인을 사용하기 위해 폴리오미노 열거 알고리즘을 사용하려고합니다. 그러나 N이 증가하면 연쇄 조합이 폭발적으로 증가하기 때문에 아직 잘 작동하지 않습니다. 누군가 도와주세요 ...
참고
- 폴리오미노 열거 - phyllo’s algorithm note
- n-omino의 열거 (Redelmeier 's algorithm) - matsu7874 블로그
- Handbook of Discrete and Computational Geometry —Third Edition—
실제로 유향인 N폴리오미노(fixed-n-omino)에는 $\lim_{n\to\infty}\frac{t(n+1)}{t(n)}$ 와 같은 경계 λ
가 존재해, 그것은 대략 4 조금이 되는 것 같다. 여기서 $t(n)$ 는 유향 $n$ 폴리오미노의 수입니다. [Handbook of Discrete and Computational Geometry | THEOREM 14.3.2] ↩
Reference
이 문제에 관하여(폴리오미노 열거 (애니메이션 Gif 포함)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/ref3000/items/af18a4532123c22a19a4
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
실제로 유향인 N폴리오미노(fixed-n-omino)에는 $\lim_{n\to\infty}\frac{t(n+1)}{t(n)}$ 와 같은 경계
λ
가 존재해, 그것은 대략 4 조금이 되는 것 같다. 여기서 $t(n)$ 는 유향 $n$ 폴리오미노의 수입니다. [Handbook of Discrete and Computational Geometry | THEOREM 14.3.2] ↩
Reference
이 문제에 관하여(폴리오미노 열거 (애니메이션 Gif 포함)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/ref3000/items/af18a4532123c22a19a4텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)