Control performance of Branch and Bound algorithm - matlab

I wrote a script (at the bottom) to solve the travelling salesman problem (TSP) with the branch and bound algorithm. My script allows two input possiblities.
1) Coordinates of the cities in an excel file with the file name 'Test'. A city can be described also by more than two dimensions. Later the script generates the distance matrix.
2) Insert direct the distance matrix in the script.
At the moment the second input variant is active for my code. (15 cities, A-O)
I have no programming experience and therefore my code looks maybe a little bit inelegant. Nevertheless I would like to measure the performance of the algorithm. What are the best ways to achieve that? Is it possible to establish a performance graph? Additionally I would like to visualize the results. Is it possible to generate a map with the city connections or even a branch and bound tree?
I hope someone could help me
Best
clear all
clc
% Choose between two input possibilities: Coordinates in Excel file
% 'Test'from different cities or insert distance matrix direct here in script
% %%%Input coordinates of the cities via Excel file
% data = xlsread('Test.xlsx',1)
% dist = dist(data(:,2:5)') % how many coordinates are necessary to describe the location from one city
% dist(dist==0) = inf
%%%Input directly distance matrix
% Input information
A = [inf, 4, 12, 7, 4, 1, 2, 8, 4, 6, 7, 12, 3, 5, 20];
B = [5, inf, 20, 18, 6, 3, 4, 8, 9, 23, 1, 12, 5, 4, 9];
C = [11, 5, inf, 6, 1, 5, 6, 8, 7, 12, 31, 5, 1, 14, 5];
D = [10, 2, 3, inf, 5, 7, 8, 8, 6, 21, 4, 7, 5, 5, 1];
E = [1, 2, 6, 9, inf, 9, 10, 8, 45, 12, 11, 5, 6, 2, 11];
F = [17, 7, 6, 5, 11, inf, 12, 8, 63, 1, 2, 3, 12, 4, 8];
G = [11, 8, 3, 9, 3, 5, inf, 4, 6, 8, 1, 3, 12, 4, 8];
H = [12, 14, 2, 5, 4, 8, 4, inf, 12, 4, 1, 23, 7, 4, 56];
I = [4, 1, 2, 8, 4, 6, 7, 12, 3, inf, 7, 5, 6, 12, 14];
J = [6, 1, 5, 6, 8, 7, 12, 31, 5, 1, inf, 12, 1, 2, 6];
K = [7, 8, 8, 6, 21, 4, 7, 5, 5, 1, 11, inf, 13, 1, 2];
L = [1, 6, 1, 5, 6, 8, 7, 12, 8, 9, 10, 12, inf, 7, 5];
M = [8, 4, 6, 7, 12, 3, 8, 4, 6, 7, 12, 3, inf, 14, 15];
N = [21, 4, 7, 5, 5, 1, 21, 4, 7, 5, 5, 1,13, inf, 1];
O = [4, 12, 7, 4, 1, 2, 8, 4, 6, 7, 12, 3, 5, 20, inf];
% Generate distance matrix
dist = [A; B; C; D; E; F; G; H; I; J; K; L; M; N; O]
% Initalization
MaxCity = length(dist);
i = 1;
n = 1;
Parentcity = 1;
Childcity = 0;
% Array
costarray = zeros(MaxCity, 2);
wayarray = zeros(MaxCity, 2);
wayarray(1,:)=[1 0]
% Reduktion und Kosten der ParentCity
row_reduction = min(dist, [], 2);
row_reduction(isinf(row_reduction)) = 0;
M_row_reduced = dist - row_reduction;
column_reduction = min(M_row_reduced);
M_working = M_row_reduced - column_reduction;
M_working(isnan(M_working)) = inf;
M_reduced = M_working;
costparent = sum(row_reduction) + sum(column_reduction);
for n = [n:1:MaxCity] % levels der baumstruktur
for i = [i:1:MaxCity]; % childcity i= childcity
if i == Parentcity ||i==1
cost = inf;
else
M_working= M_reduced;
M_working(Parentcity, :) = inf;
M_working(:, i) = inf;
M_working(i, Parentcity) = inf;
M_working(Parentcity,i) = 0; %!!!!
row_reduction = min(M_working, [], 2);
row_reduction(isinf(row_reduction)) = 0;
M_row_reduced = M_working - row_reduction;
column_reduction = min(M_row_reduced);
M_working = M_row_reduced - column_reduction;
M_working(isnan(M_working)) = inf;
cost = costparent+ sum(row_reduction) + sum(column_reduction)+ M_reduced(Parentcity, i);
end
costarray(i, :) = [i,cost];
end
i = 1;
% minimum der cost array finden
[M, I] = min(costarray);
childcity = I(1, 2);
costparent = M(1, 2);
wayarray(n +1, :) = [childcity, dist(wayarray(n,1),childcity)]; %änderung!!
% nimm childcity, reduziere matrix für diese
M_working=M_reduced;
M_working(Parentcity, childcity) = inf;
M_working(:, childcity) = inf;
M_working(childcity, Parentcity) = inf;
M_working(Parentcity,childcity) = 0; %!!!!
row_reduction = min(M_working, [], 2);
row_reduction(isinf(row_reduction)) = 0;
M_row_reduced = M_working - row_reduction;
column_reduction = min(M_row_reduced);
M_working = M_row_reduced - column_reduction;
M_working(isnan(M_working)) = inf;
M_reduced=M_working;
Parentcity = childcity;
end
wayarray(n+1,2)=dist(wayarray(n,1),1)
gesamtlaenge=sum(wayarray(:,2))

Related

Efficient replacement of x < i values in sparse array

How would I replace values less than 4 with 0 in this array without triggering a SparseEfficiencyWarning and without reducing its sparsity?
from scipy import sparse
x = sparse.csr_matrix(
[[0, 1, 2, 3, 4],
[1, 2, 3, 4, 5],
[0, 0, 0, 2, 5]])
x[x < 4] = 0
x.toarray() # verifies that this works
Note also that the sparsity between the initial version of x is 11 stored elements, which rises to 15 stored elements after doing the masking.
Manipulate the data array directly
from scipy import sparse
x = sparse.csr_matrix(
[[0, 1, 2, 3, 4],
[1, 2, 3, 4, 5],
[0, 0, 0, 2, 5]])
x.data[x.data < 4] = 0
>>> x.toarray()
array([[0, 0, 0, 0, 4],
[0, 0, 0, 4, 5],
[0, 0, 0, 0, 5]])
>>> x.data
array([0, 0, 0, 4, 0, 0, 0, 4, 5, 0, 5])
Note that the sparsity is unchanged and there are zero values unless you run x.eliminate_zeros().
x.eliminate_zeros()
>>> x.data
array([4, 4, 5, 5])
If for some reason you don't want to use a boolean mask & fancy indexing in numpy, you can loop over the array with numba:
import numba
#numba.jit(nopython=True)
def _set_array_less_than_to_zero(array, value):
for i in range(len(array)):
if array[i] < value:
array[i] = 0
This should also be faster than the numpy indexing by a fairly substantial degree.
array = np.arange(10)
_set_array_less_than_to_zero(array, 5)
>>> array
array([0, 0, 0, 0, 0, 5, 6, 7, 8, 9])

Convert 1d List to 2d List in Dart

I have a 1d list of integers like:
List<int> x = [1, 4, 2, 8, 9, 3, 6, 5, 7];
I want to convert this list to a 2d list like this:
List<List<int>> y = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
List<int> x = [1, 4, 2, 8, 9, 3, 6, 5, 7];
// make ascending list
List<int> x = (b, a) => a.compareTo(b);
// install package matrix 2d dart package link : //https://pub.dev/packages/matrix2d
list = X.reshape(3,3);

How to construct a sobel filter for kernel initialization in input layer for images of size 128x128x3?

This is my code for sobel filter:
def init_f(shape, dtype=None):
sobel_x = tf.constant([[-5, -4, 0, 4, 5], [-8, -10, 0, 10, 8], [-10, -20, 0, 20, 10], [-8, -10, 0, 10, 8], [-5, -4, 0, 4, 5]])
ker = np.zeros(shape, dtype)
ker_shape = tf.shape(ker)
kernel = tf.tile(sobel_x, ker_shape)//*Is this correct?*
return kernel
model.add(Conv2D(filters=30, kernel_size=(5,5), kernel_initializer=init_f, strides=(1,1), activation='relu'))
So far I have managed to do this.
But, this gives me error:
Shape must be rank 2 but is rank 4 for 'conv2d_17/Tile' (op: 'Tile') with input shapes: [5,5], [4].
Tensorflow Version: 2.1.0
You're close, but the args to tile don't appear to be correct. That is why you're getting the error "Shape must be rank 2 but is rank 4 for..." You're sobel_x must be a rank 4 tensor, so you need to add two more dimensions. I used reshape in this example.
from tensorflow import keras
import tensorflow as tf
import numpy
def kernelInitializer(shape, dtype=None):
print(shape)
sobel_x = tf.constant(
[
[-5, -4, 0, 4, 5],
[-8, -10, 0, 10, 8],
[-10, -20, 0, 20, 10],
[-8, -10, 0, 10, 8],
[-5, -4, 0, 4, 5]
], dtype=dtype )
#create the missing dims.
sobel_x = tf.reshape(sobel_x, (5, 5, 1, 1))
print(tf.shape(sobel_x))
#tile the last 2 axis to get the expected dims.
sobel_x = tf.tile(sobel_x, (1, 1, shape[-2],shape[-1]))
print(tf.shape(sobel_x))
return sobel_x
x1 = keras.layers.Input((128, 128, 3))
cvl = keras.layers.Conv2D(30, kernel_size=(5,5), kernel_initializer=kernelInitializer, strides=(2,2), activation='relu')
model = keras.Sequential();
model.add(x1)
model.add(cvl)
data = numpy.ones((1, 128, 128, 3))
data[:, 0:64, 0:64, :] = 0
pd = model.predict(data)
print(pd.shape)
d = pd[0, :, :, 0]
for row in d:
for col in row:
m = '0'
if col != 0:
m = 'X'
print(m, end="")
print("")
I looked at using expand_dims instead of reshape but there didn't appear any advantage. broadcast_to seems ideal, but you still have to add the dimensions, so I don't think it was better than tile.
Why 30 filters of the same filter though? Are they going to be changed afterwards?

Python quicksort only sorting first half

I'm taking Princeton's algorithms-divide-conquer course - 3rd week, and trying to implement the quicksort.
Here's my current implementation with some tests ready to run:
import unittest
def quicksort(x):
if len(x) <= 1:
return x
pivot = x[0]
xLeft, xRight = partition(x)
print(xLeft, xRight)
quicksort(xLeft)
quicksort(xRight)
return x
def partition(x):
j = 0
print('partition', x)
for i in range(0, len(x)):
if x[i] < x[0]:
n = x[j + 1]
x[j + 1] = x[i]
x[i] = n
j += 1
p = x[0]
x[0] = x[j]
x[j] = p
return x[:j + 1], x[j + 1:]
class Test(unittest.TestCase):
def test_partition_pivot_first(self):
arrays = [
[3, 1, 2, 5],
[3, 8, 2, 5, 1, 4, 7, 6],
[10, 100, 3, 4, 2, 101]
]
expected = [
[[2, 1, 3], [5]],
[[1, 2, 3], [5, 8, 4, 7, 6]],
[[2, 3, 4, 10], [100, 101]]
]
for i in range(0, len(arrays)):
xLeft, xRight = partition(arrays[i])
self.assertEqual(xLeft, expected[i][0])
self.assertEqual(xRight, expected[i][1])
def test_quicksort(self):
arrays = [
[1, 2, 3, 4, 5, 6],
[3, 5, 6, 10, 2, 4]
]
expected = [
[1, 2, 3, 4, 5, 6],
[1, 2, 3, 4, 6, 10]
]
for i in range(0, len(arrays)):
arr = arrays[i]
quicksort(arr)
self.assertEqual(arr, expected[i])
if __name__ == "__main__":
unittest.main()
so for array = [3, 5, 6, 10, 2, 4] I get [2, 3, 6, 10, 5, 4] as a result... I can't figure what's wrong with my code. It partitions just fine, but the results are off...
Can anyone chip in? :) Thank you!
it's actually so minor problem that you'd be laughing
the problem resides with quicksort function
the correct one is:
def quicksort(x):
if len(x) <= 1:
return x
pivot = x[0]
xLeft, xRight = partition(x)
print(xLeft, xRight)
quicksort(xLeft)
quicksort(xRight)
x=xLeft+xRight #this one!
return x
what happens is python created a new object out of these xleft and xright they were never an in place-sort
so this is one solution(which is not in place)
the other one is to pass the list,the start_index,end_index
and do it in place
well done fella!
edit:
and actually if you'd print xleft and xright you'd see it performed perfectly:)

Matrix dimensions must agree, Index exceeds matrix dimensions

I have the following code for positioning some subplots:
fig = figure;
fig.Units = 'centimeters';
fig.Position(3:4) = [25 25];
plotPositions = [ 3, 21, 7, 7;
12, 21, 7, 7;
];
nPlots=length(plotPositions); % shorthand variable for convenience
hAx=zeros(nPlots,1); % preallocate array for axes/subplot handles
for i = 1:length(plotPositions)
plotHandle = subplot(3, 2, i);
plotHandle.Units = 'centimeters';
plotHandle.Position = plotPositions(i,:);
hAx(i)=subplot(3, 2, i);
axis(hAx(i),[ -300 300 0 150]); %
end
If I use
plotPositions = [ 3, 21, 7, 7;
12, 21, 7, 7;
3, 12, 7, 7;
12, 12, 7, 7;
3, 3, 7, 7;
12, 3, 7, 7];
it works, but if use
plotPositions = [ 3, 21, 7, 7;
12, 21, 7, 7;
];
it does not work, and I'm getting the error:
Matrix dimensions must agree.
Index exceeds matrix dimensions.
What's going on?
You shouldn't be using the function length but instead the function size(...,1) to count the rows of plotPositions. length is actually max(size(vec)), which is 6 (number of rows, correctly) in the "working" case, and 4 (number of columns) in the non-working one.
Thus, in the 2nd case you're actually trying to access "nonexistent" rows, so MATLAB complains....