|
1553 | 1553 | - Links between webpages
|
1554 | 1554 | - Followers on social network
|
1555 | 1555 | - Dependencies between tasks
|
| 1556 | +- Any path with at least |V| edges contains a cycle |
1556 | 1557 | - For more details:
|
1557 | 1558 | - UC San Diego Course: [Basics](https://github.com/hamidgasmi/training.computerscience.algorithms-datastructures/blob/master/3-graph-algorithms/1_graph_decomposition/09_graph_decomposition_1_basics.pdf)
|
1558 | 1559 | - UC San Diego Course: [Representation](https://github.com/hamidgasmi/training.computerscience.algorithms-datastructures/blob/master/3-graph-algorithms/1_graph_decomposition/09_graph_decomposition_2_representations.pdf)
|
|
1850 | 1851 | - **Weighted** Graph:
|
1851 | 1852 | - It's a directed or undirected graph where
|
1852 | 1853 | - Every edge between 2 nodes (μ, ν) has a weight: **ω(μ, ν)**
|
1853 |
| -- For Dijkstra's algorithm ω(μ, ν) > |
1854 | 1854 | - **ω-length** of a Path:
|
1855 | 1855 | - It's denoted as: **Lω(P)**
|
1856 | 1856 | - For a path P: μ0, μ1, ..., μn
|
|
1864 | 1864 | - dω(μ, ν) = ∞ for all not connected μ and ν
|
1865 | 1865 | - Implementation, Time Complexity:
|
1866 | 1866 | - Dijkstra(G, A):
|
1867 |
| - for all u in G.V: #Initializations |
| 1867 | + for all u in G.V: # Initializations |
1868 | 1868 | dist[u] ← ∞
|
1869 | 1869 | prev[u] ← nil
|
1870 | 1870 | dist[A] ← 0
|
1871 |
| - H ← MakeQueue(V) #dist-value as keys |
| 1871 | + H ← MakeQueue(V) # dist-value as keys |
1872 | 1872 | while H is not empty:
|
1873 | 1873 | u ← H.ExtractMin(H)
|
1874 | 1874 | for v in u.E:
|
1875 |
| - if dist[v] > dist[u] + w(u, v) |
1876 |
| - dist[v] ← dist[u] + w(u, v) |
1877 |
| - prev[v] ← u |
1878 |
| - H.ChangePriority(v, dist[v]) |
| 1875 | + Relax(G, H, u, v, dist, prev) |
| 1876 | + - Relax(G, H, u, v, dist, prev) # Relax v |
| 1877 | + if dist[v] > dist[u] + w(u, v) |
| 1878 | + dist[v] ← dist[u] + w(u, v) |
| 1879 | + prev[v] ← u |
| 1880 | + H.ChangePriority(v, dist[v]) |
1879 | 1881 | - ReconstructPath(A, μ, prev):
|
1880 |
| - Similar as BFS ReconstructPath algorithm |
| 1882 | + Same as BFS ReconstructPath algorithm |
1881 | 1883 | - Time Complexity:
|
1882 | 1884 | - T(n) = T(Initializations) + T(H.MakeQueue) + |V|*T(H.ExtractMin) + |E|*T(H.ChangePriority)
|
1883 | 1885 | - Priority Queue could be implemented as an **Array**
|
|
1894 | 1896 | - In case of **dense graph**:
|
1895 | 1897 | - |E| ≈ |V|^2
|
1896 | 1898 | - **Array implementation is more efficient**: T(n) = O(|V|^2)
|
| 1899 | +- Conditions: |
| 1900 | + - **ω(μ, ν) ≥ 0** for all μ, ν in G |
| 1901 | + - E.g., see the graph below and compute Dijkstra(G, S) |
| 1902 | + - The result dist[A] = +5 => it's wrong! |
| 1903 | + - This is because Dijkstra's algorithm relies on the fact that a shortest path from s to t goes only through vertices that are closer to s than t |
| 1904 | + - t |
| 1905 | + 5/ | |
| 1906 | + S | -20 |
| 1907 | + 10\ | |
| 1908 | + B |
1897 | 1909 | - Related Problems:
|
1898 | 1910 | - [Computing the Minimum Cost of a Flight](https://github.com/hamidgasmi/training.computerscience.algorithms-datastructures/issues/133)
|
1899 | 1911 | - For more details:
|
|
1905 | 1917 | <details>
|
1906 | 1918 | <summary>Bellman-Ford algorithm</summary>
|
1907 | 1919 |
|
| 1920 | +- A **Negative weight cycle**: |
| 1921 | + - In the example below the negate cycle is: A → B → C → A => Lω(A → B → C → A) = 1 - 3 - 2 = -4 |
| 1922 | + - -2 |
| 1923 | + A ←←← C |
| 1924 | + 4↗ 1↘ ↗-3 |
| 1925 | + S B |
| 1926 | + - By going ∞ of time around the negative cycle: |
| 1927 | + - The result is that the distance between S to any connected node ν in the Graph is -∞ |
| 1928 | + - d(S, A) = d(S, B) = d(S, C) = d(S, D) = -∞ |
| 1929 | +- Conditions: |
| 1930 | + - There is no restriction on the weight: ω(μ, ν) (it could be positive or negative) |
| 1931 | + - But it must not exist any negative weight cycle in the graph |
| 1932 | +- Implementation, Time Complexity: |
| 1933 | + - Bellman-Ford(G, S): |
| 1934 | + #no negative weight cycles in G |
| 1935 | + for all u ∈ V : |
| 1936 | + dist[u] ← ∞ |
| 1937 | + prev[u] ← nil |
| 1938 | + dist[S] ← 0 |
| 1939 | + repeat |V| − 1 times: |
| 1940 | + for all (u, v) ∈ G.E: |
| 1941 | + Relax(u, v) |
| 1942 | + - Relax(G, H, u, v, dist, prev) # Relax v |
| 1943 | + Same as BFS Relax algorithm |
| 1944 | + - ReconstructPath(A, μ, prev): |
| 1945 | + Same as BFS ReconstructPath algorithm |
| 1946 | + - Time Complexity: **O(|V||E|)** |
| 1947 | +- Find Negative Cycles: |
| 1948 | + - A graph G contains a negative weight cycle if and only if |V|-th (additional) iteration of BellmanFord(G , S) updates some dist-value |
1908 | 1949 | - Related Problems:
|
| 1950 | + - Maximum product over paths: |
| 1951 | + - 0.88 0.84 8.08 |
| 1952 | + US -----> EUR ------> GBP ------> ... -> NOK ------> RUB |
| 1953 | + $1 €1 * 0.88 £1 * 0.88 * 0.84 ₽1 * 0.88 * 0.84 * ... * 8.08 (Product) |
| 1954 | + - Input: Currency exchange graph with weighted directed edges ei between some pairs of currencies with weights rei corresponding to the exchange rate |
| 1955 | + - Output: k |
| 1956 | + Maximize ∏ rej = re1 * re2 * ... * rek over paths (e1, e2, ..., ek) from USD to RUP in the graph |
| 1957 | + j=1 |
| 1958 | + - This could be reduce to a short path roblem by: |
| 1959 | + - Replace product with sum by taking logarithms of weights |
| 1960 | + - Negate weights to solve minimization problem instead of maximization problem |
| 1961 | + - k k k |
| 1962 | + Max ∏ rej <=> Max ∑ log(rej) <=> Min ∑ ( - log(rej)) |
| 1963 | + j=1 j=1 j=1 |
| 1964 | + - The new problem is: Find the shortest path between USD and RUR in a weighted graph where **ω(rei) = (− log(rei))** |
1909 | 1965 | - [Detecting Anomalies in Currency Exchange Rates](https://github.com/hamidgasmi/training.computerscience.algorithms-datastructures/issues/134)
|
1910 | 1966 | - [Exchanging Money Optimally](https://github.com/hamidgasmi/training.computerscience.algorithms-datastructures/issues/135)
|
1911 | 1967 | - For more details:
|
|
0 commit comments