謎のコアダンプ

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

謎のコアダンプ

#1

投稿記事 by taka5216 » 8年前

現在シンプレックス法のプログラムを作成中です。
以下のプログラムを書いたのですが、どうしても関数pipot中のd[j]を扱うタイミングでコアダンプが起きてしまいます。
原因をだいぶ考えたり検索したりしたのですが、わかりません。
どなたかお力添えいただけないでしょうか。

コード:

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

float z=0,w=0;

int check(float *d,int yoko){
	int j;
	for(j=1;j<=yoko;j++){
		if(d[j]<0){
			return 1;
		}else{
			return 0;
		}
	}
}

void read(float **a,float *b,float *c,float *d,int tate,int yoko)
{
	int i,j;
	for(i=1;i<=tate;i++){
		for(j=1;j<=yoko;j++){
			printf("タブロー表の値a[%d][%d]を入力してください:",i,j);
			scanf("%f",&a[i][j]);
		}
		printf("定数b[%d]を入力してください:",i);
		scanf("%f",&b[i]);
	}
	for(j=1;j<=yoko;j++){
		printf("目的関数の%d番目の係数c[%d]を入力してください:",j,j);
		scanf("%f",&c[j]);
	}
	for(j=1;j<=yoko;j++){
		printf("wの式の%d番目の係数w[%d]を入力してください:",j,j);
		scanf("%f",&d[j]);
	}
	printf("wの定数を入力してください:");
	scanf("%f",&w);
}

void pipot(float **a,float *b,float *c,float *d,int tate,int yoko,int s,int r){
	int i,j;
	double oa[tate][yoko],ob[tate],cs,ds,oz,ow;
	for(i=1;i<=tate;i++){
		for(j=1;j<=yoko;j++){
			oa[i][j]=a[i][j];
		}
		ob[i]=b[i];
	}printf("test\n");
	cs=c[s];printf("test\n");
	ds=d[s];printf("test\n");
	oz=(-1)*z;
	ow=(-1)*w;

	for(j=1;j<=yoko;j++){
		a[r][j]=oa[r][j]/oa[r][s];
	}
	b[r]=ob[r]/oa[r][s];printf("%f",oa[r][s]);
	printf("\n\n");
	for(i=1;i<=tate;i++){
		if(i!=r){
			for(j=1;j<=yoko;j++){
				a[i][j]=oa[i][j]-oa[i][s]*a[r][j];
			}
			b[i]=ob[i]-oa[i][s]*b[r];
		}
	}
	for(j=1;j<=yoko;j++){
		c[j]=c[j]-cs*a[r][j];
		d[j]=d[j]-ds*a[r][j];
	}
	z=(-1)*oz-cs*b[r];
	w=(-1)*ow-ds*b[r];
}

void simplex(float **a,float *b,float *c,float *d,int tate,int yoko)
{
	float minc=0,minba=0;
	int s,r,i,j,finish=0;

	while(1){
		if(finish==1){
			break;
		}
		finish=1;
		minc=0;
		minba=0;

		if(check(d,yoko)){
		for(j=1;j<=yoko;j++){
			if(d[j]<0 && minc>d[j]){
				finish=0;
				minc=d[j];
				s=j;
			}
		}

		if(finish==1){
			break;
		}

		for(i=1;i<=tate;i++){
			if(a[i][s] > 0){
				if(minba==0 || minba>b[i]/a[i][s]){
					minba=b[i]/a[i][s];
					r=i;
					finish=0;
				}
			}
		}

		if(finish==1){
			printf("最小値が有界ではありません\n");
			break;
		}
		}else{
		for(j=1;j<=yoko;j++){
			if(c[j]<0 && minc>c[j]){
				finish=0;
				minc=c[j];
				s=j;
			}
		}

		if(finish==1){
			break;
		}

		for(i=1;i<=tate;i++){
			if(a[i][s] > 0){
				if(minba==0 || minba>b[i]/a[i][s]){
					minba=b[i]/a[i][s];
					r=i;
					finish=0;
				}
			}
		}

		if(finish==1){
			printf("最小値が有界ではありません\n");
			break;
		}
		}

			printf("\n");
	for(i=1;i<=tate;i++){
		for(j=1;j<=yoko;j++){
			printf("%f  ",a[i][j]);
		}
		printf("%f\n",b[i]);
	}
	for(j=1;j<=yoko;j++){
		printf("%f  ",c[j]);
	}
	printf("%f\n",z);
	for(j=1;j<=yoko;j++){
		printf("%f  ",d[j]);
	}
	printf("%f\n",w);
printf("r=%d s=%d\n",r,s);

		pipot(a,b,c,d,tate,yoko,s,r);

	}
}

int main(void){
	float **a=NULL,*b=NULL,*c=NULL,*d=NULL,**pp;
	int tate,yoko,N,i,j;

	printf("制約式の数を入力してください:");
	scanf("%d",&tate);
	printf("タブロー表の変数の総数を入力してください:");
	scanf("%d",&yoko);

	if(tate>=yoko){
		N=tate;
	}else{
		N=yoko;
	}

	a=(float **)malloc(N*sizeof(float *));
	*a=(float *)malloc(N*N*sizeof(float));
	b=(float *)malloc(tate*sizeof(float));
	c=(float *)malloc(yoko*sizeof(float));
	d=(float *)malloc(yoko*sizeof(float));
    for(pp=a,i=1;i<=N;i++,pp++){
		*(pp+1)=*pp+N;
    }

	read(a,b,c,d,tate,yoko);

	simplex(a,b,c,d,tate,yoko);

			printf("\n");
	for(i=1;i<=tate;i++){
		for(j=1;j<=yoko;j++){
			printf("%f  ",a[i][j]);
		}
		printf("%f\n",b[i]);
	}
	for(j=1;j<=yoko;j++){
		printf("%f  ",c[j]);
	}
	printf("%f\n",z);
	printf("\nZ=%f\n",z);

	return 0;
}

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

Re: 謎のコアダンプ

#2

投稿記事 by box » 8年前

taka5216 さんが書きました: 以下のプログラムを書いたのですが、どうしても関数pipot中のd[j]を扱うタイミングでコアダンプが起きてしまいます。

コード:

void pipot(float **a,float *b,float *c,float *d,int tate,int yoko,int s,int r){
	int i,j;
	double oa[tate][yoko],ob[tate],cs,ds,oz,ow;
このように定義した配列oa[][]において、有効な(アクセスしてもよい)添字の範囲は、
それぞれ0~tate-1, 0~yoko-1
です。
taka5216 さんが書きました:

コード:

	for(i=1;i<=tate;i++){
		for(j=1;j<=yoko;j++){
			oa[i][j]=a[i][j];
アクセスしてはいけない場所にアクセスしているように見えます。
pipot(本当はpivotが正しい?)以外の関数でも同じようなことをしているように見えます。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

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

Re: 謎のコアダンプ

#3

投稿記事 by box » 8年前

私だったら、

コード:

for (i = 1; i <= tate; i++)
を、すべて

コード:

for (i = 0; i < tate; i++)
とします。同様に、

コード:

for (j = 1; j <= yoko; j++)
を、すべて

コード:

for (j = 0; j < yoko; j++)
とします。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

閉鎖

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