最早開始時間と最遅完了時刻を求めるプログラムをC言語で作成せよ

このQ&Aのポイント
  • 最早開始時間と最遅完了時刻を求めるプログラムをC言語で作成する課題に取り組んでいます。
  • しかし、プログラムがうまく動作していないようです。
  • どこが問題なのか、教えていただけませんか?
回答を見る
  • ベストアンサー

最早開始時間と最遅完了時刻を求めるプログラムをC言語で作成せよ、という

最早開始時間と最遅完了時刻を求めるプログラムをC言語で作成せよ、というものを学校の課題でやっているのですがうまく行きません。どこがおかしいのでしょうか。 内容としてはアローダイアグラムで表される業務についてです。所要日数は画像で記しておきました。 #include <stdio.h> int main() { int ES[7];//最早開始時刻 int LS[7];//最遅完了時刻 int i,j; //ループカウンタ int tmp; int node[7][7] = { {-1,5,-1,-1,-1,-1,-1},//1 {-1,-1,5,3,-1,-1,-1},//2 {-1,-1,-1,10,-1,12,-1},//3 {-1,-1,-1,-1,3,-1,-1},//4 {-1,-1,-1,-1,-1,0,3},//5 {-1,-1,-1,-1,-1,-1,6},//6 {-1,-1,-1,-1,-1,-1,-1}//7 }; for(i = 0;i <7;i++){ ES[i] = 0; LS[i] = 0; } //最早 for(j = 0;j <6;j++){ for(i = 0;i <6;i++){ if(node[i][j]==-1){ continue; }else{ tmp = node[i][j]+ES[i]; if(ES[j+1]==0){ ES[j+1]=tmp; }else{ if(ES[j+1]<tmp){ ES[j+1]=tmp; } } } } } printf("最早開始日\n"); for(i = 0;i <7;i++){ printf("[%2d] : %3d\n",i+1,ES[i]); } //最遅 LS[7] = ES[7]; for(i =6;i>-1;i--){ for(j =6;j>-1;j--){ if(node[i][j]==-1){ continue; }else{ tmp = LS[j+1]-node[i][j]; if(LS[i]==0){ LS[i]=tmp; }else{ if(LS[i]>tmp){ LS[i]=tmp; } } } } } printf("最遅完了日\n"); for(i = 0;i <7;i++){ printf("[%2d] : %3d\n",i+1,LS[i]); } return 0; } 最早開始日 [ 1] : 0 [ 2] : 5 [ 3] : 10 [ 4] : 20 [ 5] : 23 [ 6] : 23 [ 7] : 29 最遅完了日 [ 1] : 0 [ 2] : 5 [ 3] : 10 [ 4] : 20 [ 5] : 23 [ 6] : 23 [ 7] : 29 となるはずが、 最早開始日 [ 1] : 0 [ 2] : 0 [ 3] : 5 [ 4] : 5 [ 5] : 15 [ 6] : 8 [ 7] : 17 最遅完了日 [ 1] : -18 [ 2] : -14 [ 3] : -13 [ 4] : -9 [ 5] : -3 [ 6] : -6 [ 7] : 17 となってしまいます。

質問者が選んだベストアンサー

  • ベストアンサー
  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.3

最早開始日の定義を確認してみたら 結合点j での最早開始日は ESj=max_i{ESi + Pij} Pij: 結合点i→結合点jの所要時間 で、これを素直にプログラムにしたらその「正しい結果」になりました。 ESj=max_i{ESi+Pij]を計算するときに、 Pij=node[i][j], ESi=ES[i] としているのに、 ESj=ES[j+1] と jが変わってしまっているのが原因の一つです。 最遅完了日も同様です。 //最早 //i,jは全範囲 for(j = 0; j <7; j++) { for(i = 0; i <7; i++) { if(node[i][j]==-1) { continue; } // contiuneしたら続きは実行しないのだから、elseは不要 tmp = node[i][j]+ES[i]; // tmp >= 0 だから、ES[j]=0のときは、必ずmax(ES[j],tmp)=tmpになる if (ES[j]<tmp) { ES[j]=tmp; } } }

suzukiaen
質問者

お礼

回答ありがとうございます。参考になりました。 あと、結果を表示するところが終了条件のiの値が1つ足りてなかったことにも気がつきました。 おかげさまで解決できました。ありがとうございました。

その他の回答 (2)

回答No.2
suzukiaen
質問者

お礼

回答ありがとうございます。参考になりました。

  • asuncion
  • ベストアンサー率33% (2126/6286)
回答No.1

>int ES[7];//最早開始時刻 >int LS[7];//最遅完了時刻 この定義で >LS[7] = ES[7]; >tmp = LS[j+1]-node[i][j]; これはまずいです(後の方は、jが6のとき)。 配列の定義範囲外の領域にアクセスしています。

suzukiaen
質問者

お礼

回答ありがとうございます。 しかし回答を元にLS[7] = ES[7];をLS[6] = ES[6];に、for(j =6;j>-1;j--){をfor(j =5;j>-1;j--){に変えて再び実行しても正しい結果になりませんでした。

関連するQ&A

  • C言語でのじゃんけん

    こんちには。 C言語の乱数を用いてじゃんけんプログラムを作ろうと思っているのですが、 エラーメッセージが出てしまいうまくいきません。 どこがおかしいのでしょうか? #include <stdio.h> #include <stdlib.h> #include <time.h> int main(void) { int i,j,k; printf("じゃんけんをしましょう(ぐー:1、ちょき:2、ぱー:3)¥n"); for(k=k; k<=10; k++) { srand(time(NULL)); j=rand()%3+1; scanf("%d",&i); if(i==1&&j==1) printf("私はグーなので、あいこです¥n"); else if(i==1&&j==2) printf("私はチョキなので、あなたの勝ちです¥n"); else if(i==1&&j==3) printf("私はパーなので、あなたの負けです¥n"); else if(i==2&&j==1) printf("私はグーなので、あなたの負けです¥n"); else if(i=2&&j==2) printf("私はチョキなので、あいこです¥n"); else if(i==2&&j==3) printf("私はパーなので、あなたの勝ちです¥n"); else if(i==3&&j==1) printf("私はグーなので、あなたの勝ちです¥n"); else if(i==3&&j==2) printf("私はチョキなので、あなたの負けです¥n"); else if(i==3&&j==3) printf("私はパーなので、あいこです¥n"); else printf("1か2か3を入力してください¥n"); } } OS mountain lionで利用中ですが、 「じゃんけんをしましょう(ぐー:1、ちょき:2、ぱー:3)」 と表示されたまま、うまく動作しません。 教えてください。

    • ベストアンサー
    • Mac
  • C言語

    forの直後で1+2+3+4+5+・・・・・・・と加算し続ける式がわからないので教えてください。 #include<stdio.h> int main(void) { char moji; int i,sum; printf("正の整数を1から順に加算します。n\"); printf("加算を開始してよろしいですか。(Y=実行。N=終了)\n"); moji=getchar(); if(moji==y) { for(i=2;sum>=1001;i++) { この部分がわかりません; printf("加算値は%dです。¥n",sum); } }else if(moji=='n'){ printf("終了します。\n"); }else{ printf("YまたはNを入力してください。\n"); } return 0; }

  • C言語<素数を求めるプログラム>

    #include<stdio.h> int j; int prime(int n) { int i; if(n < 2) return 0; if(n == 2) return 1; if(n%2 == 0) return 0; for(i = 3; i*i<= n; i += 2){ if(n%i == 0) return 0; } return 1; } int main(void) { int n; for(n=1; n <= 1000; n++) { if(prime(n)){ printf("%d\n",n); j++; } } printf("素数の個数は全部で %d 件見つかりました。\n",j); return 0; } このプログラムは1から1000までの素数のみを表示させるプログラムでありますが、このアルゴリズムが全くわかりません。 int prime(int n)の中身のアルゴリズムがどういう仕組みになっているのかお分かりになりますでしょうか?

  • C言語のソートプログラム

    学校でプログラミングの課題が出たので自分のパソコンに Microsoft Visual C++ 2010 Express をインストールして作ってみました。 それが以下のプログラムです。 これは任意の値nを入力してa[n]までの配列をつくり それを降順に並び替えるものです。 #include <stdio.h> #define N 10000 int main(){ int a[N],i,j,max,min,n,temp; n=0; printf("n="); scanf("%d",&n); if(N<n){ return 0; } else if(n<=0){ return 0; } else if(n<=N){ for(i=0;i<n;i++){ printf("a[%d]",i); scanf("%d",&a[i]); } max=min=a[0]; for(i=1;i<n;i++){ if(max<a[i]){ max=a[i]; } else if(min>a[i]){ min=a[i]; } } printf("a[i]のソート結果\n"); for(i=0;i<n;i++);{ for(j=i+1;j<n;j++){ if(a[i]<a[j]){ temp=a[i]; a[i]=a[j]; a[j]=temp; } } } for(i=0;i<n;i++){ printf("a[%2d]=%d\n",i,a[i]); } printf("Max=%d\n",max); printf("Min=%d\n",min); } } これを実行すると 最初に入力した配列の順番のまま表示されてしまいます。 例えば n=4 a[0]7 a[1]4 a[2]6 a[3]1 a[i]のソート結果 a[0]7 a[1]4 a[2]6 a[3]1 のようにです。 しかしプログラミング上では for(i=0;i<n;i++);{ for(j=i+1;j<n;j++){ if(a[i]<a[j]       temp=a[i];       a[i]=a[j];            a[j]=temp;        }        }        } のようにiとjを比較して a[0]がa[1]より大きければa[0]とa[1]を交換する。 あとはa[0]とa[2], a[0]とa[3]...a[3]とa[4]まで for文の続く限り繰り返すように書いたはずです。 まだ勉強し始めた私にはどこが間違っているのか分からないので 分かる方はご指摘をお願いします。

  • C言語の問題がわからないです。

    C言語のプログラムで、列数を自分で決めて、 (例)3列         ●(この行を最後として)   □● ●□● 上記のプログラムを作りたいのですが、 上手くいきません。途中まで作ったのですが、なかなか思うようにいかないです。どうすれば上記のようになりますでしょうか? #include <stdio.h> void disp(int x, int y); main() { int i,n; printf("表示する列:"); scanf("%d",&n); disp(3,3); for(i=1;i<=n;i++){ if(i%2==0){ disp(n-i,4); disp(i,2); } else{ disp(n-i,4); disp(i,1); } disp(1,3); } } void disp(int x, int y) { int i; for(i=0;i<x;i++){ if(y==1){ printf("●"); } else if(y==2){ printf("□"); } else if(y==3){ printf("\n"); } else{ printf("\0"); } } }

  • C言語で困っています...

    入力した数値の列だけ○と×を縦に、段々になるように表示する (最後の行は×にならなければいけない)プログラムを作成しています。 (実行例) ○と×を表示します。何列?:10            ×           ○×          ×○×         ○×○×         ×○×○×       ○×○×○×      ×○×○×○×    ○×○×○×○× ×○×○×○×○× ○×○×○×○×○× 途中までプログラミングできたのですが、 偶数の数値を入れたときはきちんと最後の行は×になっても 奇数の数値を入力すると○が最後の行になってしまい、うまくいきません。 どこがだめなのでしょうか? どなたか教えてください。 /* 入力した数値の列だけ、○と×を縦に、   段々になるように表示する(最後の行は×になる) */ #include <stdio.h> int main(void) { int i, j, n; printf("○と×を表示します。何列?:"); scanf("%d", &n); for (i=0; i<n; i++){ for (j=0; j<n; j++){ if (j >= (n - 1) - i){ if (j % 2 == 0) printf("○"); else printf("×"); } else printf(" ");//全角スペース } printf("\n"); } return 0; }

  • C言語プログラムが理解できなくて…

    C言語で中抜きの正方形を作れという問題だったのですが 解答を見ても解説は無く ちんぷんかんぷんで どこでどういう処理をして、こういった解答になるのかが分からないのです 特に教えていただきたいのが何故この文で白抜きの部分ができるのかという事です 初歩的な所だと思うのですがお恥ずかしながら質問させていただきます ちなみに解答はこうありました #include<stdio.h> void main() { int hen,i,j; do { printf("2~9の数字を入力"); scanf("%d",&hen); if(hen<2||hen>9) printf("エラー\n"); } while(hen<2||hen>9); for(i=1;i<=hen;i++) { for(j=1;j<=hen;j++) { if(i==1||i==hen) putchar('*'); else { if(j==1||j==hen) putchar('*'); else putchar(' '); } } putchar('\n'); } }

  • 助けてください! c言語のプログラムです。

    #include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> #define KAMOKU_SUU 5 #define AVE_INDEX KAMOKU_SUU typedef struct { char name[32]; int scor[KAMOKU_SUU]; int mean; } STUDENT; int round(double d) { if (d < 0) return (int)(d-0.5); else return (int)(d+0.5); } #define ARRAY_OF(a) (sizeof (a) / sizeof (a[0])) int main(int argc,char* argv[]) { int i, j,k, n; int nStudets; double avrg[KAMOKU_SUU + 1]; double stdv[KAMOKU_SUU + 1]; STUDENT *mem; char buff[80]; if (argc < 2) { printf("!パラメータ不足\n"); return 1; } nStudets = atoi(argv[1]); mem = (STUDENT*)malloc(sizeof (STUDENT) * nStudets); if (mem == NULL) { printf("!アロケーション\n"); return 2; } memset(avrg, 0, sizeof (avrg)); memset(stdv, 0, sizeof (stdv)); printf("生徒 %d 名分の成績を入力してください:\n", nStudets); for (k = 0; k < nStudets; k++) { printf("%d 人目の点数と名前 > ", k + 1); gets(buff); strcpy(mem[k].name, strtok(buff," ")); mem[k].mean = 0; for (j = 0; j < KAMOKU_SUU; j++) { int i = mem[k].scor[j] = atoi(strtok(NULL," \n")); mem[k].mean += i; avrg[j] += i; stdv[j] += i * i; } mem[k].mean = round(mem[k].mean * 1.0 / KAMOKU_SUU); } for(j = 0; j < KAMOKU_SUU; j++) { avrg[AVE_INDEX] += avrg[j]; stdv[AVE_INDEX] += stdv[j]; avrg[j] = avrg[j] / nStudets; stdv[j] = sqrt(stdv[j] / nStudets - avrg[j] * avrg[j]); } n = nStudets * KAMOKU_SUU; avrg[AVE_INDEX] = avrg[AVE_INDEX]/ n; stdv[AVE_INDEX] = sqrt(stdv[AVE_INDEX] / n) - (avrg[AVE_INDEX] * avrg[AVE_INDEX]); printf("\n成績表\n"); printf("# NAME"); for (i = 1; i <= KAMOKU_SUU; ++i) printf(" #%d ", i); printf("MEAN\n"); for (k = 0; k< nStudets; k++) { printf("%d %10s",k+1,mem[k].name); for (j = 0; j < KAMOKU_SUU; j++) { printf(" %3d",mem[k].scor[j]); } printf(" %3d\n",mem[AVE_INDEX].mean); } printf("------------------------------------\n"); printf(" %10s","average"); for(j = 0; j < ARRAY_OF (avrg);j++) { printf(" %3.0f",avrg[j]); } printf("\n"); printf(" %10s","st.dev."); for ( j = 0; j < ARRAY_OF (stdv); j++) { printf(" %3.0f",stdv[j]); } printf("\n"); printf("正常終了\n"); return 0; }  実行してもできません。原因が全く分かりません。 お願いします。 修正してくださるとありがたいです。

  • Cプログラムで15パズルを作ってみたのですがうまく動作しません。何処が

    Cプログラムで15パズルを作ってみたのですがうまく動作しません。何処が間違っているのかずっと考えているのですがいまだに解決策が見つかりません。ヒントでもいいのでお願します。 #include <stdio.h> int init(void); void show(void); int chk_cmp(void); char input(void); int move(char cmd); #define N 4 int panel[N][N] = { { 1, 2, 3, 4}, { 5, 6, 7, 8}, { 9, 10, 11, 0}, {13, 14, 15, 12} }; int x, y; int main(void) { printf("これは15パズルです。\n" "左上から右に向かって「1」から「15」が並ぶよう,\n" "「0」を動かしてください。\n" "操作はテンキーで行います。( 8(上),4(左),6(右),2(下) )\n"); if( !init() ) { printf("パネルの初期化に失敗しました。「0」のパネルがありません。\n"); return 1; } while(1) { show(); if( chk_cmp() ) { printf("完成です!\n"); break; } while(1) { if( move(input()) ) { break; } else { printf("そっちには動かせません。\n"); } } } return 0; } int init(void) { int i,j; for(i=0;i<=N-1;i++){ for(j=0;j<=N-1;j++){ if(panel[i][j]==0){ x=j; y=i; return 1; } } } return 0; } void show(void) { int i,j; printf("---------------\n"); for(i=0;i<=N-1;i++){ for(j=0;j<=N-1;j++){ printf("%3d",panel[i][j]); } printf("\n"); } printf("---------------\n\n"); } int chk_cmp(void) { int i,j; for(i=0;i<=N-1;i++){ for(j=0;j<=N-1;j++){ if(i==N-1&&j==N-1){ if(panel[i][j]!=0){ return 0; } }else{ if(panel[i][j]!=N*i+j+1){ return 0; } } } } return 1; } char input(void) { int comand; while(1){ scanf("%d",&comand); if(comand==8||comand==4||comand==6||comand==2){ break; } printf("8(上),4(左),6(右),2(下)を入力してください。"); } return comand; } int move(char cmd) { int dx=0, dy=0; if(cmd==8){dy=-1;}//上 if(cmd==4){dx=-1;}//左 if(cmd==6){dx=1;}//右 if(cmd==2){dy=1;}//下 if(x+dx>=0&&x+dx<=N-1&&y+dy>=0&&y+dy<=N-1){ panel[y][x]==panel[y+dy][x+dx]; panel[y+dy][x+dx]==0; y+=dy; x+=dx; return 1; } else{return 0;} }

  • C言語のプログラムなのですが、2点の座標(SとR)を指定して片方からも

    C言語のプログラムなのですが、2点の座標(SとR)を指定して片方からもう片方への道筋を座標でcsvファイルに記述していくプログラムを作りたいのですが、うまく動きません。 参照渡しの所が間違っている様な気もするのですがわかりません。わかる方いましたらご指摘ください! エラー内容:Segmentation Fault(core dumped) #include<stdio.h> #include<stdlib.h> #include<math.h> #include<time.h> int Fugo(int); void Flooding(int *,int *,int *,int *); typedef struct{ int id; int dX; int dY; }NodeStates; NodeStates Node1[50]; NodeStates Node2[50]; int main(void) { int SX1,SY1; int RX1,RY1; int SX2,SY2; int RX2,RY2; int i=1; int j=1; FILE *fp; fp=fopen("test.csv","w"); if(fp!=NULL){ printf("S1 Node PointX>>"); scanf("%d",&SX1); printf("S1 Node PointY>>"); scanf("%d",&RX1); printf("R1 Node PointY>>"); scanf("%d",&RY1); Node1[0].id = 1; Node1[0].dX = SX1; Node1[0].dY = SY1; printf("S2 Node PointX>>"); scanf("%d",&SX2); printf("S2 Node PointY>>"); scanf("%d",&SY2); printf("R2 Node PointX>>"); scanf("%d",&RX2); printf("R2 Node PointY>>"); scanf("%d",&RY2); Node2[0].id=1; Node2[0].dX=SX2; Node2[0].dY=SY2; srand((unsigned int)time(NULL)); fprintf(fp,"First\n"); fprintf(fp,"NodeID,X,Y\n"); fprintf(fp,"%d,%d,%d\n",Node1[0].id, SX1, SY1); while(!(SX1==RX1 && SY1==RY1)){ Flooding(&SX1, &SY1, &RX1, &RY1); Node1[i].dX=SX1; Node1[i].dY=SY1; Node1[i].id=i+1; fprintf(fp,"%d,%d,%d\n",Node1[i].id,Node1[i].dX,Node1[i].dY); i++; } fprintf(fp,"Second\n"); fprintf(fp,"NodeID,X,Y\n"); fprintf(fp,"%d,%d,%d\n",Node2[0].id, SX2, SY2); while(!(SX2==RX2 && SY2==RY2)){ Flooding(&SX2,&SY2,&RX2,&RY2); Node2[j].dX=SX2; Node2[j].dY=SY2; Node2[j].id=j+1; fprintf(fp,"%d,%d,%d\n",Node2[j].id,SX2,SY2); j++; } } fclose(fp); return 0; } void Flooding(int *a,int *b,int *c,int *d){ int *e,*f,r; *a=*a-*c; *b=*b-*d; *e=Fugo(*a); *f=Fugo(*b); *a=abs(*a); *b=abs(*b); r=rand()%3; if(*a!=0&&*b!=0){ if(r==0){ *a=*a-1; } else if(r==1){ *a=*a-1; *b=*b-1; } else *b=*b-1; } else if(*a==0)*b=*a-1; else if(*b==0)*a=*b-1; *a=*a**e+*c; *b=*b**f+*d; } int Fugo(int a){ int n; if(a>=0){ n=1; } else{ n=-1; } return n; }

専門家に質問してみよう