Looping over combinations of several variables for Design Of Experiments in MATLAB - matlab

I need to loop over all the possible combinations of the different elements of a vector between lower and upper bounds.
NUMBEROFVARIABLES stores the total number of variables.
tlb < t < tub and o1b < o < oub
The elements t and o can vary in steps of tStep and oStep respectively.
The vector is: x = [t1, t2, t3, ... tn, o1, o2, o3, ... on]
For 1 < t < 10, 1.5 < o < 5, tStep = 1, oStep = 0.5 and NUMBEROFVARIABLES = 10 (divided equally/half-half between 't's and 'o's), the generated combination vectors should be something like:
x1 = [1, 1, 1, 1, 1, 1.5, 1.5, 1.5, 1.5, 1.5]
x2 = [1, 1, 1, 1, 1, 1.5, 1.5, 1.5, 1.5, 2.0]
x3 = [1, 1, 1, 1, 1, 1.5, 1.5, 1.5, 1.5, 2.5]
.
.
.
xi = [1, 1, 1, 1, 2, 5.0, 5.0, 5.0, 5.0, 5.0]
xii = [1, 1, 1, 1, 3, 5.0, 5.0, 5.0, 5.0, 5.0]
xiii = [1, 1, 1, 1, 4, 5.0, 5.0, 5.0, 5.0, 5.0]
.
.
.
xn = [10, 10, 10, 10, 10, 5.0, 5.0, 5.0, 5.0, 5.0]]
How do I loop over each parameter (like in the above example) and store the vectors xi in MATLAB?

Related

How to save Sankey diagram node positions after manual arrangement?

I am trying to create Sankey diagrams with node positions using R and plotly package (https://plotly.com/r/sankey-diagram/#define-node-position).
library(plotly)
fig <- plot_ly(
type = "sankey",
arrangement = "snap",
node = list(
label = c("A", "B", "C", "D", "E", "F"),
x = c(0.2, 0.1, 0.5, 0.7, 0.3, 0.5),
y = c(0.7, 0.5, 0.2, 0.4, 0.2, 0.3),
pad = 10), # 10 Pixel
link = list(
source = c(0, 0, 1, 2, 5, 4, 3, 5),
target = c(5, 3, 4, 3, 0, 2, 2, 3),
value = c(1, 2, 1, 1, 1, 1, 1, 2)))
fig <- fig %>% layout(title = "Sankey with manually positioned node")
fig
However, the default node positions are not good enough. So I need to manually adjust the node positions from the interactive plot. However, I need to save the new positions and update the positions in the script. Then next time when I run the script again, I don't need to adjust the positions manually again?
Is there anyway to save node positions after manual arrangement?

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?

MiniZinc Geocode not printing all solutions to CSP with "all" solutions enabled

The Issue
With solve minimize I only get one solution, even though there are multiple optimal solutions. I have enabled printout of multiple solutions in the solver configurations. The other optimal solutions are found with solve satisfy, along with non-optimal solutions.
Possible causes
Could it be that the cardinality function card() ranks by enum value where size of two sets are equal? In other words that card(A, B) > card(B, C)? If so, do I have to switch the representation of my vertices?
The Program
I am creating a MiniZinc program for finding the minimum vertex cover of a given graph. The graph in this example is this:
With Minimal Vertex Cover solutions being:
[{A, B, C, E}, {A, B, E, F}, {A, C, D, E}, {B, C, D, E}, {B, C, D, F}, {B, D, E, F}]. My code only outputs {A, B, C, E}.
Data file:
VERTEX = {A, B, C, D, E, F};
edges = [|1, 0, 1, 0, 0, 0, 0, 0, 0
|1, 1, 0, 1, 1, 0, 0, 0, 0
|0, 1, 0, 0, 0, 1, 1, 0, 0
|0, 0, 1, 1, 0, 0, 0, 1, 0
|0, 0, 0, 0, 1, 1, 0, 1, 1
|0, 0, 0, 0, 0, 0, 1, 0, 1|];
Solver program:
% Vertices in graph
enum VERTEX;
% Edges between vertices
array[VERTEX, int] of int: edges;
int: num_edges = (length(edges) div card(VERTEX));
% Set of vertices to find
var set of VERTEX: span;
% Number of vertices connected to edge resulting from span
array[1..num_edges] of var 0..num_edges: conn;
% All edges must be connected with at least one vertex from span
constraint forall(i in 1..num_edges)
(conn[i] >= 1);
% The number of connections to each edge is the number of vertices
% in span with a connection to that edge
constraint forall(i in 1..num_edges)
(conn[i] = sum([edges[vert,i]| vert in span]));
% Minimize the number of vertices in span
solve minimize card(span);
solve minimize only show one optimal solution (in some cases, intermediate values might also be shown).
If you want all optimal solutions you must use solve satisfy and add the constraint with the optimal value:
constraint card(span) = 4;
Then the model outputs all the 6 optimal solutions:
card(cpan): 4
span: {A, B, C, E}
conn: [2, 2, 1, 1, 2, 2, 1, 1, 1]
----------
card(cpan): 4
span: {B, C, D, F}
conn: [1, 2, 1, 2, 1, 1, 2, 1, 1]
----------
card(cpan): 4
span: {A, C, D, E}
conn: [1, 1, 2, 1, 1, 2, 1, 2, 1]
----------
card(cpan): 4
span: {B, C, D, E}
conn: [1, 2, 1, 2, 2, 2, 1, 2, 1]
----------
card(cpan): 4
span: {A, B, E, F}
conn: [2, 1, 1, 1, 2, 1, 1, 1, 2]
----------
card(cpan): 4
span: {B, D, E, F}
conn: [1, 1, 1, 2, 2, 1, 1, 2, 2]
----------
==========
Note: I added the output section to show all the values:
output [
"card(cpan): \(card(span))\n",
"span: \(span)\n",
"conn: \(conn)"
];
An alternative solution is to use OptiMathSAT (v. 1.6.3).
When asking for all solutions in optimization mode, the solver returns all solutions (with respect to the output variables) with the same optimal value.
Example:
~$ mzn2fzn test.mzn test.dzn # your instance
~$ optimathsat -input=fzn -opt.fzn.all_solutions=True < test.fzn
% allsat model
span = {2, 4, 5, 6};
conn = array1d(1..9, [1, 1, 1, 2, 2, 1, 1, 2, 2]);
----------
% allsat model
span = {1, 3, 4, 5};
conn = array1d(1..9, [1, 1, 2, 1, 1, 2, 1, 2, 1]);
----------
% allsat model
span = {1, 2, 3, 5};
conn = array1d(1..9, [2, 2, 1, 1, 2, 2, 1, 1, 1]);
----------
% allsat model
span = {1, 2, 5, 6};
conn = array1d(1..9, [2, 1, 1, 1, 2, 1, 1, 1, 2]);
----------
% allsat model
span = {2, 3, 4, 5};
conn = array1d(1..9, [1, 2, 1, 2, 2, 2, 1, 2, 1]);
----------
% allsat model
span = {2, 3, 4, 6};
conn = array1d(1..9, [1, 2, 1, 2, 1, 1, 2, 1, 1]);
----------
=========
The main advantage wrt. the approach presented in the accepted answer is that OptiMathSAT is incremental, meaning that the tool searches for other solutions without being restarted, so that it can re-use any useful information that has been previously generated to speed-up the search (e.g. theory lemmas). [CAVEAT: this may not be relevant for small instances; also, other MiniZinc solvers may still be faster depending on the input problem]
Note: please notice that OptiMathSAT does not print the labels of each VERTEX, because the mzn2fzn compiler removes these labels when compiling the file. However, the mapping among numbers and labels should be obvious.
Disclosure: I am one of the developers of this tool.

Control performance of Branch and Bound algorithm

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

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:)