C言語関係掲示板

過去ログ

No.532.最短経路の求解プログラムのデータ数を増やす

[戻る] [ホームページ]
No.4282

最短経路の求解プログラムに関して
投稿者---dsa(2003/01/09 22:00:09)


こんばんわ。
最短経路の求解プログラムを作ってみたのですが、
下記のような感じになっています。
このままならいいのですが、データ数を増やして計算したいので、
具体的にいうと、define N 100となっている所を600とかもっと大きいデータ
数にしたいのですが、このままの2次元配列を作ると36万個も・…
メモリが・…
といった感じになっています。
読み込みたいデータは、頂点の数は多いものの、
枝の数はたいしてありません。
うまい方法は、無いでしょうか
読み込んでるファイルは、

頂点数 枝の数
頂点番号1 頂点番号2 距離
頂点番号1 頂点番号3 距離
      ・ 
      ・  

といった書式になっています。

#include <stdio.h>
#define N 100

void main(void)
{
   int i,j;
   int n,m,vi,vj,wij,vs,vt,min,marknum;
   int adj[N+1][N+1],mark[N+1],length[N+1],pred[N+1];
   FILE *fp;

   fp=fopen("spath3goudata", "r");
   fscanf(fp,"%d%d",&n,&m);

  for(i=1;i<=n;i++)
      {
        mark[i]=0; length[i]=999;
        for(j=1;j<=n;j++)adj[i][j]=999;
      }
  for(i=1;i<=m;i++)
      {
        fscanf(fp,"%d%d%d",&vi,&vj,&wij);
        adj[vi][vj]=adj[vj][vi]=wij;
      }
printf("siten =");
scanf("%d",&vs);
printf("syuuten =");
scanf("%d",&vt);

length[vs]=0;
marknum=0;
while(marknum<n)
{
  min=999;
  for(i=1;i<=n;i++)
  {
   if(mark[i]==0&&min>=length[i])
     {
      min=length[i]; vi=i;  
     }
  }
   mark[vi]=1;marknum++;
 for(vj=1;vj<=n;vj++)
 {
  if(adj[vi][vj]!=999 && mark[vj]!=1)
   {
     if(length[vj]>(length[vi]+adj[vi][vj]))
      {
        length[vj]=length[vi]+adj[vi][vj];
        pred[vj]=vi;
      }
   }
 }
}

i=vt;
while(i!=vs){
     printf("->%d",pred[i]);
     i=pred[i];
           }		
}




No.4287

Re:最短経路の求解プログラムに関して
投稿者---kikk(2003/01/10 00:57:41)


ども。


とりあえず、以下の方法を検討してください。

1.
intより短い(unsigned)shortや(unsigned)charで用が足りないかを
検討してみる。

2.
もし、枝に方向がないならば、テーブルのサイズは半分にできる。
イメージ的にいうと、四角い2次元のテーブルの下半分(か上半分)の
直角三角形の部分だけですむので。このことを利用し、半分の
サイズの1次元の配列に格納する。アドレス計算を自前でやる必要がある。

3.
>頂点番号1 頂点番号2 距離
と同じような形式の構造体を定義し、その(1次元)配列を用意し、そこに
グラフデータを格納する。そして参照時に毎回検索する。テーブル中に
頂点の組がみつからない場合は到達不能ノードとなる。テーブルをソート
しておき、別に、ある頂点についての枝が入っている範囲を格納する配列
を用意するといいかも(やらなければ、毎回、線形探索することに)。
# グラフが密だった場合はかえって悪くなる可能性あり

1.は、基本ですね。2.および3.との組み合わせも可。
2.は、面倒な割に半分にしかならず、きれいじゃないのであまりおすすめ
しません。参考までに。
3.は、ちょっと面倒ですが、そこそこのものができるかと。


ついでに。
読み込んでいるファイルに
>頂点数 枝の数
があるので、malloc()等で動的にメモリを確保すれば、メモリをきっちり
つかえます。


では。

No.4317

Re:最短経路の求解プログラムに関して
投稿者---dsa(2003/01/12 01:40:25)


ご指摘のように、
1,2、3の方法を試してみたら
うまくいきました。
返事が遅くなってすいませんでした。
kikkさんありがとうございました。