how can I generate a code based on specific value selection in a matrix?

I want to make a function that search for a value of y in x, either one element or sum of many elements, and return 1 or 0 to matrix Z, which is the same size as X, based on the elements chosen from X.
Example:
y=7;
x=[10 -1 -2 -3];
solution will be:
1) 10-1-2=7 ==> Z=[1 1 1 0];
2) 10-3=7 ==> Z=[1 0 0 1];
Any hints?

 采纳的回答

Here is one way as long as x is not too large. This technique will use too much memory if x is too large.
b = dec2bin(0:2^numel(x)-1)=='1'; % Intermediate step of producing all possible patterns
z = b(b*x'==y,:); % Pick off the rows of b that produce the desired sum
The rows of z contain the patterns that produce the desired sum.

8 个评论

thank you so much, it really helps. and yes I'm assuming x is not big.
One issue if you can give some hints. if I assume that we have two values and two matrices and want to get the matrix z as sum of them,
Eaxmple,
x=[5 -2 -1 -1];
y1=5; y2=-2;
% using the formula you provided I found solutions for both
z1=[1 0 0 0]; % solution to y1
z2=[0 1 0 0; 0 0 1 1]; % solution to y2
I want to have the first row of z1 merged to rows of z2 as follows:
Z= [1 1 0 0; 1 0 1 1];
I used xor function but I need to match the size before I xor them, is there any other way you think I can follow? by the way, in the solution if 1 appears in the same position in z1 and z2 the solution is ignored/cancelled, Example:
if z1=[ 1 0 0 1] and z2=[0 0 0 1; 0 0 1 0] the first row of z2 need to be ignored and z will be z=[1 0 1 0]
sorry for my long post!
Assuming only z2 has multiple rows:
k = ~any(bsxfun(@and,z1,z2),2); % identify rows where there is no 1's overlap
zxor = bsxfun(@xor,z1,z2(k,:)); % xor z1 with the 'k' rows of z2
For your example result, I assume z = [1 0 1 0] is a typo and should have been z = [1 0 1 1]. True? Also, I used "xor" since you did, but since we have eliminated the 1's overlap I could have simply used "or" instead.
If both z1 and z2 could have multiple rows, then you will need to tell me what you want the result to be.
you are right and that is what I am looking for. It is very short and fast.
z1 and z2 can take multiple rows, I want Z to be the output of xoring z1 and z2 rows except the rows the have 1's overlap; I guess I need to make a for loop?
Example: z of first example is a result of xoring z1 and second raw of z2. First raw of z2 is ignored because of the appearance of 1 in both matrices.
Ex: z1=[1 0 0;0 1 0;1 0 1] z2=[0 1 1;1 0 0;1 1 0] z=xor(z1,z2) raw by raw will give z of 9*3 but if first step of ignoring the overlap is done this would result in only a z matrix of 3*3
Yes, you could put this in a loop (although I get a 2x3 result instead of your claimed 3x3 result):
m = size(z1,1);
zresult = cell(m,1);
for n=1:m
k = ~any(bsxfun(@and,z1(n,:),z2),2); % identify rows where there is no 1's overlap
zresult{n} = bsxfun(@xor,z1(n,:),z2(k,:)); % xor z1 row with the 'k' rows of z2
end
zxor = vertcat(zresult{:});
Thanks James, I really appreciate your swift reply.
Hi friends!
Please accept my small contribution:
z1=[1 0 0;0 1 0;1 0 1];
z2=[0 1 1;1 0 0;1 1 0];
jj = reshape(permute(...
bsxfun(@plus,permute(z1,[3,2,1]),z2),...
[1,3,2]),[],size(z1,2));
zout = jj(all(jj <= 1,2),:);
Thanks Andrei for your input, definitely it helps me.
This is maybe a follow-up question,
if z2 has 2's instead of 1's and I want them to appear in zout matrix, I did it like this:
z1=[1 0 0 1]; z2=[0 0 0 2; 0 0 2 0]; k = ~any(bsxfun(@and,z1,z2),2); zout = bsxfun(@xor,z1,z2(k,:)); % or as Andrei suggested
index=find(z2==2); % to find the index of 2's in z2 for i=1:length(index) j=index(i); zout(j)=zout(j)*2; % changing 1's to 2's in Zout based in position of 2's in z2 end
but did not work because of the size of zout, the index=6 7 while zout is 1*4 matrix, is there any other way?

请先登录,再进行评论。

更多回答(1 个)

There may be millions, or millions or trillions of solutions, or only a few. Your problem is classically called an integer partition .
https://en.wikipedia.org/wiki/Partition_(number_theory)
For example, the number of distinct ways the number 1000 can be written as the sum of elements from the set [1:1000] is 24061467864032622473692149727991. A BIG number.
You can download my partitions tool from the file exchange, which can generate the entire set (where that is feasible given some rational amount of time and memory.) It allows you to specify the elements to be allowed in the sum.
https://www.mathworks.com/matlabcentral/fileexchange/12009-partitions-of-an-integer

1 个评论

interesting topic, I need to look at the theory and understand it.
I appreciate your help Sir.

请先登录,再进行评论。

类别

帮助中心File Exchange 中查找有关 Matrices and Arrays 的更多信息

Community Treasure Hunt

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

Start Hunting!

Translated by