[Algorithm] Math - Integer Partition

수학 자연수 분할

Posted by lim.Chuck on September 21, 2024

Integer Partition?

자연수 분할이란, 양의 자연수를 더 작은 자연수들의 합으로 나누는 것을 의미합니다. 이때 각 합이 되는 숫자들의 순서는 상관없으며, 구성되는 숫자의 개수와 조합이 중요합니다.

예를 들어:

  • 4의 자연수 분할은:
    4, 3 + 1, 2 + 2, 2 + 1 + 1, 1 + 1 + 1 + 1 와 같습니다.

자연수 분할의 활용

자연수 분할은 여러 실용적인 응용이 있으며, 특히:

  • 조합론 (Combinatorics): 아이템을 배열하거나 결합하는 방법의 수를 계산.
  • 자연수론 (Number Theory): 자연수의 특성과 그 관계를 연구.
  • 암호학 (Cryptography): 일부 암호화 방식 및 키 생성에 사용.
  • 양자 물리학 (Quantum Physics): 양자 시스템에서 입자 상태를 모델링.
  • 동적 계획법 (Dynamic Programming): 부분 집합의 합이나 배열 분할 문제에 사용.

JavaScript 예제

다음은 주어진 자연수 n의 모든 분할을 생성하는 간단한 JavaScript 구현입니다:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function partition(n) {
  const result = [];

  function _partition(n, max, prefix) {
    if (n === 0) {
      result.push(prefix);
      return;
    }
    for (let i = Math.min(max, n); i >= 1; i--) {
      _partition(n - i, i, [...prefix, i]);
    }
  }

  _partition(n, n, []);
  return result;
}

const number = 4;
console.log(partition(number));

JavaScript 코드 설명

  1. partition(n)n의 분할을 찾는 메인 함수입니다.
  2. _partition(n, max, prefix)는 재귀적으로 n을 분할하여 결과 배열에 저장하는 함수입니다.
  3. 4를 분할한 결과는:
1
[[4], [3, 1], [2, 2], [2, 1, 1], [1, 1, 1, 1]];

Rust 예제

다음은 n의 자연수 분할을 생성하는 Rust 구현입니다:

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
fn partition(n: usize) -> Vec<Vec<usize>> {
    let mut result = Vec::new();

    fn _partition(n: usize, max: usize, prefix: Vec<usize>, result: &mut Vec<Vec<usize>>) {
        if n == 0 {
            result.push(prefix);
            return;
        }
        for i in (1..=max).rev() {
            if i <= n {
                let mut new_prefix = prefix.clone();
                new_prefix.push(i);
                _partition(n - i, i, new_prefix, result);
            }
        }
    }

    _partition(n, n, Vec::new(), &mut result);
    result
}

fn main() {
    let number = 4;
    let partitions = partition(number);
    for part in partitions {
        println!("{:?}", part);
    }
}

Rust 코드 설명

  1. partition(n)은 재귀적 도우미 함수 _partition을 호출하는 메인 함수입니다.
  2. _partition(n, max, prefix, result)는 유효한 분할을 결과 배열에 추가하면서 탐색하는 재귀 함수입니다.
  3. 4의 출력 결과는 다음과 같습니다:
1
2
3
4
5
[4]
[3, 1]
[2, 2]
[2, 1, 1]
[1, 1, 1, 1]

요약

  • 자연수 분할은 자연수를 다른 자연수들의 합으로 분해하는 과정입니다.
  • 조합론, 암호학, 동적 계획법, 물리학 등 다양한 분야에서 활용됩니다.
  • JavaScript와 Rust의 예시는 재귀적 방법을 사용하여 주어진 숫자의 모든 자연수 분할을 찾는 방법을 보여줍니다.

Integer Partition?

Integer Partition refers to the process of breaking down a positive integer into smaller non-negative integers, where the sum of those integers equals the original number. The order of the integers does not matter, but the number and composition of integers do.

For example:

  • The integer partition of 4 would include:
    4, 3 + 1, 2 + 2, 2 + 1 + 1, 1 + 1 + 1 + 1.

Applications of Integer Partition

Integer partitions have several practical applications, particularly in:

  • Combinatorics: Counting ways to arrange or combine items.
  • Number Theory: Studying the properties of integers and their relations.
  • Cryptography: In some encryption schemes and generating keys.
  • Quantum Physics: Modeling particle states in certain quantum systems.
  • Dynamic Programming: Used in problems involving subset sums or partitioning arrays.

JavaScript Example

Here’s a simple implementation in JavaScript to generate all partitions of a given integer n:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function partition(n) {
  const result = [];

  function _partition(n, max, prefix) {
    if (n === 0) {
      result.push(prefix);
      return;
    }
    for (let i = Math.min(max, n); i >= 1; i--) {
      _partition(n - i, i, [...prefix, i]);
    }
  }

  _partition(n, n, []);
  return result;
}

const number = 4;
console.log(partition(number));

Explanation of the JavaScript Code

  1. partition(n) is the main function to find partitions of n.
  2. _partition(n, max, prefix) is a recursive helper function that explores different ways to partition n using integers less than or equal to max.
  3. The result of partitioning 4 will give:
1
[[4], [3, 1], [2, 2], [2, 1, 1], [1, 1, 1, 1]];

Rust Example

Here’s a Rust implementation to generate integer partitions of a number n:

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
fn partition(n: usize) -> Vec<Vec<usize>> {
    let mut result = Vec::new();

    fn _partition(n: usize, max: usize, prefix: Vec<usize>, result: &mut Vec<Vec<usize>>) {
        if n == 0 {
            result.push(prefix);
            return;
        }
        for i in (1..=max).rev() {
            if i <= n {
                let mut new_prefix = prefix.clone();
                new_prefix.push(i);
                _partition(n - i, i, new_prefix, result);
            }
        }
    }

    _partition(n, n, Vec::new(), &mut result);
    result
}

fn main() {
    let number = 4;
    let partitions = partition(number);
    for part in partitions {
        println!("{:?}", part);
    }
}

Explanation of the Rust Code

  1. partition(n) is the main function that calls the recursive helper function _partition.
  2. _partition(n, max, prefix, result) is the recursive function that explores partitions, appending valid partitions to the result.
  3. Output for 4 will look like:
1
2
3
4
5
[4]
[3, 1]
[2, 2]
[2, 1, 1]
[1, 1, 1, 1]

Summary

  • Integer Partition is the process of decomposing an integer into sums of other integers.
  • It is used in combinatorics, cryptography, dynamic programming, and physics.
  • Both JavaScript and Rust examples illustrate how recursive approaches can be used to find all integer partitions of a given number.