有序集和自然双射(组合物种)

时间:2012-12-20 10:14:19

标签: algorithm haskell complexity-theory combinatorics

A设置一些(例如。1000, 1001, 1002, ..., 1999)。

lessThan某个顺序关系函数(例如(a lessThan b) <-> (a > b))。

index一个函数(使用反index')将A元素映射到自然元素。

示例:

index a = 2000 - a
index' n = 2000 - n

是否存在某种方法为P(多项式时间)中的所有(或某些类型)index对构造index'(和(A, lessThan))函数?

最好的问候,并提前感谢!

已编辑A可以按定义设置(例如,重复另一个大子集的所有组合),然后,我们不能假设A完全是可穿越(在P中)。

已编辑:另一个非常重要的例子,让An一个集合(像(x, y, p)这样的元素),其元素顺时针排列到n X n正方形,就像此

 1    2    3    4
12   13   14    5
11   16   15    6
10    9    8    7

然后,我们可以使用An(多项式)将Bn = [1..n^2]中的每个三元组映射到O(1)

如果有一个An元素,我们index可以Bn O(1)。 给定一个Bn元素,我们index'可以An O(1)

// Square perimeter; square x = 1, 2, 3, ...
Func<int, int, int> perimeter = ( x, n ) => 4 * ( n - 2 * x + 1 ); 

// Given main diagonal coordinates (1, 1), (2, 2), ... return cell number
Func<int, int, int> diagonalPos = ( x, n ) => -4 * x * x + ( 4 * n + 8 ) * x - 4 * n - 3; 

// Given a number, return their square
Func<int, int, int> inSquare = ( z, n ) => (int) Math.Floor(n * 0.5 - 0.5 * Math.Sqrt(n * n - z + 1.0) + 1.0); 

Func<int, int, Point> coords = ( z, n ) => { 
    var s = inSquare(z, n); 
    var l = perimeter(s, n) / 4; // length sub-square edge -1 
    var l2 = l + l; 
    var l3 = l2 + l; 
    var d = diagonalPos(s, n); 
    if( z <= d + l ) 
        return new Point(s + z - d, s); 
    if( z <= d + l2 ) 
        return new Point(s + l, s + z - d - l); 
    if( z <= d + l3 ) 
        return new Point(s + d + l3 - z, s + l); 
    return new Point(s, s + d + l2 + l2 - z); 
}; 

(我读过“组合物种”,"Ordered construction of combinatorial objects""species" haskell package和其他人)

1 个答案:

答案 0 :(得分:3)

我可能误解了你想要的东西,但万一我不是:

如果lessThan定义了该集合的总订单,您可以通过

创建indexindex'函数
  • 将集合转换为列表(或数组/向量)
  • 根据lessThan
  • 排序
  • index'定义为Data.Map.fromDistinctAscList $ zip [1 .. ] sortedList
  • index定义为Data.Map.fromDistinctAscList $ zip (map NTC sortedList) [1 .. ]

其中NTC是一个newtype构造函数,用于在Ord实例由lessThan给出的newtype中包装集合元素的类型。

newtype Wrapped = NTC typeOfElements

instance Eq Wrapped where
    (NTC x) /= (NTC y) = x `lessThan` y || y `lessThan` x
-- that can usually be done more efficiently

instance Ord Wrapped where
    (NTC x) <= (NTC y) = not $ y `lessThan` x
  

EDITED :A可以是定义的集合(例如,重复另一个大子集的所有组合),然后,我们不能假设A是完全可遍历的(在P中)。

在这种情况下,除非我遗漏了一些基本的东西,否则原则上是不可能的,因为index'函数会提供对集合的完整遍历。

因此,当且仅当该集合在多项式时间内可遍历时,才能在多项式时间内创建indexindex'函数。