Quantcast
Channel: Active questions tagged python - Stack Overflow
Viewing all articles
Browse latest Browse all 14011

lru_cache vs dynamic programming, stackoverflow with one but not with the other?

$
0
0

I'm doing this basic dp (Dynamic Programming) problem on trees (https://cses.fi/problemset/task/1674/). Given the structure of a company (hierarchy is a tree), the task is to calculate for each employee the number of their subordinates.

This:

import sysfrom functools import lru_cache  # noqasys.setrecursionlimit(2 * 10 ** 9)if __name__ == "__main__":    n: int = 200000    boss: list[int] = list(range(1, 200001))      # so in my example it will be a tree with every parent having one child    graph: list[list[int]] = [[] for _ in range(n)]    for i in range(n-1):        graph[boss[i] - 1].append(i+1)  # directed so neighbours of a node are only its children    @lru_cache(None)    def dfs(v: int) -> int:        if len(graph[v]) == 0:            return 0        else:            s: int = 0            for u in graph[v]:                s += dfs(u) + 1            return s    dfs(0)    print(*(dfs(i) for i in range(n)))

crashes (I googled the error message and it means stack overflow)

Process finished with exit code -1073741571 (0xC00000FD)

HOWEVER

import syssys.setrecursionlimit(2 * 10 ** 9)if __name__ == "__main__":    n: int = 200000    boss: list[int] = list(range(1, 200001))    # so in my example it will be a tree with every parent having one child    graph: list[list[int]] = [[] for _ in range(n)]    for i in range(n-1):        graph[boss[i] - 1].append(i+1)  # directed so neighbours of a node are only its children    dp: list[int] = [0 for _ in range(n)]    def dfs(v: int) -> None:        if len(graph[v]) == 0:            dp[v] = 0        else:            for u in graph[v]:                dfs(u)                dp[v] += dp[u] + 1    dfs(0)    print(*dp)

doesn't and it's exactly the same complexity right? The dfs goes exactly as deep in both situations too? I tried to make the two pieces of code as similar as I could.

I tried 20000000 instead of 200000 (i.e. graph 100 times deeper) and it still doesn't stackoverflow for the second option. Obviously I could do an iterative version of it but I'm trying to understand the underlying reason why there are such a big difference between those two recursive options so that I can learn more about Python and its underlying functionning.

I'm using Python 3.11.1.


Viewing all articles
Browse latest Browse all 14011

Trending Articles