[素因数分解] Trial Division / 試し割り法
Aug 19 2018試し割り法は素因数分解の一番愚直なアルゴリズムです。この解説をします。
こんちくわ。試し割り法は素因数分解の一番愚直なアルゴリズムです。この解説をします。Method
ある合成数Nの素因数pを求めたい時に、このアルゴリズムは小さい数から割り切れるかどうかを調べていきます。†小さい数から調べるので、この方法で見つかるであろうpはNの素因数の中でも最小のものであるはずですよね。pがNの最小の素因数なら、2≤p≤⌊√N⌋であるので†‡、この範囲を調べて見つからなければその数は素数ということになります†‡。Implementation in C++
vector<ll> trial_division(const ll& n) {
ll result = n;
for (ll i = 2, m = (ll)sqrt(n); i <= m; ++i)
{
if (n % i == 0) {
result = i;
break;
}
}
if (result == n) {
return { n };
} else {
vector<ll> v1 = { result };
vector<ll> v2 = trial_division(n / result);
v1.insert(v1.end(), v2.begin(), v2.end());
return v1;
}
}
Implementation in Rust
fn trivial_division(n: u64) -> Vec<u64> {
let mut result = n;
for i in 2..((n as f64).sqrt() as u64)+1 {
if n % i == 0 {
result = i;
break;
}
}
if result == n {
return vec![n];
} else {
let mut v1 = vec![result];
let mut v2 = trivial_division(n / result);
v1.append(&mut v2);
return v1;
}
}
fn main() {
println!("{:?}", trivial_division(238528));
}
† 素因数が2である確率は3である確率より大きいですよね? 範囲aからb(a,b∈Z)の中に、素因数がxの数は大体(b−a)/xくらいあるので、一般的にx<yなら素因数がxである確率はyである確率より大きいのです。なので、小さい方から探したほうが効率が良いのです。 ↩
†‡ Nの素因数は√Nを超えることもありますが、最小の素因数は√N以下です。なぜなら、√Nより大きい素因数pが存在すればNが合成数であることから他の因数f=N/pが存在するはずで、これは√N以下であるからです。 ↩
†† Nは合成数って言って話進めてますので、は2≤p≤⌊√N⌋で割り切れない場合は上の話では存在しません。(だから、ん???ってなった人に向けてこの注釈を書いてます)実際のアルゴリズムではNは自然数なので、その範囲になかった場合は素数だということです。なんかうまい書き方が見つからなかったorz ↩