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....