๐Ÿ•ท๏ธ Crawler Inspector

URL Lookup

Direct Parameter Lookup

Raw Queries and Responses

1. Shard Calculation

Query:
Response:
Calculated Shard: 143 (from laksa053)

2. Crawled Status Check

Query:
Response:

3. Robots.txt Check

Query:
Response:

4. Spam/Ban Check

Query:
Response:

5. Seen Status Check

โ„น๏ธ Skipped - page is already crawled

๐Ÿšซ
NOT INDEXABLE
โœ…
CRAWLED
7 months ago
๐Ÿค–
ROBOTS ALLOWED

Page Info Filters

FilterStatusConditionDetails
HTTP statusPASSdownload_http_code = 200HTTP 200
Age cutoffFAILdownload_stamp > now() - 6 MONTH7.5 months ago
History dropPASSisNull(history_drop_reason)No drop reason
Spam/banPASSfh_dont_index != 1 AND ml_spam_score = 0ml_spam_score=0
CanonicalPASSmeta_canonical IS NULL OR = '' OR = src_unparsedNot set

Page Details

PropertyValue
URLhttps://sungwookyoo.github.io/algorithms/BellmanFord/
Last Crawled2025-09-05 17:44:57 (7 months ago)
First Indexed2021-03-12 14:01:55 (5 years ago)
HTTP Status Code200
Meta TitleBellman-Ford and DAG Algorithms in Python - Wookโ€™s Blog - Data is the new oil
Meta DescriptionSingle source shortest path Algorithm
Meta Canonicalnull
Boilerpipe Text
1 2 3 4 5 6 7 8 9 import sys , random , string sys . path . append ( "/home/swyoo/algorithm/" ) from utils.verbose import visualize_graph , logging_time from utils.generator import randomString from collections import defaultdict from pprint import pprint from copy import deepcopy from typing import List , Tuple import numpy as np 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 def generate_graph ( n , m , randrange : Tuple [ int , int ], verbose = False ): """ |V|: n, |E|: m """ # S = set(' '.join(string.ascii_lowercase).split()[:n]) S = set ( range ( n )) seen = set () edges = [] for _ in range ( m ): while True : # start = randomString(length=1, samples=list(S)) # end = randomString(length=1, samples=list(S - {start})) while True : start , end = random . choices ( population = range ( n - 1 ), k = 2 ) if start != end : break if ( start , end ) not in seen : seen . add (( start , end )) break edges . append (( start , end , random . randint ( randrange [ 0 ], randrange [ 1 ]))) if verbose : visualize_graph ( edges , weighted = True ) graph = defaultdict ( list ) for i in S : graph [ i ] for u , v , w in edges : graph [ u ]. append (( v , w )) return graph , edges INF = 1e20 def g2m ( graph ): n , nodes = len ( graph . keys ()), sorted ( graph . keys ()) n2i = { k : v for k , v in zip ( nodes , range ( n ))} weights = [[ INF ] * n for _ in range ( n )] for i in nodes : weights [ n2i [ i ]][ n2i [ i ]] = 0 for i in nodes : for j , w in graph [ i ]: weights [ n2i [ i ]][ n2i [ j ]] = w return n2i , weights def hasNcycles ( weights , verbose = False ): n = len ( weights ) ans = deepcopy ( weights ) for k in range ( n ): for i in range ( n ): for j in range ( n ): ans [ i ][ j ] = min ( ans [ i ][ j ], ans [ i ][ k ] + ans [ k ][ j ]) # check if negative cycle exist for i in range ( n ): if ans [ i ][ i ] < 0 : if verbose : print ( "negative cycle exists from node[{}] to node[{}]" . format ( i , i )) return True return False def generate_graph_no_neg_cycle ( n , m , randrange ): weights = graph = None while True : graph , edges = generate_graph ( n , m , randrange , verbose = False ) n2i , W = g2m ( graph ) if not hasNcycles ( W ): weights = deepcopy ( W ) return n2i , weights , graph , edges n , m = 5 , 7 n2i , weights , graph , edges = generate_graph_no_neg_cycle ( n , m , randrange = ( - 10 , 100 )) visualize_graph ( edges = edges , weighted = True ) graph 1 2 3 4 5 6 defaultdict(list, {0: [(1, 48), (2, -9)], 1: [(2, 0)], 2: [(1, 72), (3, 26)], 3: [(1, 3), (2, 95)], 4: []}) ๊ธฐ๋ณธ๊ฐ€์ •: no negative weight cycle(์žˆ๋‹ค๋ฉด False return) Dijkstraโ€™s algorithm๊ณผ ๋‹ฌ๋ฆฌ Bellman Ford ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ๊ฐ€์ค‘์น˜๊ฐ€ ์Œ์ˆ˜์ธ ๊ฒฝ์šฐ์—๋„ ์ ์šฉ ๊ฐ€๋Šฅ. ์Œ์ˆ˜ ๊ฐ€์ค‘์น˜๊ฐ€ ์‚ฌ์ดํด(cycle)์„ ์ด๋ฃจ๊ณ  ์žˆ๋Š” ๊ฒฝ์šฐ์—๋Š” ์ž‘๋™ํ•˜์ง€ ์•Š๋Š”๋‹ค. naive ํ•˜๊ฒŒ ๊ทธ๋ž˜ํ”„ ์ •์  ์ˆ˜๋งŒํผ ๊ทธ๋ž˜ํ”„ ๋‚ด ๋ชจ๋“  ์—ฃ์ง€์— ๋Œ€ํ•ด edge relaxation ์„ ์ˆ˜ํ–‰ ํ•œ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด (negative weight cycle ์ด ์—†๋‹ค๋Š” ๊ฐ€์ •ํ•˜์—) ๋ชจ๋“  ์ •์ ์ˆ˜ ๋งŒํผ์˜ relaxation ์„ ๋Œ์•˜์„๋•Œ, shortest path๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ๋‹ค. Pseudo Code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 Bellman ( G , s ) # shortest distance ๊ฐ’์„ ์ €์žฅํ•  array let d [ 1 .. | G . V | ] be a new array # initialization d [ k ] = INF for all k in G . V except for k == s d [ s ] = 0 # edge relaxations for all cases O(VE) for i = 1 to | G . V | for ( u , v ) in G . E if d [ v ] > d [ u ] + w ( u , v ) d [ v ] = d [ u ] + w ( u , v ) # check whether eixist negative weight cycle # negative weight cycle ๊ฐ€ ์žˆ๋‹ค๋ฉด edge relaxation์„ ํ–ˆ์„๋•Œ # shortest path distance๋ณด๋‹ค ์ž‘์€ distance ๊ฐ€ ์กด์žฌ ํ•  ๊ฒƒ์ด๋‹ค. for ( u , v ) in G . E if d [ v ] > d [ u ] + w ( u , v ) return False return d Time Complexity ๋ชจ๋“  cases ์— ๋Œ€ํ•ด edge relaxation์„ ์ˆ˜ํ–‰ํ•ด์•ผํ•˜๋ฏ€๋กœ $T(n) =O(VE)$ c++ python Implementation graph ์˜ ์—ฃ์ง€์ •๋ณด์ธ edges ์™€ ๋…ธ๋“œ์˜ ์ด ๊ฐœ์ˆ˜ $n$ ๋งŒ ์•Œ๋ฉด ๋œ๋‹ค. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 INF = 1e20 n = len ( graph . keys ()) @ logging_time def bellman ( src , edges , n ): ans = [ INF ] * n ans [ src ] = 0 for _ in range ( n ): for i , j , w in edges : ans [ j ] = min ( ans [ j ], ans [ i ] + w ) for i , j , w in edges : if ans [ j ] > ans [ i ] + w : return False # detect negative weight cycle. return ans 1 2 3 4 5 6 7 n , m = 5 , 7 n2i , weights , graph , edges = generate_graph_no_neg_cycle ( n , m , randrange = ( - 10 , 100 )) visualize_graph ( edges = edges , weighted = True ) pprint ( graph ) print ( edges ) print ( "after run bellman ford algorithm ..." ) bellman ( 0 , edges , n , verbose = True ) 1 2 3 4 5 6 7 8 9 10 defaultdict(<class 'list'>, {0: [(2, 86), (3, 99)], 1: [(2, 79), (3, 23)], 2: [(3, 54), (0, 29)], 3: [(0, 0)], 4: []}) [(0, 2, 86), (0, 3, 99), (2, 3, 54), (2, 0, 29), (1, 2, 79), (3, 0, 0), (1, 3, 23)] after run bellman ford algorithm ... WorkingTime[bellman]: 0.01311 ms 1 [0, 1e+20, 86, 99, 1e+20] Application It can be used to detect negative weight cycle like floyd warshall algorithm ! DAG Topological sort๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Bellman Ford ๋ฅผ ์ข€๋” ๊ฐœ์„ ํ•œ ๋ฐฉ์‹ ๊ธฐ๋ณธ๊ฐ€์ •: Topological sort๋ฅผ ์‚ฌ์šฉํ•ด์•ผํ•˜๋ฏ€๋กœ DAG์— ๋Œ€ํ•ด์„œ๋งŒ ์‚ฌ์šฉ๊ฐ€๋Šฅ Bellman ford ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ naiveํ•˜๊ฒŒ ๋ชจ๋“  ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ์˜ ์ˆ˜์— ๋Œ€ํ•ด์„œ edge relaxation ์„ ์ˆ˜ํ–‰ํ•˜์˜€๋‹ค. DAG algorithm์€ ์ข€๋” ํšจ์œจ์ ์ด๊ฒŒ topolgical sort๋ฅผ ํ•œ ์ˆœ์„œ์˜ ์ •์  ๋ฆฌ์ŠคํŠธ์— ๋Œ€ํ•ด์„œ adjacent list ๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ edge relaxation ์„ ์ˆ˜ํ–‰ Pseudo Code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 Bellman ( g , s ) let d [ 1 .. | G . V | ] be a new array # initialization d [ k ] = INF for all k in G . V except for k == s d [ s ] = 0 # edge relaxations for a efficient way L = TopoSort ( G ); for u in L for ( u , v ) in G . adj [ u ] if d [ v ] > d [ u ] + w ( u , v ) d [ v ] = d [ u ] + w ( u , v ) return d Topological sort๋ฅผ ํ•œ List ์ˆœ์œผ๋กœ ์ง„ํ–‰๋˜๋ฏ€๋กœ $T(n) =O(V + E)$ c++ python Step1. Generate DAG and Topological Sort 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 def toposort ( g : dict ): seen , finish = set (), set () topo = [] hascycle = False def dfs ( i ): nonlocal hascycle seen . add ( i ) for j , w in g [ i ]: if j not in seen : dfs ( j ) elif j not in finish : hascycle = True return topo . append ( i ), finish . add ( i ) for i in g . keys (): if i not in seen : dfs ( i ) return topo [:: - 1 ], hascycle toposort ( graph ) 1 2 3 4 5 6 7 8 def generate_graph_no_cycle ( n , m , randrange ): weights = graph = None while True : graph , edges = generate_graph ( n , m , randrange , verbose = False ) n2i , W = g2m ( graph ) if not toposort ( graph )[ 1 ]: weights = deepcopy ( W ) return n2i , weights , graph , edges 1 2 3 n2i , weights , graph , edges = generate_graph_no_cycle ( 6 , 10 , randrange = ( - 10 , 30 )) visualize_graph ( edges , weighted = True ) pprint ( graph ) 1 2 3 4 5 6 7 8 defaultdict(<class 'list'>, {0: [(1, -10), (4, 24), (3, 0)], 1: [(4, 10), (3, -5)], 2: [(0, 29), (4, -6), (3, 1), (1, 21)], 3: [], 4: [(3, 15)], 5: []}) 1 ([5, 2, 0, 1, 4, 3], False) Step 2. DAG Algorithm 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 INF = 1e20 @ logging_time def DAG ( src , g , n ): def toposort ( g : dict ): seen , finish , topo , hascycle = set (), set (), [], False def dfs ( i ): nonlocal hascycle seen . add ( i ) for j , w in g [ i ]: if j not in seen : dfs ( j ) elif j not in finish : hascycle = True return topo . append ( i ), finish . add ( i ) for i in g . keys (): if i not in seen : dfs ( i ) return topo [:: - 1 ], hascycle ans = [ INF ] * n ans [ src ] = 0 L , hascycle = toposort ( g ) for i in L : for j , w in g [ i ]: ans [ j ] = min ( ans [ j ], ans [ i ] + w ) return ans if not hascycle else False 1 2 3 4 5 n2i , weights , graph , edges = generate_graph_no_cycle ( 6 , 10 , randrange = ( - 10 , 30 )) visualize_graph ( edges , weighted = True ) pprint ( graph ) n = len ( graph . keys ()) DAG ( src = 0 , g = graph , n = n , verbose = True ) 1 2 3 4 5 6 7 8 9 defaultdict(<class 'list'>, {0: [(1, 6)], 1: [], 2: [(1, 10), (3, -5), (4, -9), (0, -3)], 3: [(1, 8), (0, 28)], 4: [(3, -4), (1, 6), (0, -6)], 5: []}) WorkingTime[DAG]: 0.01574 ms 1 [0, 6, 1e+20, 1e+20, 1e+20, 1e+20] 1 2 for i in graph . keys (): print ( DAG ( src = i , g = graph , n = n , verbose = False )[ 0 ]) 1 2 3 4 5 6 7 [0, 6, 1e+20, 1e+20, 1e+20, 1e+20] [1e+20, 0, 1e+20, 1e+20, 1e+20, 1e+20] [-15, -9, 0, -13, -9, 1e+20] [28, 8, 1e+20, 0, 1e+20, 1e+20] [-6, 0, 1e+20, -4, 0, 1e+20] [1e+20, 1e+20, 1e+20, 1e+20, 1e+20, 0] Ballman Ford vs DAG ๋น„๊ต๋ฅผ ์œ„ํ•ด์„œ๋Š” ๋‘ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ๋Œ๋ฆฌ๊ธฐ ์œ„ํ•œ ์ œํ•œ์‚ฌํ•ญ์„ ๋‘˜๋‹ค ๋งŒ์กฑํ•ด์•ผํ•œ๋‹ค. ๋”ฐ๋ผ์„œ, cycle์ด ์—†๋Š” ๋‘ ๊ทธ๋ž˜ํ”„๋ฅผ ๋งŒ๋“  ํ›„, ๋น„๊ตํ•˜๊ฒ ๋‹ค. 1 2 3 4 5 6 n2i , weights , graph , edges = generate_graph_no_cycle ( 300 , 400 , randrange = ( - 10 , 30 )) visualize_graph ( edges , weighted = True ) n = len ( weights ) ans1 = bellman ( 0 , edges , n , verbose = True ) ans2 = DAG ( src = 0 , g = graph , n = n , verbose = True ) assert ans1 == ans2 1 2 3 WorkingTime[bellman]: 28.24116 ms WorkingTime[DAG]: 0.32878 ms Reference [1] Floyd Warshall [2] Topological Sort
Markdownnull
Readable Markdownnull
Shard143 (laksa)
Root Hash2566890010099092343
Unparsed URLio,github!sungwookyoo,/algorithms/BellmanFord/ s443