【问题标题】:Algorithm to distribute n people in unique pairs over n-1 days在 n-1 天内将 n 人以不同的对分配的算法
【发布时间】:2021-02-04 19:48:19
【问题描述】:

我正在尝试创建一种算法,该算法可以从偶数 n 人中创建独特的配对。之后,它应该将这些对划分为 n-1 天。所以每一天,每个人都会遇到另一个人。对不应重复。该算法应该在每次运行时提供不同的解决方案。

例如 我的起始数组是 [1,2,3,4] - 这将转换为以下对:

[1,2],[1,3],[1,4],
      [2,3],[2,4],
            [3,4]

现在这些对需要像这样在 n-1 天之间拆分

day 1 [1,2] & [3,4]
day 2 [1,3] & [2,4]
day 3 [1,4] & [2,3]

感谢您的帮助!

更新

感谢我编写此解决方案的答案

    fun createDates(userIds: List<Int>): List<DateEntity> {
        val dates = ArrayList<DateEntity>()

        val userCount = userIds.size
        val days = userCount - 1
        val half = userCount / 2

        val mutableUsers = userIds.toMutableList()

        for (day in 0 until days) {
            val firstHalf = mutableUsers.slice(0 until half)
            val secondHalf = mutableUsers.slice(half until userCount).reversed()

            for (i in firstHalf.indices) {
                dates.add(DateEntity(day, firstHalf[i], secondHalf[i]))
            }
            // rotating the array
            mutableUsers.add(1, mutableUsers.removeLast())
        }
        return dates
    }

【问题讨论】:

标签: java python algorithm kotlin logic


【解决方案1】:

循环算法:

把人排成两排。

每天上排的人都与下排的对应人配对。 如果人数是奇数,一个人等一天。

day 1
A B C
D E F
A:D B:E C:F

白班结束后,除了第一个人以外,其他人都以循环方式:

day 2
A D B
E F C
A:E D:F B:C 

day 3
A E D
F C B
A:F E:C D:B

等等。

【讨论】:

  • 非常感谢,你教给我正确的方法!
【解决方案2】:

此代码仅执行 MBo 描述的the algorithm

const cycle = (n, xs) => 
  [... xs .slice (n % xs .length), ... xs .slice (0, n % xs .length)]

const pairs = (xs) =>
  xs.length < 2 ? [] : [[xs [0], xs [xs .length - 1]], ...pairs (xs .slice (1, -1))]

const roundRobin = ([x, ...xs]) => 
  Array.from(xs, (_, i) => pairs ([x, ...cycle(i, xs)]))

console .log (roundRobin ([1, 2, 3, 4, 5, 6])) //=>
// (1 - 6)  &  (2 - 5)  &  (3 - 4)
// (1 - 2)  &  (3 - 6)  &  (4 - 5)
// (1 - 3)  &  (4 - 2)  &  (5 - 6)
// (1 - 4)  &  (5 - 3)  &  (6 - 2)
// (1 - 5)  &  (6 - 4)  &  (2 - 3)
.as-console-wrapper {max-height: 100% !important; top: 0}

cycle 只是循环一个数组n 位置,因此,例如,cycle (2, ['a', 'b', 'c', 'd', 'e']) 产生['c', 'd', 'e', 'a', 'b']pairs 将数组末端的两个元素配对,然后将它们旁边的两个元素配对,以此类推。 pairs (['a', 'b', 'c', 'd', 'e', 'f']) 产生 [['a', 'f'], ['b', 'e'], ['c', 'd']]

我们将这些组合在roundRobin 中,对于每一天,我们删除第一个值,循环剩余的值,将第一个值放回去,然后将列表成对。

如果您想要额外的随机性,我建议您在开始之前简单地打乱数组。

如果您想允许奇数个参与者,每次只有一个参与者,我会添加一个专门的参与者,然后每天与不同的参与者配对。

【讨论】:

  • 谢谢你的榜样!帮了大忙!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-09-26
相关资源
最近更新 更多