オブジェクト指向とアルゴリズムの関係


9

私がいくつかのアルゴリズムの教科書を読んでいるとき、それらはいくつかの問題(ソート、最短経路)またはいくつかの一般的な方法(再帰アルゴリズム、分割統治、動的プログラミング...)の賢い手順でいっぱいです。そこではオブジェクト指向プログラミングの痕跡をいくつか見つけました。(なぜそれらはより手続き指向であるのですか?)

それから私は考えていました:

  • アルゴリズムとOOPの関係は何ですか?2つの独立したトピックですか?
  • OOPでしか表示および解決できない問題はありますか?
  • OOPはアルゴリズムをどのように支援できますか?それともどの方向に影響を与えることができますか?

4
重複ではありませんが、関連するプログラマーです
Doc Brown

@DocBrownは...しかし、ここで私たちは、継承、ポリモーフィズムなどのオブジェクト指向の周りにいくつかの概念を考慮することができる、非常に有用だったこと、ありがとう
アフマド

1
「なぜアルゴリズムの教科書は手続き指向であるのか?」Javaもプロシージャ指向です。Javaはオブジェクト指向の手続き型言語です。
ピーターB


1
@gnat私は私の質問を変更しました、それらの説明が必要であるかどうか、または良いかどうかわかりません。しかし、Doc Brownが扱った質問には、私の懸念に関連するより多くの回答があることを認めます。
アフマド

回答:


10

まず、OOPの意味を定義しましょう。OOPとは、主に次のことを意味します。

  • クラスの詳細のカプセル化と非表示。
  • 継承と仮想メソッドによる行動の多態性。

今、あなたの質問に答えるために:

アルゴリズムとOOPの関係は何ですか?2つの独立したトピックですか?

はい。

OOPでしか表示および解決できない問題はありますか?

いいえ。OOPプライマリーは、プログラマーのためにコードについて推論する便利さと機能を提供します。それはあなたの表現力を高めません。

OOPはアルゴリズムにどのように役立ちますか?それともどの方向に影響を与えることができますか?

上で言ったように。ここで私がOOPについて説明したのはどちらの場合も当てはまります。アルゴリズムとそのデータ構造の詳細を隠すことができると、全体の理由を説明するのに役立ちます。多くのアルゴリズムには、そのアルゴリズムのユーザーがいじりたくない詳細が含まれています。これらの詳細を非表示にすると、非常に役立ちます。

ポリモーフィックな振る舞いをする能力も素晴らしいです。Listコレクション内の任意の場所にアイテムを追加/削除/クリアできると定義されています。ただし、サイズ変更可能な配列、二重リンクまたは単一リンクなどとして実装できます。複数の実装に単一のAPIがあると、再利用に役立ちます。

なぜアルゴリズムの教科書はより手続き指向であるのですか?

私が言ったように、OOPはアルゴリズムを実装する必要はありません。また、多くのアルゴリズムは古く、OOPがまだ普及していないときに作成されました。ですから、歴史的なことかもしれません。


1
テキストの古さにもかかわらず、OOPでアルゴリズムの水を濁らせたくはないでしょう。
Gusdor 2015

15

アルゴリズムOOPは2つの異なる用語であり、CS用語であることだけが共通しています。単に-アルゴリズムは料理レシピのようなものです。xを実行するには、次の材料が必要で、ステップ1、2、3、4、5、6を実行します。その後、食事を準備します。

とはいえ、手続き型の方法でアルゴリズムを記述することは自然なことのようです。手続き型とは、まずxを実行し、次にyを実行することを意味します。

一般的な問題は次のとおりです。» xのセットをソートする方法?«。理解しやすいソリューションはbubble-sort次のとおりです。

  1. 最初の要素に到達していない限り、反復中に、最後の要素からセットを反復します
  2. 最初から2番目の反復を開始し、最初の反復の現在の要素まで
  3. (2)の現在の要素をその後続要素と比較する
  4. 大きい場合は、位置を入れ替えます

これは、アルゴリズムのアルゴリズム/言語による説明ですbubblesort

手続き型/疑似コードの実装が登場

bubbleSort(Array A)
  for (n=A.size; n>1; n=n-1){
    for (i=0; i<n-1; i=i+1){
      if (A[i] > A[i+1]){
        A.swap(i, i+1)
    } 
  } 
}

それは簡単でした。

それはどのようにOOPに関係していますか?このアルゴリズムを使用して、オブジェクトのコレクション(オブジェクト自体)を処理できます

Javascriptの例(クリーンなOO-Lingoはありませんが、ボイラープレートはほとんどなく、理解しやすいです)

objects =[{"name":"Peter"}, {"name":"Paul"}, {"name":"Mary"}]

compareObjects=function(x,y){ return x.name>y.name };

sorted = objects.sort(compareObjects)

console.log(sorted)

我々は持っているの収集objectsb)は、このコレクションにメソッドの共通sort/ソートアルゴリズムと抽象化が含まc)を、当社のオブジェクトピーターポールメアリー。ソートの仕様はここにあります

アルゴリズムとOOPの関係は何ですか?2つの独立したトピックですか?

言われたことから、それは明確でなければなりません、答えはそうであるべきです:はい、彼らは独立しています。

OOPはアルゴリズムにどのように役立ちますか?それともどの方向に影響を与えることができますか?

OOPはプログラミングスタイルの1つにすぎません。それはどんな種類にも役立ちません。それ以外の場合は、オブジェクトに何かを行うためにアルゴリズムをオブジェクト指向言語で実装できます(図のように)

OOPでしか表示および解決できない問題はありますか?

私はそれを考えることができません(しかし、それが不可能だという意味ではありません)。しかし、逆に見ると、OOPは、いくつかの問題をモデル化して適切なアルゴリズムでそれを解決したい場合に役立ちます。あなたはの記録があるだろうfriendsとしてモデル化することができますobjectsとしpropertiesて、あなたがしたい場合listfriends ソートどのような方法では、あなたが正確に行うために上記の例コードを使用することができます。

なぜアルゴリズムの教科書はより手続き指向であるのですか?

前述のとおり、手続き型はアルゴリズムの特性であるため、より自然です。


7
この回答は、アルゴリズムが自然に手続き型であることを前提としています。確かにいくつかはありますが、関数型アルゴリズムなどがあります。アルゴリズムの本が手続き型である理由は、おそらくそれらがパフォーマンスに焦点を合わせているという事実とより関係があるため、抽象化の強制について心配するのは読者次第であり、命令型言語は関数型言語よりも人気があるためです。
Doval 2015

私はそうは思いません。関数型プログラミング言語といえば、アルゴリズムそのものではなく、実装についてです。例として、Haskellのクイックソート wiki.haskell.org/Introduction#Quicksort_in_Haskellを見てください。これは、quicksort-algortihmの機能的な実装であることに同意します。しかし、あなたがを説明する場合、何が行われるのか、あなたは説明のprodecuralモードでフォールバックする必要があります。この説明から、手続き型の実装を実装できます。
Thomas Junk

1
@ThomasJunkあなたはしていない機能の実装は、物事は何と言うので、説明の手続きモードにフォールバックする必要があり、一連の工程ではありません。純粋で遅延のある計算について、逐次的にどのように説明しますか?評価される式の量や、そのサブ式が計算される順序は、事前にわかりません。
ドバル2015

2
残念ながら私はCSの学位を持っていないので、以下を証明するための幅広いスキルセットに欠けています:とはいえ、すべてのアルゴリズムは何らかの方法で説明できると思うので、純粋な純粋な関数型アルゴリズムはありません。それは、ツーリングの完全性が結果として何を意味するのではないですか?
Thomas Junk、

2
@Dovalは、チューリング自身がラムダ計算とチューリングマシンが同等であることを証明したので、機能的な方法で記述できることはすべて明白であり、命令的に実行できます。また、遅延計算を命令型に変換するのは簡単です-Haskellのコンパイラは常にそれを行います...結局のところ、それは好みの問題です。機能的である方が適している場合もあれば、命令的である場合もあれば、論理的であることが最も良い場合もあります...
AK_

5

問題があります。

ビジネスドメインモデルは問題を記述し、これから処理する問題ドメインの概念を説明します。

アルゴリズムは、問題を概念的に解決する方法を表します。実装はどのようになりますか。問題を「コンピュータサイエンス」の用語に翻訳した後、どのように対処しますか。

OOP、機能的、論理的、手続き的、または非構造化のいずれのプログラミングパラダイムでも、ソリューションをどのように構造化するか、どのような形を取るか、どの「ソフトウェアエンジニアリング」の概念を採用するか、どの「プログラミング言語理論」の概念を採用します。

簡単に言うと、アルゴリズムは一般的に問題の解決策を記述します(「これは私がやろうとしていることです」)。プログラミングパラダイムは実際の実装を扱います( "これが私がやる方法です")。


おそらく不完全な方法では、宣言型言語は「方法」のステップを削減または排除することを目的としています。彼らの目標は、あなたが単に「これが私が欲しいものだ」と言うことです(たとえば、高レベルの方程式を書くことによって)。典型的なSQLクエリについて考えてみてください。「アルゴリズム的」なものはほとんどありません。必要なことをデータベースに伝えるだけで、リクエストをどのように処理するかは(当然、一定の制限内で)次第です。
Andres F.

4

アルゴリズム =「方法」ストーリーを伝える(つまり、データ構造を使用して入力データを操作し、目的の結果を生成する方法)

OOP = OO言語がメモリの安全性と抽象化を提供するプログラム(=アルゴリズム+データ構造体)を作成できるようにする「方法論

OOPは、実装アルゴリズムのパラダイムにすぎません。

良いアナロジー:映画

スタントマンの有無に関わらずシーンを記録できます。脚本(アルゴリズム)は変わりません。人々は最終結果に違いを見るべきではありません。

編集:良質のMOOCを試してみることができます:https : //www.coursera.org/course/algs4partIこれは、議論されたトピック(特にOOPアプローチ)をインターリーブし、ここで尋ねる内容の本質を与えます。


私はあなたの映画の類推を本当に楽しんだ。将来借ります。
Marc LaFleur 2016年

2

Alexander Stepanovは、C ++の基本的なアルゴリズムライブラリであるC ++標準テンプレートライブラリ(STL)の最初の作成者です。C ++は「オブジェクト指向」機能を含むマルチパラダイム言語ですが、アレクサンダーステパノフはオブジェクト指向について次のように述べています。

http://www.stlport.org/resources/StepanovUSA.html

STLはオブジェクト指向ではありません。オブジェクト指向は、人工知能とほぼ同じでっちあげだと思います。これらのオブジェクト指向の人々からの興味深いコードはまだ見ていません。

OOPは技術的に不健全だと思います。単一のタイプで変化するインターフェースの観点から世界を分解しようとします。実際の問題に対処するには、マルチソート代数-複数のタイプにまたがるインターフェースのファミリーが必要です。OOPは哲学的に健全ではないと思います。それはすべてがオブジェクトであると主張しています。たとえそれが本当であるとしても、それはそれほど興味深いことではありません-すべてがオブジェクトであると言うことは、まったく何も言っていません。OOPは方法論的に間違っていると思います。それはクラスから始まります。それはまるで数学者が公理から始めるかのようです。あなたは公理から始めるのではなく、証明から始めるのです。関連する証明がたくさん見つかった場合にのみ、公理を思い付くことができます。あなたは公理で終わります。同じことがプログラミングにも当てはまります。興味深いアルゴリズムから始める必要があります。それらをよく理解してはじめて

そのメカニズムに根本的な欠陥があり、使用してはならない理由を理解する前に、継承と仮想の用途を見つけるために何年も費やしました。

ステパノフはアルゴリズムライブラリをObjectではなくGeneric Iteratorsで表現しました。


まあ、彼は間違っています...主にSTLが非常にオブジェクト指向であるためです...用語以来、より現代のオブジェクト指向...
AK_

1
@AK_-私は彼がまったく間違っているとは思わない。STLは、用語の意味ではほぼOOでさえありません。STLを、実質的な方法で変更することなく、パラメトリックポリモーフィズムを持つ非OO言語(HaskellやSMLなど)に直接変換できます。
Jules

2

アルゴリズムは、コンピューターが何をすべきかを記述します。構造は、[ソースコードで]アルゴリズムがどのように配置されるかを示します。OOPは、特定の「オブジェクト指向」構造を活用するプログラミングスタイルです。

アルゴリズムの本は、構造ではなくアルゴリズムに焦点を当てているため、OOPを避けることがよくあります。構造に大きく依存するコードの断片は、アルゴリズムの本に載せるには不十分な例になりがちです。同様に、OOPの本は、話が雑然としているため、アルゴリズムを避けていることがよくあります。OOPのセールスポイントはその流動性であり、OOPをアルゴリズムにペグすることで、より堅固に見えます。 それは何よりも本の焦点に関するものです。

実際のコードでは、両方を並べて使用します。 アルゴリズムなしではコンピューターの問題を解決することはできません。当然のことながら、構造(OOPなど)なしで優れたアルゴリズムを作成するのは難しいでしょう。

それらが不鮮明になる例として、動的プログラミングを取り上げます。アルゴリズムブックでは、配列内の同種のデータセットを取得し、ダイナミックプログラミングを使用してソリューションに到達する方法を説明します。OOPブックでは、ビジターなどの構造に遭遇する場合があります。これは、異種オブジェクトのセット全体で任意のアルゴリズムを実行する方法です。DPブックの例は、一般にボトムアップの順序でオブジェクトを操作する非常に単純なビジターと考えることができます。VisitorパターンはDP問題の骨格と考えることができますが、肉とジャガイモがありません。実際には、両方が必要になることがよくあります。Visitorパターンを使用してデータセット全体の異質性を処理し(DPはその点で悪い)、Visitorの構造内でDPを使用してアルゴリズムを編成し、ランタイムを最小化します(Visitorしない

設計パターンの上で動作するアルゴリズムも見られます。小さなスペースでは例を言葉で説明するのは難しいですが、構造ができたら、その構造を操作したくなり、アルゴリズムを使用してそれを実行します。

OOPでしか表示および解決できない問題はありますか?

これは、あなたが思っているよりも答えるのが難しい質問です。最初に、問題を解決するためにOOPが必要な計算上の理由はありません。 簡単な証明は、すべてのOOPプログラムがアセンブリにコンパイルされることです。これは明らかに非OOP言語です。

しかし、より大まかな計画では、答えはイエスに向かって恥ずかしがり始めます。 コンピューティングの方法論だけで制限されることはほとんどありません。ほとんどの場合、ビジネスニーズや開発者のスキルなどが方程式に加わります。今日の多くのアプリケーションはOOPなしでは作成できませんでした。OOPが何らかの形でタスクの基本であるからではなく、OOPによって提供される構造がプロジェクトを順調かつ予算どおりに進めるために不可欠だったからです。

これは、将来的にOOPをいくつかの面白い新しい構造のために決して放棄しないということではありません。それは、今日の驚くべき大部分のプログラミングタスクにとって、ツールボックスの中で最も効果的なツールの1つであると言っているだけです。将来の問題により、さまざまな構造を使用して開発に取り組む必要があるかもしれません。 まず、ニューラルネットには非常に異なる開発アプローチが必要であり、「オブジェクト指向」であるとは限らない場合があります。

アルゴリズム設計者の考え方により、近い将来OOPが消え去るとは思いません。今日までの通常のパターンは、誰かがOOPを利用しないアルゴリズムを設計することです。OOPコミュニティは、アルゴリズムがOOP構造に実際には適合しておらず、実際に適合させる必要がないことを認識しているため、アルゴリズム全体をOOP構造にラップして使用を開始します。考えてくださいboost::shared_ptr。内部にある参照カウントアルゴリズムshared_ptrは、非常にOOPフレンドリーではありません。ただし、そのパターンはshared_ptr、アルゴリズムの機能をOOP構造化形式で公開するOOPラッパーを作成するまで普及しませんでした。今では非常に人気があり、C ++の最新の仕様であるC ++ 11に採用されています。

なぜこれがそんなに成功しているのですか?アルゴリズムは問題の解決には優れていますが、多くの場合、アルゴリズムの使用方法を理解するにはかなりの初期調査投資が必要です。オブジェクト指向の開発は、そのようなアルゴリズムをラップし、学習に必要な初期投資が少ないインターフェースを提供するのに非常に効果的です。


1

すばらしい答えに加えて、OOPとアルゴリズムの概念的な共通性についても触れておきます。

OOPとアルゴリズムの両方で、コードの正確性を保証するための前提条件と事後条件の使用を強く強調しています。

一般に、これはコンピュータサイエンスのすべての分野で標準的な方法です。ただし、この指針の原則により、OOPに進化的なパスが生まれ、OOP環境にアルゴリズムを実装することが相互に有益になります。

OOPでは、同じコントラクト(前提条件と事後条件)を満たすことができるオブジェクトのグループを作成して、インターフェイスを実装できます。このようなインターフェイスのユーザーは、一部のまれな状況(リークのある抽象化が発生する)を除いて、基礎となるオブジェクトでどの実装が使用されているかを知る必要はありません。

アルゴリズムは、計算を実行するために使用されるステップの実装であり、前提条件を取り、事後条件を生成します。

したがって、前提条件と事後条件の方法で抽象化のアイデアを借りて、それをアルゴリズムに適用することができます。複雑なアルゴリズムが小さいステップに分解されることがあり、これらの小さいステップは、同じ前提条件と事後条件が満たされている限り、異なる実装戦略を可能にすることがわかります。

OOPにアルゴリズムを実装することにより、これらの小さなステップを交換可能にすることができます。

最後に、FPとOOPは相互に排他的ではないことに注意してください。上記のすべては、FPにも同様に適用できます。


ポイントありがとうございます!アルゴリズムがほんの一部のステップである場合は、先に述べたように、OOPはより抽象的なステップを提供するのに役立ちます。「OOPでのアルゴリズムの実装」について指摘されましたが、質問は常に有益であるかどうかを尋ねるように変更しました。
2015

1
OOPを「Design by Contract」と混同しています。OOPがなくても非常に便利です。ほとんどのOOP言語(C#、Java)は、実際のサポートを提供していません(事前条件と事後条件ではなく、単純なインターフェースをサポートしています)
AK_

1
@AK_私は、Design by Contractが、私の回答に記載されている共通点の正しい名前であることに同意します。私が主張しているのは、デザインパラダイムとしてのOOPは、Contract by Designを強く採用しているということです-OOPの教科書を読んでください。私の最初の答えはまた、この共通性はOOPに限定されないということです。
rwong 2015

-1
What is the relation between algorithms and OOP? Are they two independent topics?

アルゴリズムは問題を解決する方法(特定の入力から出力を生成する方法)に関するものであり、OOPはソリューションを定式化または表現する方法(アルゴリズムのステップ)に関するものです。

アルゴリズムは自然言語またはアセンブリ言語で記述できますが、自然言語での概念は、それをよりよく記述して理解するのに役立ちます。たとえば、バブルソートのアルゴリズムは次のようになります。

bubbleSort(Array A)
  for (n=A.size; n>1; n=n-1){
    for (i=0; i<n-1; i=i+1){
      if (A[i] > A[i+1]){
        A.swap(i, i+1)
    } 
  } 
}

詳細情報を非表示にするswapと、それを関連付けるためにA、我々はOOPの構文と機能を使用し、その後、OO近い私たちの自然言語理解にアルゴリズムを作ります。

Are there some problems which can only be presented and solved by OOP?

いいえ、コンピューター上のプログラム(またはアルゴリズム)がCPU(チューリングマシン)で実行される一連の命令に変換されると考え、これらの命令をコンピューター上の問題を解決する究極のアルゴリズムと見なす場合、OOPこれ以上はできません。それは単に人間の理解と推論に近づけるだけです。これは、プロシージャとデータ構造をパッケージ化する方法です。

How OOP can help algorithms? Or in which direction it can affect it?

アルゴリズムをより簡単に、またはよりわかりやすく説明または定式化するのに役立つ場合があります。詳細を非表示にして、ソリューションの全体像を提供できます。

理論的には、アルゴリズムが最初で、2番目に実装されます。しかし実際には、アルゴリズムをトレースするか、期待される出力を生成するまで、アルゴリズムが期待どおりに機能するかどうかはわかりません。コンピューターはそれを行うのに役立ちますが、機械語(アセンブリ)でそれを書くことを期待していません。

この点で、OOPは、コンピューターでのアルゴリズムの実装、テスト、および改良を容易にし、コンピューター用に、自然言語に近い言語でそれを記述します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.