度数を計算

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

度数を計算

#1

投稿記事 by 大学生 » 8年前

授業の課題なのですが(11)の到着時間間隔とサービス時間の各階級の度数を計算するという問題なのですが
実行した結果
合計=3464.000000
合計=3048.000000
平均値(到着時間間隔)=69.280000
平均値(サービス時間間隔)=60.960000
標準偏差(A)=66.113397
標準偏差(S)=23.816441
最大値=264.000000(A) 115.000000(S)
最小値=1.000000(A) 6.000000(S)
階級幅=26(rA) 10(rS)
階級幅=26
変動係数=0.910675(A) 0.152638(s)
位相=1(A) 6(S)
位相=1.000000(kar) 6.000000(ksv)
下限値-上限値《到着時間間隔》=(A)
0-25
26-51
52-77
78-103
104-129
130-155
156-181
182-207
208-233
234-259
260-285
下限値-上限値《サービス時間》=(S)
0-9
10-19
20-29
30-39
40-49
50-59
60-69
70-79
80-89
90-99
100-109
110-119
階級値(A)
12
38
64
90
116
142
168
194
220
246
272
階級値(S)
4
14
24
34
44
54
64
74
84
94
104
114
度数(A)
1
13
5
8
2
1
3
1
1
1
1
度数(S)
1
4
2
5
5
1
3
2
4
2
3
0
となります。正しい結果としては
   度数(A) 度数(S)
14 1
13 2
5 2
8 2
2 6
1 7
3 14
1 7
1 3
1 3
1 1
2
となるはずなのですが適切に表示されません
先生に相談したところ等号?不等号?
検査対象が下限値と上限値と同じ数だったら,このアルゴリズムだと弾かれるよね?
と言われましたがよく意味がわかりません・・・
お願いします

/* -*-coding: utf-8-*- */
#include <stdio.h>
#include <math.h>

/* ==実験で用いる定数を定義する== */
/* #define_記号定数_文字列 */
/* プログラムの中で共通して使う値は,この位置で単純マクロとして宣言しておく */
/* →実験条件に応じて,数値は各自で変更すること */
#define R 2 /* データ列の数:本実験では「到着時間間隔」と「サービス時間」の2列が必要 */
#define G 50 /* データ(行)数:本実験ではサンプルプログラムは50人分,各自のデータは55人分 */
#define N 10 /* 度数分布表の階級の数 */
#define RG 5 /* 階級の数の調整量(必要に応じて変更) */
#define RP 50 /* モンテカルロ・シミュレーションでのシミュレーション回数:レポートでは55回,550回,5500回のシミュレーションをおこなう */
#define SA 20207 /* 到着時間間隔用の乱数の種 */
#define SS 912 /* サービス用の乱数の種 */

int main(void)
{
/*【解説1】 変数の型を宣言する */
/* →計算に必要な変数は自分で宣言すること */
/* →下に示した変数だけでは足りないので注意すること */
int i, kA, kS, rA, rS, m, n, Acnt[N+RG], Scnt[N+RG], RAcnt[N+RG][R], RScnt[N+RG][R], Asum[N+RG], Ssum[N+RG];
double sumA, sumS, avgA, avgS, devA, devS, dev_sumA, dev_sumS, stdA, stdS, cA, cS, kt, dataA[R], dataB[R];/*dataA[R]は下限値*/

/* ==一般変数を初期化する== */
sumA=0.0;
sumS=0.0;
dev_sumA=0.0;
dev_sumS=0.0;
/* ==配列変数を初期化する== */
for(i=0;i<N+RG;i++)
{
Asum=0;
Ssum=0;
}
int l;
for(i=0;i<N+RG;i++){
for(l=0;l<R;l++){
RAcnt[l]=0;
RScnt[l]=0;
}
}

/*【解説3】 解析の準備 */
/* 後の計算のため,データはダブル型で読み込んでおくこと! */
/* サンプルデータは50個,レポートでは55個のデータを用いる */
/* arrivalは到着時間間隔,serviceはサービス時間のこと */

static double arrival[G]= {11,109,171,7,46,243,101,151,8,51,213,71,195,121,34,6,39,82,161,39,68,7,27,40,83,102,98,11,68,11,264,6,37,82,160,40,67,8,26,40,12,3,1,36,47,1,73,85,96,6};
static double service[G]={ 68,70,47,70,41,32,40,25,13,61,92,51,70,36,69,71,48,70,41,25,13,61,82,51,66,55,108,97,64,61,6,56,79,110,65,60,61,82,58,85,52,44,55,78,115,64,61,61,98,60};

/*解析的アプローチの実践*/

/*== 3.1 解析的アプローチ ==*/
/*== (1) 変動係数を用いた方法の準備 ==*/
/* 各パラメータは到着時間間隔とサービス時間それぞれに対して算出すること */

/*【解説4】 (1) 基本統計量 */
/* 合計,平均値,標準偏差,最大値,最小値,階級幅,変動係数,位相を求め,表1にまとめる */
/* 有効数字,有効桁数に注意すること */


/* (1) 到着時間間隔とサービス時間の合計を算出 */
/* 例:1から10までの和を求める
int k, N;
double sum;
sum = 0.0;
N = 10;
for (k = 1;k <= N; k++)
sum = sum + k; */
int k,j;
/* (1) 到着時間間隔とサービス時間の合計を算出 */
for(k=0;k<50;k++)
devA+=arrival[k];/*devA,devSが合計*/

for(j=0;j<50;j++)
devS+=service[j];
printf("合計=%f\n", devA);
printf("合計=%f\n", devS);
/* (2) 到着時間間隔とサービス時間の平均値を算出 */
/* →ヒント:変数の型に注意すること!(int型÷double型,等) */
/* キャスト演算子を応用する */
/* s = sqrt(double)N); ← s はdouble型 */
/* S= (int)s; ←Sはint型 */
/* 到着時間隔の平均値は平均到着時間間隔 */
/* サービス時間の平均値は平均サービス時間 */
avgA=0.0;
avgS=0.0;
avgA=devA/(double)G;/*平均時間間隔*/
avgS=devS/(double)G;/*平均サービス時間*/

printf("平均値(到着時間間隔)=%f\n", avgA);
printf("平均値(サービス時間間隔)=%f\n", avgS);

/*avgA,avgSが平均値*/

/* (3) 到着時間間隔とサービス時間の標準偏差を計算(今回は母標準偏差なので"n-1"で割る) */
/* →ヒント:stdS = sqrt(dev_sumS/((double)i-1)); */
stdA=0.0;
stdS=0.0;
for(i=0;i<G;i++){
dev_sumA += (arrival-avgA)*(arrival-avgA);
dev_sumS += (service-avgS)*(service-avgS);
}
dev_sumA = dev_sumA/(double)(i-1);
dev_sumS = dev_sumS/(double)(i-1);
/*分散の計算(dev_sumA,dev_semSが分散)*/

stdA =sqrt(dev_sumA);
stdS = sqrt(dev_sumS);
printf("標準偏差(A)=%f\n", stdA);
printf("標準偏差(S)=%f\n", stdS);/*stdA,stdSが標準偏差*/

/* (4) 到着時間間隔とサービス時間の最大値と最小値を算出する */
/* →ヒント:十分に小さい数(maxA = 0.0; maxS = 0.0;)と十分に大きい数(minA = 9999.0; minS = 9999.0;)と比較すればよい */
double maxA=0.0;
double maxS=0.0;
double minA=9999.0;
double minS=9999.0;
for(i=0;i<G;i++){
if(maxA<arrival)
maxA=arrival;
}

for(i=0;i<G;i++){
if(maxS<service[i])
maxS=service[i];
}
for(i=0;i<G;i++){
if(minA>arrival[i])
minA=arrival[i];
}
for(i=0;i<G;i++){
if(minS>service[i])
minS=service[i];
}


printf("最大値=%f(A) %f(S)\n", maxA, maxS);
printf("最小値=%f(A) %f(S)\n", minA, minS);
/* (5) 到着時間間隔とサービス時間の階級幅を決定する */
/* →ヒント:rA = (maxA-minA)/N; とする */
/* 階級幅の小数点以下の値は切り捨てて,整数にする ← 上記 (2)を参考に! */
rA = (int)(maxA-minA)/N;
rS = (int)(maxS-minS)/N;
printf("階級幅=%d(rA) %d(rS)\n", rA, rS);
int A =rA;
printf("階級幅=%d\n", A);

/* (6) 到着時間間隔とサービス時間の変動係数c 2を算出 */
/* →ヒント:p.63ページ(1)の式(4.42) */
cA = dev_sumA/(avgA*avgA);
cS = dev_sumS/(avgS*avgS);

printf("変動係数=%f(A) %f(s)\n", cA, cS);

/* (7) 到着時間間隔とサービス時間の位相kをint型で算出 */
/* 到着時間間隔とサービス時間それぞれに対して算出する */
/* cAとcSはdouble型,kAとkSはint型 */
/* →ヒント:p.63(1)の式(4.46)を変形すればよい */
/* →ヒント:キャスト演算子を用いる kt = 1/cA; */
/* →ヒント:キャスト演算子を用いる kA = (int)kt; */
double ko;
kt = 1/cA;
kA = (int)kt;

ko = 1/cS;
kS = (int)ko;

printf("位相=%d(A) %d(S)\n", kA, kS);

/* (8) 到着時間間隔とサービス時間の位相kをdouble型に変換する */
/* 到着時間間隔とサービス時間それぞれに対して算出する */
/* →ヒント:キャスト演算子を用いる k = ((double)kA); */
double kar,ksv;
kar =((double)kA);
ksv = ((double)kS);

printf("位相=%f(kar) %f(ksv)\n", kar, ksv);



/*== (2) ヒストグラムを用いた方法(p.63)の準備 ==*/
/* 各パラメータは到着時間間隔とサービス時間それぞれに対して算出すること */



/*【解説5】 (2) 度数分布表=>(3) ヒストグラム */
/* 階級(上限値と下限値),階級値,度数,累積度数を求め,表2,表3にまとめる */
/* プログラムと連動させる必要はない(習っていない) */

/* (9) 到着時間間隔とサービス時間の階級(上限値と下限値)を設定する */
/* →ヒント:Arange[0][0]=0.0; */
/* Arange[1][0]=Arange[0][0]+rangeA-1.0; */


/*for(i=0;i<N+1;i++){
RAcnt[i][0]=RAcnt[i][0]+rA-1;
RAcnt[i+1][0]=RAcnt[i][i]+1;
}*/

printf("下限値-上限値《到着時間間隔》\n");
for(i=1;i<N+1;i++){
RAcnt[i][0]=RAcnt[i-1][0]+A;
RAcnt[i][1]=RAcnt[i][0]+RAcnt[i][1]+A-1;
}
printf("%d-%d\n", RAcnt[0][0], RAcnt[1][0]-1);
for(i=1;i<N+1;i++)
printf("%d-%d\n", RAcnt[i][0], RAcnt[i][1]);

printf("下限値-上限値《サービス時間》\n");
for(i=1;i<N+2;i++){
RScnt[i][0]=RScnt[i-1][0]+rS;
RScnt[i][1]=RScnt[i][0]+RScnt[i][1]+rS-1;
}
printf("%d-%d\n", RScnt[0][0], RScnt[1][0]-1);
for(i=1;i<N+2;i++)
printf("%d-%d\n", RScnt[i][0], RScnt[i][1]);



/* (10) 到着時間間隔とサービス時間の階級値を設定する */
/* →ヒント:各階級の下限値と上限値の中央値(中間値)のこと */
/* 中央値の"0.5"は切り捨てておくと,後の計算が楽になる ←(2)を参考に! */
int t,h=0;
printf("階級値(A)\n");
printf("%d\n", (RAcnt[0][0]+RAcnt[1][0]-1)/2);
for(i=1;i<N+1;i++){
t=(int)(RAcnt[i][0]+RAcnt[i][1])/2;
printf("%d\n", t);
}
printf("階級値(S)\n");
printf("%d\n", (RScnt[0][0]+RScnt[1][0]-1)/2);
for(i=1;i<N+2;i++){
h=(int)(RScnt[i][0]+RScnt[i][1])/2;
printf("%d\n", h);
}


/* (11) 到着時間間隔とサービス時間の各階級の度数を計算する */
/* →ヒント: if(data[0][n]>=Arange[0][i] && data[0][n]<=Arange[1][i]) */
/* Acnt[i]++; */

Acnt[0]=0;

for(j=0;j<N+1;j++){
Acnt[j]=0;
for(i=0;i<=G;i++){
if(arrival[i]>=RAcnt[j][0] && arrival[i]<=RAcnt[j][1]){
Acnt[j]++;
}
}
}

printf("度数\n");
for(i=0;i<N+1;i++)
printf("%d\n", Acnt[i]);


for(j=0;j<N+2;j++){
Scnt[j]=0;
for(i=0;i<=G;i++){
if(arrival[i]>=RScnt[j][0] && arrival[i]<=RScnt[j][1]){
Scnt[j]++;
}
}
}

printf("度数\n");
for(i=0;i<N+2;i++)
printf("%d\n", Scnt[i]);
return 0;
}

アバター
purin52002
記事: 235
登録日時: 8年前
連絡を取る:

Re: 度数を計算

#2

投稿記事 by purin52002 » 8年前

RAcnt[j][0]が最小値で、RAcnt[j][1]が最大値を表しているなら間違っていないような気がします。
どこか別の部分で間違えていたりして、、、?
あと正しい出力だと度数Aは12個出力されていますが間違った出力では11個出力されています。
オフトピック
プログラムが見づらいです^^;
codeタグで囲むと見やすくなるので、今後プログラムを張ることがあれば囲ってください^^
c++初心者を自負しています。
質問者さんには今後私にプログラミングを教えてくれるようにやさしく丁寧に教えるつもりです。ぎぶあんどていく^p^
回答者さんには精一杯感謝します。ぎぶおんりー^p^

白い変人

Re: 度数を計算

#3

投稿記事 by 白い変人 » 8年前

先生の言う「検査対象が下限値と上限値と同じ数だったら,このアルゴリズムだと弾かれるよね?」というのは、

例えば、データ10~10の範囲(すなわち10の値を持つ要素)の度数を求めたい場合に、

data=10;

if(data>10 && data<10) {カウント処理}

の様に書いたら、そのデータはカウントされないよね?

という話かと私は思いました。


質問者様のコードが動作しなかった上、ぱっと見た感じよく分からなかった為、適当に度数の部分だけ私が全部書いてみたら、そもそも、質問者様の正しいとする解とも違った結果が出て来ました。

私の認識が違っているような気もしてきましたので、一旦ROMりますが、参考までに私が適当に書いたコードと結果は置いていきます。

コード:

#include <stdio.h>

#define G 50

int arrival[]={11,109,171,7,46,243,101,151,8,51,213,71,195,121,34,6,39,82,161,39,68,7,27,40,83,102,98,11,68,11,264,6,37,82,160,40,67,8,26,40,12,3,1,36,47,1,73,85,96,6};
int service[]={68,70,47,70,41,32,40,25,13,61,92,51,70,36,69,71,48,70,41,25,13,61,82,51,66,55,108,97,64,61,6,56,79,110,65,60,61,82,58,85,52,44,55,78,115,64,61,61,98,60};

const int HISTGRAM_A[]={-1,25,51,77,103,129,155,181,207,233,259,285,-1};
const int HISTGRAM_S[]={-1,9,19,29,39,49,59,69,79,89,99,109,119,-1};

int get_result(int *data,int *histgram,int index){
	int i;
	int sum=0;
	
	for(i=0;i<G;i++) if(data[i]>histgram[index-1] && data[i]<=histgram[index]) sum++;
	
	return sum;
}

int main(void){
	int i;
	
	printf("\n度数A");
	
	for(i=1;HISTGRAM_A[i]>0;i++) printf("\n%d",get_result(arrival,HISTGRAM_A,i));
	
	printf("\n\n度数S");
	
	for(i=1;HISTGRAM_S[i]>0;i++) printf("\n%d",get_result(service,HISTGRAM_S,i));
	
	return 0;
}
度数A
14
13
5
8
2
1
3
1
1
1
1

度数S
1
2
2
2
6
7
14
7
3
3
1
2

返信

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