testing列是否是预定义数据集的超集
我试图比较球队的组成与已知的configuration,以便看到我可能有问题的地方:
试验列将与不同的场景进行比较,以查看列是否是特定场景的超集 (错误为默认值)。
可以使用索引+匹配/查找来完成,还是我必须编写一些VBmacros?
编辑:我已经更新与input数据的工作表的问题。
工作表: https: //drive.google.com/file/d/0BxwDbXStIEAsUmpONHp1RVRzR2s/edit ? usp = sharing Github Gist: https ://gist.github.com/lucasg/11177852(数据库的python脚本)
(xlwt模块需要创buildexcel工作簿)。
我已经用足球队简化了这个问题:我有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"] ] }
为了使它更简单,我需要在每个区域至less有一个人(目标中间进攻)能够发挥,最舒适的情况是在每个7个位置的一个人。
例如:
"no_defense_4" : ["Goalkeeper", "Wide", "Winger" ] , "no_attack_1" : ["Goalkeeper", "Centre midfield", "Centre back", ] ,
现在,给出一百个周末的名单,以及球员出现/缺席的清单,我想知道由此产生的情况。
我正在优先考虑基于公式的解决scheme,因为工作表将被上传并用于谷歌驱动器
您可以将集合表示为位向量 ,然后使用位运算符“相等”或“与”来testing哪些集匹配。 使用位向量作为集合表示将自动地解决sorting和重复值的问题,因为位向量中的每个值的位置是固定的,并且每个位将仅“设置”一次,而不pipe该值出现在定义的列中多less次集合。
在Excel中包含运算符OR,AND,NOT的简单使用位向量表示法在此处列出: http : //chandoo.org/wp/2011/07/29/bitwise-operations-in-excel/#comment-207723
例如下面的function
=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
的位vector表示forms,以便该位在该范围中的任何列中的值等于时设置:
- 位0 =
T1
- 位1 =
T2
- 位2 =
S
- 位3 =
PL
- 位4 =
CC
- 位5 =
GC
您可以通过遵循相同的复制/粘贴模式轻松地添加其他值的位。
因此,要检查某个列是否匹配某个场景,只比较位向量。 使用IF(x=y;"warn2";IF(..))
的warn2
,将y
的列的位列向量和warn2
脚本的位向量warn2
为y
。
如果需要部分匹配,则可以使用上述文章中定义的按位AND运算符。
与基于VBA的解决scheme相比,这种解决scheme需要一些复制/粘贴规则,例如,当添加新的试用列或新的场景时,只需复制/粘贴几个expression式,而不需要更新几个expression式。
基于VBA的解决scheme可以通过使用自动检测的CurrentRegions自动解决这个维护问题,所有必要的逻辑隐藏在一个macros观点击后面。
编辑:位向量概念适用于新的足球队数据集
工作表: https : //docs.google.com/spreadsheet/ccc? key = 0AtZPnBk7a3pvdHcyWDV6ZFFoUTNyWWF0bjl3VFpaRkE & usp = drive_web#gid =0
因为在一个特定的日子里,准确的团队设置是什么,因为一个玩家可能被分配到不同的位置,所以我已经简化了这个问题,而不是“存在”或“缺席”,我希望桌子包含玩家位置。 实现这个应该不是问题,就好像你知道玩家可以玩什么样的位置,而不是absent,present
你可以定义一组有效值(empty or anything else),Midfielder,Centre midfield,Wide
球员14 ,17,18。 可以使用“数据validation”规则为每个单元configuration有效可用值列表。 抽象angular色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
中计算位向量,使得范围中的每个位置仅被计数一次,并且在最终向量中每个位置具有固定的位置。 将vector的数字格式设置为自定义数字格式0000000
是有用的。 例如,一个包含Wide,Winger,Goalkeeper
的任意次数的任意数量的重复的行将评估为向量1000101
,其中最左边的位6代表Goalkeeper
而从右边的第二个位代表Wide
。 最舒适的情况是位向量评估为1111111
。 这个位vector的唯一目的是检测舒适的情况
为了将场景匹配到团队设置,我使用另一个由4位数字组成的vector ,其含义如下:
- 最左边的数字3 – 守门员人数(最多1次)
- 数字2 – 防守队员数量(最多2个)
- 数字1 – 中场数(最多2个)
- 最右边的数字0 – 向前的数目(最多2个计数)计算范围为
D2:ZZ2
向量的公式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)
将vector的数字格式设置为自定义数字格式0000
是有用的。 同样的公式可以计算团队设置和场景的4位向量。
除了位置名称之外,还可以计算像Defender
这样的抽象位置名称。
例如在一个包含中Centre back,Centre back,Goalkeeper,Goalkeeper,Goalkeeper,Defender,Defender,Midfielder,Midfielder,Winger
,向量看起来像1221
。
有(1+1)*(2+1)*(2+1)*(2+1) = 54
不同的可能的情况。 我假设他们每个都列在constraints
表中。 你应该能够很容易地用python生成它们。
有两个工作日constraints
与情景和events
与天和团队设置。 查找公式 ,该公式为第2行中的团队设置计算vector,并在constraints
表中search具有完全相同vector的行,并返回值列中的值,如下所示
=IFERROR(VLOOKUP($A2;constraints!$A:$B;2;FALSE);"?")
- $ A2 – 包含团队设置的4位数vector公式
- 约束!$ A – 工作表中带有包含场景的4位向量公式的场景的列
- 约束!$ B – 包含场景名称的场景中的列 – 您正在寻找的东西
- 2 – 列约束的索引!$ B
- FALSE – 表示查找列不必sorting
- ? – 如果未find匹配的scheme(不应发生)
上面的Google文档链接包含公式,示例3天和示例11情景。
如果有什么不清楚的地方,让我知道,我会改善答案,因为Google文档链接有一天会消失