アルゴリズムの複雑さの詳細な説明と原理

記事ディレクトリ

 

 

 

アルゴリズムの複雑さの詳細な説明と原理

著者のアバター
ミッキーInvQ
焦点を合わせる
130
投稿日 2022-10-28 10:05:06

記事ディレクトリ

 

14日間の読書チャレンジ* 努力は並大抵のものではありません~ アルゴリズムを学ぶ人は誰でも、桃源明の「桃花春」のように、アルゴリズムを解くための鍵が必要です。何十歩も歩くと突然陽気になる。」

アルゴリズムの知識ポイント

アルゴリズムの特徴

  • (1) 有限性: アルゴリズムは複数の命令から構成される有限なシーケンスであり、複数回実行されると必ず終了し、永遠に停止することは不可能です。
  • (2) 確実性: すべてのステートメントには、曖昧さのない明確な意味があります。
  • (3) 実現可能性:現在の環境では、限られた演算数でアルゴリズムを実現可能
  • (4) 入力/出力: 0 個以上の入力と 1 つ以上の出力があります。

アルゴリズムトピックの説明

シーケンスの合計を求めるアルゴリズムを作成します。

5a835a7c410031c0d5cfc8260992d5a4.png

質問のアイデア

このトピックを見てどう思いますか? forループ?whileループ?まず for ループのコードを見てください。

for ループ ソリューション


int sum1(int n){
                
                
   int sum=0;
   for(int i=1;i<=n;i++)
      sum+=pow(-1,i);//表示(-1)^i 
   return sum;
}
コピー

上記のコードは確かに合計演算を実現できますが、なぜそうではないのでしょうか?

2885c35b882c106caec7e0d3cc0c2077.png

別の書き方を見てみましょう。

誘導的解決策


int sum2(int n){
                
                
   int sum=0;
   if(n%2==0)
      sum=0;
   else
      sum=-1;
   return sum;
}
コピー

このコードを見た後、これがまだ可能であることに突然気づきましたか?これは数学者ガウスが使用したアルゴリズムではないでしょうか?

2a437571184189acc3a1492290be3d0a.png

対数は合計 50 あり、各対数の合計は 101 であるため、合計は次のようになります。

(1+100)* 50 = 5050

1787 年、他の子供たちが半日かかったのに対し、10 歳のガウスは非常に短時間で結果を計算しました。for ループを使用すると、n 回ループする必要があり、各ループで pow 演算が必要になり、加算演算が実行されることがわかります。n = 10000 の場合、このようなプロセスを 10000 回計算します。観察と帰納を通じて、2 番目の方法は 1 回だけ必要ですが、大きな違いはありますか?

ガウス法も知っていますが、同じような問題に遭遇したことがあります...私たちが使用している愚かな方法もアルゴリズムですか?答え: はい

アルゴリズムの複雑さの計算

優れたアルゴリズムの基準

  • 効率的 - 時間の複雑さ
  • 低ストレージ - スペースの複雑さ

時間計算量の計算

アルゴリズムの実行に必要な時間。現代のコンピューターは 1 秒間に多くの計算を実行できるため、秒単位で測定することはできません。同じコンピュータの 1 回の時間は比較的固定されており、構成が異なるコンピュータでは異なります。したがって、実行回数を時間計算量とみなします。


int sum=0;                  //运行1次
int total=0;                //运行1次
for(int i=1;i<=n;i++){
                
                      //运行n+1次,最后一次判断不满足循环条件
  sum=sum+i;                //运行n次
  for(j=1;j<=n;j++)         //运行n×(n+1)次
    total=total+i*j;        //运行n×n次
}
コピー

上記すべてのステートメントの実行数を合計すると、次のようになります。

1 + 1 + n+1 + n + n×(n+1) + n×n 。

这个可以用一个函数T(n) 来表示: T(n) = 2n2+3n+3 当n足够大的时候,例如n = 105 ,那么T(n) = 2 * 1010 + 3 *105 +3 可以看出,算法运行的时间主要取决于最高项,小项和常数可以忽略不计。 有些算法,如排序,查找、插入算法等,可以分为最好最坏平均情况分别去求算法的渐进复杂度。但是考察一个算法时,通常考察最坏的情况,最坏的情况对衡量算法好坏具有实际意义

空间复杂度的计算

算法占用的空间大小。 空间复杂度的本意指的是算法在运行过程中,占用了多少存储空间。算法占用的存储空间包括:

  • (1)输入、输出数据
  • (2)算法本身
  • (3)额外需要的辅助空间 输入输出占用的空间是必须的,算法本身占用的空间可以通过精简算法来缩减,但缩减的量是很小的,可以忽略不计。 算法在运行时候,所使用的辅助变量占用空间,才是衡量算法复杂度的关键因素。

常数变量复杂度

请分析如下的算法空间复杂度


void swap(int x,int y){
                
                    //交换x与y 
     int temp;
     temp=x;               //temp为辅助空间 ①
     x=y;                  //②
     y=temp;               //③
}
复制

两个数交换的过程:

942e81af28c9500c561e65b8655c83e9.png

这里使用了temp辅助变量,空间复杂度为O(1)

递归空间复杂度

在递归算法中,每次递归都需要一个栈来保存调用记录,因此在计算递归的空间复杂度的时候,需要计算递归栈的深度。


int fac(int n){
                
                 //计算n的阶乘
    if(n==0||n==1) 
        return 1; 
    else 
        return n*fac(n-1); 
}
复制

阶乘是典型的递归调用问题,递归包括地推和回归。递推是将原问题不断分解成子问题,直至满足结束条件,返回最近子问题的解。然后逆向逐一回归,最终到达递推开始的原问题,返回原问题的解。

思考:试求5的阶乘,程序将怎么计算呢? 5的阶乘的递推和回归的过程如下:

b03bc0ffb3a4648c7535f22ee19a0561.png
eee6ced27574e24ff0a849888f8fac7d.png

 

上の2つの図にあるように、再帰と回帰の過程は論理的思考によって推論され、絵の形でグラフィカルに表現されていますが、コンピュータ内部ではどのように計算が行われているのでしょうか。コンピュータでは「スタック」と呼ばれるデータ構造が使われています。「スタック」はお皿を入れる容器のようなもので、毎回上から入れる、取り出すときは上からしか取れず、挿入することもできません。または途中からの抽出はできないため、「後入れ先出し」と呼ばれます。

5254fa8d9b152bac94193e3d945740a1.png

この図から、スタックのプッシュとポップのプロセスがわかります。サブ問題は、戻り値が直接解決できるようになるまで、最初にステップごとにスタックにプッシュされ、その後、スタックからステップごとにポップアウトされます。最後に戻り値を取得します。操作中、n 個のスタックが補助空間として使用されるため、階乗再帰アルゴリズムの空間複雑さは O(n) です。n の階乗は n-1 の階乗よりも乗算演算が 1 つ多いだけであるため、時間計算量も O(n) になります (fac(n) = n * fac(n-1))。T(n) を使用して fac(n) の時間計算量を表す場合、T(n) = T(n) + 1 =T(n-1) + 1 + 1 ... = T と表すことができます。 (1) + ... 1 + 1 =n

31a982a1d0d84b2f81b15a518c4fc134.png

おすすめ

転載: blog.csdn.net/2301_76571514/article/details/130592693