Recursive method in pharo produces #SubscriptOutOfBounds:8 - pharo

I created a class in Pharo known as BinarySearchTreean i implemented a method called BinarySearchTree>>PreOrder and BinarySearchTree>>index
Preorder: myArray index: position
(myArray at: position) ~= -1
ifTrue: [
Transcript show: (myArray at: position).
self Preorder: myArray index: (position * 2).
self Preorder: myArray index: (position * 2) + 1.
].
I then provided this array #(90 60 95 50) with index 1 to make a PreOrder search in my binary tree which i implemented using arrays but it does not work.
Please help...

#at: will signal SubscriptOutOfBounds when the index is < 0 or greater than the size of the array (Smalltalk collections are 1-based, i.e. the first index is 1, not 0). 8 is clearly larger than 4 (the size of myArray).
The check at the start will never evaluate to False as your array has no entry -1, and hence the conditional block will be evaluated every time.
I can't really say where your problem lies as you've excluded all the code that is actually of interest. If you add that I can tell you more.

Related

Maximum Sum of XOR operation on a selected element with array elements with an optimize approach

Problem: Choose an element from the array to maximize the sum after XOR all elements in the array.
Input for problem statement:
N=3
A=[15,11,8]
Output:
11
Approach:
(15^15)+(15^11)+(15^8)=11
My Code for brute force approach:
def compute(N,A):
ans=0
for i in A:
xor_sum=0
for j in A:
xor_sum+=(i^j)
if xor_sum>ans:
ans=xor_sum
return ans
Above approach giving the correct answer but wanted to optimize the approach to solve it in O(n) time complexity. Please help me to get this.
If you have integers with a fixed (constant) number of c bites then it should be possible because O(c) = O(1). For simplicity reasons I assume unsigned integers and n to be odd. If n is even then we sometimes have to check both paths in the tree (see solution below). You can adapt the algorithm to cover even n and negative numbers.
find max in array with length n O(n)
if max == 0 return 0 (just 0s in array)
find the position p of the most significant bit of max O(c) = O(1)
p = -1
while (max != 0)
p++
max /= 2
so 1 << p gives a mask for the highest set bit
build a tree where the leaves are the numbers and every level stands for a position of a bit, if there is an edge to the left from the root then there is a number that has bit p set and if there is an edge to the right there is a number that has bit p not set, for the next level we have an edge to the left if there is a number with bit p - 1 set and an edge to the right if bit p - 1 is not set and so on, this can be done in O(cn) = O(n)
go through the array and count how many times a bit at position i (i from 0 to p) is set => sum array O(cn) = O(n)
assign the root of the tree to node x
now for each i from p to 0 do the following:
if x has only one edge => x becomes its only child node
else if sum[i] > n / 2 => x becomes its right child node
else x becomes its left child node
in this step we choose the best path through the tree that gives us the most ones when xoring O(cn) = O(n)
xor all the elements in the array with the value of x and sum them up to get the result, actually you could have built the result already in the step before by adding sum[i] * (1 << i) to the result if going left and (n - sum[i]) * (1 << i) if going right O(n)
All the sequential steps are O(n) and therefore overall the algorithm is also O(n).

Multivariable function local minimum using SciPy

Consider the function:
def f(x,y):
return x + 3*exp(y**2)
I was wondering, is it possible to use SciPy.optimize.minimize
to find the minimum value on say [0,1] (the unit interval) (for both, x and y)?
Here is my attempt:
bound = (0,1)
bds = [bound,bound]
x_0 = [0,0] (initial guess)
And thus,
scipy.optimize.minimize(f,x_0,method='SLSQP', \ bounds = bds)
But this isn't working.
I keep getting:
"unexpected character after line continuation character" At \ bounds = bnds
Note that I want my x and y to vary over the real numbers on [0,1]
Edit:
def f(x):
return x[0] + 3*exp(x[1]**2)
bound = (0,1)
bds = [bound,bound]
x_0 = [0,0] (initial guess)
scipy.optimize.minimize(f,x_0,method='SLSQP', bounds = bds)
Is this minimise function looking at only integer values 0 and 1? or is it looking at all real numbers in [0,1] (the unit interval?). If its the first, im not sure how to make it to the second how do I do so?
Your original code wouldn't work because
""unexpected character after line continuation character" At \ bounds = bnds":
is telling you that the "line continuation character" (the backslash) is causing a problem. You can't have anything after that character. Insert a line break after the backslash, or remove the backslash altogether
Once you fix that, you'll get an error saying
TypeError: f() missing 1 required positional argument: 'y'
This is because minimize wants a function that takes one input (read the "Parameters: fun part of the documentation). That input can be an array of shape (n, ). When you want a multivariate minimization, all n variables go into that single argument to your function
Re: "Is this minimise function looking at only integer values 0 and 1? or is it looking at all real numbers in [0,1] (the unit interval?). If its the first, im not sure how to make it to the second."
It would be a pretty useless optimizer if it only checked the values at the bounds, don't you think?
This is easy enough to check though! Your current function has a minimum at [0, 0], so it's not a great way to test what the function does. Let's define a function that has a minimum at a different number. For example, let's define a function that has a minimum at [0.5, 0.5]
def f(X):
return abs(X[0] - 0.5) * abs(X[1] - 0.5)
Running your code gives the result:
fun: 0.0
jac: array([0., 0.])
message: 'Optimization terminated successfully.'
nfev: 8
nit: 2
njev: 2
status: 0
success: True
x: array([0.5, 0.5])
which makes it pretty clear that minimize() looks in the entire interval.
It doesn't really look at all real numbers in the interval though (that would be impossible, given that there are infinite real numbers in any interval). Instead, it uses the optimization algorithms that you specify in the method argument.
The optimization result represented as a OptimizeResult object. Important attributes are: x the solution array, success a Boolean flag indicating if the optimizer exited successfully and message which describes the cause of the termination.

Search and remove algorithm

Say you have an ordered array of values representing x coordinates.
[0,25,50,60,75,100]
You might notice that without the 60, the values would be evenly spaced (25). This would be indicative of a repeating pattern, something that I need to extract using this list (regardless of the length and the values of the list). In this particular example, the algorithm should find and remove the 60.
There are no time or space complexity requirements.
Both the values in the list and the ideal spacing (e.g 25) are unknown. So the algorithm must obtain this by looking at the values. In addition, the number of values, and where the outliers are in the array are not guaranteed. There may be more than one outlier. The algorithm should return a list with the outliers removed. Extra points if the algorithm uses a threshold for the spacing.
Edit: Here is an example image
Here there is one outlier on the x axis. (green-line) There are two on the y axis. The x-coordinates of the array represent the rho of the line on that axis.
arr = [0,25,50,60,75,100]
First construct the distances array
dist = np.array([arr[i+1] - arr[i] for (i, _) in enumerate(arr) if i < len(arr)-1])
print(dist)
>> [25 25 10 15 25]
Now I'm using np.where and np.percentile to cut the array in 3 part: the main , the upper values and the lower values. I arbitrary set them to 5%.
cond_sup = np.where(dist > np.percentile(dist, 95))
print(cond_sup)
>> (array([]),)
cond_inf = np.where(dist < np.percentile(dist, 5))
print(cond_inf)
>> (array([2]),)
You now got indexes where the value is different from the others.
So, dist[2] has a problem, which mean by construction the problem is between arr[2] and arr[2+1]
I don't know if you want to remove 1 or more numbers from this array. So I think the way to solve this problem will be like this:
array A[] = [0,25,50,60,75,100];
sort array (if needed).
create a new array B[] with value i-th: B[i] = A[i+1] - A[i]
find the value of B[] elements that appear most time. It's will be our distance.
find i such that A[i+1]-A[i] != distance
find k (k>i and k min) such that A[i+k]-A[i] == distance
so, we need remove A[i+1] => A[i+k-1]
I hope it is right.

index 60 is out of bounds for axis 0 with size 60

I have a problem with my code and no matter what I do, I always get the index out of bounds error
I tried changing 60 to 40 or 80 but I always have the same problem
def Talus(Nbriter,taille):
M=np.zeros([taille,taille],int)
avalanch=[]
duree=[]
perte=[]
for gain in range(Nbriter):
iaj=rd.randint(1,taille-1)
jaj=rd.randint(1,taille-1)
M[iaj][jaj]+=1
a=1
atot=0
d=0
perdu=0
while a>0:
for i in range(1,taille-1):
for j in range(1,taille-1):
if (M[i][j]-M[i][j+1]>3) or (M[i][j]-M[i][j-1]>3) or (M[i]
[j]-M[i+1][j]>3) or (M[i][j]-M[i-1][j]>3):
M[i][j]-=4
M[i][j+1]+=1
M[i][j-1]+=1
M[i+1][j]+=1
M[i-1][j]+=1
a+=4
d+=1
else:
a=0
atot+=a
for i in range(taille):
perdu+=M[i][0]
M[i][0]=0
perdu+=M[i][-1]
M[i][-1]=0
for j in range(taille):
perdu+=M[0][j]
M[0][j]=0
perdu+=M[-1][j]
M[-1][j]=0
avalanch.append(atot)
duree.append(d)
perte.append(perdu)
return(M,avalanch,duree,perte)
M,avalanch,duree,perte=Talus(100000,40)
I always get this :
Traceback (most recent call last):
File "C:\Users\Poste1\Desktop\mon tipe\codeavalanche2.py", line 52, in
<module>
M,avalanch,duree,perte=Talus(100000,40)
File "C:\Users\Poste1\Desktop\mon tipe\codeavalanche2.py", line 26,
in Talus
if (M[i][j]-M[i][j+1]>3) or (M[i][j]-M[i][j-1]>3) or (M[i][j]-
M[i+1][j]>3) or (M[i][j]-M[i-1][j]>3):
IndexError: index 40 is out of bounds for axis 0 with size 40
It's for a project I need to submit, so please if anyone knows how I can fix it I would be very grateful. Thank you
By the way, my professor told me to change the range into xrange but I am using python 3 so it doesn't exist.
Correct me if I'm wrong, but I think you have some sort of problem understanding the way array indexes work in programming, as Python uses the classic 0 to (size-1) type of notation. Let me explain myself:
I think your problem is the index you are trying to access is relative to the size of the array. That is, you are using taille for the size and j, that in the last iteration is going to be j = taille-1. Here comes the problem, as your array is always going to be of a given size, determined by taille, let's say taille = 5, and then in the last iteration of j, (j+1) = (taille-1)+1 = taille = 5 => M[5] -> ERROR.
The error is completely reasonable, as array's indexes work in this way:
Element 1, Element 2, Element 3, Element 4, Element 5.
Index 0, Index 1, Index 2, Index 3, Index 4.
Or as I said in the beginning, the indexes go from 0 to (size-1), and that means you cannot access the taille-th element of an array size taille.
As to the solution to your problem, if you really want to access i+1 and j+1, you should then change the limits of your for loop from (1, taille-1) to (1, taille-2) in both cases.
Hope you found my answer helpful : )

How to find the actual sequence of a Longest Increasing Subsequence?

This is not a homework problem. I am reviewing myself of the Longest Increasing Subsequence problem. I read every where online. I understand how to find the "length", but I don't understand how to back-trace the actual sequence. I am using the patience sorting algorithm to find the length. Can anyone explain how to find the actual sequence? I do not really understand the version in Wikipedia. Can someone explain in a different method or different way?
Thanks.
Lets define as max(j) as the longest increasing subsequence up to A[j]. There are two options: or we use A[j] in this subsequence, or we don't.
If we dont use it, then the value will be max(j-1). If we do use it, then the value will be
max(i)+1, when i is the biggest index such that i < j and A[i] < A[j]. (Here we assume that the max(i) sequence uses i- not neccessary true, but we can solve this issue by saving for each cell 2 values- the max(j) value, and max*(j), when max*(j) is the longest increasing subsequence up to A[j] that uses A[j]. max*(j) will be calculated each time as max*(i)+1).
To sum up, the recursive formula for calculating max(j) will be:
max{max(j-1),max*(i)+1},and max*(j)= max*(i)+1.
In each array cell you can save a pointer, that tells you if you chose to use the A[j] cell or not. In this way you can find all the sequence while moving backwards on the array.
Time Complexity: The complexity of the recursive formula and finding the sequence at the end is O(n). The problem here is finding for each A[j] the corresponding A[i] such that i is the biggest index such that i < j, A[i] < A[j].
Of course you can do it naivly in O(n^2) (from each cell go backwards until you find this i). If you want to do better then I'm pretty sure that you can do it in O(nlogn) in the following way:
*Sort your Array.
1) go for the smallest integer in the array, and notate is position in the array as k.
2)For A[k+1], we have of course A[k] < A[k+1]. If A[k+1]>A[k+2] then k will feet to the k+2 cell as well, and so on until we have A[k+m] < A[k+m+1], and then k+m is feet to k+m+1,
3)delete all the cells that you found thier corresponding cell in the previous stage
4) return to 1.
Hoped that it help. Please notice that I thought about it all alone, therefore there is a very small chance that there is some mistake here- please be convinced that I'm right and ask for more clarifications, if you need.
This Python code solves the Longest Increasing Sequence problem, and also returns one of such sequences. The trick is, at the same time that the dynamic programming table gets filled, another array is also filled, storing the index of the elements that were used to construct the optimal solution.
def an_lis(nums):
table, solution = lis_table(nums)
if not table:
return (0, [])
n, maxLen = max(enumerate(table), key=itemgetter(1))
lis = [nums[n]]
while solution[n] != -1:
lis.append(nums[solution[n]])
n = solution[n]
return lis[::-1]
def lis_table(nums):
n = len(nums)
table, solution = [0] * n, [-1] * n
for i in xrange(n):
maxLen, maxIdx = 0, -1
for j in xrange(i):
if nums[j] < nums[i] and table[j] > maxLen:
maxLen, maxIdx = table[j], j
table[i], solution[i] = 1 + maxLen, maxIdx
return (table, solution)

Resources