473,462 Members | 1,243 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

How to identify which numbers in a list are within each others' range

Hi,

I have a list of numbers each with a +/- margin of error. I need to
identify which ones overlab each other.

For example:
55 +/- 3
20 +/- 2
17 +/- 4
60 +/- 3

#base, max, min
list = [
(55, 58, 52),
(20, 22, 18),
(17, 21, 13),
(60, 63, 57),
]

In this example the range of list[0] overlaps the range of list[3] AND
list[1] overlaps list[2]

What is the best way to in python to identify the list items that
overlap and the items that don't overlap with any other.

Thanks!
Erik
Jan 31 '08 #1
10 2239
erikcw <er***********@gmail.comwrites:
What is the best way to in python to identify the list items that
overlap and the items that don't overlap with any other.
This sounds like a homework problem, so the first thing I'll suggest
is that you figure out exactly what it means for two of those
intervals to overlap. That should let you write a simple program that
gets the right answer, but that can run slowly if the number of lists
gets large. The next thing to do after that is figure out how to
speed it up, if necessary. But do the first part first.
Jan 31 '08 #2
On Jan 31, 4:12*pm, erikcw <erikwickst...@gmail.comwrote:
Hi,

I have a list of numbers each with a +/- margin of error. *I need to
identify which ones overlab each other.

For example:
55 +/- 3
20 +/- 2
17 +/- 4
60 +/- 3

#base, max, min
list = [
(55, 58, 52),
(20, 22, 18),
(17, 21, 13),
(60, 63, 57),
]

In this example the range of list[0] overlaps the range of list[3] AND
list[1] overlaps list[2]

What is the best way to in python to identify the list items that
overlap and the items that don't overlap with any other.
This is definitely the best way:

=======================
lst = [
(55, 58, 52),
(20, 22, 18),
(17, 21, 13),
(60, 63, 57),
]

from itertools import chain

def overlaps(lst):
bounds = chain(*(((x[1],i), (x[2], i)) for i,x in enumerate(lst)))
inside = {}
for x, i in sorted(bounds):
if inside.pop(i, None) is None:
for j, y in inside.iteritems():
if y != x: yield i, j
inside[i] = x

==============================
>>list(overlaps(lst))
[(1, 2), (3, 0)]

--
Arnaud

Jan 31 '08 #3
On Jan 31, 8:12 am, erikcw <erikwickst...@gmail.comwrote:
Hi,

I have a list of numbers each with a +/- margin of error. I need to
identify which ones overlab each other.

For example:
55 +/- 3
20 +/- 2
17 +/- 4
60 +/- 3

#base, max, min
list = [
(55, 58, 52),
(20, 22, 18),
(17, 21, 13),
(60, 63, 57),
]

In this example the range of list[0] overlaps the range of list[3] AND
list[1] overlaps list[2]

What is the best way to in python to identify the list items that
overlap and the items that don't overlap with any other.

One way would be to use sets and check for intersection:

for idx, s in enumerate(mysets):
for next_idx, next_s in enumerate(mysets[idx+1:]):
if s.intersection(next_s):
print "mylist[%d] and mylist[%d] intersect" % (
idx, idx + next_idx + 1 )
--
Hope this helps,
Steve


Jan 31 '08 #4
Arnaud Delobelle wrote:
>
This is definitely the best way:

from itertools import chain

def overlaps(lst):
bounds = chain(*(((x[1],i), (x[2], i)) for i,x in enumerate(lst)))
inside = {}
for x, i in sorted(bounds):
if inside.pop(i, None) is None:
for j, y in inside.iteritems():
if y != x: yield i, j
inside[i] = x
Why not just

def overlaps(lst):
for i,x in enumerate(lst):
for j,y in enumerate(lst):
if i != j and x[1] y[2] x[2]:
yield i,j

It's still n^2. Or am I missing something?

Cheers,
thomas
Feb 1 '08 #5
On Jan 31, 8:12 am, erikcw <erikwickst...@gmail.comwrote:
Hi,

I have a list of numbers each with a +/- margin of error. I need to
identify which ones overlab each other.

For example:
55 +/- 3
20 +/- 2
17 +/- 4
60 +/- 3

#base, max, min
list = [
(55, 58, 52),
(20, 22, 18),
(17, 21, 13),
(60, 63, 57),
]

In this example the range of list[0] overlaps the range of list[3] AND
list[1] overlaps list[2]

What is the best way to in python to identify the list items that
overlap and the items that don't overlap with any other.
Note you just need the left-end and right-end of each interval. Mean
is redundant information. Once you sort the interval, you can just go
from left to right, retaining only necessary information.

Below method is O(n log n) + O (nk) where k is the average overlaps
per interval.
On most average case, first term dominates and hence its O(n log n);
worst case is ofcourse O(n^2) (a simple case is all n intervals
overlapping with each other)
def strip_sort (a, b):
if a[0] < b[0]:
return -1
if a[0] b[0]:
return 1
# To allow overlaps on a point, return L first then R
# If overlap on a point must not be allowed, return 1 below
if a[0] == 'L': return -1
return 0

def overlaps (strips_given):
# split each interval into two items. basically decorate with 'L'
for left-end of the interval, 'R' for right end of the interval
s2 = [((s[0], 'L', i) , (s[1], 'R', i)) for i,s in
enumerate(strips_given)]
strips = []
for s in s2: # flatten out the tuples
strips.append(s[0])
strips.append(s[1])

clique = set() # set of nodes where each overlap with everyone
else in the set
edges = [] # we are constructing a graph on N nodes where edge
i,j implies i and j overlap
# below is O(N log N) where is N is number of intervals
strips.sort(cmp=strip_sort)
for s in strips:
node = s[2]
if s[1] == 'L':
clique.add(node)
if s[1] == 'R':
# below is O(k) where k is clique size (overlaps per
interval)
new_edges = [(node, i) for i in clique if i != node]
edges += new_edges
clique.remove(node)
return edges

def main():
lst = [(52, 58), (18, 22), (13, 21), (57, 63)]
print overlaps(lst)

Output:
[(2, 1), (0, 3)]

Karthik
>
Thanks!
Erik
Feb 1 '08 #6
On Feb 1, 8:17*pm, Karthik Gurusamy <kar1...@gmail.comwrote:
[...]
def strip_sort (a, b):
* * if a[0] < b[0]:
* * * * return -1
* * if a[0] b[0]:
* * * * return 1
* * if a[0] == 'L': return -1
* * return 0

def overlaps (strips_given):
* * s2 = [((s[0], 'L', i) , (s[1], 'R', i)) for i,s in
enumerate(strips_given)]
* * strips = []
* * for s in s2:
* * * * strips.append(s[0])
* * * * strips.append(s[1])
* * clique = set()
* * edges = []
* * strips.sort(cmp=strip_sort)
* * for s in strips:
* * * * node = s[2]
* * * * if s[1] == 'L':
* * * * * * clique.add(node)
* * * * if s[1] == 'R':
* * * * * * new_edges = [(node, i) for i in clique if i !=node]
* * * * * * edges += new_edges
* * * * * * clique.remove(node)
* * return edges
Interesting. This is a long version of the algorithm I posted
earlier.

--
Arnaud

Feb 1 '08 #7
On Feb 1, 8:34*pm, "Neil Cerutti" <mr.ceru...@gmail.comwrote:
On Feb 1, 2008 3:16 PM, Arnaud Delobelle <arno...@googlemail.comwrote:
The total number of iterations is 1+2+...+n = n(n+1)/2 (when n is the
number of intervals) so this has quadratic behaviour regardless of
input.[...]
But it breaks out of the inner loop as soon as ranges on the right
cannot overlap. The loop is O(N) for all input if I define N as
"number of overlaps", a pretty reasonable definition--it's madness to
expect to report N overlaps with less than N complexity.

Unless I'm making a silly mistake. Again.
No you're not mistaken, I am. I didn't see the 'else: break' bit
which of course makes all the difference. Sorry...

On the point of complexity though, it is only O(N) is N dominates
nlogn (n being the length of input).

--
Arnaud

Feb 1 '08 #8
Arnaud Delobelle wrote:
(...)
>
from itertools import chain

def overlaps(lst):
bounds = chain(*(((x[1],i), (x[2], i)) for i,x in enumerate(lst)))
imho, this is a uselessly painful equivalent of

bounds = ((x[k],i) for i,x in enumerate(lst) for k in (1,2))

Cheers, BB
Feb 8 '08 #9
Boris Borcic wrote:
Arnaud Delobelle wrote:
(...)
>>
from itertools import chain

def overlaps(lst):
bounds = chain(*(((x[1],i), (x[2], i)) for i,x in enumerate(lst)))

imho, this is a uselessly painful equivalent of

bounds = ((x[k],i) for i,x in enumerate(lst) for k in (1,2))
even more readable :

bounds = ((bound(x),i) for bound in (min,max) for i,x in enumerate(lst))
Feb 8 '08 #10
On Feb 8, 1:48*pm, Boris Borcic <bbor...@gmail.comwrote:
Arnaud Delobelle wrote:

(...)
from itertools import chain
def overlaps(lst):
* * bounds = chain(*(((x[1],i), (x[2], i)) for i,x in enumerate(lst)))

imho, this is a uselessly painful equivalent of

* * * *bounds = ((x[k],i) for i,x in enumerate(lst) for k in (1,2))

Cheers, BB
I did mention that it was awkward (but at the time I just wrote what
came to mind) - thank you for providing a much improved version.

It doesn't deter from the fact that the algorithm is of optimal
complexity (modulo sorting of the list).

--
Arnaud
Feb 8 '08 #11

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
by: Leif K-Brooks | last post by:
I'm a newbie at C++, but no stranger to other programming languages. I'm working on my first C++ program (besides "hello world" and the like), and it needs to generate a (pseudo-)random number...
5
by: BlackFireNova | last post by:
I need to write a report in which one part shows a count of how many total records fall within the working days (Monday - Friday) inside of a (prompted) given date range, in a particular...
3
by: Stewart Allen | last post by:
Hi there I'm trying to find part serial numbers between 2 numbers. The user selects a part number from a combo box and then enters a range of serial numbers into 2 text boxes and the resulting...
28
by: Elfour | last post by:
In c++ what is the code to make teh program randomly select a number?
2
by: shihaoran | last post by:
I really need help with one my program; it is about arraylist; I do not get it. Can someone please help me with it? Here's the instruction: 1. Your instructor will provide you with a text...
13
by: Peter Oliphant | last post by:
I would like to be able to create a random number generator that produces evenly distributed random numbers up to given number. For example, I would like to pick a random number less than 100000,...
26
by: bilgekhan | last post by:
What is the correct method for generating 2 independent random numbers? They will be compared whether they are equal. What about this method: srand(time(0)); int r1 = rand(); srand(rand());...
3
by: djcamo | last post by:
Hi, I have a situation where I have a collection that holds numbers. Mostly they are concurrent eg. 125801-125899 but sometimes they are not eg. 125801-125899, 195301-399. Is there any way to...
33
by: Andreas Prilop | last post by:
To get bold numbers in ordered lists, one can write ol { font-weight: bold } ol span { font-weight: normal } <ol> <li><span>......</span></li> <li><span>......</span></li> </ol>
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.