Suppose I have 3 positive integers: $n_1$, $n_2$, and $n_3$.
How do I uniformly sample $(n_1, n_2, n_3)$ so that $50 < n_1 n_2 n_3 < 100$.
I could sample each number independently with bounds between 1 and 100, then keep re-sampling if their product is out of bound.
I need to do this with a computer program with more numbers and larger bounds, so I prefer a way that's efficient both in space and time.
Are there other ways to sample than what I described above?
EDIT (regarding the accepted answer):
At the time of this edit, there were 3 approaches answered so far:
- complete enumeration (addresses the example in the question, simple, but space and time bound for very large problems)
- rejection sampling (simple, but time bound for very large problems)
- weighted draw ("efficient" in space and time compared to other approaches, but complex)
All answers work best in different situations.
I accepted weighted drawing since it seemed to be most complete in a sense that it addressed the "efficient both in space and time" part for larger problems the best.
Depending on how large your bounds are, what you consider 'efficient', and how much preprocessing you're willing to do, one option is to do a weighted draw of $n_1$. For each $n_1$ you can compute how many $(n_2,n_3)$ pairs yield $b_{min}\leq n_1n_2n_3\leq b_{max}$; this will take $O(b_{max}^2)$ time and $O(b_{max})$ space naively. Then build a CDF table of $n_1$ from those pairs; this will ensure the appropriate probability for that variable. Once you have $n_1$ you can either do the same procedure a dimension down (but note that the tables there will be $n_1$ dependent, so you'll have to build them after choosing $n_1$ or have them available for many possible $n_1$) or do rejection sampling, though presumably with a much smaller range.
For an example, suppose we have $5\leq n_1n_2n_3\leq 10$. Then we start by making a table $T(i)$ of the number of pairs $a,b$ with $1\leq ab\leq i$, for $1\leq i\leq 10$; this looks like $[1, 3, 5, 8, 10, 14, 16, 20, 23, 27]$. (This table is buildable in $O(i^2)$ time through several means and I suspect it's buildable much faster than that in practice if you wanted to dig into the appropriate algorithms.) Now, for each $n_1$ we can compute $T(\lfloor\frac{10}{n_1}\rfloor)-T(\lceil\frac5{n_1}\rceil-1)$ (taking $T(0)=0$); this represents how many pairs $n_2,n_3$ fit the product within the bounds for that $n_1$. This table will look like $[19, 7, 4, 2, 3, 1, 1, 1, 1, 1]$. Then sampling from this table is a matter of computing the CDF (which here would be $[19, 26, 30, 32, 35, 36, 37, 38, 39, 40]$), computing an $r$ uniformly in $[1\ldots 40]$ and doing the reverse lookup to find the corresponding value of $n_1$.