How to generate non-overlap random integer tuple efficiently?

Hello.
I am doing a project which needs to generate non-overlap random integer tuple.
Suppose I have a 100-dimension vector, I need to choose 3 different indices among the 100 numbers, a naive implementation maybe:

index1 = torch.randint(0, 100, [1])
index2 = torch.randint(0, 100, [1])
while(index2 == index1):
    index2 = torch.randint(0, 100, [1])
index3 = torch.randint(0, 100, [1])
while(index3 == index1 or index3 == index2):
    index3 = torch.randint(0, 100, [1])

which is time-comsuming…
Is there a more efficient way to do the jobs ? as I need to generate many tuples at one time.
Thanks.

2 Likes

Would torch.randperm work?

x = torch.randperm(100)[:3]
2 Likes

Thanks for your reply.
I just also found randperm too. It works.
Not sure whether there is a batch version of ```randperm’’’.

Probably torch.multinomial would achieve a better performance for a whole batch:

batch_size = 10
weights = torch.ones(100).expand(batch_size, -1)
torch.multinomial(weights, num_samples=3, replacement=False)
2 Likes

Thanks. torch.multinomial did do the best jobs.

1 Like

Hello.
Sorry to disturb you again.
Indeed I am trying to make ransac algorithm as parallable as possible.
Specifically, suppose I have a 100-dimension vector, first I need to generate up to 1000 3-tuple-index variable, which can be done by multinomial as you said.
Then, I need to using every 3-tuple-index to gather number from the 100-dimension vector, which I think there should be some operation maybe called batch index, which means index a 100-dimension tensor with a 1000 * 3 tensor.
Although a intuitive solution is to expand the 100-dimension vector to 1000 * 100 shape, I think it would be more efficient to directly select from the original 100-dimension vector.
Is there any way to support this operation ?
Thanks.

1 Like

Would just indexing work?

batch_size = 1000
weights = torch.ones(100).expand(batch_size, -1)
idx = torch.multinomial(weights, num_samples=3, replacement=False)

x = torch.randn(100)
x[idx]
1 Like