我试图比较球队'组合到已知配置,以便查看我可能遇到问题的地方:
将试验列与不同的方案进行比较,以查看列是否是特定方案的超集(错误是默认值)。
可以使用索引+匹配/查找来完成,还是我必须编写一些VB宏?
编辑:我已使用包含输入数据的工作表更新了问题。
工作表:https://drive.google.com/file/d/0BxwDbXStIEAsUmpONHp1RVRzR2s/edit?usp=sharing Github Gist:https://gist.github.com/lucasg/11177852(数据源的python脚本)
(创建excel工作簿需要xlwt模块)。
我已经使用足球队简化了问题:给了7个位置(1个守门员,2个防守队员,2个中场和2个前锋)以及周末某些人的存在列表,我会想知道我是否能够提供一支完整的球队,或者我是否因为缺少关键球员而没收比赛。
职位:
styles = {
"Goalkeeper" : ["Goalkeeper"],
"Defender" : ["Centre back", "Wing"],
"Midfielder" : ["Centre midfield", "Wide"],
"Forward" : ["Centre forward","Winger"]
}
大多数足球运动员只能打一个位置,但有些人更多才多艺,可以在自己的场上打任何位置(防守 - 中场进攻)。
团队示例(18人):
example_players = {
"Forward": [
[1, "Winger"],
[2, "Winger"],
[3, "Centre forward"],
[4, "Centre forward"]
],
"Defender": [
[5, "Centre back"],
[6, "Centre back", "Wing"],
[7, "Centre back", "Wing"],
[8, "Wing"],
[9, "Centre back"]
],
"Goalkeeper": [
[10, "Goalkeeper"],
[11, "Goalkeeper"]
],
"Midfielder": [
[12, "Centre midfield"],
[13, "Centre midfield"],
[14, "Wide", "Centre midfield"],
[15, "Centre midfield"],
[16, "Centre midfield"],
[17, "Wide", "Centre midfield"],
[18, "Wide", "Centre midfield"]
]
}
为了使它变得更简单,我需要每个区域至少有一个人(目标 - 中 - 中 - 攻击)能够发挥,最舒适的情况是7个位置中的每个位置都有一个人。
前景:
"no_defense_4" : ["Goalkeeper", "Wide", "Winger" ] ,
"no_attack_1" : ["Goalkeeper", "Centre midfield", "Centre back", ] ,
现在,给出一个百周末的清单,以及球员存在/绝对的清单,我想知道结果。
我优先考虑基于公式的解决方案,因为工作表将上传并在Google云端硬盘中使用
答案 0 :(得分:1)
你可以将集合表示为位向量,然后使用位运算符"等于"或" AND"测试哪些集合匹配。使用位向量作为集合表示将自动解决排序和重复值的问题,因为位向量中的每个值的位置是固定的,并且每个位将被设置为"设置"只有一次,无论值出现在定义集合的列中的次数。
简单易用Excel中的位向量表示,包括运算符OR,AND,NOT列于此处:http://chandoo.org/wp/2011/07/29/bitwise-operations-in-excel/#comment-207723
例如关注功能
=POWER(10;0)*MIN(COUNTIF($B$3:$B$12;"T1");1)+POWER(10;1)*MIN(COUNTIF($B$3:$B$12;"T2");1)+POWER(10;2)*MIN(COUNTIF($B$3:$B$12;"S");1)+POWER(10;3)*MIN(COUNTIF($B$3:$B$12;"PL");1)+POWER(10;4)*MIN(COUNTIF($B$3:$B$12;"CC");1)+POWER(10;5)*MIN(COUNTIF($B$3:$B$12;"GC");1)
将$B$3
- > $B$12
范围内的值转换为定义了位0..5
的位向量表示形式,以便在该范围内的任何列中的值为该位时设置该位等于:
T1
T2
S
PL
CC
GC
您可以通过遵循相同的复制/粘贴模式轻松添加更多位和其他值。
因此,要检查某些列是否与某些情况匹配,只需比较位向量。使用IF(x=y;"warn2";IF(..))
之类的表达式替换x
列的位向量和warn2
方案的位向量{.1}}。
如果需要部分匹配,可以使用上面文章中定义的按位AND运算符。
与基于VBA的解决方案相比,此解决方案需要一些复制/粘贴规则,例如当添加新的试用栏或新场景时,必须复制/粘贴几个表达式,并且很少需要更新。
基于VBA的解决方案可以通过使用自动检测到的CurrentRegions自动解决此维护问题,所有必要的逻辑隐藏在一次宏观点击后面。
编辑:应用于新足球队数据集的位向量概念
由于一个玩家可能被分配不同的位置,在某一天确定的团队设置是多么模糊,我已经以这样的方式简化了问题,而不是"现在"或者"缺席"我希望桌子能够包含玩家的位置。如果您知道玩家可以玩什么位置而不是y
,您可以为玩家14,17,18定义有效值集合absent,present
,这应该不是问题。可以使用"数据验证"为每个单元格配置有效可用值的列表。规则。抽象角色(empty or anything else),Midfielder,Centre midfield,Wide
代表"这个玩家可以扮演一名中场,准确的位置还不知道"。
为表示位置,我使用用此公式计算的位向量
Midfielder
公式以这样的方式计算范围=POWER(10;6)*MIN(COUNTIF(D2:ZZ2;"Goalkeeper");1)+POWER(10;5)*MIN(COUNTIF(D2:ZZ2;"Centre back");1)+POWER(10;4)*MIN(COUNTIF(D2:ZZ2;"Wing");1)+POWER(10;3)*MIN(COUNTIF(D2:ZZ2;"Centre midfield");1)+POWER(10;2)*MIN(COUNTIF(D2:ZZ2;"Wide");1)+POWER(10;1)*MIN(COUNTIF(D2:ZZ2;"Centre forward");1)+POWER(10;0)*MIN(COUNTIF(D2:ZZ2;"Winger");1)
中的位向量,使得范围中的每个位置仅计数一次,并且在最终向量中每个位置具有固定位置。将矢量的数字格式设置为自定义数字格式D2:ZZ2
很有用。例如,以任意顺序包含任意数量重复的0000000
的行将评估为向量Wide,Winger,Goalkeeper
,其中最左边的位6代表1000101
,而右边的第2位代表第2位为Goalkeeper
。最舒适的情况是位向量评估为Wide
的情况。 位向量的唯一目的是来检测舒适的情况
为了将场景与团队设置相匹配,我使用另一个由4位数字组成的矢量,意思是:
1111111
的此向量的公式如下所示 D2:ZZ2
将矢量的数字格式设置为自定义数字格式=POWER(10;3)*MIN(COUNTIF(D2:ZZ2;"Goalkeeper");1)+POWER(10;2)*MIN(COUNTIF(D2:ZZ2;"Defender")+COUNTIF(D2:ZZ2;"Centre back")+COUNTIF(D2:ZZ2;"Wing");2)+POWER(10;1)*MIN(COUNTIF(D2:ZZ2;"Midfielder")+COUNTIF(D2:ZZ2;"Centre midfield")+COUNTIF(D2:ZZ2;"Wide");2)+POWER(10;0)*MIN(COUNTIF(D2:ZZ2;"Forward")+COUNTIF(D2:ZZ2;"Centre forward")+COUNTIF(D2:ZZ2;"Winger");2)
很有用。同样的公式可以计算团队设置和场景的4位数向量。
除了位置名称,它还可以计算抽象位置名称,如0000
。
例如,在包含Defender
的行中,向量看起来像Centre back,Centre back,Goalkeeper,Goalkeeper,Goalkeeper,Defender,Defender,Midfielder,Midfielder,Winger
。
有1221
种不同的可能情况。我假设它们中的每一个都列在(1+1)*(2+1)*(2+1)*(2+1) = 54
表中。你应该能够很容易地在python中生成它们。
有2张constraints
表示方案,constraints
表示日期和团队设置。 查找公式,它采用为第2行中的团队设置计算的向量,并在events
工作表中搜索具有完全相同向量的行,并返回值列中的值此
constraints
上面的Google文档链接包含公式,示例3天和示例11方案。
如果有不清楚的地方让我知道,我会改进答案,因为Google文档链接有一天会消失