Algorithm to find best option - algorithm

I have multiple key:value and need to find the best possible option.
Product
Price
Product
Price
Product
Price
label1
11
label2
12
label3
13
label4
14
label5
15
label6
16
I need to find all possible options starting from the first column
and find best solution like an example:
Product
Price
Product
Price
Product
Price
SUM
Result
label1
11
label2
12
label3
13
36
label1
11
label2
12
label6
16
39
label1
11
label5
15
label3
13
39
label1
11
label5
15
label6
16
42
label4
14
label5
15
label6
16
45
label4-label5-label6
label4
14
label5
15
label3
13
42
label4
14
label2
12
label3
13
39
label4
14
label2
12
label6
16
42
Please, any language, I need to understand algorithm

It seems like you are trying to maximize the sum and there is no constraint other than having only one item from each column. In that case: just take the item with the maximum value from each column.
Pseudo code:
res = []
for each col in cols:
item = getMaxItem(col)
res.push(item)
getMaxItem(col):
item = col[0]
for each i in col:
if i.price > item.price:
item = i
return item
This would be an O(n) solution, with n being the number of items in all the columns.

Related

Pivot query Oracle SQL

I have the below table and I am trying to write an Oracle select query that would result in the second table.
I understand I have to use Pivot but I can't figure at all how to do.
MSGID
KEY
COLVALUE
15
height
18
15
length
19
15
width
20
15
notImportant
xxx
16
height
21
16
length
22
16
width
23
16
notImportant
xxx
17
height
24
17
length
25
17
width
26
17
notImportant
xx
Desired result:
MsgID
height
length
width
15
18
19
20
16
21
22
23
17
24
25
26
Tried the below code but without success....
select MSGID, HEIGHT, LENGTH, WIDTH
from (select MSGID, KEY, COLVALUE
from table )
PIVOT
(
max(COLVALUE)
FOR KEY IN ('HEIGHT','LENGTH','WIDTH')
)
Do you have any tips?
Here's one option:
SQL> select msgid,
2 max(case when key = 'height' then colvalue end) height,
3 max(case when key = 'length' then colvalue end) length,
4 max(case when key = 'width' then colvalue end) width
5 from test
6 group by msgid
7 order by msgid;
MSGID HEIGHT LENGTH WIDTH
---------- ---------- ---------- ----------
15 18 19 20
16 21 22 23
17 24 25 26
SQL>
Or, with pivot:
SQL> select *
2 from test
3 pivot
4 (max(COLVALUE)
5 FOR KEY IN ('height','length','width')
6 )
7 order by 1;
MSGID 'he 'le 'wi
---------- --- --- ---
15 18 19 20
16 21 22 23
17 24 25 26
SQL>

i tried 2 style of nested loop in golang, but it has different output

i have this quiz, you should make an output like this, and i search youtube tutorials for "for golang" and it explain that it has 2 style of for in golang,
1
21
11
12
13
14
22
11
12
13
14
23
11
12
13
14
24
11
12
13
14
2
21
11
12
13
14
22
11
12
13
14
23
11
12
13
14
24
11
12
13
14
3
21
11
12
13
14
22
11
12
13
14
23
11
12
13
14
24
11
12
13
14
4
21
11
12
13
14
22
11
12
13
14
23
11
12
13
14
24
11
12
13
14
5
21
11
12
13
14
22
11
12
13
14
23
11
12
13
14
24
11
12
13
14
it should be vertically outputted, not horizontally, so i build 3 variable, i = 1, j = 21, and k = 11, and i use for to automatically increase the value, the 1st style worked, but the 2nd style somehow its different
yt vid : https://www.youtube.com/watch?v=jZ-llP_yKNo on 5:28 min he explain that for has 2 style
1st style :
for i:=1; i <= 5; i++{
fmt.Println(i)
for j:=21; j <= 24; j++ {
println(j)
for k:=11; k<=14; k++ {
fmt.Println(k)
}
}
}
2nd style :
i:=1
j:=21
k:=11
for i <= 5{
fmt.Println(i)
i++
for j <= 24 {
println(j)
j++
for k<=14 {
fmt.Println(k)
k++
}
}
}
It's not about the syntax but about your logic.
In the 1st style with for i := ..., whenever next loop run, you reset the value to the init state, means it always sets j to 21 and k to 11. So there will a many sub loop runs.
In contrast, 2nd style, you init value j and k right before going to loop. So in the second loop of i, j and k are still the same value with 25 and 15 in that order.
There are multiple options to print the output in the golang.
fmt.Println appends a new line in the end.
fmt.Printf prints content as it is.
For more details read the documentation.
for i := 1; i <= 5; i++ {
fmt.Printf("%v ", i)
for j := 21; j <= 24; j++ {
fmt.Printf("%v ", j)
for k := 11; k <= 14; k++ {
fmt.Printf("%v ", k)
}
}
}
Output
1 21 11 12 13 14 22 11 12 13 14 23 11 12 13 14 24 11 12 13 14 2 21 11 12 13 14 22 11 12 13 14 23 11 12 13 14 24 11 12 13 14 3 21 11 12 13 14 22 11 12 13 14 23 11 12 13 14 24 11 12 13 14 4 21 11 12 13 14 22 11 12 13 14 23 11 12 13 14 24 11 12 13 14 5 21 11 12 13 14 22 11 12 13 14 23 11 12 13 14 24 11 12 13 14
To add a new line use the \n escape sequence.
Check the running code link

Nested for/while loop python triangle

Code
num = int(input(“Enter the number of lines: “))
for i in range(10):
for j in range(1,i):
print(num, the end='')
num = num+1
print()
I am writing a program which is should be like this.
Enter the number of lines: 10
11 12 13 14 15 16 17 18 19 20
21 22 23 24 25 26 27 28 29
30 31 32 33 34 35 36 37
38 39 40 41 42 43 44
45 46 47 48 49 50
51 52 53 54 55
56 57 58 59
60 61 62
63 64
65
I don’t have any example from the lecturer, i just following the step from website, but the output of my code is like this: i am confused where i made the mistake, don’t get any clue to wear for or while. Please help me, thank you.
10
11 12
13 14 15
16 17 18 19
20 21 22 23 24
25 26 27 28 29 30
31 32 33 34 35 36 37
38 39 40 41 42 43 44 45
Try this:
input_data = input('Enter number of lines: ')
num = int(input_data)
# how many items to print in the first line?
items_to_print = num
# what's the starting number?
print_number = 11
for i in range(0, num):
# don't decrease num
# decrease items_to_print
# each line will reduce 1 item to print
for j in range(0, items_to_print):
print(print_number, end = ' ')
print_number += 1
print()
items_to_print -= 1
Result:
Enter number of lines: 10
11 12 13 14 15 16 17 18 19 20
21 22 23 24 25 26 27 28 29
30 31 32 33 34 35 36 37
38 39 40 41 42 43 44
45 46 47 48 49 50
51 52 53 54 55
56 57 58 59
60 61 62
63 64
65
Explanation
Start small and make your way up.
First just do this:
input_data = input('Enter number of lines: ')
num = int(input_data)
print(num)
That'll print 10 if you entered 10. Great.
Second, add the first for loop and test whether it will print 10 rows.
input_data = input('Enter number of lines: ')
num = int(input_data)
for i in range(0, num):
print(f'Printing line {i}')
Third, try to print a block of 10 x 10. So, you add another variable called items_to_print. Set it to num. If you enter 10 as input, you will get 10 rows and 10 columns.
input_data = input('Enter number of lines: ')
num = int(input_data)
print_number = 0
items_to_print = num
for i in range(0, num):
print(f'Printing line {i}')
for j in range(0, items_to_print):
print(print_number, end = ' ')
Fourth step is to reduce the number of zeros printed before restarting the i loop. So, you decrement items_to_print.
input_data = input('Enter number of lines: ')
num = int(input_data)
print_number = 0
items_to_print = num
for i in range(0, num):
print(f'Printing line {i}')
for j in range(0, items_to_print):
print(print_number, end = ' ')
items_to_print -= 1
Now that your printing is working great, let's set print_number to start with 11 and each time a print happens in j loop, increment print_number. Then you will have same code I published at the top of this answer.
Well you have three little problems so let's address them one at a time.
First: default range function starts at 0 so when your j starts at one you are missing one iteration of the cicle. That explains missing one column and row but not two so let's keep going.
Second: the range function is non inclusive meaning you're I goes from 0 to 9 then in the inner loop you go from 1 to a maximum of 8. There's your missing second iteration.
Third: you are looping from 1 to an encreasing value what you want is the opposite so you need a decreasing range.
This is how you're code should look like.
num = 11
for i in range(10, 0, - 1):
for j in range(i):
print(num, end = " ")
num += 1
print()
Good luck and happy coding

The Traveling Salesman algorithm bug

I have tried to make an algorithm solving the traveling salesman problem as follows:
%main function:
[siz, ~] = size(table);
done(1:siz) = false;
done(1) = true;
[dist, path] = bruteForce(table, done, 1);
function bruteForce:
function [distance, path] = bruteForce(table, done, index)
size = length(done);
dmin = inf;
distance = 0;
path = [];
%finding minimum distance
for i = 1:size
if ~done(i)
done(i) = true;
%iterating through all nodes using recursion
[d, p] = bruteForce(table, done, i);
if (d < dmin)
dmin = d;
path = [i p];
distance = dmin + table(i, index);
end
%freing the node again
done(i) = false;
end
end
if distance == 0
distance = table(1, index);
path = 1;
end
Unfortunately, for the following matrix:
B = [0 29 20 21 16 31 100 12 4 31 18;
29 0 15 29 28 40 72 21 29 41 12;
20 15 0 15 14 25 81 9 23 27 13;
21 29 15 0 4 12 92 12 25 13 25;
16 28 14 4 0 16 94 9 20 16 22;
31 40 25 12 16 0 95 24 36 3 37;
100 72 81 92 94 95 0 90 101 99 84;
12 21 9 12 9 24 90 0 15 25 13;
4 29 23 25 20 36 101 15 0 35 18;
31 41 27 13 16 3 99 25 35 0 38;
18 12 13 25 22 37 84 13 18 38 0];
Instead of getting the expected result:
1-8-5-4-10-6-3-7-2-11-9-1 = 253km
I get:
1-8-11-3-4-6-10-5-9-2-7-1 = 271km
Could you help me find the bug?
If brute force is a must and speed is no issue, then just use the perms function for the number of cities. This allows for an easy implementation:
table = [0 29 20 21 16 31 100 12 4 31 18;
29 0 15 29 28 40 72 21 29 41 12;
20 15 0 15 14 25 81 9 23 27 13;
21 29 15 0 4 12 92 12 25 13 25;
16 28 14 4 0 16 94 9 20 16 22;
31 40 25 12 16 0 95 24 36 3 37;
100 72 81 92 94 95 0 90 101 99 84;
12 21 9 12 9 24 90 0 15 25 13;
4 29 23 25 20 36 101 15 0 35 18;
31 41 27 13 16 3 99 25 35 0 38;
18 12 13 25 22 37 84 13 18 38 0];
[siz, ~] = size(table);
[bp, b] = bruteForce(table, siz)
function [bestpath, best] = bruteForce(table, siz)
p = perms(1:siz);
[r, c] = size(p);
best = inf;
for i = 1:r
path = p(i, :);
dist = distCalculatorReturn(table, path);
if dist < best
best = dist;
bestpath = path;
end
end
bestpath = [bestpath, bestpath(1)];
end
function [totaldist] = distCalculatorReturn(distMatrix, proposedPath)
dist = 0;
i = 1;
while i ~= length(proposedPath)
dist = dist + distMatrix(proposedPath(i),proposedPath(i+1));
i = i+1;
end
dist = dist + distMatrix(proposedPath(1), proposedPath(end));
totaldist = dist;
end
This yields the answer you are looking for. However, if you are only solving problems of that size, why not apply a standard simulated annealing. This gives much faster solution times and should solve the problem size consistently:
table = [0 29 20 21 16 31 100 12 4 31 18;
29 0 15 29 28 40 72 21 29 41 12;
20 15 0 15 14 25 81 9 23 27 13;
21 29 15 0 4 12 92 12 25 13 25;
16 28 14 4 0 16 94 9 20 16 22;
31 40 25 12 16 0 95 24 36 3 37;
100 72 81 92 94 95 0 90 101 99 84;
12 21 9 12 9 24 90 0 15 25 13;
4 29 23 25 20 36 101 15 0 35 18;
31 41 27 13 16 3 99 25 35 0 38;
18 12 13 25 22 37 84 13 18 38 0];
[path, dist] = tsp(table, length(table))
function [path, dist] = tsp(D, n)
L = 40*n;
epsi = 1e-9;
x = randperm(n);
fx = distCalculatorReturn(D, x);
T = 1000000;
while T > epsi
for i=1:L
num1 = 1 + floor(rand*n);
num2 = 1 + floor(rand*n);
while num1 == num2
num1 = 1 + floor(rand*n);
end
y = x;
swap1 = y(num1);
y(num1) = y(num2);
y(num2) = swap1;
fy = distCalculatorReturn(D,y);
if fy < fx
x = y;
fx = fy;
elseif rand < exp(-(fy - fx)/T)
x = y;
fx = fy;
end
end
T = 0.9*T;
end
path = [x, x(1)];
dist = fx;
end
Your code does not compute the distance for each possible path (as bruteForce suggests). Instead it always starts at node 1 and from there goes always to the node that is closest to the current node. As your example shows, that does not necessarily lead to the overall shortest path. You will need to go through all possible paths to be sure you find the optimum.
Here is my go at your problem:
% distance matrix
B = [0 29 20 21 16 31 100 12 4 31 18;
29 0 15 29 28 40 72 21 29 41 12;
20 15 0 15 14 25 81 9 23 27 13;
21 29 15 0 4 12 92 12 25 13 25;
16 28 14 4 0 16 94 9 20 16 22;
31 40 25 12 16 0 95 24 36 3 37;
100 72 81 92 94 95 0 90 101 99 84;
12 21 9 12 9 24 90 0 15 25 13;
4 29 23 25 20 36 101 15 0 35 18;
31 41 27 13 16 3 99 25 35 0 38;
18 12 13 25 22 37 84 13 18 38 0];
% compute all possible paths assuming we always start at node 1
nNodes = size(B,1);
paths = perms(2:nNodes);
nPaths = size(paths,1);
paths = [ones(nPaths,1) paths ones(nPaths,1)]; % start and finish tour at node 1
% with a random start point:
% paths = perms(1:nNodes);
% paths = [perms(1:nNodes) paths(:,1)];
% compute overall distance for each path
distance = inf;
for idx=1:nPaths
from = paths(idx,1:end-1);
to = paths(idx,2:end);
d = sum(diag(B(from,to)));
if d<distance
distance = d;
optPath = paths(idx,:);
end
end
This leads to the following result:
optPath = [1 9 11 2 7 3 6 10 4 5 8 1]
distance = 253

Valid values of a matrix/image under a mask [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
Suppose I want to extract values in an image or matrix in Matlab under a given mask (e.g., a 5x5 mask), but I want to extract only existing values because in the borders (or close to them) the mask will not find all values. I want to extract only the valid values of the image given this mask, no matter which pixel i am iterating. How to do that in Matlab?
You just have to compute the x and y indices applying max and min so as not to exceed the image boundaries:
img = magic(7); %// define example image
Nx = 5; %// block size in x
Ny = 5; %// block size in y
x = 2; %// pixel x
y = 6; %// pixel y
nx = (Nx-1)/2;
ny = (Ny-1)/2;
xx = max(x-nx,1):min(x+nx,size(img,1));
yy = max(y-ny,1):min(y+ny,size(img,2));
block = img(xx, yy);
Example result:
>> img
img =
30 39 48 1 10 19 28
38 47 7 9 18 27 29
46 6 8 17 26 35 37
5 14 16 25 34 36 45
13 15 24 33 42 44 4
21 23 32 41 43 3 12
22 31 40 49 2 11 20
>> block
block =
1 10 19 28
9 18 27 29
17 26 35 37
25 34 36 45
If you have the image processing toolbox, you can use the function blockproc to define your own neighborhood-based operation.
M=5; N=5;
fun = #(block_struct) block_struct.data;
B = blockproc(I,[M N],fun, 'TrimBorder', 1);
where I is your image (matrix). Then change fun to whatever you need. The TrimBorder parameter should cope with your border issue.
Hope it helps

Resources