Home > Software design >  Creating a recursive function from nested loops with dynamic assigns along the way
Creating a recursive function from nested loops with dynamic assigns along the way

Time:09-29

This one is leaving me a bit stumped but in sum, I am working on a graph problem where I 'walking' along a graph (temporally), calculating things and assigning variables along the way. Currently, I have a massive function with nested for-loops, which surely must be convertible to a recursive function. I am just not sure how. Help would be most appreciated.

MWE

Setup

from collections import OrderedDict
from itertools import product

# MWE for SO
D = {"A":(0,1), 'B':(0,1), 'C':(0,1)}
nodes = ['A','B','C']

def assign(assigned, fixed, F):
    for i in nodes:
        if i in fixed:
            assigned[i] = fixed[i]
        else:
            assigned[i] = F[i](assigned)

    return assigned

def func():
    return OrderedDict(
        {
            "A": lambda v: v["A"],
            "B": lambda v: v["B"], 
            "C": lambda v: v["C"],
        }
    )

def func2(past):
    return OrderedDict(
        {
            "A": lambda v: v["A"]^past['A'],
            "B": lambda v: v["B"]^past['B'], 
            "C": lambda v: v["C"]^past['C'],
        }
    )

First time-step (index)

# First time step
fixed1 = {'B':0}
F = func()
for j in product(*[D[i] for i in D.keys()]):
    assigned = dict(zip(D.keys(), j))
    assigned = assign(assigned, fixed1, F)
    # For each j and assigned some logic happens here

Second time-step (index)

# For second time-step, we start nesting
fixed1 = {'B':0}
fixed2 = {'A':1}
F = func()
# t=0
for j in product(*[D[i] for i in D.keys()]):
    assigned = dict(zip(D.keys(), j))
    assigned = assign(assigned, fixed1, F)
    # For each j and assigned some logic happens here

    # t=1
    G = func2(assigned)
    for jj in product(*[D[i] for i in D.keys()]):
        assigned = dict(zip(D.keys(), jj))
        assigned = assign(assigned, fixed2, G)
        # For each jj and assigned some logic happens here

Third time-step (index)

# For second time-step, we start nesting
fixed1 = {'B':0}
fixed2 = {'A':1}
fixed3 = {'A':1}
F = func()
# t=0
for j in product(*[D[i] for i in D.keys()]):
    assigned = dict(zip(D.keys(), j))
    assigned = assign(assigned, fixed1, F)
    # For each j and assigned some logic happens here

    # t=1
    G = func2(assigned)
    for jj in product(*[D[i] for i in D.keys()]):
        assigned = dict(zip(D.keys(), jj))
        assigned = assign(assigned, fixed2, G)
        # For each jj and assigned some logic happens here

        # t=2
        H = func2(assigned)
        for jjj in product(*[D[i] for i in D.keys()]):
            assigned = dict(zip(D.keys(), jjj))
            assigned = assign(assigned, fixed3, H)
            # For each jjj and assigned some logic happens here

You can see where this is going (edit for clarity: for each new time-step I need to add a new nested-loop and this is the part which I want to solve using a recursion. Worth noting that the fixed variables set the other variables to specific values and come from outside this module.

Hence, how do I make this into a recursive function? As you can imagine I am going a lot further than three indices.

CodePudding user response:

EDIT: New iteration (recursion) based on comment

This calls the fixeds/funcs for all values generated.

def do_timesteps(fixeds_funcs, assigned=None):
    (fixed, func), next_fixeds_funcs = fixeds_funcs[0], fixeds_funcs[1:]
    print(fixed, func, assigned)  # for debugging :)
    F = func(assigned)
    for j in product(*[D[i] for i in D.keys()]):
        assigned = dict(zip(D.keys(), j))
        assigned = assign(assigned, fixed, F)
        if next_fixeds_funcs:
            do_timesteps(next_fixeds_funcs, assigned)


def main():
    fixeds_funcs = [
        ({"B": 0}, func),
        ({"A": 1}, func2),
        ({"A": 1}, func2),
    ]
    do_timesteps(fixeds_funcs)
  • Related