hcictory
@hcictory (吉 dora)

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

計算量の見積りについて *C言語

解決したいこと

計算量の見積りについての質問です。
今回、現状の知識の限りで計算量の考察をしてみました。
その結果を下記に上げるので是非添削していただきたいです。
また目的がテスト対策なので、記述の仕方も含めて、総合的に評価していただけたらなと思います。結果だけでなく、その過程の導出方法についても指摘があれば是非お願いいたします。
下に、考察結果と、考察対象となったソースコードが載っています。

補足情報

ソースコードに書かれている,1から21までの数字はグラフの1から21までの数字に対応しています。
グラフに、入っている色の入った横棒は、それぞれ各ループの始点と終点に対応しています。

該当するソースコード

ソースコードを入力

#include <stdio.h>
#include <stdlib.h>
#define  N 8
#define  M 9999
int a[N+1][N+1]=
{{0,0,0,0,0,0,0,0,0},
 {0,0,1,7,2,M,M,M,M},
 {0,1,0,M,M,2,4,M,M},
 {0,7,M,0,M,M,2,3,M},
 {0,2,M,M,M,M,M,5,M},
 {0,M,2,M,M,0,1,M,M},
 {0,M,4,2,M,1,0,M,6},
 {0,M,M,3,5,M,M,0,2},
 {0,M,M,M,M,M,6,2,M}};

int main()
{
    int j,k,p,start,min,
    leng[N+1],/
    v[N+1],//
    index[N+1];//
    printf("始点");scanf("%d",&start);
    ①for(k=1;k<=N;k++)
    {
    ②〜③   leng[k]=M;v[k]=0;
    }
    ④leng [start]=0;
    ⑤index[start]=0;//
    ⑥for(j=1;j<=N;j++){
    ⑦min=M;//
    ⑧ for(k=1;k<=N;k++){
    ⑨ if(v[k]==0&&leng[k]<min){
    ⑩     p=k;min=leng[k];
                }
                }
  <11>  v[p]=1;

    <12> if(min==M){
    printf("グラフは連結していない。");
    <13>exit(1);
    }

    <14>for(k=1;k<=N;k++)
    {
    <15>if((leng[p]+a[p][k])<leng[k])
    {
    <16>leng[k]=leng[p]+a[p][k];
    <17>index[k]=p;
        }
        }
        }
        <18>for(j=1;j<=N;j++)
        {
            printf("%3d : %d",leng[j],j);
        <19>    p=j;
        <20>while(index[p]!=0){
                printf("<― %d",index[p]);
        <21>        p=index[p];
                }
                printf("\n");
}   return 0;
}

例)

def greet
  puts Hello World
end

自分で試したこと

ここに問題・エラーに対して試したことを記載してください。655612F5-165E-4B3B-8401-7F3D075B8BAC.jpeg

0

2Answer

隣接リストで実装したダイクストラ法を用いる単一始点最短経路問題を解くコードだとお見受けします.

考察対象がリストのサイズNだけなので,概ね計算量の見積りは当たっていると思います.そして本アルゴリズムは先述の名前で調べて出てくる通り${\rm O}(N^2)$ですので最終的な解は当たってます.

1Like

Comments

  1. @hcictory

    Questioner

    ご回答ありがとうございます。おっしゃる通りです。
    ついでにもう一つ質問なのですが、導出過程における記述方法などは上記の記述の仕方でも問題なさそうですが??
  2. 少し微妙なところ(O(max(1,N,N^2,N^2))など)はありますが,そこまで厳密に解かなくていいとされているなら問題なさそうです.途中途中の見積りも当たっています.
    問題文が「証明せよ」なら全然過程が足りませんが,上記のような番号が割り振られたコードを与えられて
    1 N回 計算量O(N)
    2 N回 計算量O(N)
    ...
    のような記述を続けて書くレベル感であれば問題ないと感じます.
  3. @hcictory

    Questioner

    返信ありがとうございます。
    一応目的が試験対策になっていまして、厳密な記述が求められています。
    もし厳密に記述するなら、O(MAX(1〜21の計算量の羅列))
    で最終的に、O(N^2)と記述すれば流石に大丈夫そうですかね?
  4. 最大値や最小値を取ろうとするときは基本,文字が違うときです.今回全部Nの項なので,適当な定数cが存在していて,任意のn>=1について考えたときに
    f(N) = 1 + N + N^2 + N^2 <= c(1 + N + N^2 + N^2) <= c + cN + 2cN^2 <= cN + cN + 2cN^2 <= (4c)N^2
    ∴ f(N) = O(N^2)
    みたいな書き方が正しいです.

Big-O notation

定義
ある関数$f(n)$と$g(n)$について,
$$
f(n) = O(g(n))
$$
であるとは,適当な定数$c,n_0\ge 0$が存在して,$\forall n\ge n_0$について
$$
f(n) \le c\cdot g(n)
$$
となることである.これを「$f(n)$のオーダーは$g(n)$である」という.

Big-O notation は次の性質を満たす.

\begin{align}
{\mathbf  推移律:} & f(n) = O(g(n)), g(n) = O(h(n)) \Rightarrow f(n) = O(h(n)) \\
{\mathbf  和:} & O(f(n)) + O(f(n)) = O(f(n)) \\
{\mathbf  積:} & O(f(n))O(g(n)) = O(f(n)g(n)), \quad f(n)O(g(n)) = O(f(n)g(n)) \\
{\mathbf  定数倍:} & O(cf(n)) = O(f(n)) \quad (c\neq 0) \\
{\mathbf  冪等性:} & O\left(O(f(n))\right) = O(f(n))
\end{align}

一般的な証明

問いで与えられた隣接行列で実装したダイクストラ法を用いる単一始点最短経路問題を解くコードにおいて,比較/代入/四則演算の回数$f(N)$は

f(N) = N^2 + \cdots + N + \cdots + 1 \qquad {\rm (21個全部展開してください)}

である.ここで,適当な定数$c,N_0\ge 0$が存在して,$\forall N\ge N_0$について考えたときに,

\begin{align}
f(N) & = N^2 + \cdots + N + \cdots + 1\\
& \le c(N^2 + \cdots + N + \cdots + 1) \\
& \le cN^2 + \cdots + cN + \cdots + c \\
& \le cN^2 + \cdots + cN^2 + \cdots + cN^2 \\
& \le 21c\cdot N^2
\end{align}

となるから,Big-O notationの定義より$f(N)=O(N^2)$である.$\blacksquare$

ちょっと楽な証明

出していただいた画像から察するに,先ほどのように厳密な定理を使わずにそのままオーダー記法をしていいものとして書きます.

Big-O notationの和の性質から,

$$
O(N^2) + \cdots + O(N) + \cdots + O(1) = O(N^2)
$$

となるから,このコードの計算量は$O(N^2)$である.$\blacksquare$

屁理屈(だけどこのコードを見せられているならば正しい)証明

このコードは入力のサイズに依存しない(入力は探索開始地点しか受け取っていない)ため,定数時間で実行が終了する.よって計算量は$O(1)$.$\blacksquare$

余談

"厳密な記述が求められています"とのことでしたが,私にできる範囲はこれで限界です.厳密な証明は$\varepsilon - \delta$論法を用いて関数の極限を扱う形で証明が記述されますが,私は弊学にて上記に示した一般的な証明方法でしか習っておらず,力不足になります.

以上がよほどのガチ専門じゃない限りで満点がもらえそうな解答です(補償はできませんが).
そしてこの定義上,$f(N)$の計算量は$O(N^3)$でも$O(N^4)$でも$O(N^5)$でも$O(N^6)$でも正解です(でもhcictoryさんのテストで意図された答えではなさそうなのでバツをもらいそうです).

テスト頑張ってください.

1Like

Your answer might help someone💌