All possible paths in an undirected graph with some restrictions - matlab

I should find all paths with a graph (24 nodes and 42 vertices). My starting nodes are 1, 2 or 3, and the final nodes are 10, 12, 13, 16, 17, 18, 20, 21, 22 and the rest are intermediate nodes. The sparse adjacency matrix of my graphs A is as follow.
I found the following Matlab code to find the all paths from a starting point to a target point, but the problem is that for example if the starting point is 1, we should not have node 2 in path. In the other words, only one starting point should appear in a path. Can anyone help me with this?
function paths = findpaths(Adj, nodes, currentPath, start, target)
paths = {};
nodes(start) = 0;
currentPath = [currentPath start];
childAdj = Adj(start,:) & nodes;
childList = find(childAdj);
childCount = numel(childList);
if childCount == 0 || start == target
if start == target
paths = [paths; currentPath];
end
return;
end
for idx = 1:childCount
currentNode = childList(idx);
newNodes = nodes;
newNodes(currentNode) = 0;
newPaths = findpaths(Adj, newNodes, currentPath, currentNode, target);
paths = [paths; newPaths];
end
end
Example graph:
A =
(4,1) 1
(5,1) 1
(9,1) 1
(10,1) 1
(12,1) 1
(5,2) 1
(7,2) 1
(8,2) 1
(8,3) 1
(1,4) 1
(5,4) 1
(6,4) 1
(9,4) 1
(15,4) 1
(1,5) 1
(2,5) 1
(4,5) 1
(14,5) 1
(17,5) 1
(4,6) 1
(16,6) 1
(19,6) 1
(20,6) 1
(22,6) 1
(2,7) 1
(20,7) 1
(23,7) 1
(2,8) 1
(3,8) 1
(23,8) 1
(1,9) 1
(4,9) 1
(13,9) 1
(1,10) 1
(12,10) 1
(13,10) 1
(14,11) 1
(17,11) 1
(1,12) 1
(10,12) 1
(16,12) 1
(18,12) 1
(9,13) 1
(10,13) 1
(16,13) 1
(18,13) 1
(5,14) 1
(11,14) 1
(17,14) 1
(4,15) 1
(6,16) 1
(12,16) 1
(13,16) 1
(18,16) 1
(5,17) 1
(11,17) 1
(14,17) 1
(12,18) 1
(13,18) 1
(16,18) 1
(19,18) 1
(21,18) 1
(22,18) 1
(6,19) 1
(18,19) 1
(21,19) 1
(6,20) 1
(7,20) 1
(18,21) 1
(19,21) 1
(24,21) 1
(6,22) 1
(19,22) 1
(24,22) 1
(7,23) 1
(8,23) 1
(19,24) 1
(21,24) 1
(22,24) 1

Related

delete rows in matrix in conditions in matlab

My program creates a matrix whose cell values ​​in multiple rows are the same in the corresponding column. I want to delete some rows that have 0 more than one. To clarify, my matrix has the following form,
A=[ 1 1 1 0 0 1 1 1; 1 0 0 1 1 1 1 1 1; 1 1 1 1 1 1 1 0; 1 1 1 1 0 1 1 1
1 1 0 1 0 0 1 1 ]
and I want to delete all the columns that are in the first, second and fifth rows because the number 0 is 2
or more left in the matrix of rows that are in the third and fourth rows because they have 0 one in each row.
The result should be the following matrix:
A=[ 1 1 1 1 1 1 1 1 0; 1 1 1 1 0 1 1 1 ]
i write this code for your algorithm than work correctly:
% Input Matrix
A = [1 1 1 0 0 1 1 1;1 0 0 1 1 1 1 1; 1 1 1 1 1 1 1 0;1 1 1 1 0 1 1 1;1 1 0 1 0 0 1 1 ];
% find number of rows and cols
[num_rows, num_cols] = size(A);
% Itrate on each row and find rows that have less than 2 zeros
selected_rows = [];
idx = 1;
for i=1:num_rows
num_zero = sum(A(i, 1:end) == 0);
if num_zero < 2
selected_rows(idx) = i;
idx = idx+1;
end
end
% return result matrix
result = [];
for i=1:length(selected_rows)
result = [result; A(selected_rows(i), 1:end)];
end
disp(result)

Is there a way to do this without a for-loop?

Currently I have this function in MATLAB
function [ y ] = pyramid( x )
%PYRAMID Returns a "pyramid"-shapped matrix.
y = zeros(x); % Creates an empty matrix of x by x.
rings = ceil(x/2); % Compute number of "rings".
for n = 1:rings
% Take the first and last row of the ring and set values to n.
y([n,x-n+1],n:x-n+1) = n*ones(2,x-2*(n-1));
% Take the first and last column of the ring and set values to n.
y(n:x-n+1,[n,x-n+1]) = n*ones(x-2*(n-1),2);
end
end
Which produces the following output:
piramide(4)
ans =
1 1 1 1
1 2 2 1
1 2 2 1
1 1 1 1
piramide(5)
ans =
1 1 1 1 1
1 2 2 2 1
1 2 3 2 1
1 2 2 2 1
1 1 1 1 1
piramide(6)
ans =
1 1 1 1 1 1
1 2 2 2 2 1
1 2 3 3 2 1
1 2 3 3 2 1
1 2 2 2 2 1
1 1 1 1 1 1
Is there a way to achive the same result without using a for-loop ?
If you have the Image Processing Toolbox you can use bwdist:
function y = pyramid(x)
m([1 x], 1:x) = 1;
m(1:x, [1 x]) = 1;
y = bwdist(m,'chessboard')+1;
end
Other solution using min:
pyramid = #(x) min(min((1:x),(1:x).'), min((x:-1:1),(x:-1:1).'));

how to produce every permutation of positioning 20 values of -1 in a 1-by-41 vector of ones?

I have written different code to produce different permutations of ones and minus ones. they work for matrixes with small dimensions:
for example:
S=[-1 -1 1 1 1 1 1 1];
P=unique(perms(S),'rows');
produces:
-1 -1 1 1 1 1 1 1
-1 1 -1 1 1 1 1 1
-1 1 1 -1 1 1 1 1
-1 1 1 1 -1 1 1 1
-1 1 1 1 1 -1 1 1
-1 1 1 1 1 1 -1 1
-1 1 1 1 1 1 1 -1
1 -1 -1 1 1 1 1 1
1 -1 1 -1 1 1 1 1
1 -1 1 1 -1 1 1 1
1 -1 1 1 1 -1 1 1
1 -1 1 1 1 1 -1 1
1 -1 1 1 1 1 1 -1
1 1 -1 -1 1 1 1 1
1 1 -1 1 -1 1 1 1
1 1 -1 1 1 -1 1 1
1 1 -1 1 1 1 -1 1
1 1 -1 1 1 1 1 -1
1 1 1 -1 -1 1 1 1
1 1 1 -1 1 -1 1 1
1 1 1 -1 1 1 -1 1
1 1 1 -1 1 1 1 -1
1 1 1 1 -1 -1 1 1
1 1 1 1 -1 1 -1 1
1 1 1 1 -1 1 1 -1
1 1 1 1 1 -1 -1 1
1 1 1 1 1 -1 1 -1
1 1 1 1 1 1 -1 -1
or
indices = nchoosek(1:41, 6);
N = size(indices, 1);
S = ones(N, 41);
S(sub2ind([N 41], [1:N 1:N 1:N 1:N 1:N 1:N].', indices(:))) = -1;
can produce
a matrix of 4496388_by_41 of all the permutations of 6 minus one(-1) and 35 one(1).
these codes work for smaller dimensions but they don't work for the matrixs with larger dimensions.
my goal is to produce all permutations of 20 minus one(-1) and 21 one(1) this matrix has 269128937220 rows and 41 columns. but the following codes don't work:
indices = nchoosek(1:41, 20);
N = size(indices, 1);
S = ones(N, 41);
S(sub2ind([N 41], [1:N 1:N 1:N 1:N 1:N 1:N 1:N 1:N 1:N 1:N 1:N 1:N 1:N 1:N 1:N 1:N 1:N 1:N 1:N 1:N].', indices(:))) = -1;
or
S=[-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1];
P=unique(perms(S),'rows');
I do a simple calculation on each permutation(each row of this matrix). if I could write each row of this matrix with for loops and then do the calculation on that row, I would be able to keep the best result and in this situation I wouldn't have to keep all these data in the memory and I wouldn't get out of memory errors from matlab.
if you know how to produce a matrix of all the permutations of 20 minus one(-1) and 21 one(1) with for loops or any other way to store them in my computer please help.
thanks in advance
I'm not an expert in Matlab so I can't speak for all of the resources available, however, I know that your task is feasible on a standard laptop without any fancy high performance services such as https://aws.amazon.com/hpc/.
I have authored a package in R called RcppAlgos that is capable of completing this task comfortably in a few hours. Here is the code:
options(scipen = 999)
library(parallel)
library(RcppAlgos)
## WARNING Don't run this unless you have a few hours on your hand
## break up into even intervals of one million
firstPart <- mclapply(seq(1, 269128000000, 10^6), function(x) {
temp <- permuteGeneral(c(1L,-1L), freqs = c(21,20), lower = x, upper = x + 999999)
## your analysis here
x
}, mc.cores = 8)
## get the last few results and complete analysis
lastPart <- permuteGeneral(c(1L, -1L), freqs = c(21, 20),
lower = 269128000000, upper = 269128937220)
## analysis for last part goes here
And to give you a demonstration of the efficiency of this setup, we will demonstrate how fast the first one billion results are completed.
system.time(mclapply(seq(1, 10^9, 10^6), function(x) {
temp <- permuteGeneral(c(1L, -1L), freqs = c(21, 20), lower = x, upper = x + 999999)
## your analysis here
x
}, mc.cores = 8))
user system elapsed
121.158 64.057 27.182
Under 30 seconds for 1000000000 results!!!!!!!
So, this will not take over 3000 days as #CrisLuengo calculated but rather a conservative estimate of 30 seconds per billion gives :
(269128937220 / 1000000000 / 60) * 30 ~= 134.5645 minutes
I should also note that with the setup above you are only using 1251.2 Mb at a time, so your memory will not explode.
testSize <- object.size(permuteGeneral(c(1L,-1L), freqs = c(21,20), upper = 1e6))
print(testSize, units = "Mb")
156.4 Mb ## per core
All results were obtained on a MacBook Pro 2.8GHz quad core (with 4 virtual cores.. 8 total).
Edit:
As #CrisLuengo points out, the above only measures generating that many permutations and does not factor in the time taken for analysis of each computation. After some more clarification and a new question, we have that answer now... about 2.5 days!!!

What is the immediate lower number next to One in Double precision

What is the most immediate lower number next to number 1, in double-precision number format ? How to find that in MATLAB?
For instance, the next higher number next to positive number X can be find using X+eps(X). But how to do that for an immediate lower number?
format hex # So that the difference is easy to see
X-eps(X)
appears to work just fine
use the code bellow ,B is most immediate lower number next to number 1 that is half of eps:
A = uint64(0);
bits=[1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 0 0];
for i = 1: 64
A = bitset(A, i, bits(i));
end
fileID = fopen('bits.bin','w');
fwrite(fileID, A,'uint64');
fclose(fileID);
fileID = fopen('bits.bin');
B = fread(fileID,1,'*float64');
fclose(fileID);
disp(B);
disp(1.0-B);
disp(eps(1.0))

How to count number of 1's in the matrix

I have one matrix like-
A=[1 1 3 0 0;
1 2 2 0 0;
1 1 1 2 0;
1 1 1 1 1];
From these "A" i need to count the number of 1"s of each row and after that i want to give the condition that after scanning each row of 'A' if the number of 1's >=3 then it take that. It means my final result will be
A= [1 1 1 2 0;
1 1 1 1 1].
How can I do this. Matlab experts need your valuable suggestion.
>> A(sum(A == 1, 2) >= 3, :)
ans =
1 1 1 2 0
1 1 1 1 1
Here, sum(A == 1, 2) counts the number of ones in each row, and A(... >= 3, :) selects the rows where the count is at least 3.
A=[1 1 3 0 0;...
1 2 2 0 0;...
1 1 1 2 0;...
1 1 1 1 1]
accept = sum((A == 1)')
i = 1;k = 1;
while i <= length(A(:,1))
if accept(k) < 3
A(i,:) = [];
i = i - 1;
end
i = i + 1;
k = k + 1;
end
A