Travelling salesman Basics - matlab

I'm tasked with creating a GUI solution using guide to the travelling salesman problem. It's to have a drop down menu allowing the user to select from 10,20,30...100 cities, then a button to generate a map from the cities and the unoptimized route. Another button is to optimize the solution using a simple method. I've built the code that generates the initial map onto a plot, using the drop down menu selection of cities.
My problem is the optimization. Initially, a random matrix with 2 columns and however many cities selected for rows is created, representing x, and y co-ordinates on a map. The method we are to use is split into 2 procedures, procedure 1 takes the start point, entry 1 of the matrix, and 2 other random vectors, then it's meant to take a random city, compute the distance betweeen it and all the other cities in the tour vector (the one that starts at 3 x+y co-ords), then insert itself next to the city with the shortest route. repeat the procedure until all cities are inserted into the matrix in a semi-optimized state. Procedure 2 takes the full tour matrix, and then attempts to look at each city in it and move it to the position with the least travelled distance between the two neighbouring cities.
The problem I'm seeing is that, whilst deleting a row of a matrix is an easy option, inserting and moving rows is something I've never encountered before. Are there any functions that do such a thing in the standard matlab library?

If I read the question correctly, you are just looking for basic matrix manipulation.
Suppose you have a matrix X and want to insert a row after the second row:
X = reshape(1:8,4,[])
myRow = [0 0];
X = [X(1:2,:); myRow; X(3:end,:)]
If you want to move a row:
1. Assign it to myRow
2. Delete it
3. Insert the new row with the code above
If you want to swap rows, you can take a more direct route, suppose you want to swap row 2 and 4:
X = reshape(1:8,4,[])
X([2 4],:) = X([4 2],:)
If you simply want to update a row, it gets even easier. Suppose you want to update the second row:
X = reshape(1:8,4,[])
myRow = [0 0];
X(2,:) = myRow

Related

Indexing a grid with row and column number?

Very new to QGIS. I'm using it to analyse agricultural field microplots for research.
I need to give each field plot its own object which I've done so by using the "create grid" tool. But I need to assign a column and row number to each object in the attribute table to make it easier to sort the data. This should start in the bottom left (1:1) and ascend in row for objects above (2:1) and ascend in column for objects to the right (1:2).
I've orientated the grid to start in the bottom left and learned that by using #row_number, I can re-number the objects from 1 to the total number of objects. But I need to add column number and row number to the attribute table.
Is there a simple way of doing this?
I think the most accessible option here is using the field calculator to add two integer columns to the attribute table. For a rectilinear grid with cells_y cells in the y direction (24 in this case) the expressions are something like
floor(("id" - 1) / cells_y) + 1
where id is the attribute table column with the cell number (set automatically by Vector -> Research Tools -> Create grid or, in the OP's case, to #rownumber).
For the y index it's
cells_y + 1 - if(("id" % cells_y) = 0, cells_y, "id" % cells_y)
This is for the ones based indexing asked for here; remove the + 1 bits for zero-based. Similarly, subtracting (as is done with y here) or not subtracting (x here) the modulus part flips the directions in which the cells are numbered. This approach can also be used in PyQGIS.
There's a few grid plugins for QGIS and several similar StackOverflow questions (like this one) which may also be of interest.

Looping 2 columns from an excel file into matlab

For my experiment, I am presenting participants with different images (which are numbered from 1 to 324) in a scrambled order. My goal is to overlay their gaze pattern with a saliency map.
So I have two variables in MATLAB that I want to FOR loop:
"z" is the scrambled presentation order, ex: [95,147,1...] (324 numbers in total)
"i" is the order of gaze patterns recorded (it goes in order from 1 to 324)
I have tried use 2 for loops,
for z=[95,147,1....]
for i=1:324
%open and create saliency maps for "z"
%open gaze pathways for "i"
%combine both
%save
What I was hoping was that z=95 would be paired with i=1, z=147 would be paired with i=2 and so on, however what happens is the for loop goes through i=1:324 for all of z=95 and then continues to z=147 and goes through i=1:324 again...
I have thought of putting z and i values into a table such that
ImageOrder ScatterOrder
95 1
147 2
1 3
However, I have been having difficulty for the specific steps.
I actually figured out a method,
I set
s1='A2' %first cell of the image order column
s2='B2' %first cell of the scatter order column
Then I create one for loop for
i=2:___(The row number I want to end on)
s1=['A', num2str(i)]; %Loops through rows of A
s2=['B', num2stri(i)]; %Loops through rows of B
x1=xlsread('filename.xls',[s1,':',s2]);
a=x1(:,1) %Taking image order of every row
b=x1(:,2); %Taking scatter order of every row
With the 'a' and 'b' then I can access two different variables in the same rows while it loops.

Beginner Matrix Access in MATLAB

Now first off, I am not even sure this is called a matrix, and I am new to MATLAB. But let's say I have a "matrix" that looks like this:
for n=1:10
...
someImage = mat(:,:,n) %The "matrix"
...
end
where n could be the frames in a video, for example, and the first 2 ':' are the row and column data for the 2D image (the frame).
If I only wanted the first ':' of data (the row? column? element?), how would I access only that?
Intuitively, I think something like:
row1 = mat(:,0,0)
row2 = mat(0,:,0)
row3 = mat(0,0,:)
but that doesn't seem to be working.
P.S. I know that these aren't really rows, the terminology for all this would also be greatly appreciated
Also, it may not have anything to do with this, but I am using a MATLAB GUI as well, and the "matrix" is stored like this:
handles.mat(:,:,n)
I don't think it has anything to do with my actual question, but it might so I will put it here
-Thanks!
One point I would like to make before starting: MATLAB starts indexing at 1, and not 0. This is a common mistake that most people who have a C/Java/Python programming background make going into MATLAB.
Also, by doing:
row1 = mat(:,1,1);
This accesses all of the rows for the first column and the first frame of your video. Be aware that this will produce a M x 1 vector, where M denotes the number of rows for a frame in your video.
Also:
row2 = mat(1,:,1);
This accesses all of the columns in the first row of the first frame. Be aware that this will produce a 1 x N vector, where N denotes the number of columns for a frame in your video.
Also:
row3 = mat(1,1,:);
This accesses all of the pixels in the entire video sequence at row 1 and column 1. You can think of this as a temporal slice at the top left corner of your video sequence. Be aware that this will produce a 1 x 1 x T vector, where T is the number of frames in your video. If you access just a single pixel location in your video, the first two dimensions are superfluous, and so you can use the squeeze command to shrink all of the singleton dimensions so that it simplifies to a T x 1 vector. In other words, do this:
row3 = squeeze(mat(1,1,:));
FWIW, you do have the right terminology. Rows and columns are used in image / video processing all the time. As for the "matrix", you can call this a temporal sequence or a frame sequence in terms of video processing. It certainly is a 3D matrix, but people in this domain denote it as either one of the two as it is really a sequence of images / frames stacked on top of each other.

Determining if any duplicate rows in two matrices in MatLab

Introduction to problem:
I'm modelling a system where i have a matrix X=([0,0,0];[0,1,0],...) where each row represent a point in 3D-space. I then choose a random row, r, and take all following rows and rotate around the point represented by r, and make a new matrix from these rows, X_rot. I now want to check whether any of the rows from X_rot is equal two any of the rows of X (i.e. two vertices on top of each other), and if that is the case refuse the rotation and try again.
Actual question:
Until now i have used the following code:
X_sim=[X;X_rot];
if numel(unique(X_sim,'rows'))==numel(X_sim);
X(r+1:N+1,:,:)=X_rot;
end
Which works, but it takes up over 50% of my running time and i were considering if anybody in here knew a more efficient way to do it, since i don't need all the information that i get from unique.
P.S. if it matters then i typically have between 100 and 1000 rows in X.
Best regards,
Morten
Additional:
My x-matrix contains N+1 rows and i have 12 different rotational operations that i can apply to the sub-matrix x_rot:
step=ceil(rand()*N);
r=ceil(rand()*12);
x_rot=x(step+1:N+1,:);
x_rot=bsxfun(#minus,x_rot,x(step,:));
x_rot=x_rot*Rot(:,:,:,r);
x_rot=bsxfun(#plus,x_rot,x(step,:));
Two possible approaches (I don't know if they are faster than using unique):
Use pdist2:
d = pdist2(X, X_rot, 'hamming'); %// 0 if rows are equal, 1 if different.
%// Any distance function will do, so try those available and choose fastest
result = any(d(:)==0);
Use bsxfun:
d = squeeze(any(bsxfun(#ne, X, permute(X_rot, [3 2 1])), 2));
result = any(d(:)==0);
result is 1 if there is a row of X equal to some row of X_rot, and 0 otherwise.
How about ismember(X_rot, X, 'rows')?

Preserving matrix columns using Matlab brush/select data tool

I'm working with matrices in Matlab which have five columns and several million rows. I'm interested in picking particular groups of this data. Currently I'm doing this using plot3() and the brush/select data tool.
I plot the first three columns of the matrix as X,Y, Z and highlight the matrix region I'm interested in. I then use the brush/select tool's "Create variable" tool to export that region as a new matrix.
The problem is that when I do that, the remaining two columns of the original, bigger matrix are dropped. I understand why- they weren't plotted and hence the figure tool doesn't know about them. I need all five columns of that subregion though in order to continue the processing pipeline.
I'm adding the appropriate 4th and 5th column values to the exported matrix using a horrible nested if loop approach- if columns 1, 2 and 3 match in both the original and exported matrix, attach columns 4/5 of the original matrix to the exported one. It's bad design and agonizingly slow. I know there has to be a Matlab function/trick for this- can anyone help?
Thanks!
This might help:
1. I start with matrix 1 with columns X,Y,Z,A,B
2. Using the brush/select tool, I create a new (subregion) matrix 2 with columns X,Y,Z
3. I then loop through all members of matrix 2 against all members of matrix 1. If X,Y,Z match for a pair of rows, I append A and B
from that row in matrix 1 to the appropriate row in matrix 2.
4. I become very sad as this takes forever and shows my ignorance of Matlab.
If I understand your situation correctly here is a simple way to do it:
Assuming you have a matrix like so: M = [A B C D E] where each letter is a Nx1 vector.
You select a range, this part is not really clear to me, but suppose you can create the following:
idxA,idxB and idxC, that are 1 if they are in the region and 0 otherwise.
Then you can simply use:
M(idxA&idxB&idxC,:)
and you will get the additional two columns as well.