Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to find if a point is within a set of intervals?

I am looking for the fastest way to decide whether or not a point on a line is within a subset of this line. I am given an integer Point, and I also have a "list" of either:

  1. Points, represented by an integer ( 3, 10, 1000, etc)
  2. Intervals, that I represent by 2 integers ( 2:10 is all integers from 2 to 10 inluded, 50:60, etc)

In this example, if the value of my point is 5, then I return true because it is included in an interval, same for 55. If my point is equal to 1000, I also return true because it matches the list of points.

I am looking for a fast way (quicker than linear) to check for this condition, WITHOUT having to instanciate as many integer as there are possible points (ie, for a 1:1000 interval I don't want to instanciate 1000 integers). Can this be done in a logarithmic time?

Thanks

edit : you can consider that any time taken to pre-process the list of data is equal to 0, because once my initial intervals are processed I need to apply this test to 10k points

like image 712
lezebulon Avatar asked Apr 12 '12 19:04

lezebulon


People also ask

How to Check if interval overlaps?

1) Sort all intervals in increasing order of start time. This step takes O(nLogn) time. 2) In the sorted array, if start time of an interval is less than end of previous interval, then there is an overlap.

How do you find non overlapping intervals?

Traverse all the set of intervals and check whether the consecutive intervals overlaps or not. If the intervals(say interval a & interval b) doesn't overlap then the set of pairs form by [a. end, b. start] is the non-overlapping interval.

How do you find overlapping time intervals in Python?

The basic idea is 1) first take input_start to test_start (if both of them are not equal and input_start is min) 2) always take test_start and test_end 3) take test_end to input_end if test_end is less than input end (and end_input and end_test are not equal).


3 Answers

Hm, maybe you can use an interval or a segment tree:

  • http://en.wikipedia.org/wiki/Segment_tree
  • http://en.wikipedia.org/wiki/Interval_tree
like image 84
Samuel Gosselin Avatar answered Nov 16 '22 02:11

Samuel Gosselin


If you have the integers ranges sorted and the ranges are non-overlapping, you can perform binary search to find the correct range in logarithmic time.

Are there any constraint on the range? Based on that you can probably come up with hashing function to search in constant time. But this depends on how your constraints are.

like image 42
cgcoder Avatar answered Nov 16 '22 02:11

cgcoder


After reflexion, I think that the following code should work in logarithmic time, excluding the time needed to build the map:

enum pointType {
    point,
    open,
    close
};
std::map<long int, pointType> mapPoints;

mapPoints.insert(std::pair<long int, pointType>(3, point));

//create the 5:10 interval:
mapPoints.insert(std::pair<long int, pointType>(5, open));
mapPoints.insert(std::pair<long int, pointType>(10, close));

int number = 4;
bool inside = false;
std::map<long int, pointType>::iterator it1 = mapPoints.lower_bound(number);

if(it1->first == number || it1->second == close) {
    inside = true;
}

I think this should work as long as the map is filled properly with non-overlapping intervals

like image 38
lezebulon Avatar answered Nov 16 '22 02:11

lezebulon