Java スパニングツリー構造 ポイント間の最短経路アルゴリズム

Java スパニングツリー構造 ポイント間の最短経路アルゴリズム

まずは二分木についてお話しましょう。二分木は、各ポイントが 2 つのポイントに接続されているツリー構造です。下に行くほどポイントの数が増え、形が木のように見えるため、二分木と呼ばれます。二分木は、データ構造で高速検索、リソースの節約、効率の向上に使用されます。 2点間の経路は1つだけなので計算は必要ありません。もちろん、次のアルゴリズムを使用して計算することもできます。

バイナリツリー図:

二分木の変形である多分岐木について説明します。名前が示すように、各ポイントは N 個のポイントに接続できます。 同様に、2 点間の経路も 1 つしかないため、計算する必要はありません。もちろん、次のアルゴリズムを使用して計算することもできますが、これも非常に困難です。

図に示すように:

スパニング ツリーは、マルチ ブランチ ツリーの変形です。各ノードは N 個のノードに接続されています。上、下、左、右のいずれであるかは関係ありません。混乱しています。最終的な結果は、いずれかのノードを切断しても、他のノードを接続するパスが残ることです。

図に示すように:

このグラフは最小全域木に属します。スレッドの状況は極めて混沌として複雑になる可能性があります。以下はテストに使用したグラフです。完全な全域木ではありませんが、マルチフォークと全域木の中間です。

ルーティング テーブルの概念について説明しましょう。実際のネットワーク構造は、上記のテスト図に似ています。あるマシンから別のマシンに情報を送信するには、最短パスを見つける必要があります (もちろん、実際には考慮する必要がある予期しない状況が多数ありますが、これは最も基本的な状況にすぎません)。 実際、なぜ自分のマシンで計算しなければならないのか、と私は思います。ルーティング テーブルを保存するだけでも、非常に多くのスペースを占有します。他のユーザーに情報を送信する必要があるたびに、隣接するノードを見つけて、最終目的地までのパス コストを尋ね、最小のものを選択して送信します。全員が次のステップを尋ね、最終的には必ず最終目的地に到達できます。さらに、ローカル マシンは次のホップが誰であるかを知るだけでよく、ルーティング情報全体を保存する必要はありません。

まあ、このマシンで計算しないといけないので、ちょっとお見せしますね。

考え方は同じで、段階的に何をすべきかを尋ねます。

(パス情報の追加とルーティング情報の削除の計算原理はコードの後半で示します)

まず、パス情報をすべて記述する必要がありますね。コンピューターに画像を渡して、それを理解させるだけではだめです (将来的には、さらなる技術開発によって可能になるかもしれません)。

文章で説明すると、簡単に言えば、点 * 別の隣接する点 * それらの間のコスト となります。

たとえば、この図では、2 つのポイント間のコストが 1 であると仮定します。

A*B*1

1*C*1 です

双方向接続なので、

1 点

1 位

したがって、このアルゴリズムは、片方向の接続がある場合でも計算できます。

これらの接続情報を文字列配列に保存します。

例えば: String[] s = {"A*B*1", "B*A*1", "B*A*1", "C*A*1"}

順番は関係ありません。好きなようにしてください。

2 番目のステップはキーポイントです。上記のアイデアを使用して、最初からステップごとに検索します。各ポイントについて、それに直接接続されているすべてのポイント (もちろん、質問するポイントを除く) に質問します。最終目的地に到達するにはどのくらいのコストがかかりますか? 最終結果は、終了ポイントからステップごとに前方に計算し、最小のものを保持し、その他を破棄することです。 典型的な反復思考。 すべて 1 回の反復で完了します。

まず、以下のように使いやすいようにstring[]をリストにします。

注意すべき点が 1 つあります: 重要!!! 重複がある可能性があります。

次のような状況があります: A は E への最短経路を望んでいます。

A が B に質問し、B が C に質問し、C が D に質問し、D が再度 B に質問する場合があります。

したがって、通過したポイントを保存するための別のリストが必要です。検索するたびに過去を振り返ることはなく、以前に表示されたポイントに戻ることもありません。

今回見つけたルートが最短ではないかもしれないと心配しないでください。すべてのルートを一度ずつ通るので、最終的にはすべてのルートを一緒に通った後、間違いなく最短になります。

では、アルゴリズムを見てみましょう。リスト (すべてのパス情報を保存)、ポイント (それ自体)、宛先を渡し、次のホップ ポイント (通話のコストを含む) を計算します。

もちろん、このアルゴリズムは最適ではありません。繰り返し計算が行われ、最初に見つかったものを見つけるために最短経路が選択されます(そのポイントに行くたびにこの経路を取らないようにランダムに作成し、他の経路も負荷を分散できるようにする必要があります)。

参考用ですので、お気軽にご連絡ください。

JAVAバージョン:

(ベクトルはリストです)

  1. 公共 クラスFindNextRout {
  2. プライベートベクターal;
  3. プライベート文字列sourcePort;
  4. プライベート文字列destPort;
  5. プライベート文字列 nextPort;
  6. パブリックFindNextRout(ベクトル al、文字列 sourcePort、文字列 destPort) {
  7.  これ.al = al;
  8.   .sourcePort = sourcePort;です
  9.  これは.destPort = destPort;
  10. 次のルート();
  11. }
  12.  パブリック文字列getNextPort() {
  13.   nextPortを返します
  14. }
  15.  公共  void NextRout() {
  16.  整数a = - 1 ;
  17. 文字列 rout = "" ;
  18.   for (オブジェクト項目: al) {
  19. ArrayList all =新しいArrayList();
  20. 文字列[] ss = (item + "" ).split( "\\*" );
  21. すべてを追加します(ss[ 0 ]);
  22.   if (sourcePort.equals(ss[ 0 ])) {
  23.   if (ss[ 1 ].equals(destPort)) {
  24.   int b = Integer.parseInt(ss[ 2 ]);
  25.   b < a || a == - 1場合
  26. a = b;
  27. 次ポート = ss[ 1 ];
  28. }
  29. }それ以外{
  30.   int b = getLeastCost(all, ss[ 1 ], destPort);
  31.   int c = b + Integer.parseInt(ss[ 2 ]);
  32.   b != - 1場合
  33.   (a == - 1 )の場合{
  34. a = c;
  35. 次ポート = ss[ 1 ];
  36. }それ以外{
  37.  もし(c < a){
  38. a = c;
  39. 次ポート = ss[ 1 ];
  40. }
  41. }
  42. }
  43. }
  44. }
  45. }
  46.    
  47. }
  48.    
  49.  公共  int getLeastCost(ArrayList all、String sourcePort、String destPort) {
  50.  整数a = - 1 ;
  51.   if (!all.contains(sourcePort)) {
  52. すべてを追加します(ソースポート);
  53.   for (オブジェクト項目: al) {
  54. 文字列[] ss = (item + "" ).split( "\\*" );
  55.   if (sourcePort.equals(ss[ 0 ])) {
  56.   ss[ 1 ]を含む場合
  57.   if (ss[ 1 ].equals(destPort)) {
  58.   int b = Integer.parseInt(ss[ 2 ]);
  59.   b < a || a == - 1場合
  60. a = b;
  61. }
  62. }それ以外{
  63.   int b = getLeastCost(all, ss[ 1 ], destPort);
  64.   int c = b + Integer.parseInt(ss[ 2 ]);
  65.   b != - 1場合
  66.   (a == - 1 )の場合{
  67. a = c;
  68. }それ以外{
  69.  もし(c < a){
  70. a = c;
  71. }
  72. }
  73. }
  74. }
  75. }
  76. }
  77. }
  78.    
  79. }
  80.  を返します
  81. }
  82. }

Python バージョン: (Python に翻訳してくれた Zhang Dongfang に感謝します)

  1. os、sysをインポート
  2. ツールのインポートから*
  3. クラスFindNextAddress:
  4. def __init__(自己、 宛先アドレス 、 UI ):
  5. 試す
  6. 自己.nextAddress = UI.routeTable[destAddress]
  7. #アドレスがルートテーブルにあるかどうかを確認します 
  8. #UI.addline('試してみる')  
  9. を除外する
  10. #UI.addline('ex1')  
  11. 自分.UI = UI
  12. 自己.sourceAddress = UI.address
  13. 自己.destAddress = 宛先アドレス
  14. 自己.tool = tool()
  15. #UI.addline(宛先アドレス)  
  16. #UI.addline('ex2')  
  17. 自己.nextAddress =自己.findNextAddress()
  18. # アドレスがルートテーブルにない場合は、ルートを再計算します。  
  19. #UI.addline(自己.nextAddress)  
  20. #UI.addline('ex3')  
  21. def getNextAddress(自己):
  22. 戻る 自己.nextAddress
  23. #送信元から送信先までの次のアドレスを見つける 
  24. def findNextAddress(自己):
  25. a=- 1  
  26. tempNextAddress = ''  
  27. アイテム 自己.UI.routeInfo:
  28. #self.UI.addline(item+" //// アイテム")  
  29. すでにパス済み=[]
  30. 結果 = item.split( '*' )
  31. 自己.tool.addItemInList(すでにパス、結果[ 0 ])
  32. もし 自己.sourceAddress == 結果 [ 0 ]:
  33. 結果[ 1 ] == self .destAddressの場合:
  34. b = int(結果[ 2 ])
  35. b<aまたはa==- 1 の場合:
  36. a=b
  37. tempNextAddress = 結果[ 1 ]
  38. それ以外
  39. b = self.getLeastCost (alreadyPass,result[ 1 ], self.destAddress ) です。
  40. c=b+int(結果[ 2 ])
  41. b != - 1 の場合:
  42. a==- 1 の場合:
  43. a=c
  44. tempNextAddress = 結果[ 1 ]
  45. それ以外
  46. c<aの場合:
  47. a=c
  48. tempNextAddress = 結果[ 1 ]
  49. tempNextAddressを返す
  50. #最も適切なパスを取得する 
  51. def getLeastCost( self 、 alreadyPass 、 sourceAddress 、 destAddress ):
  52. a=- 159判定=自己.tool.search(alreadyPass,sourceAddress)
  53. 判定がFalseの場合:
  54. 自己.tool.addItemInList(すでにパス、ソースアドレス)
  55. アイテム 自己.UI.routeInfo:
  56. 結果 = item.split( '*' )
  57. sourceAddress==result[ 0 ]の場合:
  58. 判断 =自己.tool.search(alreadyPass,結果[ 1 ])
  59. 判定がFalseの場合:
  60. 結果[ 1 ] == 宛先アドレスの場合:
  61. b = int(結果[ 2 ])
  62. b<aまたはa==- 1 の場合:
  63. a=b
  64. それ以外
  65. b = self .getLeastCost(alreadyPass,result[ 1 ],destAddress)
  66. c=b+int(結果[ 2 ])
  67. b!=- 1の場合:
  68. a == - 1 の場合 またはc<a:
  69. a=c
  70. 返す

さて、次にパス情報が変更になった場合にどうするかについて説明します。

パス情報が変更されました。簡単に言えば、ルーティング テーブル全体を削除して再計算します。これをルーティング テーブルの更新と呼びます。

パスが更新されると、コンピュータはどの部分が更新されたかを直接確認できず、どのポイントを計算することもできません。コンピュータは、すべてを再度確認する必要があります。確認したので、再計算しても違いがないため、すべて削除することができます。 ルーティング テーブルを使用する場合、どの宛先に行きたいかを計算し、計算を保存します。次回必要になったときに、保存した情報にジャンプするだけです。必要ない場合は、無視します。このように、すべての宛先が一度に送信されていない場合は、パス情報が更新されます。使用されていない宛先はまったく計算されず、計算する必要もありません。これにより、コンピューター リソースを節約できます。

オリジナルリンク: http://www.cnblogs.com/kevinGuo/archive/2011/12/07/2278702.html

【編集者のおすすめ】

  1. Java 文字エンコーディングの基礎
  2. Java でのオブジェクト等価性の比較
  3. Javaカスタム例外クラス
  4. Java プログラミング: データの切り捨てと丸め
  5. Aスターアルゴリズムの実装手順のJavaバージョン

<<:  HASHアルゴリズムとCSDNパスワード漏洩事件についての簡単な説明

>>:  Aスターアルゴリズムの実装手順のJavaバージョン

ブログ    

推薦する

ディープラーニングモデルは「大きいほど良い」というわけではなく、気候変動問題を引き起こす可能性がある

今月初め、OpenAIは、史上最大の人工知能モデルを構築したと発表した。これは「GPT-3」と名付け...

...

...

MITとGoogle BrainはAIを使って「現代のロゼッタストーン」として知られる失われた古代の文書を解読する

この記事はAI新メディアQuantum Bit(公開アカウントID:QbitAI)より許可を得て転載...

2019 年の NLP における最先端のブレークスルーを振り返る

この記事はAI新メディアQuantum Bit(公開アカウントID:QbitAI)より許可を得て転載...

...

DragGANはオープンソース化から3日間で23,000のスターを獲得し、DragDiffusionが登場しました。

AIGC の魔法の世界では、画像を「ドラッグ」することで、必要な画像を変更したり合成したりできます...

AI、エッジコンピューティング、IoT、クラウドコンピューティングが車両管理をどのように変えるのか

毎日生成されるデータの量は増加し続けています。その結果、これらの企業はこれまで以上に多くのデータを保...

データセンターで AI を活用する 5 つの理由

人工知能はかなり前から存在しており、その継続的な開発により、パフォーマンスの向上とコストの削減という...

...

...

無料ですか?寄生? ChatGPTに夢中です!

51CTOウェブサイトコンテンツ調査に参加するにはクリックしてくださいマット・アセイ編纂者:Qia...

MD5アルゴリズムの暗号化プロセス

MD5とは何か MD5 はアルゴリズムです。MD5 の MD はMessage Digest の略で...

Reverse Midjourneyがオンラインになりました!デジタルアーティストがスティーブ・ジョブズに魅了され、写真がボルヘスの精神世界に入る

ブラウザに住むアーティストが開発した、ニューヨーク発のAIカメラアプリが人気を集めている。もしスティ...