'How to speed up this Python DFS search with DP?
I have the following code, which works correctly, but which runs too long on large numbers of input. I thought I had optimized it pretty well, but I can't figure out what to do next to improve runtime for large input sets.
The goal (from CodeSignal) is to check at every time interval and see if we can start a new task, based on whether or not its precedent tasks have finished - and then return an array of the tasks with their start times.
def dfs(node, adj, dp, vis):
vis[node] = True
for i in range(0, len(adj[node])):
if not vis[adj[node][i]]:
dfs(adj[node][i], adj, dp, vis)
dp[node] = max(dp[node], 1 + dp[adj[node][i]])
def addEdge(adj, u, v):
adj[u].append(v)
def findLongestPath(adj, n):
global dp
dp = [0] * (n + 1)
vis = [False] * (n + 1)
for i in range(1, n + 1):
if not vis[i]:
dfs(i, adj, dp, vis)
def solution(quota,inputs,duration):
n=len(inputs)
adj=[[] for i in range(n + 1)]
for i in range(n):
p=inputs[i]
for j in range(len(p)):
addEdge(adj,p[j],i)
findLongestPath(adj,n)
done=0
moment=0
einterval=1
result=[-1]*(n)
status=[-1]*(n)
elapsed=[-1]*(n)
quotaused=0
nextmoment=float('inf')
dpmap=[]
for i in range(n):
dpmap.append([])
mmoments=[float('inf')]*(n)
for i in range(len(dpmap)):
dpmap[i]=[]
for t in range(len(dp)-1):
index=dp[t]
dpmap[index].append(t)
while (done==0):
done=1
nextmoment=float('inf')
for i in range(n):
if (elapsed[i]>=0):
elapsed[i]=elapsed[i]+einterval
if (elapsed[i]==duration[i]):
status[i]=2
mmoments[i]=float('inf')
quotaused=quotaused -1
for i in range(n):
if (status[i]==-1):
ready=1
for t in range(len(inputs[i])):
task=inputs[i][t]
if (status[task]<2):
ready=0
break
if (ready==1):
status[i]=0
for l in range(len(dpmap)-1,-1,-1):
if (quotaused==quota):
break
for t in range(len(dpmap[l])):
task=dpmap[l][t]
if (status[task]==0):
status[task]=1
elapsed[task]=0
quotaused=quotaused +1
result[task]=moment
mmoments[task]=moment+duration[task]
done=0
if (quotaused==quota):
break
for i in range(n):
nextmoment=min(nextmoment,mmoments[i])
einterval=nextmoment-moment
moment=nextmoment
if (done==1):
for i in range(n):
if (result[i]==-1):
done=0
break
return result
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
