通过轮次将4个不同的玩家分配给一个站点,没有重复

问题描述 投票:0回答:1

我正在构建一个r脚本,它使用4个不同变量的所有可能组合:Rounds,Stations和Players(Male和Female)。下面是我的数据集的dput版本:

structure(list(x = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 
3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
3L, 3L, 3L, 3L, 3L, 3L), .Label = c("round1", "round2", "round3"
), class = "factor"), x.x = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
3L, 3L, 3L, 3L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 
3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L), .Label = c("station1", "station2", 
"station3"), class = "factor"), x.y = structure(c(1L, 1L, 1L, 
1L, 1L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 
4L, 5L, 5L, 5L, 5L, 5L, 6L, 6L, 6L, 6L, 6L, 1L, 1L, 1L, 1L, 1L, 
2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L, 5L, 
5L, 5L, 5L, 5L, 6L, 6L, 6L, 6L, 6L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 
2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L, 5L, 5L, 5L, 
5L, 5L, 6L, 6L, 6L, 6L, 6L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 
2L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L, 5L, 5L, 5L, 5L, 5L, 
6L, 6L, 6L, 6L, 6L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 3L, 
3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L, 5L, 5L, 5L, 5L, 5L, 6L, 6L, 
6L, 6L, 6L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 
3L, 3L, 4L, 4L, 4L, 4L, 4L, 5L, 5L, 5L, 5L, 5L, 6L, 6L, 6L, 6L, 
6L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 
4L, 4L, 4L, 4L, 4L, 5L, 5L, 5L, 5L, 5L, 6L, 6L, 6L, 6L, 6L, 1L, 
1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 
4L, 4L, 4L, 5L, 5L, 5L, 5L, 5L, 6L, 6L, 6L, 6L, 6L, 1L, 1L, 1L, 
1L, 1L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 
4L, 5L, 5L, 5L, 5L, 5L, 6L, 6L, 6L, 6L, 6L), .Label = c("male1", 
"male2", "male3", "male4", "male5", "male6"), class = "factor"), 
y = structure(c(2L, 3L, 4L, 5L, 6L, 1L, 3L, 4L, 5L, 6L, 1L, 
2L, 4L, 5L, 6L, 1L, 2L, 3L, 5L, 6L, 1L, 2L, 3L, 4L, 6L, 1L, 
2L, 3L, 4L, 5L, 2L, 3L, 4L, 5L, 6L, 1L, 3L, 4L, 5L, 6L, 1L, 
2L, 4L, 5L, 6L, 1L, 2L, 3L, 5L, 6L, 1L, 2L, 3L, 4L, 6L, 1L, 
2L, 3L, 4L, 5L, 2L, 3L, 4L, 5L, 6L, 1L, 3L, 4L, 5L, 6L, 1L, 
2L, 4L, 5L, 6L, 1L, 2L, 3L, 5L, 6L, 1L, 2L, 3L, 4L, 6L, 1L, 
2L, 3L, 4L, 5L, 2L, 3L, 4L, 5L, 6L, 1L, 3L, 4L, 5L, 6L, 1L, 
2L, 4L, 5L, 6L, 1L, 2L, 3L, 5L, 6L, 1L, 2L, 3L, 4L, 6L, 1L, 
2L, 3L, 4L, 5L, 2L, 3L, 4L, 5L, 6L, 1L, 3L, 4L, 5L, 6L, 1L, 
2L, 4L, 5L, 6L, 1L, 2L, 3L, 5L, 6L, 1L, 2L, 3L, 4L, 6L, 1L, 
2L, 3L, 4L, 5L, 2L, 3L, 4L, 5L, 6L, 1L, 3L, 4L, 5L, 6L, 1L, 
2L, 4L, 5L, 6L, 1L, 2L, 3L, 5L, 6L, 1L, 2L, 3L, 4L, 6L, 1L, 
2L, 3L, 4L, 5L, 2L, 3L, 4L, 5L, 6L, 1L, 3L, 4L, 5L, 6L, 1L, 
2L, 4L, 5L, 6L, 1L, 2L, 3L, 5L, 6L, 1L, 2L, 3L, 4L, 6L, 1L, 
2L, 3L, 4L, 5L, 2L, 3L, 4L, 5L, 6L, 1L, 3L, 4L, 5L, 6L, 1L, 
2L, 4L, 5L, 6L, 1L, 2L, 3L, 5L, 6L, 1L, 2L, 3L, 4L, 6L, 1L, 
2L, 3L, 4L, 5L, 2L, 3L, 4L, 5L, 6L, 1L, 3L, 4L, 5L, 6L, 1L, 
2L, 4L, 5L, 6L, 1L, 2L, 3L, 5L, 6L, 1L, 2L, 3L, 4L, 6L, 1L, 
2L, 3L, 4L, 5L), .Label = c("female1", "female2", "female3", 
"female4", "female5", "female6"), class = "factor")), .Names = c("x", 
"x.x", "x.y", "y"), row.names = c(55L, 109L, 163L, 217L, 271L, 
10L, 118L, 172L, 226L, 280L, 19L, 73L, 181L, 235L, 289L, 28L, 
82L, 136L, 244L, 298L, 37L, 91L, 145L, 199L, 307L, 46L, 100L, 
154L, 208L, 262L, 58L, 112L, 166L, 220L, 274L, 13L, 121L, 175L, 
229L, 283L, 22L, 76L, 184L, 238L, 292L, 31L, 85L, 139L, 247L, 
301L, 40L, 94L, 148L, 202L, 310L, 49L, 103L, 157L, 211L, 265L, 
61L, 115L, 169L, 223L, 277L, 16L, 124L, 178L, 232L, 286L, 25L, 
79L, 187L, 241L, 295L, 34L, 88L, 142L, 250L, 304L, 43L, 97L, 
151L, 205L, 313L, 52L, 106L, 160L, 214L, 268L, 56L, 110L, 164L, 
218L, 272L, 11L, 119L, 173L, 227L, 281L, 20L, 74L, 182L, 236L, 
290L, 29L, 83L, 137L, 245L, 299L, 38L, 92L, 146L, 200L, 308L, 
47L, 101L, 155L, 209L, 263L, 59L, 113L, 167L, 221L, 275L, 14L, 
122L, 176L, 230L, 284L, 23L, 77L, 185L, 239L, 293L, 32L, 86L, 
140L, 248L, 302L, 41L, 95L, 149L, 203L, 311L, 50L, 104L, 158L, 
212L, 266L, 62L, 116L, 170L, 224L, 278L, 17L, 125L, 179L, 233L, 
287L, 26L, 80L, 188L, 242L, 296L, 35L, 89L, 143L, 251L, 305L, 
44L, 98L, 152L, 206L, 314L, 53L, 107L, 161L, 215L, 269L, 57L, 
111L, 165L, 219L, 273L, 12L, 120L, 174L, 228L, 282L, 21L, 75L, 
183L, 237L, 291L, 30L, 84L, 138L, 246L, 300L, 39L, 93L, 147L, 
201L, 309L, 48L, 102L, 156L, 210L, 264L, 60L, 114L, 168L, 222L, 
276L, 15L, 123L, 177L, 231L, 285L, 24L, 78L, 186L, 240L, 294L, 
33L, 87L, 141L, 249L, 303L, 42L, 96L, 150L, 204L, 312L, 51L, 
105L, 159L, 213L, 267L, 63L, 117L, 171L, 225L, 279L, 18L, 126L, 
180L, 234L, 288L, 27L, 81L, 189L, 243L, 297L, 36L, 90L, 144L, 
252L, 306L, 45L, 99L, 153L, 207L, 315L, 54L, 108L, 162L, 216L, 
270L), class = "data.frame")`

以下是前10行:

     Round  Station Partner1 Partner2
55  round1 station1    male1  female2
109 round1 station1    male1  female3
163 round1 station1    male1  female4
217 round1 station1    male1  female5
271 round1 station1    male1  female6
10  round1 station1    male2  female1
118 round1 station1    male2  female3
172 round1 station1    male2  female4
226 round1 station1    male2  female5
280 round1 station1    male2  female6

在此数据集中,有以下内容:

3轮,3站,6名男性,6名女性

我该怎么做:

1)任何人不得在同一车站两次

2)任何人不得在同一轮两次

3)任何人不得与同一个人合作两次

4)每个站需要2名男性和2名女性

5)理想情况下,每个人应该与前一轮中没有与他们在一起的一轮中的人。

6)最后一个号码相同的男性(男性1,女性1)永远不应该合作

其中一轮的最终输出看起来应该是这样的:

     Round  Station Partner1 Partner2
55  round1 station1    male1  female5
109 round1 station1    male3  female4
163 round1 station2    male2  female3
217 round1 station2    male4  female1
271 round1 station3    male5  female6
10  round1 station3    male6  female2

对于第2轮,所有3个站仍然应该存在但是男性和女性伙伴需要改变并且应该遵循上述规则。

另外,如果不添加额外的电台,这在数学上是不可能的。

任何帮助都会很棒!

r dplyr combinations permutation
1个回答
1
投票

这是一个简单的解决方案。我忽略了(5),因为它似乎并不是一个严格的要求(我认为这不是一个严格的规则)。

此函数将有效的第一轮作为输入,并输出第二轮的良好配置(如果再次应用,则输出第三轮)。

我修改了你的数据,使其数字比字符串更容易操作。严格地说,只有Partner列(更名为MaleFemale)需要是函数的数字才能工作。

# data
r1 = read.table(text = "     Round  Station Partner1 Partner2
55  round1 station1    male1  female5
109 round1 station1    male3  female4
163 round1 station2    male2  female3
217 round1 station2    male4  female1
271 round1 station3    male5  female6
10  round1 station3    male6  female2", header = T)

# numericize
r1$Round = as.numeric(substr(r1$Round, 6, 6))
r1$Station = as.numeric(substr(r1$Station, start = 8, stop = 8))
r1$Male = as.numeric(substr(r1$Partner1, 5, 5))
r1$Female = as.numeric(substr(r1$Partner2, 7, 7))
r1[c("Partner1", "Partner2")] = list(NULL)

# function
next_round = function(r) {
  r$Male = r$Male[c(3, 4, 5, 6, 1, 2)]
  r$Female = r$Female[c(5, 6, 1, 2, 3, 4)]
  problems = which(r$Male == r$Female)
  # switch male problems
  switch_with = ifelse(problems %% 2 == 0, problems - 1, problems + 1)
  r$Male[c(rbind(switch_with, problems))] = r$Male[c(rbind(problems, switch_with))]
  # increment round
  r$Round = r$Round + 1
  return(r)
}

# demonstration
r1
#     Round Station Male Female
# 55      1       1    1      5
# 109     1       1    3      4
# 163     1       2    4      3
# 217     1       2    2      1
# 271     1       3    5      6
# 10      1       3    6      2
(r2 = next_round(r1))
#     Round Station Male Female
# 55      2       1    2      6
# 109     2       1    4      2
# 163     2       2    6      5
# 217     2       2    5      4
# 271     2       3    1      3
# 10      2       3    3      1
(r3 = next_round(r2))
#     Round Station Male Female
# 55      3       1    6      3
# 109     3       1    5      1
# 163     3       2    1      6
# 217     3       2    3      2
# 271     3       3    4      5
# 10      3       3    2      4

基本上这样做是男性和女性与起始站的同性伴侣保持联系。男性每轮向下移动一个站号,女性每轮向上移动一个站号,如果有一个男性=女性碰撞,那个站的男性会切换到正确的。我受到广场舞的启发,男性和女性在不同的方向上移动以旋转伙伴是常见的。

© www.soinside.com 2019 - 2024. All rights reserved.