ソフトウェア開発の4色定理が教えてくれること

4色の定理は、マップに関連する数学的定式化です。 インターネットで見つけた地図の例はすべて複雑すぎて紹介できないので、私は自分の見た目の絵をスケッチしました。









別の角度から見ると、グラフとして見ることができます。すべての領域を円に縮小し、地図の隣接する領域に対応する円を接続するだけです。









4色の定理は、私の(またはそれに対応するグラフ)に似た図面をマークするには4色で十分であるため、同じ色の隣接領域がないことを示しています。 つまり、アメリカやヨーロッパの地図を、これらのすべての奇妙な境界線で取り、各州や国に独自の色を割り当てた場合、地図全体をマークするには4色で十分です。



一部のカードは4色すべてを必要とせず、2色または3色しか必要としません。 1色で着色できるカードはあまり面白くないので、スキップします。



ソフトウェア開発者として最初に思い付いたのは、 4色では不十分です。 どのグラフも4色だけでペイントできることは印象的なようです。 データを交換するオブジェクトがエッジで接続されているコードベースのいくつかのグラフを描画すると、簡単に数十色が必要になるようです。



それで、4色の定理には1つの条件があります。 グラフは平面(平坦)でなければなりません。 これは、エッジが交差できないことを意味します。 交差することなく2次元の平面に重ね合わせることができなければなりません。 つまり、平面に重ね合わせることができない交差点を持つグラフがある場合、4色の定理は適用されません。 4色以上が必要になりますが、交差なしで描画するには少なくとも3次元が必要です。



したがって、これを行うことができます。









しかし、そうではありません:









難易度



これらの色で何が面白いのでしょうか? なぜ彼らは誰かを気にしなければならないのですか? なぜこの投稿を書いているのですか? 簡潔に言えば、 複雑さという言葉で表現できます。 グラフに色を付けるために必要な色の数は、その複雑さを示しています。より複雑なグラフには、より多くの色が必要です。 これが実際にどのように見えるかを理解するために、グラフを色付けしてみましょう。 以下のグラフは同じ数のノードを持っていますが、色付けには異なる数の色が必要です(元の記事では、グラフはインタラクティブであり、ノードをクリックすることで色付けできます)。









2番目のグラフは、直感的にはより複雑であるか、少なくとも順序が少なくなっています。 その複雑さを評価するための特定の測定可能な方法があります:それはペイントするためにより多くの色を必要とします。 2番目のグラフでは、最初のグラフでは2色のみが4色必要です。 なんで?



グラフ接続の性質から複雑さが生じます。 2番目のグラフの一部のコンポーネントは、最初のグラフのノードとは異なり、高度に相互接続されています。 実際、最初のグラフは一連のルールに基づいています。これはツリーです。 2番目のグラフは私が作成したものです。マウスを任意にクリックして、多くの関係を作成しました。



グラフには、特定の論理規則に従って順序付けされている間、色の数を増やすことなく、任意の数のリンクを含めることができます。 各ノードに接続されているノードの数は重要ではありません。









グラフ内の要素の数:









実際、リンクの数が多いコンポーネントは、グラフの色の数を増やします。 三角形には3つの色がありますが、実際には、三角形は含まれるノードの数に対して非常に相互接続されています完全なグラフです。 興味深い課題は、3色から4色への移行です。 この場合、すでに接続されているコンポーネント間に接続を追加する必要があります。 次の2つのグラフを結合するとします。











合計を増やしたり増やしたりせずにこれを行う方法があります。 それはすべて、新しいrib骨がどのように追加されるかに依存します。









(2番目のグラフは交差したエッジで描画されますが、実際には平面です。元の記事で下のノードを引き上げると、修正されます。)



最初の列では、ノード3を使用して2番目のグラフに接続しました。 ノード3は菱形の一種の「インターフェース」であり、アクセスを制限します。 このパターンに従うことにより、グラフの複雑さは増加しません。



2番目の列では、ノード1、2、および4に 、より大きなサブグラフとの接続があります。 この場合、菱形へのアクセスを制限するノードはありません。 大きなグラフには、菱形の複数のノードに接続する機能があります。 これにより、システム全体の複雑さが増しました。 さらに、複雑さはシステムの大部分にカスケードされました。ノードの色の1つだけを変更することはできませんが、変更をより大きなサブグラフに広げる必要があります。



ソフトウェア開発



これらのグラフは、コードベースの依存関係グラフに似ています。 各クラスにノードを追加し、データを交換するクラスの間にエッジを描画すると、上記のいずれかに似たグラフになります。 「コンポーネント」および「モジュール」という用語の私の言及は、ソフトウェアの観点からこれらのグラフを知覚したという事実に影響されました。 最後の例では、重要なトピックに触れます。モジュールの相互接続方法を制御すれば、複雑さを増すことなく、成長するコードベースを管理できます。 明確に定義された方法でデータを交換する小さな相互接続モジュールで構成されるコードベースは、モジュールがランダムにデータを交換するデータベースに比べて複雑さが軽減されます。



これは、エッジではなくポイントに沿ってインタラクションを制御するのが最善の方法の例です。 つまり、1つの対話ポイントを持つモジュールは、コードベースの複雑さを汚染することなく、独自のダイナミクスを維持できるということです。 プログラマがコードベースのモジュールをどのように接続するかを考えず、結果のモジュールに多くの相互作用点がある場合、コードベースの複雑さが増します。



複雑さの色の測定に関しては、木は非常に単純です。 それらをペイントするには、2色のみが必要です。 ツリー構造は、相互接続されたクラスターの作成を防ぎ、親ノードが子ノードへのアクセスを制限するため、複雑さが急増します。 依存関係図では、親ノードは、子ノードによって提供される機能の上にある抽象化のようなものです。 他のノードが子ノードに直接接続されている場合、抽象化は破棄されます。



ただし、コードの再利用のため、ほとんどの依存関係スキームはツリーではありません。 プログラマは、1つのオブジェクトを他の多くのオブジェクトで使用する必要があります。 ただし、特定のポイントにのみ-データストレージレベルと直接通信するためにWebプレゼンテーションは必要ありません。第1に、Webレイヤーは別の抽象化レベルにあり、第2に、Webレイヤーには他の責任がある可能性が高いため、 1か所でデータストレージ層と直接通信することは、あまりにも多く行われます。



これらの考えからの主な結論は、コードベースの複雑さを管理する良い方法は、他のグループの上にAPIを作成するオブジェクトを使用することだということでした。 内側のグラフの境界点に接続して接続を作成すると、グラフの複雑さが増すことはありません。 しかし、「内側」を開くと、すぐに非常に複雑なグラフに到達できます。



All Articles