我想要随机分析6个测试题,以及正确的答案。问题#1和#2,#3和#4,#5和#6属于同一类型。为了不让测试变得太容易,我不希望连续显示#1和#2(对于这个问题,不要#3和#4,或#5和#6)。
为此目的,我认为我应该使用这个约束来改变列表[1, 2, 3, 4, 5, 6]
:1和2,3和4,5和6是不相邻。例如,[ 1,2 ,4,6,3,5]是不可接受的,因为1和2彼此相邻。然后,我想将新订单应用于问题列表和答案列表。
作为编程新手,我只知道如何在没有约束的情况下对列表进行随机播放,如下所示:
question = [1, 3, 5, 2, 4, 6]
answer = ['G', 'Y', 'G', 'R', 'Y', 'R']
order = list(zip(question, answer))
random.shuffle(order)
question, answer = zip(*order)
任何帮助将不胜感激!
答案 0 :(得分:5)
这是一种“蛮力”的方法。它只是重复洗牌,直到找到有效的排序:
import random
def is_valid(sequence):
similar_pairs = [(1, 2), (3, 4), (5, 6)]
return all(
abs(sequence.index(a) - sequence.index(b)) != 1
for a, b in similar_pairs
)
sequence = list(range(1, 7))
while not is_valid(sequence):
random.shuffle(sequence)
print(sequence)
# One output: [6, 2, 4, 5, 3, 1]
对于这么小的输入,这很好。 (计算机很快。)对于更长的输入,你想要考虑做一些更高效的事情,但听起来你是在采用一种简单的实用方法,而不是理论上最优的方法。
答案 1 :(得分:1)
我看到两种简单的方法:
如果符合约束条件,则随机播放列表并接受随机播放,否则重复播放。
迭代地对数字进行采样并使用约束来限制可能的数字。例如,如果您首先绘制1,则第二次绘制可以是3..6。这也可能导致解决方案不可行,因此您必须考虑到这一点。
答案 2 :(得分:1)
使用列表元素作为顶点绘制图形。如果元素u和v在输出列表中可以相邻,则在它们之间绘制边(u,v),否则不要。
现在你必须在这张图上找到汉密尔顿路径。这个问题通常是难以解决的(NP-complete),但如果图形几乎完成(约束很少,即缺少边缘),它可以通过DFS有效地解决。
对于像您的示例中的小型输入集,可能更容易生成所有排列,然后过滤掉那些违反其中一个约束的排列。
答案 3 :(得分:0)
你可以试试这个。这适用于小型列表。正如您在下面看到的,我使用了一组python集来表示约束。代码构建了逐个元素所需的排列。
如果在某些时候,列表中的其余元素都受到约束的限制,那么逐个元素构建元素会导致无效排列。
示例:如果代码生成4,1,3,2,6它被强制尝试使用5作为最后一个元素,但这是无效的,所以函数尝试进行另一个排列。
生成随机混洗并检查其是否有效(smarx给出的答案)比蛮力方法(在性能方面)更好。
注意:如果没有可能满足约束的排列,该函数将导致无限循环。
import random
def shuffler(dataList, constraints):
my_data_list = list(dataList)
shuffledList = [random.choice(dataList)]
my_data_list.remove(shuffledList[0])
for i in range(1, list_size):
prev_ele = shuffledList[i - 1]
prev_constraint = set()
for sublist in constraints:
if prev_ele in sublist:
prev_constraint = set.union(prev_constraint, sublist)
choices = [choice for choice in my_data_list if choice not in prev_constraint]
if len(choices) == 0:
print('Trying once more...')
return shuffler(dataList,constraints)
curr_ele = random.choice(choices)
my_data_list.remove(curr_ele)
shuffledList.append(curr_ele)
return shuffledList
if __name__ == '__main__':
dataList = [1, 2, 3, 4, 5, 6]
list_size = len(dataList)
constraints = [{1,2},{3,4},{5,6}]
print(shuffler(dataList,constraints))
答案 4 :(得分:0)
您可以尝试以下方式:
shuffle the list
while (list is not good)
find first invalid question
swap first invalid question with a different random question
endwhile
我还没有完成任何计时,但它可能比重新整理整个列表要快。它在第一个无效问题之前部分保留了有效部分,因此它应该更快地达到良好的排序。