所以我有一个问题列表作为字典,例如
{"Question1": 3, "Question2": 5 ... }
这意味着“Question1”有3个点,第二个有5个等等。
我正在尝试创建一定数量的问题和点之间的所有问题子集。
我尝试过像
这样的东西questions = {"Q1":1, "Q2":2, "Q3": 1, "Q4" : 3, "Q5" : 1, "Q6" : 2}
u = 3 #
v = 5 # between u and v questions
x = 5 #
y = 10 #between x and y points
solution = []
n = 0
def main(n_):
global n
n = n_
global solution
solution = []
finalSolution = []
for x in questions.keys():
solution.append("_")
finalSolution.extend(Backtracking(0))
return finalSolution
def Backtracking(k):
finalSolution = []
for c in questions.keys():
solution[k] = c
print ("candidate: ", solution)
if not reject(k):
print ("not rejected: ", solution)
if accept(k):
finalSolution.append(list(solution))
else:
finalSolution.extend(Backtracking(k+1))
return finalSolution
def reject(k):
if solution[k] in solution: #if the question already exists
return True
if k > v: #too many questions
return True
points = 0
for x in solution:
if x in questions.keys():
points = points + questions[x]
if points > y: #too many points
return True
return False
def accept(k):
points = 0
for x in solution:
if x in questions.keys():
points = points + questions[x]
if points in range (x, y+1) and k in range (u, v+1):
return True
return False
print(main(len(questions.keys())))
但它没有尝试所有可能性,只是将所有问题都放在第一个索引上。
我不知道我做错了什么。
答案 0 :(得分:0)
您的代码存在三个问题。
第一个问题是reject
功能中的第一次检查始终是True
。您可以通过多种方式解决此问题(您评论说您现在正在使用solution.count(solution[k]) != 1
)。
第二个问题是,您的accept
函数使用变量名称x
来表示它打算成为两个不同的东西(来自solution
循环中for
的问题以及最小点数的全局x
。这不起作用,当您尝试将其传递给TypeError
时,您将获得range
。一个简单的解决方法是重命名循环变量(我建议q
,因为它是questions
的一个键。检查值是in
还是range
也有点尴尬。使用链式比较通常会更好:if x <= points <= y and u <= k <= v
第三个问题是你根本没有回溯。回溯步骤需要将全局solution
列表重置为调用Backtracking
之前的状态。您可以在功能结束时,return
之前使用solution[k] = "_"
执行此操作(您评论说您已添加此行,但我认为您将其放在了错误的位置)
无论如何,这是你的功能的固定版本:
def Backtracking(k):
finalSolution = []
for c in questions.keys():
solution[k] = c
print ("candidate: ", solution)
if not reject(k):
print ("not rejected: ", solution)
if accept(k):
finalSolution.append(list(solution))
else:
finalSolution.extend(Backtracking(k+1))
solution[k] = "_" # backtracking step here!
return finalSolution
def reject(k):
if solution.count(solution[k]) != 1: # fix this condition
return True
if k > v:
return True
points = 0
for q in solution:
if q in questions:
points = points + questions[q]
if points > y: #too many points
return True
return False
def accept(k):
points = 0
for q in solution: # change this loop variable (also done above, for symmetry)
if q in questions:
points = points + questions[q]
if x <= points <= y and u <= k <= v: # chained comparisons are much nicer than range
return True
return False
仍然有可能在那里改进的东西。我认为让solution
成为具有虚拟值的固定大小的全局列表尤其是unpythonic(作为参数传递的动态增长列表会更自然)。我还建议使用sum
来加点,而不是使用自己的显式循环。