3

I'm a new programmer, and I'm working through Stanford's algorithms course on edX.

One of the programming assignments is to find strongly connected components using Kosaraju's algorithm, on a graph with ~1,000,000 vertices. My implementation is the most basic translation from the textbook's pseudo code into Python, and it works fine on smaller graphs, so I think it's correct.

With Python's default recursion limit of 1000 it reaches the limit.

I've tried sys.setrecursionlimit(1000000), but that doesn't help, and instead I get "Process finished with exit code -1073741571" which is a stack overflow.

I found these two pages for increasing stack size limits, but am not sure how to use either of them: Set stack size, ulimit command.

Another relevant bit of information is that Python doesn't optimize tail recursion, but I'm not sure that applies to my code as it currently is.

G = {}
for i in range(1, 875715):
    G[i] = [0]
for l in open('SCC.txt'):
    items = list(map(int, l.split()))
    G[items[0]].append(items[1])

Grev = {}
for i in range(1, 875715):
    Grev[i] = [0]
for l in open('SCC.txt'):
    items = list(map(int, l.split()))
    Grev[items[1]].append(items[0])

def TopoSort(G):
    for v in G:
        if G[v][0] == 0:
            DFStopo(G, v)

def DFStopo(G, s):
    G[s][0] = 1
    global orderedVertexList
    for v in G[s][1:]:
        if G[v][0] == 0:
            DFStopo(G, v)
    orderedVertexList.insert(0, s)

def Kosaraju(G, Grev):
    TopoSort(Grev)
    global numSCC
    for v in orderedVertexList:
        if G[v][0] == 0:
            numSCC = numSCC + 1
            DFSSCC(G, v)

def DFSSCC(G, s):
    G[s][0] = 1
    global SCC
    SCC.append(numSCC)
    for v in G[s][1:]:
        if G[v][0] == 0:
            DFSSCC(G, v)

numSCC = 0
orderedVertexList = []
SCC = []

Kosaraju(copy.deepcopy(G), copy.deepcopy(Grev))
Adam Tolnay
  • 139
  • 2
  • 2
    Since your code works, but you need help optimizing it, you might also ask on the [codereview.se] stack site – G. Anderson Sep 03 '20 at 22:08
  • 1
    it's very common to build your own programmatic stack instead of relying on recursion stack. – M Z Sep 03 '20 at 22:09
  • 1
    I suspect using nested lists of `int` objects uses far more memory than you really need. Consider using a `numpy` array instead. – chepner Sep 03 '20 at 22:13
  • 1
    +1 WRT @MZ's comment. Eliminating recursion in favor of an outer loop, and using your own stack to keep track of the state of your algorithm, is how I'd approach your problem. – CryptoFool Sep 03 '20 at 22:58
  • 2
    [Re-posted on CR](https://codereview.stackexchange.com/q/248900). @G.Anderson: I usually link to the [on-topic page](https://codereview.stackexchange.com/help/on-topic) when referring a user to a different forum, occasionally to [How do I ask a Good Question?](https://codereview.stackexchange.com/help/how-to-ask) – greybeard Sep 04 '20 at 06:22

0 Answers0