I have some questions.
1.How to create disjoint pattern data bases for 15 puzzle?
2.What does pattern database (5-5-5) or (6-3-2) mean?
You are trying to do too much at once. Consider this state of the puzzle:
1 2 3 4
5 10 6 8
9 7 _ 12
13 14 11 15
(where _ is the empty space). A permutation (in this context) is an exchange of the empty space with a neighboring tile:
1 2 3 4
5 10 6 8
9 7 12 _
13 14 11 15
A pattern is a partial specification of a state, in which (in this context) some tiles may be unspecified, like this:
1 2 3 4
5 * * *
9 * * *
13 * * _
This particular pattern looks like a target pattern, which is to say a partial specification of the goal state. The pattern database of this pattern is the set of all patterns that can be obtained from this pattern by permutation, with the corresponding minimum number of moves needed to reach that state from this one. Here is another target pattern:
* * * *
* 6 7 8
* 10 11 12
* 14 15 _
Notice that these two target patterns are disjoint (they have no tiles in common), so their pattern databases are called disjoint pattern databases.
Does that help?
That mean first we must generate all posible permutation from
1 2 3 4
5 * * *
9 * * *
13 * * _
for example it will be
1 * 3 4
5 2 * *
9 * * *
13 * * _
1 2 3 *
5 * * 4
9 * * *
13 * * _
and then from this permutation run BFS and try to reach goal state ?
How to generate all this permutation from this numbers 1,2,3,4,5,9,13 some pseudocode ?
Related
I am working on a game using the Key operator to create simple parent tree nodes connected with children. Like (1 3 2 7 11 12) with 1 as a parent node and 3 2 7 11 12 children. The array has all the information via Key to create the nested array. Of course its extremely fast. But I actually need 2 or 3 more depth. I can create a different tree construction shown on the 'same' array - second image. This different encoding (1 2 1 1 2 3 1 3 3.....) allows arbitrarily nesting vector depth and works perfectly. - with just a simple array.
There could be enough information with the Key transformation on the array then more code to connect the children nodes - for needed depth. Are there any same or similar APL/Co-dfns for (1.) transforming the array into the tree (2.) - and back? I am new to APL and focusing on the rectangular. Tree wrangling is down the road. I need almost the same for Key speed due to very long arrays and their nested arrays.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
1 2 1 1 2 3 1 3 3 3 1 1 2 7 8 9 16 4
Using Key:
{⊂⍵}⌸1 2 1 1 2 3 1 3 3 3 1 1 2 7 8 9 16 4
(1 3 4 7 11 12) (2 5 13) (6 8 9 10) (14) (15) (16) (17) (18)
Using maybe Key and something else....
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
1. 1 2 1 1 2 3 1 3 3 3 1 1 2 7 8 9 16 4
2. (1 3 4 (7 14) 11 12) (2 5 13) (6 (8 15) (9 (16 17)) 10) (,18)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
1 2 2 2 2 2 1 7 8 3 10 11 10 10 10 15 9
(different array for same tree encoding)
(1(7(8 (9 17)))) (2 3 4 5 6) (10(11 12) 13 14 (15 16))
({⊂⍵}⌸⍠ 2) 1 2 1 1 2 3 1 3 3 3 1 1 2 7 8 9 16 4
Perhaps using Variant on Key down the road?
There are some ways to do this, but the best method will depend on what you want to do with the results. If you really do have very large arrays, then producing the "nested children" representation of arrays is going to be expensive no matter how you compute them, because the underlying representation is expensive (though, no more expensive than the same sort of representation in another language).
Section 3.2 of (Hsu 2019) discusses this in detail:
"A data parallel compiler hosted on the GPU". Hsu, Aaron W.
https://scholarworks.iu.edu/dspace/handle/2022/24749
Generally speaking, if you intend to work with the data in some way, it is almost always faster and easier to work directly with the parent vector or depth vector representation instead of first converting to a record-type style representation.
One technique is to query the data in parent vector form first, to identify the relevant nodes over which you intend to work, and only then to extract the children nodes for that limited set using primitives like membership (∊) or where (⍸).
If you can describe the sort of operations you intend to perform over these nested representations, there might be a better algorithm that does not require the conversion.
If you do wish to simply create the full record-type representation, there is some conversion code in (Hsu 2019). You can also look at the P2D and D2P functions in the Co-dfns compiler:
https://github.com/Co-dfns/Co-dfns/blob/master/src/codfns/P2D.aplf
https://github.com/Co-dfns/Co-dfns/blob/master/src/codfns/D2P.aplf
These may give you some additional help in converting between the formats.
If you need to convert directly between the parent and record-type representation, you can use something akin to this:
kids←{0=≢k←⍸p=⍵:⍵ ⋄ ⍵,∇¨k~⍵}¨
And apply it to the root nodes of your tree like this:
kids ⍸p=⍳≢p
where p is your parent vector.
I hope this helps!
I am trying to smooth the temporal history of each pixel in my matrix- in other words, trying to smooth each pixel through both 'space' (mxn) and 'time'(third dimension). I am using the function movmean to create an average of each pixel in time of a 1000x1000x8 matrix.
I am currently using the following code to take an average, using a window size of 5, operating along the third dimension:
av_matrix = movmean(my_matrix,5,3)
This is creating an average as expected, but I'm wondering if the window is just operating in the mxn direction and not taking the average along the third dimension as well.
To compute a moving average along the n dimensions of an n-dimensional array (the "window" is an n-dimensional rectangle), the simplest way is to use convolution (see convn).
You need to be careful with edge effects, that is, when the convolution kernel (or n-dimensional window) partially slides out of the data. What movmean does is average over the actual data points only. To achieve that behaviour you can
compute the sum over the kernel via convolution with the 'same' option; and then
divide each entry by the number of actual data points from which it was computed. This number can also be obtaind via convolution, namely, applying the kernel to an array of ones.
So, all you need is:
my_matrix = randi(9,5,5,3); % example 3D array
sz = [3 3 2]; % 3D window size
av_matrix = convn(my_matrix, ones(sz), 'same') ... % step 1
./convn(ones(size(my_matrix)), ones(sz), 'same'); % step 2
Check:
The following examples use
>> my_matrix
my_matrix(:,:,1) =
6 8 2 1 8
4 6 7 9 8
4 5 1 4 3
5 5 8 7 9
3 6 6 4 9
my_matrix(:,:,2) =
8 8 5 3 6
8 9 6 9 1
9 5 6 2 2
1 7 4 1 2
5 4 7 4 9
my_matrix(:,:,3) =
6 5 8 6 6
1 6 8 6 1
5 5 1 6 7
1 1 2 9 8
1 2 6 1 2
With edge effects:
>> mean(mean(mean(my_matrix(1:2,1:2,1:2))))
ans =
7.125000000000000
>> av_matrix(1,1,1)
ans =
7.125000000000000
Without edge effects:
>> mean(mean(mean(my_matrix(1:3,1:3,1:2))))
ans =
5.944444444444445
>> av_matrix(2,2,1)
ans =
5.944444444444445
We have an original array and a list of filters where each filter consists of indices which are allowed through the filter. The filters are rather nice, e.g. they are grouped for each power of 2 in the following way (the filters are upto n = 20).
1 (2^0) = 1 3 5 7 9 11 13 15 17 19
2 (2^1) = 1 2 5 6 9 10 13 14 17 18
4 (2^2) = 1 2 3 4 9 10 11 12 17 18 19 20
8 (2^3) = 1 2 3 4 5 6 7 8 17 18 19 20
I hope you get the idea. Now we would apply some or all of these filters (user dictates which filters to apply) to the original array and the xor of the elements of the transformed array is the answer. To take an example if the original array would have been [3 7 8 1 2 9 6 4 11] e.g. n = 9 and we needed to apply the filters of 4, 2 and 1, the transformations would be like this.
After applying filter of 4 - [3 7 8 1 x x x x 11]
After applying filter of 2 - [3 7 x x x x x x 11]
After applying filter of 1 - [3 x x x x x x x 11]
Now the xor of 3 and 11 e.g. 8 is the answer. I can solve this O(n * no. of filters) time, but I need a better solution which might give the answer in O(no of filters) time. Is there any way to take advantage of the properties of xor and/or pre-compute the results for some and then give the answer for the filters. This is because there are many queries with filters, so I need to answer the queries in O(no of filters) time. Any kind of help will be appreciated.
It can be done in O(M) where M is the number of items that pass all filters (independent of the number of filters) by iterating over the array in a particular way, generating only the indexes that pass all the filters.
This is easier to see if you write down the examples starting at zero:
1: 0 2 4 6 8 10 12 14 16 18 (numbers that don't contain 1)
2: 0 1 4 5 8 9 12 13 16 17 (numbers that don't contain 2, etc)
4: 0 1 2 3 8 9 10 11 16 17 18 19
8: 0 1 2 3 4 5 6 7 16 17 18 19
The filters are really just a constraint on the bits of the indexes in the array. That constraint is of the form index & filters = 0, where filters is just the sum of all the individual filters (eg 1 + 2 + 4 = 7). Given a valid index i the next valid index i' can be computed with only primitive operations: i' = (i | filters) + 1 & ~filters. The idea here is to set the bits that are filtered to zero so the +1 will carry through them, then filtered bits are cleared again to make the index valid. The total effect is that the unfiltered bits are incremented and the filtered bits stay zero.
This gives a simple algorithm to iterate directly over all valid indexes. Start at 0 (which is always valid) and increment using the rule above until the end of the array is reached:
for (int i = 0; i < N; i = (i | filters) + 1 & ~filters)
// do something with array[i], like XOR them all together
If an array contains N number of elements (elements can be repeated) and the goal is to make all the elements equal by a +1 on an element and a -1 on another element in each iteration, how can we determine whether it's possible or not to normalize the array? What will be the optimal algorithm to solve the problem?
Ex.
For the array 1 2 3, if I apply +1 on 1 and -1 on 3, the array becomes 2 2 2. That means it's possible in 1 iteration.
For the array 1 2 1, it's not possible to make all the elements equal.
First, since you're not disturbing the sum by each iteration, since you're increasing one number and decreasing another, the optimal target value is going to be the average.
If this average is a whole number, you should be able to achieve it with the iterations, however if the average is a fractional number then you will not be able to achieve it.
The number of steps is going to be the sum of the distances between each number and the target, divided by 2.
Every iteration pick one number above target and one below and apply the operations to them.
PS! As per commented, if all you want is answers to the following two questions:
Can it be done
What will the value be
Then the answers are:
Yes, provided the average number is a whole number
The value repeated in the whole array is the average number
Anyway, if you want the actual operations getting from the input to the target values, here's a longer example:
1 2 3 4 5 6 7 = 28, 28/7 = 4 (optimal target)
+ -
2 2 3 4 5 6 6
+ -
3 2 3 4 5 6 5
+ -
4 2 3 4 5 6 4
+ -
4 3 3 4 5 5 4
+ -
4 4 3 4 5 4 4
+ -
4 4 4 4 4 4 4
6 steps, let's total the distances from the first number:
1 2 3 4 5 6 7
3 2 1 0 1 2 3 = 12, divided by 2 = 6
Here's the example from the comments on the question:
1 9 10 12 3 7 = 42 / 6 = 7 (optimal target)
Distances:
1 9 10 12 3 7
6 2 3 5 4 0 = 20, divided by 2 = 10 (steps)
1 9 10 12 3 7
+ - step 1
2 8 10 12 3 7
+ - step 2
3 7 10 12 3 7
+ - step 3
4 7 9 12 3 7
+ - step 4
5 7 8 12 3 7
+ - step 5
6 7 7 12 3 7
+ - step 6
7 7 7 11 3 7
- + step 7
7 7 7 10 4 7
- + step 8
7 7 7 9 5 7
- + step 9
7 7 7 8 6 7
- + step 10
7 7 7 7 7 7
Here is a more pseudo-code like algorithm description:
Calculate SUM of all the elements
COUNT all the elements
If AVERAGE (SUM/COUNT) is not whole number, solution is not possible to achieve
STEPS = SUM(ABS(numberN - AVERAGE))/2
Each iteration, pick one number below AVERAGE and one above
Apply + operation to number below and - operation to number above
Repeat steps 5 and 6 until target achieved
I have a 1 x 15 array of values:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
I need to rearrange them into a 3 x 5 matrix using a for loop:
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
How would I do that?
I'm going to show you three methods. One where you need to have a for loop, and two others when you don't:
Method #1 - for loop
First, create a matrix that is 3 x 5, then keep track of an index that will go through your array. After, create a double for loop that will help you populate the array.
index = 1;
array = 1 : 15; %// Array we wish to access
matrix = zeros(3,5); %// Initialize
for m = 1 : 3
for n = 1 : 5
matrix(m,n) = array(index);
index = index + 1;
end
end
matrix =
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
Method #2 - Without a for loop
Simply put, use reshape:
matrix = reshape(1:15, 5, 3).';
matrix =
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
reshape will take a vector and restructure it into a matrix so that you populate the matrix by columns first. As such, we want to put 1 to 5 in the first column, 6 to 10 in the second and 11 to 15 in the third column. Therefore, our output matrix is in fact 5 x 3. When you see this, this is actually the transposed version of the matrix we want, which is why you do .' to transpose the matrix back.
Method #3 - Another method without a for loop (tip of the hat goes to Luis Mendo)
You can use vec2mat, and specify that you need to have 5 columns worth for your matrix:
matrix = vec2mat(1:15, 5);
matrix =
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
vec2mat takes a vector and reshapes it into a matrix of as many columns as you specify in the second parameter. In this case, we need 5 columns.
For the sake of (bsx)fun, here is another option...
bsxfun(#plus,1:5,[0:5:10]')
ans =
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
less readable, maybe faster, but who cares if it is such a small of an array...
A = [ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ] ;
A = reshape( A' , 3 , 5 ) ;
A' = 1 2 3 4 5
6 7 8 9 10
11 12 13 14 15