Sorting different numbers into equal stacks - matlab

Hello I'm sort of new to matlab but I am working on a program that will take a bunch of numbers (prices) and sort them into groups that have near the same or near equivalent value (equal cost). However I'm not sure how to program that... does this already exist? If not how should I go about sorting these items.
Ex. sort 3 4 4 4 5 6 7 into 4 piles. 33/4 = 8.25 = Avg
Piles are 7 (4+4) (3+6) (4+5) or 7 8 9 9
Obviously these would also have two decimal places behind them (3.XX) any ideas?

Related

How do I set random numbers that fall in a range in kdb+?

In Kdb+, how do I use the "roll" function to make the random numbers generated fall within a range that doesn't start with 0? For example what if I wanted the range to be within 2-10 instead of 0-10?
What do I have to add to the code to make it fall into a range instead of the default 0-x? I have tried and looked for every method but can't seem to find one.
You could also just roll from 0-8 then add two. This doesn't require a list to be pre-generated
q)2+5?9
10 2 7 10 7
Assuming you want 2-10 inclusive
// quick and simple method
q)10?2+til 8
6 2 4 3 4 3 4 5 4 7
// or function (x)=num to be dealt, (y) start range, (z) end range
q)f:{x?y+til 1+z-y}
q)f[10;10;20]
12 17 10 11 19 12 11 18 18 11
If you supply a list in the right hand argument then you will get a random value from that list. To roll for a random range from 2-10 you can use til to generate the range:
q)2+til 9
2 3 4 5 6 7 8 9 10
q)1?2+til 9
,6
You can even supply a general list to randomly draw from:
q)3?(`abc;2 3f;10;20;30;"text")
2 3f
`abc
"text"
Simple math function for random number generator is:
(rand() mod (1+max- min)) + min
q) f:{x+rand[0] mod 1+y-x}
q) f[5;10]
q) 7
Update: I failed to notice that you wanted to generate couple of random numbers in the range. You could easily modify above function for that:
q) f:{x+(z?0) mod 1+y-x}
q) f[2;10;4]
q) 6 4 7 2

MATLAB/OCTAVE - Branching loops? or parallel looping?

Still new to the programing game but I need a little help! I'm not exactly sure how to describe what I want to do but I'll give it my best shot. I have a set of numbers produced by an algorithm I've put together. e.g. :
....
10 10 10
11 11 11
12 1 2
13 3 4
14 12 13
15 6 7
16 5 15
17 8 9
....
Essentially what I want to do is assign these index numbers to groups. Lets say I start with the number 14 in the first column. It is going to belong to group 1, so I label it in a new column in row 14 "1" for group one. The second and the third column show other index numbers that are grouped with the index 14. So I use a code like:
FindLHS = find(matrix(:,1)==matrix(14,2));
and
FindRHS = find(matrix(:,1)==matrix(14,3));
so clearly this will produce the results of
FindLHS = 12
FindRHS = 13
I will then proceed to label both 12 and 13 as belonging to group "1" as I did for 14
now my problem is I want to do this same procedure for both 12 and 13 of finding and labelling the indexs for 12 and 13 being (1,2) and (3,4). Is there a way to repeat that code for both idx of 1,2,3 and 4? because the real dataset has over 5000 data points in it...
Do you understand what I mean?
Thanks
James
All you really want to do is find wherever matrix(:,1) contains one of the numbers you've already found, include the numbers in the second and third columns into your group list (presuming they aren't already there), and stop when that list stops growing, right? This may not be the most efficient way of doing it but it gives you the basic idea:
while ~(numel(oldnum)==numel(num))
oldnum = num;
idx = ismember(matrix(:,1),oldnum)
num = unique(matrix(idx,:))
end
Output:
num =
1
2
3
4
12
13
14
Now if your first column is literally just your numbers 1 through 5000 in order, you don't need to even find the index, you can just use your number list directly.
To do this for multiple groups you would just need an outer loop that stores the information for each group, then picks out the next unused number. I'm presuming that your individual groups are consistent so that no matter which of those numbers you pick you end up with the same result - e.g. starting at 2 or 14 gives you the same result (if not, it becomes more complex).

MATLAB: Step through iterations of a vector

all.
I have a 15 element array = [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15];.
I was wondering if there was a command such that it would step through iterations of the array without repeating itself. In other words, since there is a chance that randperm() will create the same matrix twice, I want to step through each permutation only once and perform a calculation.
I concede that there are factorial(15) permutations, but for my purposes, these two vectors (and similar) are identical and don't need to be counted twice:
[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15]
[15 14 13 12 11 10 9 8 7 6 5 4 3 2 1]
Thus, is there any way to step through this?
Thanks.
I think what you are looking for is perms. randperm returns a single random permutation, you want all the permutations.
So use
my_permuations = perms([1:15]);
If forward-backward is the same as backward-foward then you can use the top half of the list only...
my_permutation_to_use = my_permutations(1:length(my_permutations)/2, :);
You may compare all permutations, but this would require to store all past permutations. Instead a local decision is better. I recommend this simple rule:
A permutation is valid, if the first element is smaller than the last element.
A permutation is redundant, if the first element is larger than the last element.
For small sizes, this could simply be done with this code:
%generate all permutations
x=perms(1:10)
%select only the valid lines, remove all redundant lines
x(x(:,1)<x(:,end),:)
Remains the problem, that generating x for 1:15 breaks all memory limits and would require about 100h.

Finding maximum value from a file

I want to find out first maximum value (x, ymax) from an array from a file, which contains
x y
1 3
2 4
3 1
4 5
5 4
6 8
7 8
9 8
10 8
The answer will be: (6, 8)
How can I obtain it with Matlab commands? I have started Matlab just today.
Hint to the answer:
As you are looking for the maximum you can find it by using max
Try to use this on the second column (or the vector y if you have it), if you want to find the location of the maximum you will need to use it with multiple output arguments.
Try help max and look at the examples
b=dlmread('filename','',1,0);
[~,i]=max(b(:,2));
disp(b(:,i))% shows 6,8
You need to first delete the first line from your file ("x y").

Strange behaviour of MATLAB combnk function

I am trying to generate all combination of 2 elements in a given range of numbers. I am using 'combnk' function as follows.
combnk(1:4,2)
ans =
3 4
2 4
2 3
1 4
1 3
1 2
combnk(1:6,2)
ans =
1 2
1 3
1 4
1 5
1 6
2 3
2 4
2 5
2 6
3 4
3 5
3 6
4 5
4 6
5 6
The order of combinations returned appears to change. I need to know the order in advance for my program to work properly.
Is there any solution to make sure I get the combinations in a consistent order?
Also, why is MATLAB showing this strange behavior?
The only solution I can think of so far is to first check the 1st entry of the result matrix and flip it up side down using 'flipud' function.
Update: By a little bit of experimenting I noticed the reverse order occurs only when the length of the set of numbers is less than 6. This is why combnk(1:6,2) produce the 'correct' order. Where as combnk(1:5,2) produce the results backwards. This is still big problem.
You could try nchoosek instead of combnk. I don't have the matlab statistics toolbox (only octave), so I don't know if nchoosek has any significant disadvanvatages.
This will solve the ordering issue:
a=combnk(1:4,2);
[~,idx]=sortrows(a);
aNew=a(idx,:);
I don't know why MATLAB is showing this behavior.