Resuming a recursive function from a saved state

I have a recursive function that produces all combinations of length k from the set n. Commonly referred to as "nCk" ("n selects k"). I want to get rid of it with rather large values ​​(56C22), which will produce 2 142 582 442 263 900 results. Due to implementation restrictions (I have to use VBScript and cannot stay on the computer for longer than I was at work), I can’t let it work until it is complete in one go. Thus, I would like to periodically save the current state of the function and resume it later ... but I cannot figure out how to do this. Recursion is tinkering with my ability to think it logically.

I reviewed the proposed solutions here on SO and otherwise searched for “resuming a recursive function” and the like, but to no avail. I would appreciate some pointers (NOT a pun for programming) to get me on the right track.

The actual algorithm (pseudo-code in order) is preferable to a long explanation that does not include the actual code. If you want to actually encode it, I am most familiar with C, C ++, Pascal, VB, JavaScript and VBScript (and, as indicated, works with VBScript at the moment).

Here is my recursive function:

function nCk(aSet, iSetIndex, aSubset, iSubsetIndex)
    'Found result
    if (iSubsetIndex > ubound(aSubset)) then
        log "output.txt", join(aSubset), 1, false

        exit function
    end if

    'No more characters available
    if (iSetIndex >= ubound(aSet) + 1) then
        exit function
    end if

    'With aSet[iSetIndex]
    aSubset(iSubsetIndex) = aSet(iSetIndex)
    nCk aSet, iSetIndex + 1, aSubset, iSubsetIndex + 1

    'Without
    nCk aSet, iSetIndex + 1, aSubset, iSubsetIndex
end function  'nCk

FYI: I am 50 years old; this is not homework.

+4
source share
2 answers

, , . , , . , / .

:

  • 0s 1s. 0 , , 1 - [1, 0, 1] {1,2,3} {1,3}. , N .
  • , ""
  • -1 → / .

(-, ):

def calc_subsets(state, N):#N - number of elements in the original set
     while True: #just iterate
        if storeFlag:#you need to set this flag to store and interrupt
            store(state)
            return
        if len(state)==N and state[-1]!=-1: #a full subset is reached
            evaluate(state)
            state.append(-1)#mark for unwind

        if state[-1]==-1:#means unwind state
            state.pop()
            if not state: #state is empty
                return #unwinded last element, we are done
            if state[-1]==1:#there is noting more to be explored
               state[-1]=-1#mark for unwind in the next iteration
            else:# = 0 is explored, so 1 is the next to explore
               state[-1]=1
        else: #means explore
            state.append(0) # 0 is the first to explore

evaluate , :

def evaluate(state):
    print state

3 , :

calc_subsets([0], 3)
>>>
[0, 0, 0]
[0, 0, 1]
[0, 1, 0]
[0, 1, 1]
[1, 0, 0]
[1, 0, 1]
[1, 1, 0]
[1, 1, 1]

:

calc_subsets([0,1,1,-1], 3) 
>>>
[1, 0, 0]
[1, 0, 1]
[1, 1, 0]
[1, 1, 1]

. ( -1 ), .

0

, , . , , , .

:

stack = [[argument1,argument2,argument3,...etc.]]

while stack is not empty
  current_parameters = stack.pop

  aSet      = current_parameters[0]
  iSetIndex = current_parameters[1]
  ...etc.

  if ...

else ...
    // push to stack instead of calling nCk
    stack.push([aSet, iSetIndex + 1, aSubset, iSubsetIndex + 1])

if it time to go home
    write stack to disc
    break
0

Source: https://habr.com/ru/post/1648110/


All Articles