DP(Dynamic Programming)をVue3.0 With TS & PrimeVUEで視覚化する

DP(Dynamic Programming)をVue3.0 With TS & PrimeVUEで視覚化する

やること

典型的な動的計画法(Dynamic Programming)を使うナップサック問題をVue3.0の学習がてら視覚化していく

技術

  • Vue3.0
  • TypeScript
  • PrimeVUE
PrimeVUE

PrimeVUEはVue3.0に対応しており、良さげだったので使用。

あとせっかくなのでVueのCompositon APIで書いてみた。

余談:

Vue3.0のビルドが早くて驚いた。

また、Compositon APIを使うことにより型が厳密に定義できとても良いなと感じた。

ナップサック問題

ナップサック問題 - Wikipedia

今回のナップサックにつめこむ対象はこれら、

※Maxの重量は5とする

JavaScript

nup: [          
  { w: 2, v: 3 },
  { w: 1, v: 2 },
  { w: 3, v: 4 },
  { w: 2, v: 2 },
],
// w = weight
// v = 
valuemax_weight = 5;

愚直に再帰で全探索をするとO(2^n)かかってしまう。

そこで下記のような漸化式を作成し、

wikipediaより

今回は上(indexが小さい)から計算してくので漸化式は

JavaScript

dp[0][j] = 0
dp[i+1][j] {
  dp[i][j] (j < nup[i].w)
  max(dp[i][j], dp[i][j-num[i].w] + nup[i].v)
}

このようになる。

こうすることによりO(nW)で計算ができるようになる。

C++で書くとこんな感じ

C++
void solve() {
  for (int i=0;i<n;i++) {
    for (int j=0; j<=totalWeight; j++) {
      if (j < weight[i]) {
        dp[i+1][j]=dp[i][j];
      } else {
        dp[i+1][j]=max(dp[i][j], dp[i+1][j-weight[i]] + value[i]);
      }
    }
  }
  cout << dp[n][totalWeight] << endl;
}

これにSleepを入れ、画面上に計算の過程を色を付けて示すようにした。

作ったもの

GitHub - kooooohe/dp-vue3.0-primeviue
Contribute to kooooohe/dp-vue3.0-primeviue development by creating an account on GitHub.

PrimeVUEのDataTabelの仕様上、DPテーブル等ちょっとわかりにくくイレギュラーな形になっているが、ご愛嬌、ということで

そのうち拡張して、荷物の重さや価値、許容重量を決めれるようにして、いろいろと試せるようにしていく予定である

Gif

DPや再帰処理はなれるまで紙に書いたり動きを1つ1つ追って理解する必要があった。

初見の際は難しく感じたが、実際に動きを見れてしまえば単純なもので、アルゴリズムというのはやはり楽しいなと感じた。

おすすめ本

プログラミングコンテストチャレンジブック [第2版] ~問題解決のアルゴリズム活用力とコーディングテクニックを鍛える~ | 秋葉 拓哉, 岩田 陽一, 北川 宜稔 | 工学 | Kindleストア | Amazon
Amazonで秋葉 拓哉, 岩田 陽一, 北川 宜稔のプログラミングコンテストチャレンジブック [第2版] ~問題解決のアルゴリズム活用力とコーディングテクニックを鍛える~。アマゾンならポイント還元本が多数。一度購入いただいた電子書籍は、KindleおよびFire端末、スマートフォンやタブレットなど、様々な端末でもお楽しみいただけます。

Amazon.co.jp: なっとく!アルゴリズム eBook : アディティア・Y・バーガバ, 株式会社クイープ, 株式会社クイープ: 本
Amazon.co.jp: なっとく!アルゴリズム eBook : アディティア・Y・バーガバ, 株式会社クイープ, 株式会社クイープ: 本