递归函数无限转下去python
Recursive function keeps turning infinitely python
我正在尝试编写一些代码来解决这个数学问题:有 8 支球队,所有球队都会互相踢足球(所以总共 7+6+...+1 = 28 场比赛)并且他们只有两种结果机会:赢或输。每支球队有多少种至少 1 胜 1 负的组合。如果您无法回答问题,请说出来,让我再次尝试解释。问题是我的代码打印无限增加的数字(这是一个无限循环,我在函数中写了打印语句来理解问题所在)这是我的代码,你认为问题是什么?谢谢。
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)
解释:我为比赛宣布了一条道路并将它们放入一个数组中(第 1 队对第 2 队,第 1 队对第 3 队等)然后我按照该数组的顺序将它们付诸行动。如果这条路是否满足我们的条件,可能会为每场比赛建立一个关于输赢的树,并在每个分支的末端建立一个控制结构。如果遇到就把how_many_stats的值增加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 个并再次 运行ning 它确实终止了:
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
所以你需要找出一个更好的算法来计算匹配的数量,而无需暴力破解匹配树并计算满足你的要求的结果
at least 1 win and 1 lose
例如,您可以计算每支球队恰好赢一场或输一场的可能性的数量,然后从可能结果的总数中减去(只要确保不要将它们作为这两个部分计算两次)或者可以独立发生)
target=total_number-exactly_one_win-exactly_one_loss+exactly_one_win_and_one_loss
我正在尝试编写一些代码来解决这个数学问题:有 8 支球队,所有球队都会互相踢足球(所以总共 7+6+...+1 = 28 场比赛)并且他们只有两种结果机会:赢或输。每支球队有多少种至少 1 胜 1 负的组合。如果您无法回答问题,请说出来,让我再次尝试解释。问题是我的代码打印无限增加的数字(这是一个无限循环,我在函数中写了打印语句来理解问题所在)这是我的代码,你认为问题是什么?谢谢。
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)
解释:我为比赛宣布了一条道路并将它们放入一个数组中(第 1 队对第 2 队,第 1 队对第 3 队等)然后我按照该数组的顺序将它们付诸行动。如果这条路是否满足我们的条件,可能会为每场比赛建立一个关于输赢的树,并在每个分支的末端建立一个控制结构。如果遇到就把how_many_stats的值增加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 个并再次 运行ning 它确实终止了:
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
所以你需要找出一个更好的算法来计算匹配的数量,而无需暴力破解匹配树并计算满足你的要求的结果
at least 1 win and 1 lose
例如,您可以计算每支球队恰好赢一场或输一场的可能性的数量,然后从可能结果的总数中减去(只要确保不要将它们作为这两个部分计算两次)或者可以独立发生)
target=total_number-exactly_one_win-exactly_one_loss+exactly_one_win_and_one_loss