Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to select specific item from cartesian product without calculating every other item

I'm mostly convinced that there is an answer to this problem, but for the life of me can't figure out how to do it.

Let's say I have three sets:

A = [ 'foo', 'bar', 'baz', 'bah' ]
B = [ 'wibble', 'wobble', 'weeble' ]
C = [ 'nip', 'nop' ]

And I know how to calculate the cartesian / cross product, (ant it's covered all over the place, on this site and elsewhere) so I won't go over that here.

What I'm looking for is an algorithm that would allow me to simply select a specific item from the cartesian product without generating the whole set or iterating until I reach the nth item.

Of course, I could easily iterate for a small example set like this, but the code I am working on will be working with much larger sets.

Therefore, I'm looking for a function, let's call it 'CP', where:

CP(1) == [ 'foo', 'wibble', 'nip' ]
CP(2) == [ 'foo', 'wibble', 'nop' ]
CP(3) == [ 'foo', 'wobble', 'nip' ]
CP(4) == [ 'foo', 'wobble', 'nop' ]
CP(5) == [ 'foo', 'weeble', 'nip' ]
CP(6) == [ 'foo', 'weeble', 'nop' ]
CP(7) == [ 'bar', 'wibble', 'nip' ]
...
CP(22) == [ 'bah', 'weeble', 'nop' ]
CP(23) == [ 'bah', 'wobble', 'nip' ]
CP(24) == [ 'bah', 'wobble', 'nop' ]

And the answer is produced in O(1) time, more or less.

I've been following the idea that it should be possible, (heck, even simple!) to calculate the indices of the elements from A,B,C that I want and then simply return the them from the original arrays, but my attempts to make this work correctly have so far, um, not worked.

I'm coding in Perl, but I can handily port a solution from Python, JavaScript, or Java (and probably a few others)

like image 401
Hercynium Avatar asked Mar 30 '12 14:03

Hercynium


People also ask

How to find Cartesian product of a and B?

In mathematics, the Cartesian Product of sets A and B is defined as the set of all ordered pairs (x, y) such that x belongs to A and y belongs to B. For example, if A = {1, 2} and B = {3, 4, 5}, then the Cartesian Product of A and B is {(1, 3), (1, 4), (1, 5), (2, 3), (2, 4), (2, 5)}.

How to CALCULate the Cartesian product of two tables?

For two non-empty sets (say A & B), the first element of the pair is from one set A and the second element is taken from the second set B. The collection of all such pairs gives us a Cartesian product. Cartesian product A×B = {(a1,b1), (a1,b2), (a1,b3), ( a2,b1), (a2,b2),(a2,b3), (a3,b1), (a3,b2), (a3,b3)}.

Are Cartesian products ordered?

What Is a Cartesian Product? Cartesian product is the product of any two sets, but this product is actually ordered i.e, the resultant set contains all possible and ordered pairs such that the first element of the pair belongs to the first set and the second element belongs to the second set.

What is Cartesian product in computer science?

Cartesian Product: A new set can be constructed by associating every element of one set with every element of another set. The Cartesian product of two sets A and B, denoted by A × B is the set of all ordered pairs (a, b) such that a is a member of A and b is a member of B.


1 Answers

The number of possible combinations ist given by

N = size(A) * size(B) * size(C)

and you can index all items by an index i ranging from 0 to N (exclusive) via

c(i) = [A[i_a], B[i_b], C[i_c]]

where

i_a = i/(size(B)*size(C)) 
i_b = (i/size(C)) mod size(B)
i_c = i mod size(C)

(all sets are assumed to be indexable starting wih zero, / is integer division).

In order to get your example you may shift the index by 1.

like image 101
Howard Avatar answered Sep 22 '22 05:09

Howard