我正在写我要在硕士论文中进行的实验的代码。我基本上已经完成了,但最后一个问题我无法找到解决的方法。我有一个公益游戏,有16个参与者,分成8个两组。我有4个治疗,我平衡了比赛,每一个治疗是由4个球员每轮(他们是12)。我现在缺少的是我希望每个球员每轮都能打3次。这个随机化是在下面的代码中执行的,理论上是可行的,但实际上我从来没有设法结束它。在20分钟内,我设法在第10轮结束时得到,但未能使程序找到满足上述第11轮和第12轮两个条件的组合。我知道这有点棘手,如果你喜欢的话更容易理解,但是。。。你有什么建议吗? 谢谢!在
class Subsession(BaseSubsession):
def before_session_starts(self):
info_condition = ['Bel', 'Bel', 'Act', 'Act', 'Ctrl', 'Ctrl', 'No', 'No']
i = 0
condition = True
while condition:
i+= 1
print('I am in the loop: {} th time. Round{}.'.format(i, self.round_number))
self.group_randomly()
for gr_index, g in enumerate(self.get_groups()):
g.info = info_condition[gr_index]
for p in g.get_players():
p.info_player = g.info
condition = any(not p.can_go_on(p.info_player) for p in self.get_players())
if condition == False:
break
p.count_treat()
print('I am out of the loop. Round{}'.format(self.round_number))
class Player(BasePlayer):
runs = models.CharField()
def count_treat(self):
ctrl_count = 0
no_count = 0
bel_count = 0
act_count = 0
for p in self.in_all_rounds():
if p.info_player == "Ctrl":
ctrl_count += 1
elif p.info_player == "No":
no_count += 1
elif p.info_player == "Bel":
bel_count += 1
elif p.info_player == "Act":
act_count += 1
p.runs = dict()
p.runs['Ctrl'] = ctrl_count
p.runs['Bel'] = bel_count
p.runs['No'] = no_count
p.runs['Act'] = act_count
def can_go_on(self, activity):
self.count_treat()
print(self.id_in_subsession, self.runs[activity] < 4, activity, self.runs[activity])
return self.runs[activity] < 4
我决定添加另一个答案,而不是编辑前一个答案,因为第一个答案在您不需要重组组的情况下仍然是有用的。在
所以,假设你有四种治疗方法-[A,B,C,D]
有三个条件:
条件1:玩家从这一组中随机进行3轮治疗,然后进行下一个(随机)治疗3回合等
我们可以将一个特定玩家的序列描述为一个列表:aaabbbccddd,其中一个字母对应于一个治疗,它在这个字符串中的位置对应于一个整数。
条件2:每一轮比赛中,有四名选手进行相同的治疗。
因为人们总是连续打三个回合(比如AAA,或者BBB),为了简洁起见,让我们把三连体AAA描述为a,等等。因此aaabbbccddd将是ABCD。在
下面的代码生成一个12X16矩阵,每个玩家连续播放三次每个治疗,并且满足所有3个条件。在
代码远远不是最优的,我相信经验丰富的python程序员可以很容易地以一种更高效的方式来实现这一点。但它是有效的。您只需将这个矩阵赋给任何
session.vars
变量,然后每个玩家就可以根据自己的id和整数获得他/她的治疗。在函数}和
by_letters
比较两个序列,如果两个序列中的同一位置至少有一个字母,则返回True
。因此它返回abcd
和bdca
的True
,因为c
,但它返回{badc
的False
。在我们在开始时生成了我们四种治疗方法的所有(24)种可能的排列。这是我们可以使用的序列库。在
函数
filtered
返回没有一致字母的可用序列的子集(基于by_letters
函数)。在当找到治疗矩阵时,
triple
函数只会重复每个治疗3次。在因此,我们通过从我们的一组处理中产生排列来获得初始数据。在
我们从中选取一个随机序列,然后根据第一次绘制筛选出剩余的数据。这是我们的第二个序列。在
我们发现了两个集合的交集,这两个集合的字母都不与序列1和序列2都重合。然后从剩下的子集中我们画了一条随机线。这是我们的第三个序列。在
我们做同样的三个集合的交集来得到第四个序列。 这是我们的第一个4X4矩阵。 我们从初始数据中过滤出所有的序列(通过使用
itertools.filterfalse
),并使用初始数据循环四次,但是没有我们刚刚找到的序列。在由于并非每次都能找到4个满足所有条件的4X4矩阵,我们用
try.. except..
来绘制另一个随机起始序列。在输出是这样的:
^{pr2}$我不是百分之百确定我有问题,但如果我建议任务是在受试者设计中随机选择治疗顺序,那么每个玩家将在每种治疗中玩三次,但这个顺序应该在玩家之间随机进行。我想可以这样做:
在
models.py
中:我们在这里做什么? 在
Constants
中,我们创建了一个包含一组处理方法的列表(不是最优雅的方式,因此如果您需要改变轮次的长度,可以用更python的方式来做,但出于懒惰的考虑,它起作用了)。在然后,当每个
Subsession
被启动时,您将获得这个列表列表,对于每个组,我们将它们洗牌(每个子列表中的项目那时不会被洗牌),然后使它们变平,因此它只是一个列表。之后我们将这个随机处理的列表添加到会话级别的(列表)列表中。在因此,在
treatments
会话变量中的第一轮之后,您就有了每个组所有治疗的完整数组。在然后您只需将
treatment
模型中的treatment
字段设置为个性化治疗列表中的项目,对应于当前回合和组id更新:使两组的治疗顺序相同
相关问题 更多 >
编程相关推荐