将n个元素的排序列为k类

时间:2013-09-22 02:35:55

标签: algorithm matlab

我有n个事件{v1,...,vn}将在某些特定时间{t1,...,tk}发生,其中k <= n(多个可以同时出现),以及我需要列出发生这种情况的每种方式。

例如,如果我们有2个事件,我可以:

{v1&lt; v2},{v2&lt; v1}(2次)

{v1 = v2}(1次)

如果我们有3个事件,我可以拥有3个不同时间的所有6个订单,加上

{v1 = v2&lt; v3},{v1 = v3&lt; v2},{v2 = v3&lt; v1},{v1&lt; v2 = v3},{v2&lt; v1 = v3},{v3&lt; v1 = v2}(2次)

{v1 = v2 = v3}(1次)

所以我实际上并不想要所有可能的分组,因为{v1 = v2&lt; v3}相当于{v2 = v1&lt;例如,v3}。

我的想法是我需要为k = n的情况生成n个事件的所有排列,我有一个方法要做,所以也许我可以在此基础上生成可能的类别然后删除重复,但我不知道如何检查,例如,{v3 = v4 = v2&lt; v1 = v6&lt; v5}是我们以前有效接受的东西的复制品。

也许从排列列表中进行操作可以更系统化,并找出如何删除重复项而不用我们目前存档的列表重新检查?

我意识到即使是大量的事件,这也不会在合理的时间内发挥作用,但我想尽可能高地推动它,6可以,8或10甚至更​​好。

我正在使用MATLAB,但我愿意采用任何有人可能建议的语言来解决这个问题,并且非常欢迎和赞赏任何关于一般语言不可知方法的建议。

1 个答案:

答案 0 :(得分:1)

这是一种方法(代码如下):

使用任何标准算法生成v1…vn的排列(显然有n个排列)。对于每个排列vp1…vpn枚举所有可能的公式:

vp1 R1 vp2 R2 vp3 … Rn-1 vpn

其中Ri始终为<,如果=也可以是pi < pi+1

例如,如果n为3:

v1 v2 v3: v1 < v2 < v3; v1 < v2 = v3; v1 = v2 < v3; v1 = v2 = v3
v1 v3 v2: v1 < v3 < v2; v1 = v3 < v2
v2 v1 v3: v2 < v1 < v3; v2 < v1 = v3
v2 v3 v1: v2 < v3 < v1; v2 = v3 < v1
v3 v1 v2: v3 < v1 < v2; v3 < v1 = v2
v3 v2 v1: v3 < v2 < v1

你可以递归地进行关系的枚举(这实际上是我在上面手工完成的)。

编辑:这是Sloane序列A000670,该链接包含各种可能的有用参考。对于n = 9,计数是7087261,这看起来非常实用;对于n = 10,它是102247563,很容易在现代桌面计算的范围内。 (不过我不知道matlab。)

这是一个python实现:

def rels(perm):
  if len(perm) == 1:
    yield perm
  else:
    for p in rels(perm[1:]):
      yield (perm[0], '<') + p
      if perm[0] < perm[1]:
        yield (perm[0], '=') + p

def orders(n):
  return reduce(lambda a,b:a+b,
                [[i for i in rels(p)] for p in itertools.permutations(range(n))])

>>> print '\n'.join(map(repr,[o for o in orders(4)]))
(0, '<', 1, '<', 2, '<', 3)
(0, '=', 1, '<', 2, '<', 3)
(0, '<', 1, '=', 2, '<', 3)
(0, '=', 1, '=', 2, '<', 3)
(0, '<', 1, '<', 2, '=', 3)
(0, '=', 1, '<', 2, '=', 3)
(0, '<', 1, '=', 2, '=', 3)
(0, '=', 1, '=', 2, '=', 3)
(0, '<', 1, '<', 3, '<', 2)
(0, '=', 1, '<', 3, '<', 2)
(0, '<', 1, '=', 3, '<', 2)
(0, '=', 1, '=', 3, '<', 2)
(0, '<', 2, '<', 1, '<', 3)
(0, '=', 2, '<', 1, '<', 3)
(0, '<', 2, '<', 1, '=', 3)
(0, '=', 2, '<', 1, '=', 3)
(0, '<', 2, '<', 3, '<', 1)
(0, '=', 2, '<', 3, '<', 1)
(0, '<', 2, '=', 3, '<', 1)
(0, '=', 2, '=', 3, '<', 1)
(0, '<', 3, '<', 1, '<', 2)
(0, '=', 3, '<', 1, '<', 2)
(0, '<', 3, '<', 1, '=', 2)
(0, '=', 3, '<', 1, '=', 2)
(0, '<', 3, '<', 2, '<', 1)
(0, '=', 3, '<', 2, '<', 1)
(1, '<', 0, '<', 2, '<', 3)
(1, '<', 0, '=', 2, '<', 3)
(1, '<', 0, '<', 2, '=', 3)
(1, '<', 0, '=', 2, '=', 3)
(1, '<', 0, '<', 3, '<', 2)
(1, '<', 0, '=', 3, '<', 2)
(1, '<', 2, '<', 0, '<', 3)
(1, '=', 2, '<', 0, '<', 3)
(1, '<', 2, '<', 0, '=', 3)
(1, '=', 2, '<', 0, '=', 3)
(1, '<', 2, '<', 3, '<', 0)
(1, '=', 2, '<', 3, '<', 0)
(1, '<', 2, '=', 3, '<', 0)
(1, '=', 2, '=', 3, '<', 0)
(1, '<', 3, '<', 0, '<', 2)
(1, '=', 3, '<', 0, '<', 2)
(1, '<', 3, '<', 0, '=', 2)
(1, '=', 3, '<', 0, '=', 2)
(1, '<', 3, '<', 2, '<', 0)
(1, '=', 3, '<', 2, '<', 0)
(2, '<', 0, '<', 1, '<', 3)
(2, '<', 0, '=', 1, '<', 3)
(2, '<', 0, '<', 1, '=', 3)
(2, '<', 0, '=', 1, '=', 3)
(2, '<', 0, '<', 3, '<', 1)
(2, '<', 0, '=', 3, '<', 1)
(2, '<', 1, '<', 0, '<', 3)
(2, '<', 1, '<', 0, '=', 3)
(2, '<', 1, '<', 3, '<', 0)
(2, '<', 1, '=', 3, '<', 0)
(2, '<', 3, '<', 0, '<', 1)
(2, '=', 3, '<', 0, '<', 1)
(2, '<', 3, '<', 0, '=', 1)
(2, '=', 3, '<', 0, '=', 1)
(2, '<', 3, '<', 1, '<', 0)
(2, '=', 3, '<', 1, '<', 0)
(3, '<', 0, '<', 1, '<', 2)
(3, '<', 0, '=', 1, '<', 2)
(3, '<', 0, '<', 1, '=', 2)
(3, '<', 0, '=', 1, '=', 2)
(3, '<', 0, '<', 2, '<', 1)
(3, '<', 0, '=', 2, '<', 1)
(3, '<', 1, '<', 0, '<', 2)
(3, '<', 1, '<', 0, '=', 2)
(3, '<', 1, '<', 2, '<', 0)
(3, '<', 1, '=', 2, '<', 0)
(3, '<', 2, '<', 0, '<', 1)
(3, '<', 2, '<', 0, '=', 1)
(3, '<', 2, '<', 1, '<', 0)