2017-04-17 52 views
1

我想写一些代码来解决这个数学问题:有8个团队,他们都会玩足球游戏(所以总共7 + 6 + ... + 1 = 28场比赛),他们只有两次胜负的机会:输或赢。每支球队至少有1次胜利和1次输球的数量有多少。如果你不能得到这个问题,请说,让我再试一次。问题是我的代码打印无限增加的数字(这是一个无限循环,我写了打印语句的功能,以了解问题是什么)这是我的代码,你认为什么问题?谢谢。递归函数不断变化无穷python

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) 

Explainment:我宣布了游戏的道路,并把他们到一个数组(第一队VS第二队,第一队VS 3团队等等),那么我带他们到行动中该数组的顺序。如果这条道路符合我们的条件,可能会为每场比赛的胜利和失败建立一棵树,并在每个分支的末端建立一个控制结构。如果为了1而增加how_many_stats的值并且往后退一步去尝试另一条道路等,如果不相遇,再往前走一步查找其他道路。如果已经查看了下面的两个节点,请再次返回,依此类推。

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 
)) 

,并让它运行了一下:

回答

1

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

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 

所以,你需要找出一个更好的算法,能够计算匹配的数量,而不brute-迫使匹配树和计数符合您

至少1胜的要求,1赔

佛的结果举个例子,你可以计算出每个团队只有一个胜利或者完全松散的可能性的数量,并从可能结果的总量中减去可能性的数量(只要确保不要将它们计数两次,或者可以独立发生)

target=total_number-exactly_one_win-exactly_one_loss+exactly_one_win_and_one_loss 
+0

是的,它真的非常强大。但蛮力意味着这个过程只需要很长时间,但不会给错误的结果我错了吗?如果不是为什么这个算法给出错误的结果呢?刚刚徘徊,谢谢你的时间。 –

+0

你是对的,看着输出结果,它应该只计算所有队伍数量大于0的队伍数量,因为否则,他们缺少需要一场胜利的数据,而且显然没有这样做。但要弄清楚为什么,我必须真正理解你的代码....所以看到我的更新答案为不同的方法,应该解决这两个问题。 –