how to select a set of numbers randomly which meets a condition
4 次查看(过去 30 天)
显示 更早的评论
I want to get some random numbers that meet conditions.
For example, span is input of my function, and i want random combination of (hf,b,bf,bw) that meets these condition.
hf = (b-bw)/16
b = span/4
bw = -2*bf + b
bf <= 8*hf
4 个评论
John D'Errico
2019-5-30
编辑:John D'Errico
2019-5-30
It is good that I did not bother to answer this as if the numbers were continuous, which owuld have been my default assumption. As you asking for uniformly distributed integers that satisfy the constraints?
How large is span typically? What is the maximum expected value of span?
Do you want to generate ONE set of such random numbers, or many at once?
采纳的回答
John D'Errico
2019-5-30
编辑:John D'Errico
2019-5-30
Lol. Ok. I'll give a new answer since the old was was on a different set of constraints. Lets see. With the new set of constraints...
Assume span = 1800, just to get a measure of things.
span = 1800; b = span/4;
So b = 450, as above.
We still have
bw > b
and therefor b lives in [1,449], since these are positive integers.
Since
hf = (b - bw)/16
then hf must live in the interval [1,(450-1)/16]
(450-1)/16
ans =
28.0625
So hf lives in [1,28], again, integer.
We also have
bw = -2*bf + b
So
bf = (b-bw)/2
That limits bf.
(450-1)/2
ans =
224.5
So bf must live in [1,224].
Finally, we see that bf is limited by the limits on hf too.
bf <= 8*hf
But we see that
8*28
ans =
224
So this does not impact the upper limit on bf.
So far, I see no inconsistencies in this.
You just want to now generate a set of random integers that satisfy the constraints, chosen uniformly over the admissable set. That part is now easy, since the set of points we need to consider is not that large.
span = 1800;
b = span/4;
[hf,bf,bw] = meshgrid(1:28,1:224,1:449);
K = (hf == (b-bw)/16) & (bw == -2*bf + b) & (bf <= 8*hf);
valid = [hf(K),bf(K),bw(K)];
What does this tell us?
size(valid)
ans =
28 3
valid
valid =
28 224 2
27 216 18
26 208 34
25 200 50
24 192 66
23 184 82
22 176 98
21 168 114
20 160 130
19 152 146
18 144 162
17 136 178
16 128 194
15 120 210
14 112 226
13 104 242
12 96 258
11 88 274
10 80 290
9 72 306
8 64 322
7 56 338
6 48 354
5 40 370
4 32 386
3 24 402
2 16 418
1 8 434
So there are exactly 28 possible combinations of integers that satisfy all of the constraints. Pick ANY of them at random, and the result will be what you want. For example:
valid(randi(size(valid,1),1),:)
ans =
16 128 194
Those correspond to hf, bf, and bw. If you change the value of span, just redo the above computations to generate the complete set of admissable solutions. Then pick one of them randomly.
I will add that because these operations are on integers, AND that because you never divice by any number that is not a pure power of 2, then those tests are entirely valid. You need not use a tolerance on the result.
Finally, I would note that the set of valid parameters seems to be rather simple. That is, at least for the case of scan=1800, there are only 28 possible sets of parameters. I could as easily have chosen a random value for hf, from the set [1:28]. Then I could apparently have chosen a unique pair of values for bf and bw. That scheme would arguably be far less computationally intensive. What I cannot assure you is that for other values of scan, the feasible set looks the same as this.
So let me start over. Suppose we had said scan=2000.
scan = 2000;
b = scan/4: % 500
% hf = (b-bw)/16
% so hf is limited to floor((500-1)/16)
499/16
ans =
31.1875
% assume that hf is any integer from the set [1:31].
hf = 1:31;
bw = b - 16*hf;
bf = (b - bw)/2;
So, whatever the value of hf here, as long as it does not exceed (b-1)/16, then we can choose bf and bw directly. So just pick hf randomly between the allowed limits, and the other variables follow directly.
更多回答(1 个)
John D'Errico
2019-5-30
编辑:John D'Errico
2019-5-30
Its actually a bit difficult to find even ONE solution to the problem, even ignoring the question of them being integer.
Lets pick span arbitrarily as 1800. Then we have
span = 1800;
b = span/4
b =
450
Next, we see that
hf = (b-bw)/16.
Since hf must be positive, this puts an upper limit on bw. That is bw <= b, since all are positive integers. (Actually, bw < b, to be picky.) So in this case, bf is no larger than 450.
As well, we see that hf has an upper limit too, of b/16, since hf is maximized when bw is as small as possible. That gives us
b/16
ans =
28.125
So hf is no larger than 28.
How about bf? Since we see this constraint, with b == 450:
bw = 2*bf + b
and bw lives in the interval [0,450]. Then
bf = (bw - b)/2.
But we learned before that bw could be NO larger than b for any solution to exist.
The conclusion is simple and even trivial. There exists NO solution to your problem. EVER. I never had to consider the constraint that bf<=8*hf.
Had I chosen a different value for span, the conclusion would stay the same. No set of numbers exists that are all positive numbers, such that those constraints apply. Period.
Think of it like this. Your constraints imply that both of these conditions apply:
b - bw > 0
AND
bw - b > 0
b is a fixed number. There exists no value for bw that satisfies both conditions.
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Creating and Concatenating Matrices 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!