Effacer les filtres
Effacer les filtres

How can I find all possible pairs within a range that result in the same average?

2 vues (au cours des 30 derniers jours)
I'm trying to figure out how to output multiple pairs of values that happen to have the same average (added together and divided by 2) within a range. For example, if I set an array to be:
array= [0:1:100]
and I want all possible pairs that output an average of 2.
avg= 2
So for example, 2 pairs would be (0,2) and (2,2) and the avg. of both of these seprately is 2.
I'm sure I'll probably need a for loop, but I've read here on several function such as permutations or combinations, but I feel like this should be more simple. Obviously I'll have a lot more conditions involved, but the basic premise of getting this to work is somehow eluding me, so I'd appreciate a little nudge in the right direction here on how to go about this. Thank you!

Réponse acceptée

Torsten
Torsten le 9 Juin 2022
Modifié(e) : Torsten le 9 Juin 2022
Do you know if there's any way that this can be done by just using for loops and nested for loops with if statements to get the same result?
Sure. A very slow version would be
mean_compare = 2.0;
a = 0:100;
n = numel(a);
ifound = 0;
b = [];
tic
for i = 1:n
value1 = a(i);
for j = 1:n
value2 = a(j);
if value1 + value2 == 2*mean_compare
ifound = ifound + 1;
b = [b,[value1;value2]];
end
end
end
toc
Elapsed time is 0.003877 seconds.
b
b = 2×5
0 1 2 3 4 4 3 2 1 0
  2 commentaires
Aly Osman
Aly Osman le 9 Juin 2022
This is more what I was looking for. Thank you!
Torsten
Torsten le 10 Juin 2022
Modifié(e) : Torsten le 10 Juin 2022
A better solution is the following:
Let
m = min(a)
and
M = max(a)
Let
feasible_range = min(mean_compare - m, M - mean_compare)
Consider the points
union( (m,m) , (m-(1:feasible_range).',m+(1:feasible_range).') , (m+(1:feasible_range).',m-(1:feasible_range).') )
The intersection with
a x a
is the solution (at least if "a" is an array of integers).

Connectez-vous pour commenter.

Plus de réponses (3)

KSSV
KSSV le 9 Juin 2022
a = 0:10 ;
b = permn(a,2) ;
idx = mean(b,2)==2 ;
iwant = b(idx,:)
You can download the function permn from the file exchange: https://in.mathworks.com/matlabcentral/fileexchange/7147-permn
  2 commentaires
Aly Osman
Aly Osman le 9 Juin 2022
Do you know if there's any way that this can be done by just using for loops and nested for loops with if statements to get the same result?
KSSV
KSSV le 10 Juin 2022
The function permn should have loops.... Check the function...

Connectez-vous pour commenter.


Steven Lord
Steven Lord le 9 Juin 2022
As long as your arrays aren't that large just brute force it:
array= 0:1:100;
desiredAverage = 2;
ind = find(array+array.' == 2*desiredAverage)
ind = 5×1
5 105 205 305 405
[r, c] = ind2sub(numel(array)*[1 1], ind)
r = 5×1
5 4 3 2 1
c = 5×1
1 2 3 4 5
B = array([r, c]) % 5 pairs of numbers each of whose average is 2
B = 5×2
4 0 3 1 2 2 1 3 0 4
mean(B, 2) == desiredAverage % all true
ans = 5×1 logical array
1 1 1 1 1
If you had to do this with a loop (because that's one of the requirements of your homework assignment, for instance) you only need one.
Hint: I'm thinking of two numbers whose average is 10. One of the numbers is 5. What's the other? How did you determine the answer?
What if instead I told you one of the numbers was 17. What's the other?

DGM
DGM le 10 Juin 2022
I know Steven hinted at it, but I'm just going to give an example. Since the assignment forces you to accept bad decisions (and you've already accepted them), I might as well demonstrate that the consequences aren't trivial.
candidatevalues = 0:1:100; % the set
desiredAverage = 2; % the target
companionvalues = 2*desiredAverage - candidatevalues;
isvalidpair = ismember(companionvalues,candidatevalues);
validpairs = [candidatevalues(isvalidpair); companionvalues(isvalidpair)].' % these are the pairs
validpairs = 5×2
0 4 1 3 2 2 3 1 4 0
mean(validpairs,2) % their average is as expected
ans = 5×1
2 2 2 2 2
Despite the use of ismember(), this naive algebra approach can be much faster than any of the examples given to meet the loop-based requirements. For a set size of 10E3 and a target mean of 25, on my hardware in R2019b, the 3-line example above is between 1400 to 35000 times as fast as the other examples. For a set size of 100, the smallest speed advantage is a factor of 5. Is my example ideal? I doubt it, but it's a remarkable amount better than what's been deemed acceptable.
I'm no compsci professor, but I'm sure there's a lesson to be found here regarding computational complexity.
  3 commentaires
DGM
DGM le 10 Juin 2022
Ah. It's good to explore. I'm just too eager to critique what I think are unhelpful homework tropes, that's all.
Aly Osman
Aly Osman le 10 Juin 2022
No problem at all! Thanks for looking out!

Connectez-vous pour commenter.

Catégories

En savoir plus sur Loops and Conditional Statements dans Help Center et File Exchange

Produits


Version

R2022a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by