[アルゴリズム]Dijkstra'sアルゴリズム


最短パスアルゴリズム


最短パスアルゴリズムは、2つのノードを接続する最短パスを探すアルゴリズムです.
  • 重み付け図と幹線重み付け値の和を最小にする方法を探ることを目的とする.
  • 最短パス問題タイプ
  • 単点出発単点到達問題(単点源と単点目的地の最短経路問題):出発地と目的地が与えられ、その間に最短経路を探す問題.
  • 単一出発問題(単一ソース最短パス問題)
  • 全対題(all-pair):出発地と目的地がない場合、すべてのペアの最短経路を検索する問題
  • の代表的なアルゴリズムには複数のアルゴリズムがある.
  • Dijkstra'sアルゴリズム

  • マルチ出口アルゴリズムは典型的な最短経路アルゴリズムであり、単一の出発問題に対して、1つの頂点から別の頂点までの最短距離を求めるアルゴリズムである.
  • の最初のノードを基準に、接続ノードを追加し、最短距離を更新する方法.
  • 人工衛星GPSソフトなどによく用いられる.
  • 幅優先探索(BFS)と同様である.
  • 以前からノードまでの最短距離を用いて,問題を動的プログラミング問題と見なす.
  • 全体の順序
  • 初期ノードの距離は0であり、他のノードの距離は無限大である.
  • 最初の頂点情報は、
  • PriorityQueueにのみ追加されます.
  • PriorityQueueでは、ノード(u)に接続されているノード(v)を参照するノードがポップアップされ、接続されているvのエッジの重量+uの距離がvの距離よりも小さい場合は、値が更新され、Queueにvが追加されます.
  • PriorityQueueが許しを請うまで、
  • 3番の授業を繰り返します.
  • マルチカーブアルゴリズムの実装



    👨🏻‍💻 コード実装のために作成されたオブジェクト。


    コードを実装するために、ノード名とウェイト情報、および最終結果を格納するノード情報と最終距離を含むノードDistanceオブジェクトを作成しました.NodeDistanceオブジェクトはPriorityQueueでポーリングするため、Compareableメソッドを再定義します.
    class NodeWeight {
    	char node;
    	int weight;
    	
    
    	public NodeWeight(char node, int weight) {
    		this.node = node; 
    		this.weight = weight;
    	}
    	
    }
    
    class NodeDistance  implements Comparable<NodeDistance>{
    	char node; 
    	int distance;
    	
    	public NodeDistance(char node, int distance) {
    		this.node = node;
    		this.distance = distance;
    	}
    	
    	@Override
    	public int compareTo(NodeDistance o) {
    		// TODO Auto-generated method stub
    		return this.distance > o.distance? 1:-1;
    	}	
    }

    👨🏻‍💻 Full Code

    package algorithm;
    
    import java.util.*;
    
    class NodeWeight {
    	char node;
    	int weight;
    	
    
    	public NodeWeight(char node, int weight) {
    		this.node = node; 
    		this.weight = weight;
    	}
    	
    }
    
    class NodeDistance  implements Comparable<NodeDistance>{
    	char node; 
    	int distance;
    	
    	public NodeDistance(char node, int distance) {
    		this.node = node;
    		this.distance = distance;
    	}
    	
    	@Override
    	public int compareTo(NodeDistance o) {
    		// TODO Auto-generated method stub
    		return this.distance > o.distance? 1:-1;
    	}	
    }
    
    public class Dijkstra {
    
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		
    		// Node들의 연결점, 가중치를 갖고 있는 map
    		HashMap<Character, NodeWeight[]> map = new HashMap<>();
    		NodeWeight[] temp = new NodeWeight[3];
    		temp[0] = new NodeWeight('B', 8);
    		temp[1] = new NodeWeight('C', 1);
    		temp[2] = new NodeWeight('D', 2);
    		map.put('A', temp);
    
    		temp = new NodeWeight[0];
    		map.put('B', temp);
    		
    		temp = new NodeWeight[2];
    		temp[0] = new NodeWeight('B', 5);
    		temp[1] = new NodeWeight('D', 2);
    		map.put('C', temp);
    
    		temp = new NodeWeight[2];
    		temp[0] = new NodeWeight('E', 3);
    		temp[1] = new NodeWeight('F', 5);
    		map.put('D', temp);
    		
    		temp = new NodeWeight[1];
    		temp[0] = new NodeWeight('F', 1);
    		map.put('E', temp);
    
    		temp = new NodeWeight[1];
    		temp[0] = new NodeWeight('A', 5);
    		map.put('F', temp);
    
    
    		HashMap<Character, NodeDistance> result = dijkstra(map, 'A');
    		for (Character c: result.keySet()) {
    			System.out.println(result.get(c).node + ", " + result.get(c).distance);
    		}
    		
    	}
    	
    	public static HashMap<Character, NodeDistance> dijkstra(HashMap<Character, NodeWeight[]> map, char start) {
    		
    		HashMap<Character, NodeDistance> distance = new HashMap<>();
    		for (Character c : map.keySet()) {
    			if (c == start) {
    				distance.put(c, new NodeDistance(c, 0));
    				continue;
    			}
    			distance.put(c, new NodeDistance(c, 1000)); // 무한대 대신 임시로 1000대임
    		}
    		
    		PriorityQueue<NodeDistance> queue = new PriorityQueue<>();
    		queue.offer(distance.get(start));
    		
    		while(!queue.isEmpty()) {
    			NodeDistance currentNode = queue.poll();
    			//System.out.println(currentNode.node + ", "+ currentNode.distance);
    			
    			if (currentNode.distance > distance.get(currentNode.node).distance)
    				continue;
    			
    			for (NodeWeight n: map.get(currentNode.node)) {
    			
    				int newDistance = currentNode.distance + n.weight;
    				
    				// 현재 위치한 node+ 현재 node로 부터 연결된 node의 weight이 현재 연결된 node에 저장된 거리보다 작으면 값 변경
    				if(newDistance < distance.get(n.node).distance) {
    					distance.put(n.node, new NodeDistance(n.node, newDistance));
    					queue.offer(new NodeDistance(n.node, newDistance));
    				}
    			}			
    		}
    		return distance;
    	}
    
    }
    

    時間の複雑さ


    「Daextra」という1各ノードのすべての隣接するエッジのプロシージャと2を確認します.ノード/距離情報を優先キューに追加し、削除します.
    各ノードが隣接するすべてのエッジをチェックする場合、すべてのエッジをチェックするにはO(E)の時間が必要です.
  • すべてのEdgeをチェックし、更新距離がより少ない場合、PriorityQueueは対応するノード情報を追加します.最悪の場合、追加操作は各Edgeで1回発生する可能性があり、O(E)時間がかかり、O(E)ノード/距離情報の優先キューが保持されます.𝑂(𝑙𝑜𝑔𝐸)必要です.
  • 従って、全O(E)+O(ElogE)=O(E+ElogE)=O(ElogE)は時間的複雑さを必要とする.

    🔗 Reference

  • Fast Campas-JavaとSpring Web開発のプライマリ・ハイパー・パケットのオンライン化を一度に完了します。
  • https://blog.naver.com/PostView.naver?blogId=ndb796&logNo=221234424646&redirect=Dlog&widgetTypeCall=true&directAccess=false