递归函数不断转向python

时间:2017-04-17 13:17:48

标签: python function tree functional-programming infinite-loop

我正在尝试编写一些代码来解决这个数学问题:有8个团队,所有人都会互相踢足球比赛(总共有7 + 6 + ... + 1 = 28场比赛)他们有只有两次结果的机会:赢或输。每支球队至少有1场胜利和1场失利。如果你无法得到问题,请说出来让我再试一次。问题是我的代码打印无限增加的数字(这是一个无限循环,我在函数中写了print语句来理解问题是什么)这是我的代码,你觉得有什么问题?谢谢。

num = 8
team = [0,0,0,0,0,0,0,0]
order = []
how_many_stats = 0
temp = 0

for i in range(num):
    for t in range(i+1 , num):
        order.append([i,t])
total_matches = len(order) - 1
curr_matches = - 1

def do_match():
    global num
    global team
    global order
    global how_many_stats
    global temp
    global total_matches
    global curr_matches
    print(how_many_stats)
    curr_matches += 1
    team[order[curr_matches][0]] += 1                               # first wins

    if not curr_matches == total_matches:
        do_match()
    else:
        for i in range(num):
            if team[i] > 0 and team[i] < 7:                                            #7/8?
                temp += 1

        if temp == num:
            how_many_stats += 1
        temp = 0


    team[order[curr_matches][0]] -= 1                              # take back the action

    team[order[curr_matches][1]] += 1                              # second wins

    if not curr_matches == total_matches:
        do_match()
    else:
        for i in range(num):
            if team[i] > 0 and team[i] < 7:                                         #7/8?
                temp += 1

        if temp == num:
            how_many_stats += 1
        temp = 0


    team[order[curr_matches][1]] -= 1

    curr_matches -= 1
    return

do_match()
print(how_many_stats)

解释:我宣布了一场比赛的道路并将他们分成阵列(第一队与第二队,第一队与第三队等)然后我按照阵列的顺序将它们付诸行动。如果这条道路符合我们的条件,可能会为每场比赛建造一个关于胜利和失败的树以及每个分支末端的控制结构。如果满足会增加how_many_stats的值为1并通过后退一步来尝试另一条道路,如果没有遇到,则再往前走一步再查找其他道路。如果已经查看了下面的两个节点,请再次退回,依此类推。

1 个答案:

答案 0 :(得分:1)

在第21行添加一些调试逻辑后:

print("called do_match with num: %d, team: %s, order: %s, how_many_stats: %d, temp: %d, total_matchs: %d, curr_matches: %d" % (
    num, str(team), str(order), how_many_stats, temp, total_matches, curr_matches
))

让它运行一下:

called do_match with num: 8, team: [7, 4, 4, 1, 4, 1, 2, 4], order: [[0, 1], [0, 2], [0, 3], [0, 4], [0, 5], [0, 6], [0, 7], [1, 2], [1, 3], [1, 4], [1, 5], [1, 6], [1, 7], [2, 3], [2, 4], [2, 5], [2, 6], [2, 7], [3, 4], [3, 5], [3, 6], [3, 7], [4, 5], [4, 6], [4, 7], [5, 6], [5, 7], [6, 7]], how_many_stats: 0, temp: 0, total_matchs: 27, curr_matches: 26
called do_match with num: 8, team: [7, 4, 4, 1, 4, 0, 3, 3], order: [[0, 1], [0, 2], [0, 3], [0, 4], [0, 5], [0, 6], [0, 7], [1, 2], [1, 3], [1, 4], [1, 5], [1, 6], [1, 7], [2, 3], [2, 4], [2, 5], [2, 6], [2, 7], [3, 4], [3, 5], [3, 6], [3, 7], [4, 5], [4, 6], [4, 7], [5, 6], [5, 7], [6, 7]], how_many_stats: 0, temp: 0, total_matchs: 27, curr_matches: 25
...
called do_match with num: 8, team: [7, 4, 4, 1, 3, 1, 3, 4], order: [[0, 1], [0, 2], [0, 3], [0, 4], [0, 5], [0, 6], [0, 7], [1, 2], [1, 3], [1, 4], [1, 5], [1, 6], [1, 7], [2, 3], [2, 4], [2, 5], [2, 6], [2, 7], [3, 4], [3, 5], [3, 6], [3, 7], [4, 5], [4, 6], [4, 7], [5, 6], [5, 7], [6, 7]], how_many_stats: 0, temp: 0, total_matchs: 27, curr_matches: 26
called do_match with num: 8, team: [7, 4, 4, 1, 3, 0, 4, 3], order: [[0, 1], [0, 2], [0, 3], [0, 4], [0, 5], [0, 6], [0, 7], [1, 2], [1, 3], [1, 4], [1, 5], [1, 6], [1, 7], [2, 3], [2, 4], [2, 5], [2, 6], [2, 7], [3, 4], [3, 5], [3, 6], [3, 7], [4, 5], [4, 6], [4, 7], [5, 6], [5, 7], [6, 7]], how_many_stats: 0, temp: 0, total_matchs: 27, curr_matches: 25

我得出结论,你的代码确实终止了,你的问题是你的匹配树中有太多的可能性。

例如,通过将团队数量减少到4并再次运行,它确实终止了:

called do_match with num: 4, team: [0, 0, 0, 0], order: [[0, 1], [0, 2], [0, 3], [1, 2], [1, 3], [2, 3]], how_many_stats: 0, temp: 0, total_matchs: 5, curr_matches: -1
....
called do_match with num: 4, team: [0, 1, 2, 2], order: [[0, 1], [0, 2], [0, 3], [1, 2], [1, 3], [2, 3]], how_many_stats: 32, temp: 0, total_matchs: 5, curr_matches: 4
32

所以你需要找出一个更好的算法,它能够计算匹配数而不会强制匹配树并计算符合你要求的结果

  

至少1胜1负

例如,您可以计算每个团队只有一个胜利或者只有一个松散的可能性的数量,并从可能结果的总量中减去(只是确保不计算它们的两个部分,或者可以独立发生)

target=total_number-exactly_one_win-exactly_one_loss+exactly_one_win_and_one_loss