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

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

ただいまの
回答率

90.83%

  • C

    3218questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

シンプレックス法の実現

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 80

shrtk

score 5

 前提・実現したいこと

C言語で線形計画問題のシンプレックス法を実現したい

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

例題を解いてみたが、プログラムが終了しない。
永遠にシンプレックスタブローの計算をしてしまっている

目的関数:
 第1変数の係数>12変数の係数>13変数の係数>1
条件式:
 第1条件式の係数:
 第1変数の係数>12変数の係数>-13変数の係数>21条件式の定数>82条件式の係数:
 第1変数の係数>22変数の係数>-33変数の係数>-12条件式の定数>1
シンプレックス表:( ) は変数の番号
 -1.000 -1.000 -1.000  0.000  0.000  0.000
  1.000 -1.000  2.000  1.000  0.000  8.000 (4)
  2.000 -3.000 -1.000  0.000  1.000  1.000 (5)
シンプレックス表:( ) は変数の番号
  0.000 -2.500 -1.500  0.000  0.500  0.500
  0.000  0.500  2.500  1.000 -0.500  7.500 (4)
  1.000 -1.500 -0.500  0.000  0.500  0.500 (1)
シンプレックス表:( ) は変数の番号
 -1.667  0.000 -0.667  0.000 -0.333 -0.333
  0.333  0.000  2.333  1.000 -0.333  7.667 (4)
 -0.667  1.000  0.333 -0.000 -0.333 -0.333 (2)
シンプレックス表:( ) は変数の番号
  0.000 -2.500 -1.500  0.000  0.500  0.500
  0.000  0.500  2.500  1.000 -0.500  7.500 (4)
  1.000 -1.500 -0.500  0.000  0.500  0.500 (1)
シンプレックス表:( ) は変数の番号
 -1.667  0.000 -0.667  0.000 -0.333 -0.333
  0.333  0.000  2.333  1.000 -0.333  7.667 (4)
 -0.667  1.000  0.333 -0.000 -0.333 -0.333 (2)
シンプレックス表:( ) は変数の番号
  0.000 -2.500 -1.500  0.000  0.500  0.500
  0.000  0.500  2.500  1.000 -0.500  7.500 (4)
  1.000 -1.500 -0.500  0.000  0.500  0.500 (1)
シンプレックス表:( ) は変数の番号
 -1.667  0.000 -0.667  0.000 -0.333 -0.333
  0.333  0.000  2.333  1.000 -0.333  7.667 (4)
 -0.667  1.000  0.333 -0.000 -0.333 -0.333 (2)
シンプレックス表:( ) は変数の番号
  0.000 -2.500 -1.500  0.000  0.500  0.500
  0.000  0.500  2.500  1.000 -0.500  7.500 (4)
                ......

 該当のソースコード

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

#define K 3 // 変数の個数
#define L 2 // 条件式の数
#define M L+1 // タブローの全行数
#define N K+L+1 // タブローの全列数

// タブローの入力
void inputTab(double tab[M][N],int ids[L]){
  int i,j,k;
  double elm;

  // クリヤー
  for(i=0;i<M;i++) {
    for(j=0;j<N;j++) {
      tab[i][j] = 0.;
    }
  }
  // 目的関数の係数入力
  printf("目的関数:\n");
  for(j=0;j<K;j++) {
    printf(" 第%d変数の係数>",j+1);
    scanf("%lf",&elm);
    tab[0][j] = -elm;
  }
  // 条件式の係数と定数の入力
  printf("条件式:\n");
  for(i=1;i<M;i++) {
    printf(" 第%d条件式の係数:\n",i);
    for(j=0;j<K;j++) {
      printf(" 第%d変数の係数>",j+1);
      scanf("%lf",&tab[i][j]);
    }
    printf(" 第%d条件式の定数>",i);
    scanf("%lf",&tab[i][N-1]);
  }
  // スラック単位行列
  for(i=1;i<M;i++) {
    for(j=K;j<N-1;j++) {
      tab[i][j] = 0.;
    }
    tab[i][K+i-1] = 1.;
  }
  // スラック変数idの登録
  for(k=0;k<L;k++) {
    ids[k] = K+k+1;//@
  }
  return;
}
// タブローの表示
void printTab(double tab[M][N],int ids[L]){
  int i,j;

  printf("シンプレックス表:( ) は変数の番号\n");
  for(i=0;i<M;i++) {
    for(j=0;j<N;j++) {
      printf(" %6.3f",tab[i][j]);
    }
    if( i==0 ) printf("\n");
    else printf(" (%d)\n",ids[i-1]);
  }
  return;
}
// 変数列の第1行で最小列を探す→kmin(-1; not found)
int srchnxt(double target[K]){
  int jvar,kmin;
  double maxv;

  kmin = -1;
  for(maxv=jvar=0;jvar<K;jvar++) {
    if(fabs(target[jvar]) > maxv ) {
      maxv = fabs(target[jvar]);
      kmin = jvar;
    }
  }
  return kmin;
}
// 選んだ変数列の中で行を選ぶ
int select(int jvar,double tab[M][N],int ids[L]){
  int icon;
  double tstv;
  double minv;
  int jmin;

  for(icon=1;icon<M;icon++) {
    tstv = tab[icon][N-1]/tab[icon][jvar];
    if( icon==1 ) {
      minv = tstv;
      jmin = icon;
    } else {
      if(tstv<minv) {
    minv = tstv;
    jmin = icon;
      }
    }
  }
  ids[jmin-1] = jvar+1;//@
  return jmin;
}
// 変数(jvar)の第(icon)条件をピボットとして消去
int reduce(double tab[M][N],int icon,int jvar) {
  int i,j;
  double pivot,ipv;

  pivot = tab[icon][jvar];
  if( pivot == 0 ) return 1;
  for(j=0;j<N;j++) {
    tab[icon][j] /= pivot;
  }
  for(i=0;i<N;i++) {
    if( i==icon ) continue;
    ipv = tab[i][jvar];
    for(j=0;j<N;j++) {
      tab[i][j] -= ipv*tab[icon][j];
    }
  }
  return 0;
}
// シンプレックス法
int simplex(double tab[M][N],int ids[L]){
  int icon,jvar,kerr;
  int k;
  while( (jvar=srchnxt(tab[0])) >= 0 ) {
    icon = select(jvar,tab,ids);
    kerr=reduce(tab,icon,jvar);
    printTab( tab,ids );
    if( kerr ) {
      printf("ピボット縮退のため中止。\n");
      return 1;
    }
  }
  printf("シンプレックス解\n");
  for(k=1;k<=K;k++) {
    printf("変数 (%d): %6.3f\n",ids[k-1],tab[k][N-1]);
  }
  printf("目的関数: %6.3f\n",tab[0][N-1]);
  return 0;
}
int main(){
  double tab[M][N];
  int ids[L];

  inputTab( tab,ids );
  printTab( tab,ids );
  simplex ( tab,ids );
  return 0;
}
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

回答、ではないですが、
VisualStudioやEclipseなど、C言語で、ソース上で任意の行でブレークさせ、変数の値をモニタしながらワンステップづつ実行させるという機能を持った統合環境がありますので、そういうのでデバッグなされたらどうでしょうか。

#おまけに無料です

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 90.83%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

  • 受付中

    身長と標準体重の対応表のつくりかた

    こんな模範解答が本にありましたが、他の方法を知っている方がいましたら教えてください。答えに不満というわけではないのですが、 ほかの方法もできれば知りたいです。 宜しくお願いします。

  • 受付中

    OpenCVで動画の読み込みがうまくできません。

    以前別のプログラムで動画の読み込みができましたが、今現在取り組んでいるプログラムではうまくいきません。 言語はC++でopencv2.4.9を使用しています。 Os windo

  • 解決済

    gaussの消去法について、C言語によるプログラム

    ガウスの消去法についてC言語によるプログラムを作成したのですが、 解が表示されることなくエラーが出ます。 プログラムのどこが間違っているのか教えていただけると 幸いです。

  • 解決済

    結果の表示について

    課題で、 キーボードから入力された数値の平均を計算して表示し、平均以上の数値、平均より小さい数値を表示するプログラムを考えているのですが、 実行例 ./a.out

  • 解決済

    C言語 行列のファイル読み込み(と、ガウス消去法計算)

    大学の課題で、コンパイルは通ったのですが、うまく読み込んでいないようです。 ガウス消去法を用いて Ax = B を x について解くというもので、行列Aと行列Bはそれぞれ.c

  • 解決済

    正規乱数を生成し、その平均値と分散を求めるプログラムの出力がうまくいきません。

    前提・実現したいこと 乱数を二つ生成し、Box-Muller法を用いて、平均1、分散4に従う正規乱数を生成するプログラムを作成し、乱数をn個生成し、標本平均値と標本分散をいくつか

  • 解決済

    無限ループしてしまうようになった

    解決したいこと 一度はうまくいったのですが、作り直したらなぜか無限ループしてしまうようになってしまいましたのですが、わかる方いますか。コンパイルも通っているのですが。 追記 #

  • 受付中

    プログラムを見やすく改良したい

    正常に動くプルグラムを見やすく改良したい。 具体的に教えていただければありがたいです。セグメンテーションフォルトでベスト7まで表示して停止します。173行あたりだと思うのですが、よ

同じタグがついた質問を見る

  • C

    3218questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。