|
But you're not doing a binary search on each item. You're doing one sort and one binary search.
Think of it this way... Say the sort and the next operation were each O(n)... Obviously they wouldn't be, but as an example. Then you're doing an O(n) followed by an O(n), or 2 * O(n). But in Big O, we eliminate constants, so it simplifies to just O(n)...
If the two operations are of different complexity, we take the larger one... If it was O(n log(n)) followed by O(n), we'd say the Big O was O(n log n).
|
|
|
|
|
Ian Shlasko wrote: You're doing one sort and one binary search.
But you are not doing that, you are doing the binary search n times looking for a pair that add up to the constant X.
Dave.
|
|
|
|
|
Sorry, mixed it up a bit, but I'm still right about the complexity.
A binary search is O(log n) ... And we'd be doing that n times... Hence, O(n log(n)) for all of the searches.
But this is still done AFTER the sort, not inside it, so it adds to the sort instead of multiplying with it.
|
|
|
|
|
You had it right the first time -- Only one binary search is done. It's done to find the upper bound of number pairs that could possibly add up to x.
|
|
|
|
|
I agree with your algo, however I would rephrase it in a more symmetric way, making the O(n) part more clear:
1. Sort the array in ascending order
2. let int i=0 and int j=n-1
3. if i>=j then search is over
4. calculate sum=array[i]+array[j]
5. if sum<x, increment i and goto (3)
6. if sum>x, decrement j and goto (3)
7. since sum==x, solution found (either stop; or increment i, decrement j and goto 3)
(1) is O(n ln(n))
(2)-(7) is O(n) as i and j move towards each other in steps of 1
hence overall O(n ln(n))
Luc Pattyn
I only read code that is properly indented, and rendered in a non-proportional font; hint: use PRE tags in forum messages
|
|
|
|
|
in the name of god<br />
hello and thanks for your answers.<br />
it is the code i wrote in c++:<br />
<br />
int main(){<br />
cin<<x;<br />
mergeSort(Arbegin,Arend);
int i=0;<br />
while(i<j){<br />
int sum=A[i]+A[j];<br />
if(x < sum){<br />
i++;<br />
}<br />
if(x < sum){<br />
j--;<br />
}<br />
if(sum==x){<br />
a=i;<br />
b=j;<br />
break;<br />
}<br />
}<br />
}<br />
valhamdolelah.
modified on Friday, October 30, 2009 8:20 AM
|
|
|
|
|
Lets say I'm standing on a matrix and
1. There are obstacles where I cant stand
2. There is a goal in some x,y
3. I only know the content of the 8 adjacent points
4. I need to return one move based on the one i'm standing each time.
Any ideas on the algorithm for returning my move each time?
I'm more interested in the correctiness rather than the efectiveness
|
|
|
|
|
Follow an expanding spiral from your starting position. When you encounter am obstacle, circle around it in the same direction (clockwise/counter~) as your spiral.
|
|
|
|
|
Nice idea, hadnt thought about spirals.., thanks.
Though "circle around an obstacle" its not that simple because there might be several obstacles one each to the other, making a kind of wall.. for example
########
#
goal # me
#####
#
#
|
|
|
|
|
Treat several obstacles as one big obstacle, and make a bigger circle.
One way to do this is with a direction vector, the pair of x,y offsets in the direction of your spiral. When you hit an obstacle, you rotate this direction vector 90 degrees (45 degrees if diagonal moves are permitted). When you find a free cell around the obstacle, you rotate back in the other direction.
Intuitively, it's like going through a maze, always keeping your right hand on the right wall, as you circle around obstacles.
|
|
|
|
|
"several obstacles as one obstacle" makes me consider using Disjoint Sets..
|
|
|
|
|
You may be making it more complex than it needs to be. If you were feeling your way through a maze in the dark with your right hand on the right wall, you'd just keep going straight until you hit an obstacle. Then since you couldn't continue in the same direction, you'd rotate your direction vector 45 degrees to the left. If that direction was free you'd advance, else you'd rotate again.
|
|
|
|
|
For this particular problem, you may also want to store the coordinates of the spiral you've already traversed, so that you take up where you left off once you've circled around obstacles.
|
|
|
|
|
Any ideas for a "contour follow" algorithm?
Like "contour follow with left hand on wall" and "countour follow with right hand on wall"
|
|
|
|
|
A potentials approach and you make a walk through the troughs.. again Probably more work then you really need. (and a lot of floating point calculations)
|
|
|
|
|
In general, rotate your direction vector right at each step, and when you hit an obstacle rotate left.
With your right hand on the wall, you try to rotate right (into the wall) at each step. Since you can't go into the wall, you then rotate left, and your resulting path is a straight line along the wall.
If you come to a corner, when you rotate right you turn right, which takes you around the corner.
If you come to an obstacle, rotating right doesn't work, so you rotate left (aiming straight ahead). Since there's an obstacle, going straight doesn't work, so you rotate left again. If that path is clear, you proceed in that direction (left from your original direction). If that path is also blocked (a dead end), you rotate left again (facing backwards) and advance back the way you came.
|
|
|
|
|
I replied you, look my reply :P
|
|
|
|
|
P.S. After you've found the goal, you can optimize the path as follows:
If a coordinate appears twice in your path, delete all the moves from after the first time the coordinate is reached, up to and including the last time that same coordinate is reached.
This eliminates any backtracking that was done.
|
|
|
|
|
Sorry, I havent had the time to read your replies.. but I swear I'll read it tomorrow.
Meanwhile, the ones interested in this problem, I found an algorithm called "bug-1" and "bug-2", search for it.. its just what I needed.
I've been trying to found other algorithms but in the papers they just talk about the bug algorithm and after that they jump to other problems such as the one knowing the entire map or knowing more than the eight adjacent points.
|
|
|
|
|
Excuse me, but you initially stated that you only knew the 8 cells adjacent to the current cell and that there was "some x,y goal location" and that you are at some starting location. The Bug algorithm assumes that you also know the exact location of the goal so you can construct a line between the start position and the goal and use that as a direction to try to follow.
My later posts work from your initially stated "known" parameters. It seems that for that to work, you need some additional parameters, i.e., the bounds of the grid. The bounds are not necessary if you use the bug algorithm, but the assumption is that the obstacles are finite and do not extend forever (or extend to some edge where you cannot proceed to go around them). More pieces of required information are: Wwhat identifies the starting location?, What identifies the goal location?, What identifies the obstacle locations?.
Which of the two above problem are you really trying to solve? What are all of the known parameters?
Dave.
|
|
|
|
|
"The Bug algorithm assumes that you also know the exact location of the goal"
You are wrong.
Its way I've always said:
What you know is: the eight adjacent points and the DIRECTION of the goal, that is: N, NE, NW, S, etc. That information is refreshed after each move.
|
|
|
|
|
You never mentioned that you knew the "DIRECTION" of the goal, please re-read your first post. You want the method to "refresh" the direction and the adjacent locations after each move. This is impossible for the method to do if you do not know the current location and the goal location so that you can calculate a new direction. The goal location need not be "exactly" known if its "relative" position is known, but its position relative to the current location is necessary to make any prediction about the "refreshed" direction upon return from the call. You still need the matrix dimensions to determine if you can go around the end of a barrier, or at least that all barriers are finite and contained inside the matrix so that it is safe to go around the end of the barrier.
Dave.
|
|
|
|
|
My apolagizes.. Its true, I didnt mention I knew the direction... im so lame.
Though Im still right that the bug algorithms dont need the exact location of the goal but just the direction of it.
Imagine the problem as implementing a method
Direction Move ( adjacents[], Direction direction )
Which is called from the outside, so you dont have to worry about refreshing and stuff. Direction could be an enum
So... recalling... Do you know more algorithms like BUG? That apply for the exact same situation?
|
|
|
|
|
As I mentioned, you wanted to have someone supply you with an algorithm. Which algorithm, the algorithm to do the refresh, or the algorithm to decide the move?
The algorithm to do the refresh NEEDS to know at least the location of the goal relative to the current location in order to supply a refreshed direction. It also NEEDS the definition of the identifiers used to specify the start location, the goal location, and barrier locations so it can return the array of adjacents. It also NEEDS the definition of the ordering of the returned array - is it N, NE, E, SE, S, SW, W, NW, or is it a two dimensional array (adjacents[3][3]) where the middle element is never filled in? You wanted algorithm correctness as well, and this implies that it NEEDS to know the matrix bounds. It is not correct to allow the caller to step outside of the array and cause a memory access fault or array bound fault. It NEEDS to know what the current location is so it can check in the matrix to return whatever lies in the adjacent 8 locations. What happens when the caller reaches the edge of the
The move algorithm is trivial. It NEEDS to know the current location and the direction desired. It just refreshes the current location x and y indices. Since the caller does not know its current location (your specification says it only knows the the adjacents and the goal direction), it is assumed that the current location is globally known (the current location x and y values).
You can combine the refresh and move algorithms into one by supplying the location of the direction value in the call instead of the just the value itself. The value of the direction at entry would indicate which direction you wanted to go from the current location, and on return could contain the refreshed direction of the goal. This does cause a bit of a problem at the beginning because the caller does not know the initial conditions (what the adjacent locations are) so it cannot supply any meaningful direction for the initial move which would return the initial adjacents and direction to the goal. Maybe it would be appropriate to have a special value (-1) supplied for the first move as an indicator that this is an initial move.
The caller would also NEED to know the definition of the identifiers used to specify the goal location and barrier locations so that it can determine if a barrier is blocking the way in some direction, or if the goal is in one of the adjacent cells (the returned direction should contain the direction to the goal, but the actual).
Note: The Bug algorithm seems to assume that the current location is known to the caller as well as the adjacents and direction to the goal because it "remembers" the location of the barrier encounter and if it sees this location again, it back tracks.
My solution I gave in the three posts below also requires that the caller know the matrix bounds, the identifiers, and the start, goal and barrier locations.
Dave.
|
|
|
|
|
So how would it be the algorithm for surrounding an obstacle?
Lets say that every node of the matrix have an obstacleId,
and that if two obstacles are adjacent.. then they have the same obstacleId (and by induction, a block of obstacles whould have the same obstacleId too)
So, I can treat an obstacle block as being the same obstacle.
How do I follow it with the right (or left) hand on it all the time?
(dont worry about stopping, thats easy)
I think its the hardest part on the algorithm.
I think I would need to introduce a "robot orientation" helper variable maybe
|
|
|
|
|