合計値と要素数から要素を求める方法


えみ  2014-05-14 20:57:48  No: 46333

合計値と、要素数をインプットとしてそれを満たす整数の要素の組み合わせ全てをstringgridに出力したいです。

合計値4
要素2

結果
[1][3]
[2][2]
[3][1]

n個の要素を選ぶ全ての組み合わせを求めてから、合計が一致するものだけをピックアップする方法でやってみたのですが、数字が大きいと処理に時間がかかり過ぎてしまいます。
何かいい方法は無いでしょうか?


tor  2014-05-14 22:19:26  No: 46334

ばっと見「整数の分割」と呼ばれる問題かと思ったけれど、成分の数が固定されているわけですね。
これは再帰的なアルゴリズムでできるのではないかと思います。

以下説明のため、求める合計値スモ、要素数スヲサという記号で表します。
そして、モを個の整数の組み合わせで表す手続きをヲサミィモャゥヲサと表します。

まずスイの時の手続きヲサミィモャイゥヲサに限定して考えます。これは
  ロアンロモュアン
  ロインロモュイン
  ョョョ
  ロモュインロイン
  ロモュアンロアン
という組み合わせをモュア回ループして生成すればできます。簡単ですね。

ではスウになったらどうでしょう。
まず先頭の要素がアだった場合、残りはモュアでイ要素残っているので、ロアンヲサの後にヲサミィモュアャイゥヲサの結果をくっつければできます。
先頭の要素がイだとしたら、残りはモュイでイ要素残っているので、ロインの後にミィモュイャイゥの結果をくっつければいいです。
この考え方で続けていくと、ミィモャウゥヲサは
  ロアンヲサォヲサミィモュアャイゥの結果
  ロインヲサォヲサミィモュイャイゥの結果
  ロウンヲサォヲサミィモュウャイゥの結果
  ……
  ロモュインヲサォヲサミィイャイゥの結果
  ロモュアンヲサォヲサミィアャイゥの結果
という手順で作り出せることがわかります。
同じ考え方で、スエの時の手続きヲサミィモャエゥヲサは
  ロアンヲサォヲサミィモュアャウゥの結果
  ロインヲサォヲサミィモュイャウゥの結果
  ロウンヲサォヲサミィモュウャウゥの結果
  ……
  ロモュインヲサォヲサミィイャウゥの結果
  ロモュアンヲサォヲサミィアャウゥの結果
でできます。パターンが見えてきましたね。

最後に自明なケースとして、スアヲサの時の手続きヲサミィモャアゥヲサは単にヲサロモンヲサを生成するだけです。(合計がモになるア要素の組み合わせは一通りしかないので)
以上を一般化して、ミィモャゥヲサは次のような再帰的手続きで表せます。

ヲサミィモャヲサゥ

ヲサヲサヲサヲサヲサヲサスヲサアヲサ
ヲサヲサヲサヲサヲサヲサヲサヲサロモンヲサを生成
ヲサヲサヲサヲサ
ヲサヲサヲサヲサヲサヲサヲサヲサヲサヲサコスヲサアヲサヲサモュアヲサ
ヲサヲサヲサヲサヲサヲサヲサヲサヲサヲサヲサヲサロンヲサォヲサミィモュャヲサュアゥヲサを生成

スススススススススススススススススススススススススススススススススススススススス
ニコ 
トコ イーアエッーオッアエィ水ゥ アウコイエコーオ  書込者ノト:ロ 」 ァ」ハノ

 ン

おっと、合計値ヲサ要素数ヲサになったら分割不可能なので、ループの停止条件は
×ヲサヲサヲサコスヲサアヲサヲサモュアヲサ
○ヲサヲサヲサコスヲサアヲサヲサモュヲサ
ですね。
スススススススススススススススススススススススススススススススススススススススス
ニコ 
トコ イーアエッーオッアエィ水ゥ アオコイオコエキ  書込者ノト:ロ 」 ァ」ハノ

 ン

言いっ放しも何なので実コードにしてみました。
で、実際に動かしてみたら終了条件がまだ微妙に間違っていたので訂正。

ヲサミモィヲサコヲサヲサヲサテサヲサコヲサノサヲサモャヲサコヲサテゥサ

ヲサヲサコヲサテサ

ヲサヲサヲサヲサヲサスヲサーヲサ
ヲサヲサヲサヲサナ
ヲサヲサヲサヲサヲサスヲサアヲサ
ヲサヲサ
ヲサヲサヲサヲサロンヲサコスヲサモサ
ヲサヲサヲサヲサッッヲサこれで組み合わせが一つ分完成したので出力
ヲサヲサヲサヲサ゜ィゥサ
ヲサヲサ
ヲサヲサ
ヲサヲサ
ヲサヲサヲサヲサヲサヲサコスヲサアヲサヲサモヲサュヲサヲサォヲサアヲサ
ヲサヲサヲサヲサ
ヲサヲサヲサヲサヲサヲサロンヲサコスヲササ
ヲサヲサヲサヲサヲサヲサミモィャヲサヲサォヲサアャヲサモヲサュヲサャヲサヲサュヲサアゥサ
ヲサヲサヲサヲササ
ヲサヲササ

入口はこんな風にして呼び出します。
ヲサミィモャヲサコヲサテゥサ

ヲサヲサコヲサヲサヲサテサ

ヲサヲサモフィャヲサゥサヲサッッヲサ作業結果をしまっておく配列を用意してョョョ
ヲサヲサミモィャヲサーャヲサモャヲサゥサヲサッッヲサ最初の一発を呼び出す

スススススススススススススススススススススススススススススススススススススススス
ニコ えみ
トコ イーアエッーオッアエィ水ゥ アカコークコーケ シ  スュアセシ中級者セ シッニセシノヘヌ ス「コッッョョョッッイョ「 ス「ー「セ 書込者ノト:ロ ・ゥァ、、   ン

コードまで載せて頂いてありがとうございます!
なんとか期待通りの結果が出力出来そうです。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加