ナップサック問題での疑問です

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
dpkp

ナップサック問題での疑問です

#1

投稿記事 by dpkp » 14年前

『価格の合計を最大化するナップサック問題をDPで解く関数 solveMax を作成せよ』
という問題ですが、以下のような組み方をしたらセグメントエラーが起きてしまいました。


コード:


int solveMax(int limit, const Item *items, int n_items){
  long newvalue, value[limit+1];
  int item[limit+1],i,s,p;
  for(i=0;i<=9;i++)
  value[i]=0;

  printTableHead(limit);


  for(i=0;i<6;i++){
    for(s=items[i].size;s<=limit;s++){
      p=limit-s;
      newvalue=solveMax(p,items,n_items)+items[i].price;
      if(newvalue>value[s]){
	value[s]=newvalue;
	item[s]=i;
      }
printTableBody(*value, limit, *item) ;
    }
  }

}




またメインプログラム他関数ははじめから用意されており以下のデータ構造です

コード:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MIN 1

enum { MINIMIZE, MAXIMIZE };

typedef struct __Item {
	char *name;
	int size;
	int price;
} Item;

int solveMax(int limit, const Item *items, int n_items);
void printSolve(int limit, const Item *items, int *item, int *value);
void printTableHead(int limit);
void printTableBody(int *value, int limit, int *item);

int main(void) {
	Item items[]={
		{"plum", 4, 4500},
		{"apple", 5, 5700},
		{"orange", 2, 2250},
		{"strawberry", 1, 1100},
		{"melon", 6, 6700},
		{"grape", 3, 3400}
	};
	int limit = 8;
	int n_items = 6;
	int v;
	
	printf("Input Limit: ");
	scanf("%d", &limit);

	v = solveMax(limit, items, n_items);
}
//

// 最適解表示用
void printSolve(int limit, const Item *items, int *item, int *value) {
	int s, v;
	
	printf("     Items|  Price\n");
	printf("----------+-------\n");
	for(s = limit; s >= MIN; s = s - items[item[s]].size) {
		printf("%10s|%7ld\n", items[item[s]].name, items[item[s]].price);
	}
	printf("----------+-------\n");
	v = value[limit];
	printf("     Total|%7ld\n", v);
}

// テーブル表示用
void printTableHead(int limit) {
	int j;
	
	for (j = 1; j <= limit; j++) {
		printf("%7d|", j);
	}
	printf("\n");
	for (j = 1; j <= limit; j++) {
		printf("=======+");
	}
	printf("\n");
}

void printTableBody(int *value, int limit, int *item) {
	int j, v;
	
	for (j = 1; j <= limit; j++) {
		v = value[j];
		printf("%7d|", v);
	}
	printf("\n");
	for (j = 1; j <= limit; j++) {
		if (item[j] >= 0)
			printf("%7d|", item[j]);
		else
			printf("      -|");
	}
	printf("\n");
	for (j = 1; j <= limit; j++) {
		printf("-------+");
	}
	printf("\n");
}





OSはLinux コンパイラはgcc 期限は2/23までですよろしくお願いします。

beatle
記事: 1281
登録日時: 14年前
住所: 埼玉
連絡を取る:

Re: ナップサック問題での疑問です

#2

投稿記事 by beatle » 14年前

-Wallオプションをつけてgccでコンパイルし、出てきた警告をすべて解消するように頑張ってみましょう。
警告だからといって無視していると今回のようなバグに悩まされることになります。
$ gcc -Wall main.c

ちなみに、僕の環境でコンパイルした場合のコンパイラの出力は以下です。たくさん警告が出ていますね。

コード:

main.c: 関数 ‘main’ 内:
main.c:31:9: 警告: 変数 ‘v’ が設定されましたが使用されていません [-Wunused-but-set-variable]
main.c: 関数 ‘solveMax’ 内:
main.c:57:13: 警告: 1 番目の ‘printTableBody’ の引数へ渡すときに整数からキャスト無しにポインタを作成しています [デフォルトで有効]
main.c:18:6: 備考: expected ‘int *’ but argument is of type ‘long int’
main.c:57:13: 警告: 3 番目の ‘printTableBody’ の引数へ渡すときに整数からキャスト無しにポインタを作成しています [デフォルトで有効]
main.c:18:6: 備考: expected ‘int *’ but argument is of type ‘int’
main.c: 関数 ‘printSolve’ 内:
main.c:70:9: 警告: 書式 ‘%ld’ は引数の型が ‘long int’ であると予期されますが、第 3 引数の型は ‘int’ です [-Wformat]
main.c:74:5: 警告: 書式 ‘%ld’ は引数の型が ‘long int’ であると予期されますが、第 2 引数の型は ‘int’ です [-Wformat]
main.c: 関数 ‘solveMax’ 内:
main.c:61:1: 警告: 制御が非 void 関数の終りに到達しました [-Wreturn-type]
main.c: 関数 ‘main’ 内:
main.c:37:1: 警告: 制御が非 void 関数の終りに到達しました [-Wreturn-type]
この警告をヒントに修正を試みてください。ちょっと修正したらまたコンパイルして、警告が解消されているか、確認してまた修正を繰り返します。
それでもお手上げになったら、また質問してください。

box
記事: 2002
登録日時: 15年前

Re: ナップサック問題での疑問です

#3

投稿記事 by box » 14年前

与えられたコードをまねするなどして、インデント(字下げ)を適切に行なう方がいいのではないか、と思います。
dpkp さんが書きました:

コード:

  for(i=0;i<=9;i++)
  for(i=0;i<6;i++){
9とか6とかいう謎のような値は、何を意味しているのでしょうか。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

閉鎖

“C言語何でも質問掲示板” へ戻る