質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

1回答

906閲覧

Java 動的計画法を使ってナップサック問題を解く

keyakizaka17

総合スコア8

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

0クリップ

投稿2018/07/04 10:13

前提・実現したいこと

javaを使ってなってナップサック問題を動的計画法を使用して解きたいです
データはcsvファイルから取りこむ形で、重さw[],価値v[]に格納して計算しようとしています。

発生している問題・エラーメッセージ

まずなぜこのような結果が表示されているのかわかりません。
また、実行時間はほかのメソッドで違う手法で計算してその計算時間も出しているのですが、それに依存して同じ時間が表示されている状況です。

動的計画法で解いた場合 [I@1b6d3586番目の組み合わせが最適解 実行時間... time: 41241.268756 ms.

該当のソースコード

メソッドと出力のところが違うと考えています
また、 sol = dp(b); // 動的計画法のメソッドの呼び出しと最適値の受け取り
の部分の**(b)の部分もおかしいです**。。

java

1import java.io.*; 2public class Knupsuq5 { 3 static final int N = 20; // 製品数 4 static final int W = 15;// 重量上限 5 static int[] w = new int[N]; // 製品iの重量 6 static int[] v = new int[N]; // 製品iの価値 7 static int[] b = new int[N]; // 入れるか入れないかの0-1変数 8 static int i = 0; 9 static int[][] dp=new int[w.length+1][W+1]; 10static int dp(int []bootlearn){ 11 int ret = 0; 12 for (int i = 0; i < w.length; i++) { 13 for (int j = 0; j <= W; j++) { 14 if (w[i] <= j) { 15 dp[i + 1][j] = Math.max(dp[i][j], dp[i][j - w[i]] + v[i]); 16 ret = Math.max(ret, dp[i + 1][j]); 17 } else { 18 dp[i + 1][j] = dp[i][j]; 19 } 20 } 21 for(int j=0;j<N;j++) { 22 bootlearn[j]=dp[i][j]; 23 System.out.println(); 24 return dp[0][0]; 25 } 26 } 27 return ret; 28 } 29public static void main(String[] args) { 30 // TODO 自動生成されたメソッド・スタブ 31 String str; 32 i = 0; 33 int sol; 34 String[] s = {"詰めない", "詰める"}; // 解表示用文字列 35 // データの読み込み 36 try{ 37 File data = new File("C:\data.csv"); 38 BufferedReader br = new BufferedReader(new FileReader(data)); 39 while((str = br.readLine()) != null){ 40 String[] st = str.split(",", 0); 41 w[i] = Integer.parseInt(st[0]); 42 v[i] = Integer.parseInt(st[1]); 43 System.out.printf("%2d %2d %2d\n",i, w[i], v[i]); 44 i++; 45 } 46 }catch(FileNotFoundException e){ 47 System.out.println("ファイルが見つかりませんでした."); 48 }catch(IOException e){ 49 System.out.println("入出力でエラーが発生しました"); 50 } 51 52// 動的計画法で解く場合 53 System.out.println("動的計画法で解いた場合"); 54 t0 = System.nanoTime(); 55 sol = dp(b); // 動的計画法のメソッドの呼び出しと最適値の受け取り 56 System.out.println(dp[0] + "番目の組み合わせが最適解"); 57 System.out.printf("実行時間...%ntime: %f ms.%n", time/1000000.0); 58 59 } 60 61 62 }

最後に・・・

javaを使ってのプログラムプログラムは約1年ぶりのため忘れていることも多いです。なので訳のわからないコードになっていると思われますが
回答をよろしくお願いします。

補足情報(FW/ツールのバージョンなど)

開発環境はequlipseを使っています。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

shiron46

2018/07/04 11:54

貼られたコードが古かったりしないでしょうか?コンパイルエラーはありますし、dpメソッドはほとんどループせずに抜けているので40秒もかかるコードには見えませんが…
keyakizaka17

2018/07/04 13:31

コードは古いはずはないんですけどもなぜこんなに時間がかかるのかもわかりません。これを実装する前に別の解法のものでやりましたが0.4秒程度でできたのでやはりこのメソッド自体が悪い可能性がありますよね?
shiron46

2018/07/04 15:29 編集

そうですか…。では本コードについて、怪しそうな箇所を回答に追記しておきます。
guest

回答1

0

ベストアンサー

現時点で分かっている箇所について回答しておきます。

まずなぜこのような結果が表示されているのかわかりません。

原因は↓です。

Java

1 static int[][] dp=new int[w.length+1][W+1]; 2 // (中略) 3 System.out.println(dp[0] + "番目の組み合わせが最適解");

dpは2次元配列ですが、1次元分しかインデックスを指定していないためです。


以下は見直し方が良さそうな箇所です。

  • dpメソッド内のループ条件

特に下記のコードは問題があります。
-- ループに入ると無条件でreturnしてしまいます。
-- 配列dp の2次元目は大きさW(15)ですが、N(20)までループさせようとしています。

Java

1 for(int j=0;j<N;j++) { 2 bootlearn[j]=dp[i][j]; 3 System.out.println(); 4 return dp[0][0]; 5 }

 

参考URL

pieceofnostalgy.blogspot.com/2013/12/01.html

投稿2018/07/04 12:00

編集2018/07/05 10:22
shiron46

総合スコア111

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

keyakizaka17

2018/07/04 13:34 編集

ご丁寧な回答を ありがとうございます。 そのやり方で 少し考えてみます!
keyakizaka17

2018/07/05 03:57

なるほど! 最初の設定と処理ががずれてるとことですね もう一回考察してみます。 わかりやすい回答をありがとうございます! もしよければshiron46さんであれば どういう風にこの問題を解くか教えていただけませんでしょうか?
shiron46

2018/07/05 10:20

すみません、コードを読み間違えていました。ナップサックの残容量は考慮されていますね。 回答は修正しておきます。 問題を解く方針は同じになると思いますが、重さと価値をもつ製品クラスは作ります。 回答に追記した参考URLに詳しい解説およびJavaのサンプルコードが載っていますので、ぜひ参考にしてみてください。
keyakizaka17

2018/07/06 03:26

ありがとうございます なんとか行けそうな気がします! ご丁寧に回答をありがとうございました! あと3日他の方のコメントがなければベストアンサーにさせていただきます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問