42 views (last 30 days)

Show older comments

function [N,V,seq] = addition1_opt( n,m,P )

%UNTITLED Summary of this function goes here

% Detailed explanation goes here

%n = str2num(n);

%m = str2num(m);

%x = str2num(x);

'wait for initializing all sequence combinations ...';

L = ceil((6*(n-1)+1)/2);

N = (factorial(L)/factorial(L-m))^n;

C = nchoosek(1:L,m);

H = (factorial(L)/(factorial(m)*factorial(L-m)));

k=1;

done = false;

required_number_of_solutions = 10;

for i = 1: H

x_temp=perms(C(i,:));

for j=1: factorial(m)

x(k,:) = x_temp(j,:);

k=k+1;

end

end

x;

% for ro = 1:n

% mtx(ro,:) = x(

%

%

'Total number of sequences is'; k;

if n>4

'please enter n<=4';

end

if n==2

v=1;

for i=1:k-1

mtx(1,:) = x(i,:);

for j = 1:k-1

mtx(2,:) = x(j,:);

Test='F';

s=1;

rst(s)=0;

for co1 = 1:m

for co2 = 1:m

if co1 ~= co2

if sum(rst == mtx(1,co1) + mtx(2,co2))==0

Test='T';

rst(s) = mtx(1,co1) + mtx(2,co2);

s=s+1;

else

Test='F';

break;

end

end

end

if Test=='F'

break;

end

end

if Test=='T'

seq(:,:,v) = mtx;

v=v+1;

if v > required_number_of_solutions

done = true;

break;

end

if v>P

break;

end

end

clear rst

end

if done; break; end

if v>P

break;

end

end

end

if n==3

v=1;

for i=1:k-1

mtx(1,:) = x(i,:);

for j = 1:k-1

mtx(2,:) = x(j,:);

for l = 1:k-1

Test='F';

mtx(3,:) = x(l,:);

s=1;

rst=0;

mtx;

for co1 = 1:m

for co2 = 1:m

if co1 ~= co2

if sum(rst == mtx(1,co1) + mtx(2,co2))==0

Test='T';

rst(s) = mtx(1,co1) + mtx(2,co2);

s=s+1;

else

Test='F';

break;

end

end

end

if done; break; end

if Test=='F'

break;

end

end

if done; break; end

if Test=='F'

break;

end

for co2 = 1:m

for co3 = 1:m

if co2 ~= co3

if sum(rst == mtx(2,co2) + mtx(3,co3))==0

Test='T';

rst(s) = mtx(2,co2) + mtx(3,co3);

s=s+1;

else

Test='F';

break;

end

end

end

if done; break; end

if Test=='F'

break;

end

end

if done; break; end

% if Test=='F'

% break;

% end

if Test=='T'

seq(:,:,v) = mtx;

v=v+1;

if v > required_number_of_solutions

done = true;

break;

end

if v>P

break;

end

end

clear rst

end

if done; break; end

if v>P

break;

end

end

if done; break; end

if v>P

break;

end

end

end

if n==4

v=1;

for i=1:k-1

mtx(1,:) = x(i,:);

for j = 1:k-1

mtx(2,:) = x(j,:);

for l = 1:k-1

mtx(3,:) = x(l,:);

for h = 1:k-1

Test='F';

mtx(4,:) = x(h,:);

s=1;

rst=0;

mtx;

for co1 = 1:m

for co2 = 1:m

if co1 ~= co2

if sum(rst == mtx(1,co1) + mtx(2,co2))==0

Test='T';

rst(s) = mtx(1,co1) + mtx(2,co2);

s=s+1;

else

Test='F';

break;

end

end

end

if done; break; end

if Test=='F'

break;

end

end

if done; break; end

if Test=='F'

break;

end

for co2 = 1:m

for co3 = 1:m

if co2 ~= co3

if sum(rst == mtx(2,co2) + mtx(3,co3))==0

Test='T';

rst(s) = mtx(2,co2) + mtx(3,co3);

s=s+1;

else

Test='F';

break;

end

end

end

if done; break; end

if Test=='F'

break;

end

end

if done; break; end

if Test=='F'

break;

end

for co3 = 1:m

for co4 = 1:m

if co3 ~= co4

if sum(rst == mtx(3,co3) + mtx(4,co4))==0

Test='T';

rst(s) = mtx(3,co3) + mtx(4,co4);

s=s+1;

else

Test='F';

break;

end

end

end

if done; break; end

if Test=='F'

break;

end

end

if done; break; end

if Test=='T'

seq(:,:,v) = mtx;

v=v+1;

if v > required_number_of_solutions

done = true;

break;

end

end

if v>P

break;

end

clear rst

end

if done; break; end

if v>P

break;

end

end

if done; break; end

if v>P

break;

end

if done; break; end

end

if v>P

break;

end

end

end

'The unique sequences are:';

'! DONE !';

Rik
on 16 Sep 2021

Edited: Rik
on 16 Sep 2021

Apparently your code doesn't guarantee the creation of the seq variable. Since it only occurs in block starting with Test=='T', that must mean Test is not equal to 'T' at the correct times.

Because you decided to not use any comments, it is difficult to follow your code and give meaningful suggestions to fix the issue. Why don't you make sure you explain what your code is doing? Why is everything in one large function, instead of splitting up tasks in smaller (documented!) units?

Also, why don't you have a block at the start of your function that checks if the inputs are correct? If n is only allowed to be a positive integer below 5, check that and return a meaningful error.

Image Analyst
on 16 Sep 2021

I agree with Rik that it's an uncommented alphabet soup mess of code. Anyway, have the first few lines of your program be

function [N, V, seq] = addition1_opt(n, m, P)

% Create the output variables so we'll at least have something even if something goes wrong.

N = [];

V = [];

seq = [];

% Rest of code follows this.

So now seq will be defined. It's null, but it's still defined and you won't get that particular error about it not being defined, though you may get other errors of a different kind.

If you need more help, comment your code and tell us what you sent in for n, m, and P.

Image Analyst
on 17 Sep 2021

Sorry but the uncommented code would take far longer for me to understand that I allow for Answers forums questions. But I'll show you how you can figure it out on your own:

Actually another way is to just put in comments. Often I find that when people put in comments they discover errors in the code/logic. So try that. Otherwise you just have to slog though it line by line with the debugger. But that's way too much work for Rik or I to donate to you - sorry.

Schubie
on 29 Sep 2021 at 0:08

If you are still there...

I see a couple of issues with your program:

1.) There is a conflict between the variables "P" and "required_number_of_solutions" -> P comes from the input argument list and "required_number_of_solutions" is defined as "10", in line 14. Later in the program code both terms are used:

if v > required_number_of_solutions

and

if v>P

which leads to some complications.

2.) Line 28 to 30 are:

if n>4

'please enter n<=4';

end

which does exactly nothing, but in the code there are three separate loops for "n==2", "n==3" and "n==4". Accordingly nothing happens if you enter a number for "n" which is not 2, 3 or 4. In particular, no "seq" will be calculated.

3.) In the output argument list there is an upper case "V", but in the code only lower case "v" is used.

4.) Lines like:

'Total number of sequences is'; k;

do absolutely nothing -> write

disp(['Total number of sequences is: ',num2str(k)]);

instead, if you want to have any feedback on the screen.

5.) There is no guarantee that the program will find a solution at all. In this case "seq" is not defined and that is the cause for your error message. You got a version from "Image Analyst" where he added "seq=[]" - this obviously suppresses the error message, which, however, indicated deeper problems with the program.

n+1.) I am not sure that the list is complete.

However, as a personal brain teaser, I deducted the original task from the submitted program and created a working version (at least it is working on my MATLAB Version 7.1.0.246 (R14))...

There isn't much left of the original program code, as I found it awkward to process different values for "n" separately. I took a recursive approach. So I don't know if it helps you anyway?

Best regards, Sebastian

function [N,V,seq] = addition3_opt(n,m,p)

%This program solves a task that user Hothifa Hasanat presented in the

%"MATLAB ANSWERS" forum.

%

%The task itself was deduced from the faulty original program:

%

%Our field of activity are matrices with n rows and m columns

%We are looking for arrangements in which all sums of each two numbers

%in consecutive rows and different columns are different.

%

%These solutions are stored in "seq".

%As soon as "p" solutions have been found, the program stops.

%

%Since the variable number of lines influences both the structure of the

%matrix and the evaluation, the task was solved by a recursive function.

%

%kind regards, Sebastian®

global nn x k v pp seq isum

if n>10;disp('please enter n<=10');return;end

if n<2;disp('please enter n>=2');return;end

if m<2;disp('please enter m>=2');return;end

%if n>4;disp('please enter n<=4');return;end

disp(['number of rows n= ',num2str(n)]);

disp(['number of columns m= ',num2str(m)]);

disp(['number of Solutions: p= ',num2str(p)]);

disp(' ');

disp(['wait for initializing all combinations ...']);

L = ceil((6*(n-1)+1)/2);% % % % % % ??? where does this formula come from ???

N = (factorial(L)/factorial(L-m))^n;

H = nchoosek( L,m);%number of combinations to choose m out of L Elements

C = nchoosek(1:L,m);%all possible combinations of m out of L Elements

x=[];%build list of all possible rows:

for i=1:H;

x=[x;perms(C(i,:))];

end

k=size(x,1);%number of possible rows

disp(['Total number of possible rows is: ',num2str(k)]);

disp([num2str(k^n),' combinations of rows are possible: ',]);

disp(' ');

%invent an index matrix for summation

[na,nb]=meshgrid(1:m);fab=find(na~=nb);

isum=[na(fab),nb(fab)+m];

x=x.';%I prefer working with columns

seq=[];%empty matrix for solutions

v=0;%counts number of solutions

pp=p;%maximum number of solutions

nn=n;%required number of rows

%start recursion with 0 rows and empty matrix

%==============================

rec_add1opt(0,[],[]);%first row

%==============================

V=v;%number of solutions found

disp([num2str(v),' solutions found:']);

%disp(seq);

%========================================================================

%Here comes the recursive function

function rec_add1opt(nloc,mtx,ksum)

global nn x k v pp seq isum

if v>=pp;return;end;

nloc=nloc+1;%now working in row "nloc"

%disp(['now working in row: ',num2str(nloc)]);

if nloc>=2;

ksum=[ksum;isum+(nloc-2)*size(x,1)];%append sum indices for next row

end

%------------------------------------------------------------------------

for i=1:k;%add and try all possible rows

mtxloc=[mtx,x(:,i)];

if v>=pp;return;end;

if (nloc<nn);%if not enough rows

%==========================================

rec_add1opt(nloc,mtxloc,ksum);%one more row

%==========================================

else;%rows complete, therefore we check if mtx is a solution

if nloc>=2;%sums are only available with min 2 rows

sumlist=sum(mtxloc(ksum),2);%list of all required sums to check

if sum(diff(sort(sumlist))==0)==0;%all sums are different !!!!

disp(['solution nr: ',num2str(v)]);%display nr of solution

disp(mtxloc.');%display solution

v=v+1;seq(:,:,v)=mtxloc.';%store solution in seq()

end

end

end

end

%========================================================================

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

Start Hunting!