Shuffle an array of unequally repeating entries, so they do not repeat [closed] - arrays

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
I am writing an experiment in Matlab Psychtoolbox and my conditions are stored in an array like this
Cond = ["VM" "VM" "VN" "VS" "AM" "AM" "AN" "AS" "CM" "CM" "CN" "CS"...
"VM" "VM" "VN" "VS" "AM" "AM" "AN" "AS" "CM" "CM" "CN" "CS"];
I now want to shuffle the array in a way that I don't have repeating conditions.
There are a lot of treats regarding this problem e.g.this one, but they always have every condition equally often.
Some suggested a brute force method, shuffling so often until this criteria is reached. But since I have tree of this condition arrays and I have to shuffle them several times per experimental run I don't think that is a good solution.
Hope someone can help

I devised an algorithm that should do what you're asking for. Given a sequence, it will randomly reorder it such that no value repeats. However, it does appear to have a tendency to create repeated sub-sequences (e.g. ..."A" "B" "C" "A" "B" "C"...). I wrapped it in a function reorder_no_reps:
function seq = reorder_no_reps(seq)
% Find unique values and counts:
N = numel(seq);
[vals, ~, index] = unique(seq(:), 'stable');
counts = accumarray(index, 1);
[maxCount, maxIndex] = max(counts);
% Check the maximum number of occurrences:
if (2*maxCount-1 > N)
error('Can''t produce sequence without repeats!');
end
% Fill cell array column-wise with permuted and replicated set of values:
C = cell(maxCount, ceil(N/maxCount));
if (3*maxCount-1 > N)
permIndex = [maxIndex(1) ...
setdiff(randperm(numel(vals)), maxIndex(1), 'stable')];
else
permIndex = randperm(numel(vals));
end
C(1:N) = num2cell(repelem(vals(permIndex), counts(permIndex)));
% Transpose cell array and extract non-empty entries:
C = C.';
seq = reshape([C{~cellfun('isempty', C)}], size(seq));
end
A description of the steps for the algorithm:
Find the unique values in the input sequence (vals) and how many times they each appear (counts).
Find the maximum occurrence of a single value (maxCounts) and check if it is too large to make a sequence without repreats.
A random permutation order is applied to both the unique values and their counts. If the maximum occurrence exceeds a given threshold, the corresponding value index is moved to the beginning of the randomized order (the reason why is addressed in the next bullet).
Each unique value is then replicated in place by its number of occurrences in the sequence. A cell array is filled in column-wise order with these replicated values, possibly leaving some cells at the end empty. Since the cell array has a number of rows equal to the maximum occurrence of a value, no single row of the resulting cell array will have a value appearing more than once in it. In addition, the last value in each row should be different than the first value in the subsequent row (ensured by filling first with the most frequently occurring value in certain cases).
Transpose the cell array, then pull all the non-empty cell values in column-wise order and reshape them into the same size as the input sequence. This is the same as pulling values row-wise from the non-transposed cell array, which should give you a sequence without repeated values.

Related

Solution to make all array elements equal [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 days ago.
Improve this question
Can you advise the solution for this..
ARRAY EQUALITY
Problem Statement
Amy has an array A, of N integers. She wants to make all the elements of the array equal.
On each day she can select a subarray of A, with length exactly M and perform following operation: ยท
Pick any element of the selected subarray and increase or decrease it by 1. She can perform this operation any number of times she wants (possibly 0), on that day.
Find the minimum number of days required to make all the elements of the array A equal. NOTE: A subarray is the sequence of consecutive elements of the array. You are given T independent test cases.
Constraints
`
All input values are integers.
Input Format First-line contains T.
First line of each test case consists of two space separated integers N and M.
Second line of each test case consists of N space separated integers denoting the array A. Output Format Print in a newline for each test case single integer denoting the minimum number of days required to make all the elements of the array A equal.
Sample Input 1
1
5 3
1 2 2 3 1
Sample Output 1
1
I want to know the aproach to solve this problem?

Number of intervals that contains a given query point

I know a similar question exists here. My question is also same that I have N intervals (some possibly overlapping some even same). Then Q point queries are given and I need to tell how many intervals contains this point.
I tried to develop my algorithm by sorting the end point array then counting the number of overlapped interval by +1, -1 trick as mentioned in an answer. But after performing the binary search what I should do? Because its not always the case that the corresponding index of the prefix sum array is the answer.
e.g.
Intervals are : [1,4] [5,7] [6,10] [7,13]
sorted end point array : [1,4,5,6,7,7,10,13]
+1/-1 array : [1,-1,1,1,1,-1,-1,-1]
prefix sum array : [1,0,1,2,3,2,1,0]
Query : 10
my algorithm gives 1 (corresponding prefix array)
but actual ans should be 2.
How should I fix my algorithm?
There are no good answers in the question you linked, so:
First:
Put the entry and exit positions of each interval into separate arrays. (if you are using closed intervals then exit position is end position + 1, i.e., in [4,6], entry is 4, exit is 7.
Sort the arrays.
Then, for each point p:
Binary search in the entry array to find the number of entry positions <= p.
Binary search in the exit array to find the number of exit positions <= p.
The number of intervals that contain the point is entry_count - exit_count
NOTE that the number of positions <= p is the index of the first element > p. See: Where is the mistake in my code to perform Binary Search? to help you get that search right.
For your example:
Intervals: [1,4], [5,7], [6,10], [7,13]
Entry positions: [1,5,6,7]
Exit positions: [5,8,11,14]
Entry positions <= 6: 3
Exit positions <= 6: 1
Intervals that contains 6: 3-1 = 2
Problem is your intervals are [] instead of [), and the answer probably was made for the latter . First transform your end indendexes to value -1.
After this + "compressing" repeated coordinates you should have:
points = [1,5,6,7,8,11,14]
sums = [1,0,1,1,-1,-1,-1]
accumulated = [1,1,2,3,2,1,0]
Then for a query, if query < points[0] or query > points[max] return 0. If not, binary search over points to get index and the answer lies on accumulated[index].

MATLAB how to apply a function to cell arrays

I have the following cell array:
<20x2>
<32x2>
<28x2>
<30x2>
What I am trying to do is read into row 1 of the cell array which is <20x2> and once I am in <20x2> I would like to apply the following function to the first column only.
In the first one I would like every row of column 1 in C{1,1} to be subtracted by 0.1. In the second one C{2,1} (<32x2>) I would like every row of column 1 to be subtracted by 0.2 and so on...
So to clarify I am trying to subtract n*0.1 from the first column of each submatrix in the cell array where n= row number of the cell array. So if there was a section in the cell array in row 8, column 1 would be subtracted by 8*0.1 = 0.8
I hope the question is clear enough, I have tried to word it as clear as I can.
Thanks in advance for any help/suggestions
Attempt
First = C{1,1}(:,1);
Subtraction = First - 0.1
Gives me my desired result but only for row 1 of my cell array.
Unique question to Applying function to vectors row by row because this involves a cell array as opposed to a matrix. The aspect of reading into a cell array makes it a different variant of the problem so if somebody was having a similar problem to this question the mentioned 'duplicate' question would not help, especially with little MATLAB knowledge like myself
It is very easy to adapt your attempt to a loop:
for n = 1:size(c,1)
C{n,1}(:,1) = C{n,1}(:,1) - n*0.1;
end

store value of zero in zero array in matlab

I need to store some values of certain size (nsents) into a variable like scount below. This array stores numbers (scores) and later the values in the variable scount will be divided with those of a similar array in order to get total scores. Some of these values (scores) are zero. During scoring, not all of the indexes in the array are considered. The positions with 0 score are taken as 'empty' whereas actually the index was considered. I could change the size of the array but that won't work for the rest of my code.
scount = zeros(1,nsents);
If I ignore the zeros with something like
totalscores(totalscores==0) = [];
then along with the indexes that were not used I ignore those that were used but had zero score. Do you have any idea how I could solve this problem ? I am very new to Matlab so I apologize if my question is not very clear. Thanks
It is easy to solve.First,find the position where scount is not zero,the code is:
LL=find(scount~=0);
then,scoring the non-zeros elements only.For example,the scoring function is score=1./scount,the code is:
score=zeros(1,nsents);
score(LL)=1./scount(LL);
so,with the help of position variable LL,the scoring process has nothing to do with the scounts that are zero.
Hope it's helpful.Thanks.

Finding whether a value is equal to the value of any array element in MATLAB

Can anyone tell me if there is a way (in MATLAB) to check whether a certain value is equal to any of the values stored within another array?
The way I intend to use it is to check whether an element index in one matrix is equal to the values stored in another array (where the stored values are the indices of the elements which meet a certain criteria).
So, if the indices of the elements which meet the criteria are stored in the matrix below:
criteriacheck = [3 5 6 8 20];
Going through the main array (called array) and checking if the index matches:
for i = 1:numel(array)
if i == 'Any value stored in criteriacheck'
%# "Do this"
end
end
Does anyone have an idea of how I might go about this?
The excellent answer previously given by #woodchips applies here as well:
Many ways to do this. ismember is the first that comes to mind, since it is a set membership action you wish to take. Thus
X = primes(20);
ismember([15 17],X)
ans =
0 1
Since 15 is not prime, but 17 is, ismember has done its job well here.
Of course, find (or any) will also work. But these are not vectorized in the sense that ismember was. We can test to see if 15 is in the set represented by X, but to test both of those numbers will take a loop, or successive tests.
~isempty(find(X == 15))
~isempty(find(X == 17))
or,
any(X == 15)
any(X == 17)
Finally, I would point out that tests for exact values are dangerous if the numbers may be true floats. Tests against integer values as I have shown are easy. But tests against floating point numbers should usually employ a tolerance.
tol = 10*eps;
any(abs(X - 3.1415926535897932384) <= tol)
you could use the find command
if (~isempty(find(criteriacheck == i)))
% do something
end
Note: Although this answer doesn't address the question in the title, it does address a more fundamental issue with how you are designing your for loop (the solution of which negates having to do what you are asking in the title). ;)
Based on the for loop you've written, your array criteriacheck appears to be a set of indices into array, and for each of these indexed elements you want to do some computation. If this is so, here's an alternative way for you to design your for loop:
for i = criteriacheck
%# Do something with array(i)
end
This will loop over all the values in criteriacheck, setting i to each subsequent value (i.e. 3, 5, 6, 8, and 20 in your example). This is more compact and efficient than looping over each element of array and checking if the index is in criteriacheck.
NOTE: As Jonas points out, you want to make sure criteriacheck is a row vector for the for loop to function properly. You can form any matrix into a row vector by following it with the (:)' syntax, which reshapes it into a column vector and then transposes it into a row vector:
for i = criteriacheck(:)'
...
The original question "Can anyone tell me if there is a way (in MATLAB) to check whether a certain value is equal to any of the values stored within another array?" can be solved without any loop.
Just use the setdiff function.
I think the INTERSECT function is what you are looking for.
C = intersect(A,B) returns the values common to both A and B. The
values of C are in sorted order.
http://www.mathworks.de/de/help/matlab/ref/intersect.html
The question if i == 'Any value stored in criteriacheck can also be answered this way if you consider i a trivial matrix. However, you are proably better off with any(i==criteriacheck)

Resources