Find all subarrays of fixed length with a given ranking












12















I have an array of numbers, for example:



A = [1, 5, 2, 4, 3]


and an array that determines a rank, for example:



B = [0, 2, 1]


My goal is to find all the subarrays of A that "obey" the rank B. If a subarray obeys the rank, that means that the i-th smallest element of the subarray must have B[i] as its (subarray) index. So for a subarray to match, the smallest element within it must be in position 0, the second smallest must be in position 2, and the biggest element must be in position 1.



So for example here, there are two subarrays of A that match the ranking: [1, 5, 2] (because A[0] < A[2] < A[1]) and [2, 4, 3].



So far, I've managed to find a solution that has an O(mn) (m is len(A) and n is len(B)) time complexity, it iterates over all the subarrays of length 3 and verifies if they are correctly ordered:



A = [1, 5, 2, 4, 3]
B = [0, 2, 1]
m = len(A)
n = len(B)
for i in range(m - n + 1):
current_subarray = A[i:i + n]
# we now do n - 1 comparaisons to check whether the subarray is correctly ordered.
for B_index in range(n - 1):
if current_subarray[B[B_index]] > current_subarray[B[B_index + 1]]:
break
else:
print("Subarray found:", current_subarray)


Result:



Subarray found: [1, 5, 2]
Subarray found: [2, 4, 3]


This works, but I was wondering if there was a better optimized algorithm (better than O(mn)) to fulfill this task.










share|improve this question




















  • 3





    are you looking for something with a lower time complexity specifically? because i am not sure such a thing exists.

    – Paritosh Singh
    Jan 5 at 17:43











  • @ParitoshSingh Yes, that is what I'm looking for. Maybe it doesn't, but I guess that's why I asked :). What makes me doubt though is that I'm working on subarrays, and some of these subarrays overlap - maybe there's a way to reduce the amount of computations by caching some, like how optimised string searching (such as KMP) algorithms work ?

    – ping guo
    Jan 5 at 17:50











  • The issue i see with that is this. consider [0,1,3,2]. In the first sublist, [1,3] would have relative ranks of 1 and 2, whereas in the second sublist, [1,3] would have a relative rank of 0 and 2. Essentially, the result depends on the "window", and so you'd need a re-evaluation to be sure. In such a scenario, whatever result you may cache would end up needing a re-check, losing out on all benefits. (And someone please correct me if im wrong)

    – Paritosh Singh
    Jan 5 at 17:53











  • @ParitoshSingh Correct, however consider subarrays that are of length > 2. For example when I'm going from [0, 1, 3] to [1, 3, 2] (on your list), lets say I've done comparaisons on the first subarray and deduced that it didn't obey. I move on to the second subarray, however I have possibly already done some comparaisons (last two elements become the first two elements of the second subarray). Even though, as you say, knowing that 1 < 3 isn't useful because 2 is in the middle, there are some cases where that overlapping part of the subarrays must be useful - at least, that's what I think.

    – ping guo
    Jan 5 at 17:59











  • Indeed, but because its "some" cases and not all, you'd have to do a recheck for all cases anyways. And since comparisons are a constant time operation, you'd end up on square 1. changing the window changes everything about the comparisons that are favourable and which aren't.

    – Paritosh Singh
    Jan 5 at 18:03
















12















I have an array of numbers, for example:



A = [1, 5, 2, 4, 3]


and an array that determines a rank, for example:



B = [0, 2, 1]


My goal is to find all the subarrays of A that "obey" the rank B. If a subarray obeys the rank, that means that the i-th smallest element of the subarray must have B[i] as its (subarray) index. So for a subarray to match, the smallest element within it must be in position 0, the second smallest must be in position 2, and the biggest element must be in position 1.



So for example here, there are two subarrays of A that match the ranking: [1, 5, 2] (because A[0] < A[2] < A[1]) and [2, 4, 3].



So far, I've managed to find a solution that has an O(mn) (m is len(A) and n is len(B)) time complexity, it iterates over all the subarrays of length 3 and verifies if they are correctly ordered:



A = [1, 5, 2, 4, 3]
B = [0, 2, 1]
m = len(A)
n = len(B)
for i in range(m - n + 1):
current_subarray = A[i:i + n]
# we now do n - 1 comparaisons to check whether the subarray is correctly ordered.
for B_index in range(n - 1):
if current_subarray[B[B_index]] > current_subarray[B[B_index + 1]]:
break
else:
print("Subarray found:", current_subarray)


Result:



Subarray found: [1, 5, 2]
Subarray found: [2, 4, 3]


This works, but I was wondering if there was a better optimized algorithm (better than O(mn)) to fulfill this task.










share|improve this question




















  • 3





    are you looking for something with a lower time complexity specifically? because i am not sure such a thing exists.

    – Paritosh Singh
    Jan 5 at 17:43











  • @ParitoshSingh Yes, that is what I'm looking for. Maybe it doesn't, but I guess that's why I asked :). What makes me doubt though is that I'm working on subarrays, and some of these subarrays overlap - maybe there's a way to reduce the amount of computations by caching some, like how optimised string searching (such as KMP) algorithms work ?

    – ping guo
    Jan 5 at 17:50











  • The issue i see with that is this. consider [0,1,3,2]. In the first sublist, [1,3] would have relative ranks of 1 and 2, whereas in the second sublist, [1,3] would have a relative rank of 0 and 2. Essentially, the result depends on the "window", and so you'd need a re-evaluation to be sure. In such a scenario, whatever result you may cache would end up needing a re-check, losing out on all benefits. (And someone please correct me if im wrong)

    – Paritosh Singh
    Jan 5 at 17:53











  • @ParitoshSingh Correct, however consider subarrays that are of length > 2. For example when I'm going from [0, 1, 3] to [1, 3, 2] (on your list), lets say I've done comparaisons on the first subarray and deduced that it didn't obey. I move on to the second subarray, however I have possibly already done some comparaisons (last two elements become the first two elements of the second subarray). Even though, as you say, knowing that 1 < 3 isn't useful because 2 is in the middle, there are some cases where that overlapping part of the subarrays must be useful - at least, that's what I think.

    – ping guo
    Jan 5 at 17:59











  • Indeed, but because its "some" cases and not all, you'd have to do a recheck for all cases anyways. And since comparisons are a constant time operation, you'd end up on square 1. changing the window changes everything about the comparisons that are favourable and which aren't.

    – Paritosh Singh
    Jan 5 at 18:03














12












12








12


5






I have an array of numbers, for example:



A = [1, 5, 2, 4, 3]


and an array that determines a rank, for example:



B = [0, 2, 1]


My goal is to find all the subarrays of A that "obey" the rank B. If a subarray obeys the rank, that means that the i-th smallest element of the subarray must have B[i] as its (subarray) index. So for a subarray to match, the smallest element within it must be in position 0, the second smallest must be in position 2, and the biggest element must be in position 1.



So for example here, there are two subarrays of A that match the ranking: [1, 5, 2] (because A[0] < A[2] < A[1]) and [2, 4, 3].



So far, I've managed to find a solution that has an O(mn) (m is len(A) and n is len(B)) time complexity, it iterates over all the subarrays of length 3 and verifies if they are correctly ordered:



A = [1, 5, 2, 4, 3]
B = [0, 2, 1]
m = len(A)
n = len(B)
for i in range(m - n + 1):
current_subarray = A[i:i + n]
# we now do n - 1 comparaisons to check whether the subarray is correctly ordered.
for B_index in range(n - 1):
if current_subarray[B[B_index]] > current_subarray[B[B_index + 1]]:
break
else:
print("Subarray found:", current_subarray)


Result:



Subarray found: [1, 5, 2]
Subarray found: [2, 4, 3]


This works, but I was wondering if there was a better optimized algorithm (better than O(mn)) to fulfill this task.










share|improve this question
















I have an array of numbers, for example:



A = [1, 5, 2, 4, 3]


and an array that determines a rank, for example:



B = [0, 2, 1]


My goal is to find all the subarrays of A that "obey" the rank B. If a subarray obeys the rank, that means that the i-th smallest element of the subarray must have B[i] as its (subarray) index. So for a subarray to match, the smallest element within it must be in position 0, the second smallest must be in position 2, and the biggest element must be in position 1.



So for example here, there are two subarrays of A that match the ranking: [1, 5, 2] (because A[0] < A[2] < A[1]) and [2, 4, 3].



So far, I've managed to find a solution that has an O(mn) (m is len(A) and n is len(B)) time complexity, it iterates over all the subarrays of length 3 and verifies if they are correctly ordered:



A = [1, 5, 2, 4, 3]
B = [0, 2, 1]
m = len(A)
n = len(B)
for i in range(m - n + 1):
current_subarray = A[i:i + n]
# we now do n - 1 comparaisons to check whether the subarray is correctly ordered.
for B_index in range(n - 1):
if current_subarray[B[B_index]] > current_subarray[B[B_index + 1]]:
break
else:
print("Subarray found:", current_subarray)


Result:



Subarray found: [1, 5, 2]
Subarray found: [2, 4, 3]


This works, but I was wondering if there was a better optimized algorithm (better than O(mn)) to fulfill this task.







python algorithm ranking






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 5 at 18:12







ping guo

















asked Jan 5 at 17:23









ping guoping guo

615




615








  • 3





    are you looking for something with a lower time complexity specifically? because i am not sure such a thing exists.

    – Paritosh Singh
    Jan 5 at 17:43











  • @ParitoshSingh Yes, that is what I'm looking for. Maybe it doesn't, but I guess that's why I asked :). What makes me doubt though is that I'm working on subarrays, and some of these subarrays overlap - maybe there's a way to reduce the amount of computations by caching some, like how optimised string searching (such as KMP) algorithms work ?

    – ping guo
    Jan 5 at 17:50











  • The issue i see with that is this. consider [0,1,3,2]. In the first sublist, [1,3] would have relative ranks of 1 and 2, whereas in the second sublist, [1,3] would have a relative rank of 0 and 2. Essentially, the result depends on the "window", and so you'd need a re-evaluation to be sure. In such a scenario, whatever result you may cache would end up needing a re-check, losing out on all benefits. (And someone please correct me if im wrong)

    – Paritosh Singh
    Jan 5 at 17:53











  • @ParitoshSingh Correct, however consider subarrays that are of length > 2. For example when I'm going from [0, 1, 3] to [1, 3, 2] (on your list), lets say I've done comparaisons on the first subarray and deduced that it didn't obey. I move on to the second subarray, however I have possibly already done some comparaisons (last two elements become the first two elements of the second subarray). Even though, as you say, knowing that 1 < 3 isn't useful because 2 is in the middle, there are some cases where that overlapping part of the subarrays must be useful - at least, that's what I think.

    – ping guo
    Jan 5 at 17:59











  • Indeed, but because its "some" cases and not all, you'd have to do a recheck for all cases anyways. And since comparisons are a constant time operation, you'd end up on square 1. changing the window changes everything about the comparisons that are favourable and which aren't.

    – Paritosh Singh
    Jan 5 at 18:03














  • 3





    are you looking for something with a lower time complexity specifically? because i am not sure such a thing exists.

    – Paritosh Singh
    Jan 5 at 17:43











  • @ParitoshSingh Yes, that is what I'm looking for. Maybe it doesn't, but I guess that's why I asked :). What makes me doubt though is that I'm working on subarrays, and some of these subarrays overlap - maybe there's a way to reduce the amount of computations by caching some, like how optimised string searching (such as KMP) algorithms work ?

    – ping guo
    Jan 5 at 17:50











  • The issue i see with that is this. consider [0,1,3,2]. In the first sublist, [1,3] would have relative ranks of 1 and 2, whereas in the second sublist, [1,3] would have a relative rank of 0 and 2. Essentially, the result depends on the "window", and so you'd need a re-evaluation to be sure. In such a scenario, whatever result you may cache would end up needing a re-check, losing out on all benefits. (And someone please correct me if im wrong)

    – Paritosh Singh
    Jan 5 at 17:53











  • @ParitoshSingh Correct, however consider subarrays that are of length > 2. For example when I'm going from [0, 1, 3] to [1, 3, 2] (on your list), lets say I've done comparaisons on the first subarray and deduced that it didn't obey. I move on to the second subarray, however I have possibly already done some comparaisons (last two elements become the first two elements of the second subarray). Even though, as you say, knowing that 1 < 3 isn't useful because 2 is in the middle, there are some cases where that overlapping part of the subarrays must be useful - at least, that's what I think.

    – ping guo
    Jan 5 at 17:59











  • Indeed, but because its "some" cases and not all, you'd have to do a recheck for all cases anyways. And since comparisons are a constant time operation, you'd end up on square 1. changing the window changes everything about the comparisons that are favourable and which aren't.

    – Paritosh Singh
    Jan 5 at 18:03








3




3





are you looking for something with a lower time complexity specifically? because i am not sure such a thing exists.

– Paritosh Singh
Jan 5 at 17:43





are you looking for something with a lower time complexity specifically? because i am not sure such a thing exists.

– Paritosh Singh
Jan 5 at 17:43













@ParitoshSingh Yes, that is what I'm looking for. Maybe it doesn't, but I guess that's why I asked :). What makes me doubt though is that I'm working on subarrays, and some of these subarrays overlap - maybe there's a way to reduce the amount of computations by caching some, like how optimised string searching (such as KMP) algorithms work ?

– ping guo
Jan 5 at 17:50





@ParitoshSingh Yes, that is what I'm looking for. Maybe it doesn't, but I guess that's why I asked :). What makes me doubt though is that I'm working on subarrays, and some of these subarrays overlap - maybe there's a way to reduce the amount of computations by caching some, like how optimised string searching (such as KMP) algorithms work ?

– ping guo
Jan 5 at 17:50













The issue i see with that is this. consider [0,1,3,2]. In the first sublist, [1,3] would have relative ranks of 1 and 2, whereas in the second sublist, [1,3] would have a relative rank of 0 and 2. Essentially, the result depends on the "window", and so you'd need a re-evaluation to be sure. In such a scenario, whatever result you may cache would end up needing a re-check, losing out on all benefits. (And someone please correct me if im wrong)

– Paritosh Singh
Jan 5 at 17:53





The issue i see with that is this. consider [0,1,3,2]. In the first sublist, [1,3] would have relative ranks of 1 and 2, whereas in the second sublist, [1,3] would have a relative rank of 0 and 2. Essentially, the result depends on the "window", and so you'd need a re-evaluation to be sure. In such a scenario, whatever result you may cache would end up needing a re-check, losing out on all benefits. (And someone please correct me if im wrong)

– Paritosh Singh
Jan 5 at 17:53













@ParitoshSingh Correct, however consider subarrays that are of length > 2. For example when I'm going from [0, 1, 3] to [1, 3, 2] (on your list), lets say I've done comparaisons on the first subarray and deduced that it didn't obey. I move on to the second subarray, however I have possibly already done some comparaisons (last two elements become the first two elements of the second subarray). Even though, as you say, knowing that 1 < 3 isn't useful because 2 is in the middle, there are some cases where that overlapping part of the subarrays must be useful - at least, that's what I think.

– ping guo
Jan 5 at 17:59





@ParitoshSingh Correct, however consider subarrays that are of length > 2. For example when I'm going from [0, 1, 3] to [1, 3, 2] (on your list), lets say I've done comparaisons on the first subarray and deduced that it didn't obey. I move on to the second subarray, however I have possibly already done some comparaisons (last two elements become the first two elements of the second subarray). Even though, as you say, knowing that 1 < 3 isn't useful because 2 is in the middle, there are some cases where that overlapping part of the subarrays must be useful - at least, that's what I think.

– ping guo
Jan 5 at 17:59













Indeed, but because its "some" cases and not all, you'd have to do a recheck for all cases anyways. And since comparisons are a constant time operation, you'd end up on square 1. changing the window changes everything about the comparisons that are favourable and which aren't.

– Paritosh Singh
Jan 5 at 18:03





Indeed, but because its "some" cases and not all, you'd have to do a recheck for all cases anyways. And since comparisons are a constant time operation, you'd end up on square 1. changing the window changes everything about the comparisons that are favourable and which aren't.

– Paritosh Singh
Jan 5 at 18:03












4 Answers
4






active

oldest

votes


















3














Instead of iterating over B to compare ranks, you could use scipy.stats.rankdata to get the ranks directly:



from scipy.stats import rankdata

A = [1, 5, 2, 4, 3]
B = [0, 2, 1]

m = len(A)
n = len(B)

for i in range(m - n + 1):
current_subarray = A[i:i + n]

ranked_numbers = (rankdata(current_subarray).astype(int) - 1).tolist()
if ranked_numbers == B:
print("Subarray found:", current_subarray)

# Subarray found: [1, 5, 2]
# Subarray found: [2, 4, 3]


Note: rankdata() starts ranks from 1 instead of 0, which is why the above minuses 1 from every element in the numpy array.






share|improve this answer


























  • Thanks, however I'm more interested in the algorithm used, and I've looked at the scipy source - correct me if I'm wrong - but it looks like they're sorting the list - so in the end the complexity isn't better than O(mn) ?

    – ping guo
    Jan 5 at 17:47






  • 1





    @pingguo Yeah it looks like it uses mergesort or quicksort from the source code. In that case the above will probably be slower since it needs to perform O(nlogn) sorting for each ranking. You would have to time both to be sure. I don't think you can do any better than the solution you have.

    – RoadRunner
    Jan 5 at 17:56





















3














Here's a numpy solution based on some linear algebra.



First convert B to a basis:



import numpy as np
A = [1, 5, 2, 4, 3]
B = [0, 2, 1]

b = np.eye(len(B))[B]
print(b)
#array([[1, 0, 0],
# [0, 0, 1],
# [0, 1, 0]])


Now we can go through each subarray of A and project it into this space. If the resulting vector is sorted, that means the subarray followed the ranking.



for i in range(0, (len(A) - len(B))+1):
a = np.array(A[i:i+len(B)])
if (np.diff(a.dot(b))>0).all():
print(a)
#[1 5 2]
#[2 4 3]


I'm not a numpy expert, so there may be a way to optimize this further and eliminate the loop.





Update, here's a cleaner version:



def get_ranked_subarrays(A, B):
m = len(A)
n = len(B)
b = np.eye(n)[B]
a = np.array([A[i:i+n] for i in range(0, m - n+1)])
return a[(np.diff(a.dot(b))>0).all(1)].tolist()

A = [1, 5, 2, 4, 3]
B = [0, 2, 1]
get_ranked_subarrays(A, B)
#[[1, 5, 2], [2, 4, 3]]




Performance Results:



Your solution is very good for small n, but the numpy solution outperforms as the size of A grows large:



Here's your code which I turned into a function that returns the desired subarrays (instead of printing):



def get_ranked_subarrays_op(A, B):
m = len(A)
n = len(B)
out =
for i in range(m - n + 1):
current_subarray = A[i:i + n]
# we now do n - 1 comparisons to check whether the subarray is correctly ordered.
for B_index in range(n - 1):
if current_subarray[B[B_index]] > current_subarray[B[B_index + 1]]:
break
else:
out.append(current_subarray)
return out


Timing results for a large random A:



array_size = 1000000
A = np.random.randint(low=0, high=10, size=array_size)
B = [0, 2, 1]

%%timeit
get_ranked_subarrays_op(A, B)
#1 loop, best of 3: 1.57 s per loop

%%timeit
get_ranked_subarrays(A, B)
#1 loop, best of 3: 890 ms per loop


However, if m also grows large, your solution is slightly better because of the short circuiting (the likelihood of a short circuit grows large for large m). Here is the timing results of we let m be 100.



array_size = 1000000
basis_size = 100
A = np.random.randint(low=0, high=10, size=array_size)
B = range(basis_size)
np.random.shuffle(B)

%%timeit
get_ranked_subarrays_op(A, B)
#1 loop, best of 3: 1.9 s per loop

%%timeit
get_ranked_subarrays(A, B)
#1 loop, best of 3: 2.79 s per loop





share|improve this answer


























  • Thanks for this answer - I'd never have thought of doing it that way ! However, although this improves the speed, it looks to me like its still O(nm) because dot product is O(n) :(. And yes on top of that the large m lead to a smaller time thanks to the break.

    – ping guo
    Jan 5 at 22:06



















2














You can loop over A and check the resulting subarrays:



A, B = [1, 5, 2, 4, 3], [0, 2, 1]
def results(a, b):
_l = len(b)
for c in range(len(a)-_l+1):
_r = a[c:c+_l]
new_r = [_r[i] for i in b]
if all(new_r[i] < new_r[i+1] for i in range(len(new_r)-1)):
yield _r

print(list(results(A, B)))


Output:



[[1, 5, 2], [2, 4, 3]]





share|improve this answer





















  • 6





    What's with all the underscores you've been using in your variables?

    – coldspeed
    Jan 5 at 17:30











  • @coldspeed Merely a personal style

    – Ajax1234
    Jan 5 at 17:30











  • Thanks for the prompt answer ! However maybe I wasn't clear enough in my question, I only need the subarrays of A that obey the ranking. Your solution gives me all the possible subarrays that obey the ranking, but most of these aren't subarrays of A. Doesn't that make this method longer (as I have to remove the subarrays that are not of A) ?

    – ping guo
    Jan 5 at 17:40













  • @pingguo Based on the results of the timings, it appears that you really can't get any better than what you already have for a solution.

    – Ajax1234
    Jan 5 at 18:57











  • @pault I added new timings, however, if you feel they are inaccurate, I will remove them.

    – Ajax1234
    Jan 5 at 18:58



















1














At the very least, we could could rule out candidate windows much more quickly by considering the (binary) relation of neighbouring elements, which could allow for parallel examination. Call less than 0 and greater than 1. Then:



A = [1,  5,  2,  4,  3]
A'= [0, 1, 0, 1]

B'= [0, 1]
B = [0, 2, 1]


Clearly any candidate must match the relation sequence. Also note that the only type of section of B that could admit overlap is an ascending or descending sequence (means we can possibly skip ahead a priori if a match is found).






share|improve this answer

























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54054370%2ffind-all-subarrays-of-fixed-length-with-a-given-ranking%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    4 Answers
    4






    active

    oldest

    votes








    4 Answers
    4






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    3














    Instead of iterating over B to compare ranks, you could use scipy.stats.rankdata to get the ranks directly:



    from scipy.stats import rankdata

    A = [1, 5, 2, 4, 3]
    B = [0, 2, 1]

    m = len(A)
    n = len(B)

    for i in range(m - n + 1):
    current_subarray = A[i:i + n]

    ranked_numbers = (rankdata(current_subarray).astype(int) - 1).tolist()
    if ranked_numbers == B:
    print("Subarray found:", current_subarray)

    # Subarray found: [1, 5, 2]
    # Subarray found: [2, 4, 3]


    Note: rankdata() starts ranks from 1 instead of 0, which is why the above minuses 1 from every element in the numpy array.






    share|improve this answer


























    • Thanks, however I'm more interested in the algorithm used, and I've looked at the scipy source - correct me if I'm wrong - but it looks like they're sorting the list - so in the end the complexity isn't better than O(mn) ?

      – ping guo
      Jan 5 at 17:47






    • 1





      @pingguo Yeah it looks like it uses mergesort or quicksort from the source code. In that case the above will probably be slower since it needs to perform O(nlogn) sorting for each ranking. You would have to time both to be sure. I don't think you can do any better than the solution you have.

      – RoadRunner
      Jan 5 at 17:56


















    3














    Instead of iterating over B to compare ranks, you could use scipy.stats.rankdata to get the ranks directly:



    from scipy.stats import rankdata

    A = [1, 5, 2, 4, 3]
    B = [0, 2, 1]

    m = len(A)
    n = len(B)

    for i in range(m - n + 1):
    current_subarray = A[i:i + n]

    ranked_numbers = (rankdata(current_subarray).astype(int) - 1).tolist()
    if ranked_numbers == B:
    print("Subarray found:", current_subarray)

    # Subarray found: [1, 5, 2]
    # Subarray found: [2, 4, 3]


    Note: rankdata() starts ranks from 1 instead of 0, which is why the above minuses 1 from every element in the numpy array.






    share|improve this answer


























    • Thanks, however I'm more interested in the algorithm used, and I've looked at the scipy source - correct me if I'm wrong - but it looks like they're sorting the list - so in the end the complexity isn't better than O(mn) ?

      – ping guo
      Jan 5 at 17:47






    • 1





      @pingguo Yeah it looks like it uses mergesort or quicksort from the source code. In that case the above will probably be slower since it needs to perform O(nlogn) sorting for each ranking. You would have to time both to be sure. I don't think you can do any better than the solution you have.

      – RoadRunner
      Jan 5 at 17:56
















    3












    3








    3







    Instead of iterating over B to compare ranks, you could use scipy.stats.rankdata to get the ranks directly:



    from scipy.stats import rankdata

    A = [1, 5, 2, 4, 3]
    B = [0, 2, 1]

    m = len(A)
    n = len(B)

    for i in range(m - n + 1):
    current_subarray = A[i:i + n]

    ranked_numbers = (rankdata(current_subarray).astype(int) - 1).tolist()
    if ranked_numbers == B:
    print("Subarray found:", current_subarray)

    # Subarray found: [1, 5, 2]
    # Subarray found: [2, 4, 3]


    Note: rankdata() starts ranks from 1 instead of 0, which is why the above minuses 1 from every element in the numpy array.






    share|improve this answer















    Instead of iterating over B to compare ranks, you could use scipy.stats.rankdata to get the ranks directly:



    from scipy.stats import rankdata

    A = [1, 5, 2, 4, 3]
    B = [0, 2, 1]

    m = len(A)
    n = len(B)

    for i in range(m - n + 1):
    current_subarray = A[i:i + n]

    ranked_numbers = (rankdata(current_subarray).astype(int) - 1).tolist()
    if ranked_numbers == B:
    print("Subarray found:", current_subarray)

    # Subarray found: [1, 5, 2]
    # Subarray found: [2, 4, 3]


    Note: rankdata() starts ranks from 1 instead of 0, which is why the above minuses 1 from every element in the numpy array.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Jan 5 at 17:46

























    answered Jan 5 at 17:41









    RoadRunnerRoadRunner

    11.2k31340




    11.2k31340













    • Thanks, however I'm more interested in the algorithm used, and I've looked at the scipy source - correct me if I'm wrong - but it looks like they're sorting the list - so in the end the complexity isn't better than O(mn) ?

      – ping guo
      Jan 5 at 17:47






    • 1





      @pingguo Yeah it looks like it uses mergesort or quicksort from the source code. In that case the above will probably be slower since it needs to perform O(nlogn) sorting for each ranking. You would have to time both to be sure. I don't think you can do any better than the solution you have.

      – RoadRunner
      Jan 5 at 17:56





















    • Thanks, however I'm more interested in the algorithm used, and I've looked at the scipy source - correct me if I'm wrong - but it looks like they're sorting the list - so in the end the complexity isn't better than O(mn) ?

      – ping guo
      Jan 5 at 17:47






    • 1





      @pingguo Yeah it looks like it uses mergesort or quicksort from the source code. In that case the above will probably be slower since it needs to perform O(nlogn) sorting for each ranking. You would have to time both to be sure. I don't think you can do any better than the solution you have.

      – RoadRunner
      Jan 5 at 17:56



















    Thanks, however I'm more interested in the algorithm used, and I've looked at the scipy source - correct me if I'm wrong - but it looks like they're sorting the list - so in the end the complexity isn't better than O(mn) ?

    – ping guo
    Jan 5 at 17:47





    Thanks, however I'm more interested in the algorithm used, and I've looked at the scipy source - correct me if I'm wrong - but it looks like they're sorting the list - so in the end the complexity isn't better than O(mn) ?

    – ping guo
    Jan 5 at 17:47




    1




    1





    @pingguo Yeah it looks like it uses mergesort or quicksort from the source code. In that case the above will probably be slower since it needs to perform O(nlogn) sorting for each ranking. You would have to time both to be sure. I don't think you can do any better than the solution you have.

    – RoadRunner
    Jan 5 at 17:56







    @pingguo Yeah it looks like it uses mergesort or quicksort from the source code. In that case the above will probably be slower since it needs to perform O(nlogn) sorting for each ranking. You would have to time both to be sure. I don't think you can do any better than the solution you have.

    – RoadRunner
    Jan 5 at 17:56















    3














    Here's a numpy solution based on some linear algebra.



    First convert B to a basis:



    import numpy as np
    A = [1, 5, 2, 4, 3]
    B = [0, 2, 1]

    b = np.eye(len(B))[B]
    print(b)
    #array([[1, 0, 0],
    # [0, 0, 1],
    # [0, 1, 0]])


    Now we can go through each subarray of A and project it into this space. If the resulting vector is sorted, that means the subarray followed the ranking.



    for i in range(0, (len(A) - len(B))+1):
    a = np.array(A[i:i+len(B)])
    if (np.diff(a.dot(b))>0).all():
    print(a)
    #[1 5 2]
    #[2 4 3]


    I'm not a numpy expert, so there may be a way to optimize this further and eliminate the loop.





    Update, here's a cleaner version:



    def get_ranked_subarrays(A, B):
    m = len(A)
    n = len(B)
    b = np.eye(n)[B]
    a = np.array([A[i:i+n] for i in range(0, m - n+1)])
    return a[(np.diff(a.dot(b))>0).all(1)].tolist()

    A = [1, 5, 2, 4, 3]
    B = [0, 2, 1]
    get_ranked_subarrays(A, B)
    #[[1, 5, 2], [2, 4, 3]]




    Performance Results:



    Your solution is very good for small n, but the numpy solution outperforms as the size of A grows large:



    Here's your code which I turned into a function that returns the desired subarrays (instead of printing):



    def get_ranked_subarrays_op(A, B):
    m = len(A)
    n = len(B)
    out =
    for i in range(m - n + 1):
    current_subarray = A[i:i + n]
    # we now do n - 1 comparisons to check whether the subarray is correctly ordered.
    for B_index in range(n - 1):
    if current_subarray[B[B_index]] > current_subarray[B[B_index + 1]]:
    break
    else:
    out.append(current_subarray)
    return out


    Timing results for a large random A:



    array_size = 1000000
    A = np.random.randint(low=0, high=10, size=array_size)
    B = [0, 2, 1]

    %%timeit
    get_ranked_subarrays_op(A, B)
    #1 loop, best of 3: 1.57 s per loop

    %%timeit
    get_ranked_subarrays(A, B)
    #1 loop, best of 3: 890 ms per loop


    However, if m also grows large, your solution is slightly better because of the short circuiting (the likelihood of a short circuit grows large for large m). Here is the timing results of we let m be 100.



    array_size = 1000000
    basis_size = 100
    A = np.random.randint(low=0, high=10, size=array_size)
    B = range(basis_size)
    np.random.shuffle(B)

    %%timeit
    get_ranked_subarrays_op(A, B)
    #1 loop, best of 3: 1.9 s per loop

    %%timeit
    get_ranked_subarrays(A, B)
    #1 loop, best of 3: 2.79 s per loop





    share|improve this answer


























    • Thanks for this answer - I'd never have thought of doing it that way ! However, although this improves the speed, it looks to me like its still O(nm) because dot product is O(n) :(. And yes on top of that the large m lead to a smaller time thanks to the break.

      – ping guo
      Jan 5 at 22:06
















    3














    Here's a numpy solution based on some linear algebra.



    First convert B to a basis:



    import numpy as np
    A = [1, 5, 2, 4, 3]
    B = [0, 2, 1]

    b = np.eye(len(B))[B]
    print(b)
    #array([[1, 0, 0],
    # [0, 0, 1],
    # [0, 1, 0]])


    Now we can go through each subarray of A and project it into this space. If the resulting vector is sorted, that means the subarray followed the ranking.



    for i in range(0, (len(A) - len(B))+1):
    a = np.array(A[i:i+len(B)])
    if (np.diff(a.dot(b))>0).all():
    print(a)
    #[1 5 2]
    #[2 4 3]


    I'm not a numpy expert, so there may be a way to optimize this further and eliminate the loop.





    Update, here's a cleaner version:



    def get_ranked_subarrays(A, B):
    m = len(A)
    n = len(B)
    b = np.eye(n)[B]
    a = np.array([A[i:i+n] for i in range(0, m - n+1)])
    return a[(np.diff(a.dot(b))>0).all(1)].tolist()

    A = [1, 5, 2, 4, 3]
    B = [0, 2, 1]
    get_ranked_subarrays(A, B)
    #[[1, 5, 2], [2, 4, 3]]




    Performance Results:



    Your solution is very good for small n, but the numpy solution outperforms as the size of A grows large:



    Here's your code which I turned into a function that returns the desired subarrays (instead of printing):



    def get_ranked_subarrays_op(A, B):
    m = len(A)
    n = len(B)
    out =
    for i in range(m - n + 1):
    current_subarray = A[i:i + n]
    # we now do n - 1 comparisons to check whether the subarray is correctly ordered.
    for B_index in range(n - 1):
    if current_subarray[B[B_index]] > current_subarray[B[B_index + 1]]:
    break
    else:
    out.append(current_subarray)
    return out


    Timing results for a large random A:



    array_size = 1000000
    A = np.random.randint(low=0, high=10, size=array_size)
    B = [0, 2, 1]

    %%timeit
    get_ranked_subarrays_op(A, B)
    #1 loop, best of 3: 1.57 s per loop

    %%timeit
    get_ranked_subarrays(A, B)
    #1 loop, best of 3: 890 ms per loop


    However, if m also grows large, your solution is slightly better because of the short circuiting (the likelihood of a short circuit grows large for large m). Here is the timing results of we let m be 100.



    array_size = 1000000
    basis_size = 100
    A = np.random.randint(low=0, high=10, size=array_size)
    B = range(basis_size)
    np.random.shuffle(B)

    %%timeit
    get_ranked_subarrays_op(A, B)
    #1 loop, best of 3: 1.9 s per loop

    %%timeit
    get_ranked_subarrays(A, B)
    #1 loop, best of 3: 2.79 s per loop





    share|improve this answer


























    • Thanks for this answer - I'd never have thought of doing it that way ! However, although this improves the speed, it looks to me like its still O(nm) because dot product is O(n) :(. And yes on top of that the large m lead to a smaller time thanks to the break.

      – ping guo
      Jan 5 at 22:06














    3












    3








    3







    Here's a numpy solution based on some linear algebra.



    First convert B to a basis:



    import numpy as np
    A = [1, 5, 2, 4, 3]
    B = [0, 2, 1]

    b = np.eye(len(B))[B]
    print(b)
    #array([[1, 0, 0],
    # [0, 0, 1],
    # [0, 1, 0]])


    Now we can go through each subarray of A and project it into this space. If the resulting vector is sorted, that means the subarray followed the ranking.



    for i in range(0, (len(A) - len(B))+1):
    a = np.array(A[i:i+len(B)])
    if (np.diff(a.dot(b))>0).all():
    print(a)
    #[1 5 2]
    #[2 4 3]


    I'm not a numpy expert, so there may be a way to optimize this further and eliminate the loop.





    Update, here's a cleaner version:



    def get_ranked_subarrays(A, B):
    m = len(A)
    n = len(B)
    b = np.eye(n)[B]
    a = np.array([A[i:i+n] for i in range(0, m - n+1)])
    return a[(np.diff(a.dot(b))>0).all(1)].tolist()

    A = [1, 5, 2, 4, 3]
    B = [0, 2, 1]
    get_ranked_subarrays(A, B)
    #[[1, 5, 2], [2, 4, 3]]




    Performance Results:



    Your solution is very good for small n, but the numpy solution outperforms as the size of A grows large:



    Here's your code which I turned into a function that returns the desired subarrays (instead of printing):



    def get_ranked_subarrays_op(A, B):
    m = len(A)
    n = len(B)
    out =
    for i in range(m - n + 1):
    current_subarray = A[i:i + n]
    # we now do n - 1 comparisons to check whether the subarray is correctly ordered.
    for B_index in range(n - 1):
    if current_subarray[B[B_index]] > current_subarray[B[B_index + 1]]:
    break
    else:
    out.append(current_subarray)
    return out


    Timing results for a large random A:



    array_size = 1000000
    A = np.random.randint(low=0, high=10, size=array_size)
    B = [0, 2, 1]

    %%timeit
    get_ranked_subarrays_op(A, B)
    #1 loop, best of 3: 1.57 s per loop

    %%timeit
    get_ranked_subarrays(A, B)
    #1 loop, best of 3: 890 ms per loop


    However, if m also grows large, your solution is slightly better because of the short circuiting (the likelihood of a short circuit grows large for large m). Here is the timing results of we let m be 100.



    array_size = 1000000
    basis_size = 100
    A = np.random.randint(low=0, high=10, size=array_size)
    B = range(basis_size)
    np.random.shuffle(B)

    %%timeit
    get_ranked_subarrays_op(A, B)
    #1 loop, best of 3: 1.9 s per loop

    %%timeit
    get_ranked_subarrays(A, B)
    #1 loop, best of 3: 2.79 s per loop





    share|improve this answer















    Here's a numpy solution based on some linear algebra.



    First convert B to a basis:



    import numpy as np
    A = [1, 5, 2, 4, 3]
    B = [0, 2, 1]

    b = np.eye(len(B))[B]
    print(b)
    #array([[1, 0, 0],
    # [0, 0, 1],
    # [0, 1, 0]])


    Now we can go through each subarray of A and project it into this space. If the resulting vector is sorted, that means the subarray followed the ranking.



    for i in range(0, (len(A) - len(B))+1):
    a = np.array(A[i:i+len(B)])
    if (np.diff(a.dot(b))>0).all():
    print(a)
    #[1 5 2]
    #[2 4 3]


    I'm not a numpy expert, so there may be a way to optimize this further and eliminate the loop.





    Update, here's a cleaner version:



    def get_ranked_subarrays(A, B):
    m = len(A)
    n = len(B)
    b = np.eye(n)[B]
    a = np.array([A[i:i+n] for i in range(0, m - n+1)])
    return a[(np.diff(a.dot(b))>0).all(1)].tolist()

    A = [1, 5, 2, 4, 3]
    B = [0, 2, 1]
    get_ranked_subarrays(A, B)
    #[[1, 5, 2], [2, 4, 3]]




    Performance Results:



    Your solution is very good for small n, but the numpy solution outperforms as the size of A grows large:



    Here's your code which I turned into a function that returns the desired subarrays (instead of printing):



    def get_ranked_subarrays_op(A, B):
    m = len(A)
    n = len(B)
    out =
    for i in range(m - n + 1):
    current_subarray = A[i:i + n]
    # we now do n - 1 comparisons to check whether the subarray is correctly ordered.
    for B_index in range(n - 1):
    if current_subarray[B[B_index]] > current_subarray[B[B_index + 1]]:
    break
    else:
    out.append(current_subarray)
    return out


    Timing results for a large random A:



    array_size = 1000000
    A = np.random.randint(low=0, high=10, size=array_size)
    B = [0, 2, 1]

    %%timeit
    get_ranked_subarrays_op(A, B)
    #1 loop, best of 3: 1.57 s per loop

    %%timeit
    get_ranked_subarrays(A, B)
    #1 loop, best of 3: 890 ms per loop


    However, if m also grows large, your solution is slightly better because of the short circuiting (the likelihood of a short circuit grows large for large m). Here is the timing results of we let m be 100.



    array_size = 1000000
    basis_size = 100
    A = np.random.randint(low=0, high=10, size=array_size)
    B = range(basis_size)
    np.random.shuffle(B)

    %%timeit
    get_ranked_subarrays_op(A, B)
    #1 loop, best of 3: 1.9 s per loop

    %%timeit
    get_ranked_subarrays(A, B)
    #1 loop, best of 3: 2.79 s per loop






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Jan 5 at 19:55

























    answered Jan 5 at 18:27









    paultpault

    15.4k32449




    15.4k32449













    • Thanks for this answer - I'd never have thought of doing it that way ! However, although this improves the speed, it looks to me like its still O(nm) because dot product is O(n) :(. And yes on top of that the large m lead to a smaller time thanks to the break.

      – ping guo
      Jan 5 at 22:06



















    • Thanks for this answer - I'd never have thought of doing it that way ! However, although this improves the speed, it looks to me like its still O(nm) because dot product is O(n) :(. And yes on top of that the large m lead to a smaller time thanks to the break.

      – ping guo
      Jan 5 at 22:06

















    Thanks for this answer - I'd never have thought of doing it that way ! However, although this improves the speed, it looks to me like its still O(nm) because dot product is O(n) :(. And yes on top of that the large m lead to a smaller time thanks to the break.

    – ping guo
    Jan 5 at 22:06





    Thanks for this answer - I'd never have thought of doing it that way ! However, although this improves the speed, it looks to me like its still O(nm) because dot product is O(n) :(. And yes on top of that the large m lead to a smaller time thanks to the break.

    – ping guo
    Jan 5 at 22:06











    2














    You can loop over A and check the resulting subarrays:



    A, B = [1, 5, 2, 4, 3], [0, 2, 1]
    def results(a, b):
    _l = len(b)
    for c in range(len(a)-_l+1):
    _r = a[c:c+_l]
    new_r = [_r[i] for i in b]
    if all(new_r[i] < new_r[i+1] for i in range(len(new_r)-1)):
    yield _r

    print(list(results(A, B)))


    Output:



    [[1, 5, 2], [2, 4, 3]]





    share|improve this answer





















    • 6





      What's with all the underscores you've been using in your variables?

      – coldspeed
      Jan 5 at 17:30











    • @coldspeed Merely a personal style

      – Ajax1234
      Jan 5 at 17:30











    • Thanks for the prompt answer ! However maybe I wasn't clear enough in my question, I only need the subarrays of A that obey the ranking. Your solution gives me all the possible subarrays that obey the ranking, but most of these aren't subarrays of A. Doesn't that make this method longer (as I have to remove the subarrays that are not of A) ?

      – ping guo
      Jan 5 at 17:40













    • @pingguo Based on the results of the timings, it appears that you really can't get any better than what you already have for a solution.

      – Ajax1234
      Jan 5 at 18:57











    • @pault I added new timings, however, if you feel they are inaccurate, I will remove them.

      – Ajax1234
      Jan 5 at 18:58
















    2














    You can loop over A and check the resulting subarrays:



    A, B = [1, 5, 2, 4, 3], [0, 2, 1]
    def results(a, b):
    _l = len(b)
    for c in range(len(a)-_l+1):
    _r = a[c:c+_l]
    new_r = [_r[i] for i in b]
    if all(new_r[i] < new_r[i+1] for i in range(len(new_r)-1)):
    yield _r

    print(list(results(A, B)))


    Output:



    [[1, 5, 2], [2, 4, 3]]





    share|improve this answer





















    • 6





      What's with all the underscores you've been using in your variables?

      – coldspeed
      Jan 5 at 17:30











    • @coldspeed Merely a personal style

      – Ajax1234
      Jan 5 at 17:30











    • Thanks for the prompt answer ! However maybe I wasn't clear enough in my question, I only need the subarrays of A that obey the ranking. Your solution gives me all the possible subarrays that obey the ranking, but most of these aren't subarrays of A. Doesn't that make this method longer (as I have to remove the subarrays that are not of A) ?

      – ping guo
      Jan 5 at 17:40













    • @pingguo Based on the results of the timings, it appears that you really can't get any better than what you already have for a solution.

      – Ajax1234
      Jan 5 at 18:57











    • @pault I added new timings, however, if you feel they are inaccurate, I will remove them.

      – Ajax1234
      Jan 5 at 18:58














    2












    2








    2







    You can loop over A and check the resulting subarrays:



    A, B = [1, 5, 2, 4, 3], [0, 2, 1]
    def results(a, b):
    _l = len(b)
    for c in range(len(a)-_l+1):
    _r = a[c:c+_l]
    new_r = [_r[i] for i in b]
    if all(new_r[i] < new_r[i+1] for i in range(len(new_r)-1)):
    yield _r

    print(list(results(A, B)))


    Output:



    [[1, 5, 2], [2, 4, 3]]





    share|improve this answer















    You can loop over A and check the resulting subarrays:



    A, B = [1, 5, 2, 4, 3], [0, 2, 1]
    def results(a, b):
    _l = len(b)
    for c in range(len(a)-_l+1):
    _r = a[c:c+_l]
    new_r = [_r[i] for i in b]
    if all(new_r[i] < new_r[i+1] for i in range(len(new_r)-1)):
    yield _r

    print(list(results(A, B)))


    Output:



    [[1, 5, 2], [2, 4, 3]]






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Jan 5 at 19:39

























    answered Jan 5 at 17:29









    Ajax1234Ajax1234

    41.3k42853




    41.3k42853








    • 6





      What's with all the underscores you've been using in your variables?

      – coldspeed
      Jan 5 at 17:30











    • @coldspeed Merely a personal style

      – Ajax1234
      Jan 5 at 17:30











    • Thanks for the prompt answer ! However maybe I wasn't clear enough in my question, I only need the subarrays of A that obey the ranking. Your solution gives me all the possible subarrays that obey the ranking, but most of these aren't subarrays of A. Doesn't that make this method longer (as I have to remove the subarrays that are not of A) ?

      – ping guo
      Jan 5 at 17:40













    • @pingguo Based on the results of the timings, it appears that you really can't get any better than what you already have for a solution.

      – Ajax1234
      Jan 5 at 18:57











    • @pault I added new timings, however, if you feel they are inaccurate, I will remove them.

      – Ajax1234
      Jan 5 at 18:58














    • 6





      What's with all the underscores you've been using in your variables?

      – coldspeed
      Jan 5 at 17:30











    • @coldspeed Merely a personal style

      – Ajax1234
      Jan 5 at 17:30











    • Thanks for the prompt answer ! However maybe I wasn't clear enough in my question, I only need the subarrays of A that obey the ranking. Your solution gives me all the possible subarrays that obey the ranking, but most of these aren't subarrays of A. Doesn't that make this method longer (as I have to remove the subarrays that are not of A) ?

      – ping guo
      Jan 5 at 17:40













    • @pingguo Based on the results of the timings, it appears that you really can't get any better than what you already have for a solution.

      – Ajax1234
      Jan 5 at 18:57











    • @pault I added new timings, however, if you feel they are inaccurate, I will remove them.

      – Ajax1234
      Jan 5 at 18:58








    6




    6





    What's with all the underscores you've been using in your variables?

    – coldspeed
    Jan 5 at 17:30





    What's with all the underscores you've been using in your variables?

    – coldspeed
    Jan 5 at 17:30













    @coldspeed Merely a personal style

    – Ajax1234
    Jan 5 at 17:30





    @coldspeed Merely a personal style

    – Ajax1234
    Jan 5 at 17:30













    Thanks for the prompt answer ! However maybe I wasn't clear enough in my question, I only need the subarrays of A that obey the ranking. Your solution gives me all the possible subarrays that obey the ranking, but most of these aren't subarrays of A. Doesn't that make this method longer (as I have to remove the subarrays that are not of A) ?

    – ping guo
    Jan 5 at 17:40







    Thanks for the prompt answer ! However maybe I wasn't clear enough in my question, I only need the subarrays of A that obey the ranking. Your solution gives me all the possible subarrays that obey the ranking, but most of these aren't subarrays of A. Doesn't that make this method longer (as I have to remove the subarrays that are not of A) ?

    – ping guo
    Jan 5 at 17:40















    @pingguo Based on the results of the timings, it appears that you really can't get any better than what you already have for a solution.

    – Ajax1234
    Jan 5 at 18:57





    @pingguo Based on the results of the timings, it appears that you really can't get any better than what you already have for a solution.

    – Ajax1234
    Jan 5 at 18:57













    @pault I added new timings, however, if you feel they are inaccurate, I will remove them.

    – Ajax1234
    Jan 5 at 18:58





    @pault I added new timings, however, if you feel they are inaccurate, I will remove them.

    – Ajax1234
    Jan 5 at 18:58











    1














    At the very least, we could could rule out candidate windows much more quickly by considering the (binary) relation of neighbouring elements, which could allow for parallel examination. Call less than 0 and greater than 1. Then:



    A = [1,  5,  2,  4,  3]
    A'= [0, 1, 0, 1]

    B'= [0, 1]
    B = [0, 2, 1]


    Clearly any candidate must match the relation sequence. Also note that the only type of section of B that could admit overlap is an ascending or descending sequence (means we can possibly skip ahead a priori if a match is found).






    share|improve this answer






























      1














      At the very least, we could could rule out candidate windows much more quickly by considering the (binary) relation of neighbouring elements, which could allow for parallel examination. Call less than 0 and greater than 1. Then:



      A = [1,  5,  2,  4,  3]
      A'= [0, 1, 0, 1]

      B'= [0, 1]
      B = [0, 2, 1]


      Clearly any candidate must match the relation sequence. Also note that the only type of section of B that could admit overlap is an ascending or descending sequence (means we can possibly skip ahead a priori if a match is found).






      share|improve this answer




























        1












        1








        1







        At the very least, we could could rule out candidate windows much more quickly by considering the (binary) relation of neighbouring elements, which could allow for parallel examination. Call less than 0 and greater than 1. Then:



        A = [1,  5,  2,  4,  3]
        A'= [0, 1, 0, 1]

        B'= [0, 1]
        B = [0, 2, 1]


        Clearly any candidate must match the relation sequence. Also note that the only type of section of B that could admit overlap is an ascending or descending sequence (means we can possibly skip ahead a priori if a match is found).






        share|improve this answer















        At the very least, we could could rule out candidate windows much more quickly by considering the (binary) relation of neighbouring elements, which could allow for parallel examination. Call less than 0 and greater than 1. Then:



        A = [1,  5,  2,  4,  3]
        A'= [0, 1, 0, 1]

        B'= [0, 1]
        B = [0, 2, 1]


        Clearly any candidate must match the relation sequence. Also note that the only type of section of B that could admit overlap is an ascending or descending sequence (means we can possibly skip ahead a priori if a match is found).







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Jan 6 at 15:46

























        answered Jan 6 at 15:37









        גלעד ברקןגלעד ברקן

        12.6k21541




        12.6k21541






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54054370%2ffind-all-subarrays-of-fixed-length-with-a-given-ranking%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Biblatex bibliography style without URLs when DOI exists (in Overleaf with Zotero bibliography)

            ComboBox Display Member on multiple fields

            Is it possible to collect Nectar points via Trainline?