简体   繁体   English

当x <y时如何获得给定索引的(x,y)坐标?

[英]How to get the (x,y) coordinates given a index when x < y?

In the past I've often used loops of the following kind (Haskell example): 在过去,我经常使用以下类型的循环(Haskell示例):

  upperBoundToTuples :: Int -> [(Int, Int)]
  upperBoundToTuples n = [(x,y) | x <- [0..n], y <- [x+1..n]]

The above code produces tuples of range (0,1)..(n,n) where for all x < y. 上面的代码生成范围为(0,1)..(n,n)的元组,其中所有x <y。

I was wondering if it there was an efficient way of getting those (x,y) indices given a single index? 我想知道是否有一种有效的方法来获得给定单个索引的(x,y)索引? Possible applications include optimization problems on the GPU where loops are not allowed and each thread only gets an index. 可能的应用包括GPU上的优化问题,其中不允许循环且每个线程仅获得一个索引。

Also if it is possible for the 2D case, could such an algorithm be generalized to multiple dimensions? 另外,如果2D情况可行,是否可以将这种算法推广到多个维度?

You're asking for a bijection from [0, N(N+1)/2) to pairs (x, y) with 0 <= x < y <= N. 您正在要求从[0,N(N + 1)/ 2)到(x,y)对具有0 <= x <y <= N的双射。

Here's one simple way to define it (in pseudocode, but should be trivial to convert to Haskell): 这是定义它的一种简单方法(使用伪代码,但转换为Haskell应该很简单):

x0, y0 = i / (N + 1), i % (N + 1)
if x0 < y0 then result = (x0, y0)
else result = (N - 1 - x0, N - y0)

Here's a visualisation of the function for N=6. 这是N = 6函数的可视化。 The map is laid out in a table with rows of length N+1=7, with the first row representing the value of the function for i=0 to 6, the next i=7 to 13 and so on. 该映射被布置在一个表中,该表的行长为N + 1 = 7,第一行代表i = 0到6的函数值,下一个i = 7到13等等。 If you look very closely and carefully, you can see that things above the leading diagonal map to their own location in the table, and things on or below the diagonal map rotationally to the later entries. 如果仔细仔细地查看,您会发现在对角线上方的东西映射到表中它们自己的位置,在对角线上或下方的东西旋转地映射到后面的条目。

5,6  0,1  0,2  0,3  0,4  0,5  0,6
4,6  4,5  1,2  1,3  1,4  1,5  1,6
3,6  3,5  3,4  2,3  2,4  2,5  2,6

And here's the opposite of this visualisation: a table T of size (N+1) by (N+1) with T[x, y] = i where i is mapped to (x, y) by the function above. 这与可视化相反:表格T的大小为(N + 1)x(N + 1),其中T[x, y] = i ,其中上述函数将i映射到(x,y)。

 -   1   2   3   4   5   6
 -   -   9  10  11  12  13
 -   -   -  17  18  19  20
 -   -   -   -  16  15  14
 -   -   -   -   -   8   7
 -   -   -   -   -   -   0
 -   -   -   -   -   -   -

Higher dimensions 更高尺寸

This method can probably be made to work in higher dimensions, but I don't immediately see how. 可以使这种方法在更高的维度上起作用,但是我还没有马上看到如何做。 As an alternative, here's a simple but somewhat inefficient method that does work in arbitrary dimensions. 作为替代方案,这是一种简单但效率低下的方法,可以在任意维度上使用。

First, note there's choose(N + 1, k) increasing sequences of length k from the numbers from 0 to N (where choose(N, k) is the binomial coefficient ). 首先,请注意choose(N + 1, k)0N的数字中有一个长度为kchoose(N + 1, k)递增序列(其中choose(N, k)二项式系数 )。 Of those, choose(N, k - 1) of them end with N . 其中, choose(N, k - 1)N结尾。 That gives this recursive function that generates the sequences in descending colexicographical order (again in pseudocode): 这提供了此递归函数,该函数以降序(按伪代码形式)按顺序依次产生序列:

sequence(N, k, index)
    = []                                           if k == 0
    = sequence(N - 1, k - 1, index) + [N]          if index < choose(N, k - 1)
    = sequence(N - 1, k, index - choose(N, k - 1)) otherwise

Here's, sequence(5, 3, index) for index between 0 and 19: 这里, sequence(5, 3, index)index 0和19之间:

 0 -> [3, 4, 5]
 1 -> [2, 4, 5]
 2 -> [1, 4, 5]
 3 -> [0, 4, 5]
 4 -> [2, 3, 5]
 5 -> [1, 3, 5]
 6 -> [0, 3, 5]
 7 -> [1, 2, 5]
 8 -> [0, 2, 5]
 9 -> [0, 1, 5]
10 -> [2, 3, 4]
11 -> [1, 3, 4]
12 -> [0, 3, 4]
13 -> [1, 2, 4]
14 -> [0, 2, 4]
15 -> [0, 1, 4]
16 -> [1, 2, 3]
17 -> [0, 2, 3]
18 -> [0, 1, 3]
19 -> [0, 1, 2]

We may equivalently consider [(x,y) | x<-[0..n], y<-[0..x-1]] 我们可以等效地考虑[(x,y) | x<-[0..n], y<-[0..x-1]] [(x,y) | x<-[0..n], y<-[0..x-1]] . [(x,y) | x<-[0..n], y<-[0..x-1]] This list has length 此清单有长度

n = x =0n x = n ·( n +1) / 2 . ℓN = X = 0Σ 的N× = N·(N + 1)/ 2

Hence we can get, to a given , the nearest lower n through 因此,我们可以得到,给定ℓ,最近的低n通过

n = n ·( n +1) = n 2 + n 2·ℓN = N·(N + 1)= N 2 + N

n ~ = -½ ± √(¼ + 2· n ) N〜=-½±√(¼+ 2·ℓn)的

In particular, for a given index i , 特别是对于给定的索引i

n i = ⌊-½ ± √(¼ + 2· i )⌋ n i =⌊-½±√(¼+ 2· i )⌋

is the x-length of the last fully completed triangle. 是最后一个完全完成的三角形的x长度。 Thus, the index i lies in the row n i +1. 因此,该指数出在第n行第I - +1。 That triangle had an area of 该三角形的面积为

n i = n i ·( n i +1) / 2 ℓN I - = N I - ·(N I - 1)/ 2

which we therefore need to subtract from i to get the remainder index (in y-direction). 因此,我们需要从i中减去它以获得余数索引(在y方向上)。 This gives rise to the definition 这引起了定义

lowerTriangularTuple :: Int -> (Int,Int)
lowerTriangularTuple i = (nmin+1, i - (nmin*(nmin+1))`div`2)
 where nmin = floor $ -1/2 + sqrt(1/4 + 2 * fromIntegral i)

Example: 例:

GHCi> lowerTriangularTuple <$> [0..30]
[(1,0),(2,0),(2,1),(3,0),(3,1),(3,2),(4,0),(4,1),(4,2),(4,3),(5,0),(5,1),(5,2),(5,3),(5,4),(6,0),(6,1),(6,2),(6,3),(6,4),(6,5),(7,0),(7,1),(7,2),(7,3),(7,4),(7,5),(7,6),(8,0),(8,1),(8,2)]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM