computing cost in optimum way in high dimensional space - visual-c++-6

how to find contours of equal function value on a high dimensional space in optimal way provided function values is monotonically non-decreasing along all dimensions.

As your function is monotonic in both X and Y this becomes straight forward to find the contour. Lets find the solutions of f(x,y)-K = 0.
Step 1. Calculate the function at the four corners. This will tell you which edges the contour intersects.
Step 2. Pick one of the edges with a solution. Use a subdivision algorithm to find a solution on this edge. First find the mid-point and calculate the value there. This splits the edge in two, exactly one will have sign change, pick that edge and repeat. This process will give the unique solution on the edge.
Step 3. Starting at the end point use a zero following technique. We start with a square with a solution on one edge, and known values at two corners. Evaluate the function at the other two corners. Compare signs and find the other edge with a solution on it. Get the adjacent square and repeat.
This will follow the curve until we reach the other solution on the boundary. Being monotonic means there are no tricky cases to deal with.
More on step 3: We have a rectangle with two know points
+ ____ -
| |
| |
? ____ ?
there are three possibilities
+ ____ -
| |
| | take the right hand side
+ ____ +
+ ____ -
| | take the bottom side
| |
+ ____ -
+ ____ -
| |
| | take the left hand side
- ____ -
One option can't occur as the function is monotonic
+ ____ -
| | impossible
| |
- ____ +

If you evaluate the function at four corners of a square, the four values will tell you if the square is crossed by the iso-K curve.
Now subdivide the square in four sub-squares and check the function values at the new corners (this costs 5 function evaluations). Thanks to the monotonicity property, you are ensured that at least one of the squares can be discarded.
If you continue this process recursively, the number of points is reduced by at least 25% on every stage, and 32 stages will suffice to reduce from 10000 to 1 (0.75^32 = 0.000100...), requiring in total no more than 32 x 5 = 160 function evaluations.

Related

Finding all the rectangles within a given rectangle that do not intersect with an arbitrary shape

I need to find an algorithm to find the least number of overlapping rectangles within a given rectangle R that do not intersect with the union of a set of other rectangles contained within R. These inner rectangles can overlap. Here's a terrible ASCII drawing of an example R:
A-----------------B-------------------------+
| |
| |
| |
| |
| +--------+ |
| |........| |
| |........| |
C +---D........| |
| |.........+--+ |
| |.........| |
| ++........+------+ |
| |...............| |
G +---H...........| |
| |...........| |
| |...........| |
| |...........| |
| +-----------+ |
| |
| |
| |
E-------------I----F------------------------+
The rectangles here would include (A, D), (A, I), (G, F). This seems like a problem for which the solution is well-understood, but for which I simply lack the vocabulary. Any answers, pointers, RTFMs cheerfully and gratefully accepted. Thanks!
EDIT: As per #Paul's observation below, what I'm trying to do is find a set of rectangles that cover the space in R without covering any of polygon comprised of the union of the inner set. If that makes sense.
I believe this is one possible way to solve.
I will refer to the overlapping rectangles as "white", and the ones in the solution as "black"
First of all, let's assume we have a data structure suitable for search on intersection. One possible data structure is an Interval Tree, using points on one of the coordinates as intervals (for example, if a rectangle is defined by two points (x0,y0) and (x1, y1), use (x0, y1) as interval. The link also explain how to extend to higher dimensions (in your case you need 2).
I won't go in the detail of an implementation of such data structure, but let's assume we have one called Rectangles, with the following API defined:
void add(Rectangle r)
void remove(Rectangle r)
Rectangle[] getIntersecting(Rectangle r)
Rectangle[] getAdjacent(Rectangle r)
Ok, now create two instances of Rectangles called black and white. Initialize white with all the white rectangles. Initializie black with the R rectangle (the whole domain).
For each rectangle rw in white get the array arr of intersecting rectangles from black.
For each rectangle rb in black, determine the result of rw-rb. This is a set set of 0, 1, 2, 3 or 4 rectangles, depending on how the two rectangles intersect.
remove rw from white, and add the content of set to it. This may require merging rectangles from set with rectangle already in white, if such rectangles together form a larger rectangle (they're adjacent sharing one side)
remove rb from black
repeat from 1 until there are no more rectangles in black
Using some basic math, we could say the solution to your problem would be the decomposition of the rectilinear polygon R \ union(rs), where union(rs) represents the polygon inside R. Calculating R \ union(rs) can be done using the Greiner-Hormann-algorithm. Note that this step will result in a polygon with holes and - only if the inner polygon contains holes - multiple other polygons. The decomposition is described here (this is only an approximation, but i wasn't able to find a precise algorithm so far).

Find a line connecting two faces of a cubic volume

Imagine a volumetric cube of N³ resolution that is filled with occluding voxels. The cube could be completely filled, or contain curvy "tunnels", or walls - or just a few stray voxels; We now pick any two of the six faces of the bounding cube and attempt to find a line that connects those two faces without hitting any voxel inside it. If such a line exists, the faces can see each other, otherwise, they're completely occluded.
My question is: does an O(n) (or better) algorithm exist to quickly discern if such a line can be drawn? The exact parameters of the line do not matter.
I'm somewhat unclear on the exact parameters of being a straight line in this (continuous? discrete?) space, but I wonder if you're looking for a dynamic programming solution?
Perhaps lets restrict to 2-D left to right case to build the algorithm and then generalize:
Loop over first column of the array,
for each opaque square, mark that it is impossible to build a ray which reaches this square
for each non opaque square, mark that it is possible to reach this square -AND- track ranges of slopes can reach this square. You may restrict the set of slopes in this initialization by the set of slopes that could potentially reach the opposite end of your voxel volume.
Then loop over the next column
Each square is potentially able to be reached by any square in the previous column, but only if the range of slopes that can reach the square in the previous column intersects the range of slopes necessary to reach the current square from the square in the previous column.
You thus set the valid range of slopes in the current square to the union of the intersections of the valid ranges from previous squares with valid ranges to current square.
You continue looping over columns until you hit the far end, and any reachable entries on the far end will report the ranges of slopes of vectors that allow hitting that square.
The speed of the algorithm is heavily dependent on how quickly you can union and intersect ranges of slopes (or in the 3D case, arbitrary ranges of UV coordinates). In 2D continuous space this operation can be done quickly by sorting, in a 3D discrete space, you can use a set of possible vector slopes in X,Y dependent on dimensions of your voxel space. In a 3D continuous space, some type of quadtree would probably approach what can be achieved by sorting in 2D.
The algorithm loops once over each cell in your input (Do you consider this O(n) or O(n^3)?), and takes time that will be bounded by the union of intersections call times the number of elements in your space (Worst case O(n^2) in discrete case I believe, but will shrink dramatically in the initialization step if the opposite end of the volume is far away, and may shrink quickly in the case of many opaque cells and proper data structures)
As far as I can tell, processing order of slices of the volume doesn't actually matter, so if you know that certain spots are very opaque (by sum of opaque cells or whatever), you might use a heuristic to reorder intersection operations.
A Voxel cube would look like a Rubik Cube, voxel structure is a 3D matrix of blocks, so to draw a line from one side to the other, we need to draw within each related block the line that connects to the next, together the lines form one continuous line through the cube.
The following algorithm works fine if implemented well, since you're going to work on local coordinates within the cube, any transformations of the cube itself will be applied automatically by the 3D engine when it translate it into world coordinates.
Time Complexity
MATRIX.MAX_Z * (
Time(MATRIX.GET_VOXEL(x,y,z))
+ Time(VOXEL.DRAW-LINE(0,0,0, 0,0,VOXEL_DEPTH))
)
Algorithm
FUNCTION DRAW (INTEGER X, INTEGER Y)
INTEGER VOXEL_X = X / MATRIX.VOXEL_WIDTH
INTEGER VOXEL_Y = Y / MATRIX.VOXEL_HEIGHT
FOR i = 0 .. (MATRIX.MAX_Z-1)
VOXEL V = MATRIX.GET_VOXEL(VOXEL_X, VOXEL_Y, i)
INTEGER X_0 = X % MATRIX.VOXEL_WIDTH
INTEGER Y_0 = Y % MATRIX.VOXEL_HEIGHT
INTEGER Z_0 = 0
INTEGER X_1 = X_0
INTEGER Y_1 = Y_0
INTEGER Z_1 = (MATRIX.VOXEL_DEPTH-1)
V.DRAW-LINE(X_0,Y_0,Z_0, X_1,Y_1,Z_1)
END-FOR
END-FUNCTION
So one easy way to do this test is to render the view (orthographic) from the source to the target cube at arbitrary resolution. If there is any background pixel left, there exists a line between the two rectangles. So the complexity comes down to two things:
The resolution at which you render
How fast can you render an orthographic, binary view
Now for that binary rendering the only thing you need to know is covered/not covered. That comes down to two octrees, one for minimum and one for maximum. The minimum tree tracks "is there any open child node (or)" the maximum tracks "is there any closed child node (and)". Building those trees is n log(n), but the query is only log(n).
For the target resolution, m, it should be only log(m). Even if you go up to m=2^23 for float size.
Breaking the problem down to two dimensions, it is clear that some voxel configurations are obviously impenetrable from, say, left to right:
+-+-+-+ +-+-+-+-+-+
| |#| | |#| | | | |
+-+-+-+ +-+-+-+-+-+
| |#| | |#| | |#| |
+-+-+-+ +-+-+-+-+-+
| |#| | |#| | |#| |
+-+-+-+ +-+-+-+-+-+
|#| | |#| |
+-+-+-+-+-+
| | | |#| |
+-+-+-+-+-+
... but this might not be impenetrable, depending on how you handle your corners:
+-+-+-+-+-+
|#| | | |/|
+-+-+-+-+-+
|#| | |/| |
+-+-+-+-+-+
|#| |/|#| |
+-+-+-+-+-+
|#|/| |#| |
+-+-+-+-+-+
|/| | |#| |
+-+-+-+-+-+
... and this is definitely possible:
+-+-+-+-+-+
|#| | | | |
+-+-+-+-+-+
|#| | | | |
+-+-+-+-+-+
|#| | | | |
+-+-+-+-+-+
| | | |#| |
+-+-+-+-+-+
| | | |#| |
+-+-+-+-+-+
Now, if you can think of any trick that can tell the upper 2D-cubes from the lower one, that might eliminate at least some impossible pixel/voxel configurations -- but I'm afraid you need to test every pixel on your target side for light coming through from your source side from any angle, which sounds awfully like an n-squared problem (2D), or n^4 in 3D.
In 2D, I'd start at the top of the left side and check if the line connecting my voxel centre to the top right hits an occluding pixel: if not, we're done; if it does, you advance your angle so that the ray passes the lower left corner of the occlusion and continue checking until you either find a passage or get to the end of the right side.
Continue with every pixel on your source side, until you are done -- one way or the other.
But that's brute-force, and I'd be interested to see a more elegant solution, perhaps by G. Bach ...?

find the outline of adjacent polygons

I'm searching for a way to find the outline of two adjacent polygons.
The polygons are defined by a list of points ordered by occurrence in the polygon. In my use case, there are no overlapping polygons, there are no gaps between the polygons, and there are no polygons with "holes".
I want to calculate the outline of the two polygons without any "holes".
These pictures show the expected results.
I know that there are a lot of libraries for clipping polygons, but for most of them the performance is not very good because they work for any kind of polygon (with holes, overlapping polygons etc.). In my use case the algorithm has to work in real time for a lot of polygons (>20.000). How can I most efficiently calculate the outline?
Given
no overlapping polygons, there are no gaps between the polygons and there are no polygons with "holes"
the following algorithm should do the trick.
Discard duplicate line segments.
Compute the natural combinatorial embedding of what's left as a doubly connected edge list. Each segment gives rise to two nodes (half edges, reverses of each other, with one endpoint of the segment being the head (respectively, the tail) and the other being the tail (respectively, the head)), and each half edge links to the next half edge with the same head in counterclockwise order.
Extract the faces. A face in the combinatorial embedding is a minimal, nonempty set of half edges such that, for each half edge e, the reverse of the next half edge from e is in the set. The set of faces is a partition of the half edges. See the ASCII art diagram below.
U----V----W
| | |
| | |
Z----Y----X
The infinite face is {U->Z, Z->Y, Y->X, X->W, W->V, V->U}. The next half edge from W->V is U->V. The reverse of the next half edge from W->V is V->U. The other faces are {U->V, V->Y, Y->Z, Z->U} and {V->W, W->X, X->Y, Y->V}.
Retain only the infinite faces by summing signed counterclockwise angles and testing the sign. A finite face like {U->V, V->Y, Y->Z, Z->U} has negative sum
/_UVY - 180 + /_VYZ - 180 + /_YZU - 180 + /_ZUV - 180
= 4 * (90 - 180) = -360.
The infinite face has positive sum
/_UZY - 180 + /_ZYX - 180 + /_YXW - 180 + /_XWV - 180 + /_WVU - 180 + /_VUZ - 180
= 4 * (270 - 180) + 2 * (180 - 180) = 360.

Find the Closest intersection point in plan

I was asked following question in interview recently:
Let suppose you have, following grid on Cartesian coordinate system ( Quadrant I).
o - x - x - x - o
| | | | |
x - x - x - o - x
| | | | |
x - o - o - x - x
where, o => person at intersection and x => no person at intersection
class Point {
int x;
int y;
boolean hasPerson;
}
Point findNearestPointWhereAllPeopleCanMeet(Point[] people) {
}
Implement a routine where given a list of people location (points), find a location(point) such that is closest point to all given point.
How would you solve this problem ?
1) Approach is k-d tree, but do you know any other solution ?
If the problem calls for minimizing the Manhattan distance (that is, people only walk parallel to the axes), then the problem is then pretty trivial. First, selecting the x coordinate and the y coordinate are independent problems.
Then, for the each coordinate, simply find the median value of the position of the people along that axis. For many configurations of people, there can be more than one point that minimizes the sum of the walking distances of all people. (Just consider 2 people separated by more than 2 blocks in x and at the same y coordinate; any intersection in between will require the same total walking by the two people.)
If the problem calls for minimizing the Euclidean distance, then the goal is to find the 2-variable L1 median. This is a standard problem, but it is far from trivial. (See here, for instance.) There is a unique answer. Given that this was an interview question, I suspect that this does not apply.
Before going to study k-d trees these are some thoughts that came to my mind:
Iterate every point of your matrix, graph, or whatever it is
Assign to each point (x,y) a value representing the MAX_distance from the Point to any of the people. (See a clarification example below)
Take any of the points that have the lowest MAX_distance
E.G. Given Point(0,0):
For (1,0) the distance is: 1
For (2,0) the distance is: 2
For (0,2) the distance is: 2
For (3,1) the distance is: 4
For (4,2) the distance is: 6
The MAX_distance for (0,0) is 6. Given your input the lowest MAX_distance should be 3 and there are many Points with that value like (2,1) for instance.
There should be ways to make this algorithm more efficient.. Maybe with k-d trees :p or with other tweaks like checking the total number of people, their relative location/distance, the MAX_distance value at any iteration, etc..
This will probably give you more of an approximate than the correct answer.
But maybe you can try some sort of clustering (see medical image processing)
What if you project all points onto the Y axis:
3*
4*
3*
Then project onto the X axis:
2* 2* 2* 2* 2*
Legend: 3* means 3 people at this coordinate on the axis
Now find the median also using the weights (weight #location = how many people at that location on axis)
If you find the median for both axis then you could take the meeting points as (medianX, medianY).
You could get the correct closest point if when you calculate median on one axis, you also make sure to minimize distance by calculating the median of the other axis. This latter case is harder.

Positioning squares on a circle with minimum diameter

Given n squares with edge length l, how can I determine the minimum radius r of the circle so that I can distribute all squares evenly along the perimeter of the circle without them overlapping? (Constraint: the first square will always be positioned at 12 o'clock.)
Followup question: how can I place n identical rectangles with height h and width w?
(source: n3rd.org)
There may be a mathematically clever way to do this, but I wouldn't know.
I think it's complicated a bit by the fact that the geometry is different for every different number of squares; for 4 it's a rhombus, for 5 it's a pentagon and so on.
What I'd do is place those squares on a 1 unit circle (much too small, I know, bear with me) distributed equally on it. That's easy enough, just subtend (divide) your 360 degrees by the number of squares. Then just test all your squares for overlap against their neighbors; if they overlap, increase the radius.
You can make this procedure less stupid than it sounds by using an intelligent algorithm to approach the right size. I'm thinking of something like Newton's algorithm: Given two successive guesses, of which one is too small and one is too big, your next guess needs to be the average of those two.
You can iterate down to any precision you like. Stop whenever the distance between guesses is smaller than some arbitrary small margin of error.
EDIT I have a better solution:
I was thinking about what to tell you if you asked "how will I know if squares overlap?" This gave me an idea on how to calculate the circle size exactly, in one step:
Place your squares on a much-too-small circle. You know how: Calculate the points on the circle where your 360/n angles intersect it, and put the center of the square there. Actually, you don't need to place squares yet, the next steps only require midpoints.
To calculate the minimum distance of a square to its neighbor: Calculate the difference in X and the difference in Y of the midpoints, and take the minimum of those. The X's and Y's are actually just cosines and sines on the circle.
You'll want the minimum of any square against its neighbor (clockwise, say). So you need to work your way around the circle to find the very smallest one.
The minimum (X or Y) distance between the squares needs to become 1.0 . So just take the reciprocal of the minimum distance and multiply the circle's size by that. Presto, your circle is the right size.
EDIT
Without losing generality, I think it's possible to nail my solution down a bit so it's close to coding. Here's a refinement:
Assume the squares have size 1, i.e. each side has a length of 1 unit. In the end, your boxes will surely be larger than 1 pixel but it's just a matter of scaling.
Get rid of the corner cases:
if (n < 2) throw new IllegalArgumentException();
if (n == 2) return 0.5; // 2 squares will fit exactly on a circle of radius 0.5
Start with a circle size r of 0.5, which will surely be too small for any number of squares > 2.
r = 0.5;
dmin = 1.0; // start assuming minimum distance is fine
a = 2 * PI / n;
for (p1 = 0.0; p1 <= PI; p1+=a) { // starting with angle 0, try all points till halfway around
// (yeah, we're starting east, not north. doesn't matter)
p2 = p1 + a; // next point on the circle
dx = abs(r * cos(p2) - r * cos(p1))
dy = abs(r * sin(p2) - r * sin(p1))
dmin = min(dmin, dx, dy)
}
r = r / dmin;
EDIT
I turned this into real Java code and got something quite similar to this to run. Code and results here: http://ideone.com/r9aiu
I created graphical output using GnuPlot. I was able to create simple diagrams of boxes arranged in a circle by cut-and-pasting the point sets from the output into a data file and then running
plot '5.dat' with boxxyerrorbars
The .5's in the file serve to size the boxes... lazy but working solution. The .5 is applied to both sides of the center, so the boxes end up being exactly 1.0 in size.
Alas, my algorithm doesn't work. It makes the radii far too large, thus placing the boxes much further apart than necessary. Even scaling down by a factor of 2 (could have been a mistake to use 0.5 in some places) didn't help.
Sorry, I give up. Maybe my approach can be salvaged, but it doesn't work the way I had though it would. :(
EDIT
I hate giving up. I was about to leave my PC when I thought of a way to salvage my algorithm:
The algorithm was adjusting the smaller of the X or Y distances to be at least 1. It's easy to demonstrate that's just plain silly. When you have a lot of boxes then at the eastern and western edges of the circle you have boxes stacked almost directly on top of each other, with their X's very close to one another but they are saved from touching by having just enough Y distance between them.
So... to make this work, you must scale the maximum of dx and dy to be (for all cases) at least the radius (or was it double the radius?).
Corrected code is here: http://ideone.com/EQ03g http://ideone.com/VRyyo
Tested again in GnuPlot, it produces beautiful little circles of boxes where sometimes just 1 or 2 boxes are exactly touching. Problem solved! :)
(These images are wider than they are tall because GnuPlot didn't know I wanted proportional layout. Just imagine the whole works squeezed into a square shape :) )
I would calculate an upper bound of the minimum radius, by working with circles enclosing the squares instead of with the squares themselves.
My calculation results in:
Rmin <= X / (sqrt(2) * sin (180/N) )
Where:
X is the square side length, and N is the required number of squares.
I assume that the circles are positioned such that their centers fall on the big circle's circumference.
-- EDIT --
Using the idea of Dave in the comment below, we can also calculate a nice lower bound, by considering the circles to be inside the squares (thus having radius X/2). This bound is:
Rmin >= X / (2 * sin (180/N) )
As already noted, the problem of positioning n points equally spaced round the circumference of a circle is trivial. The (not-terribly) difficult part of the problem is to figure out the radius of the circle needed to give a pleasing layout of the squares. I suggest you follow one of the other answers and think of the squares being inside a circular 'buffer' big enough to contain the square and enough space to satisfy your aesthetic requirements. Then check the formula for the chord length between the centres of neighbouring squares. Now you have the angle, at the centre of the circle, subtended by the chord between square centres, and can easily compute the radius of the circle from the trigonometry of a triangle.
And, as to your follow up question: I suggest that you work out the problem for squares of side length min(h,w) on a circle, then transform the squares to rectangles and the circle to an ellipse with eccentricity h/w (or w/h).
I would solve it like this:
To find the relation between the radius r and length l let's analyze dimensionless representation
get the centres on a circle (x1,y1)..(xn,yn)
from each center get lower right corner of the i-th square and upper left corner of the i+1-th square
the two points should either have equal x or equal y, whichever yields smaller l
procedure should be repeated for each center and the one that yields smallest l is the final solution.
This is the optimal solution and can be solved it terms of r = f(l).
The solution can be adapted to rectangles by adjusting the formula for xLR[i] and yUL[i+1].
Will try to give some pseudo code.
EDIT:
There's a bug in the procedure, lower right and upper left are not necessary closest points for two neighbouring squares/rectangles.
Let's assume you solved the problem for 3 or 4 squares.
If you have n >= 5 squares, and position one square at the top of the circle, you'll have another square fall into the first quadrant of a cartesian plane concentric with your circle.
The problem is then to find a radius r for the circle such that the left side of the circle next to the top one, and the right side of the top circle do not 'cross' each other.
The x coordinate of the right side of the top circle is x1 = L/2, where L is the side of a square. The x coordinate of the left side of the circle next to the top one is x2 = r cos a - L/2, where r is the radius and a is the angle between each pair of square centres (a = 360/n degrees).
So we need to solve x1 <= x2, which leads to
r >= L / cos a.
L and a are known, so we're done :-)
You start with an arbitrary circle (e.g., with a diameter of (* n l)) and position the squares evenly on the circumference. Then you go through each pair of adjacent squares and:
calculate the straight line connecting their mid points,
calculate the intersection of this line with the intervening square sides (M1 and M2 are the mid points, S1 and S2 the corresponding intersections with the square side:
S2 S1
M1--------------*----------*---------------M2
------------------------
| |
| |
| |
| |
| M1 |
| \ |
| \ |
| -------*------- +--------
| | \ | |
| | \ | |
-------+---------*------ |
| \ |
| M2 |
| |
| |
| |
| |
-------------------------
calculate the scale factor you would need to make S1 and S2 fall together (simply the ratio of the sum of M1-S1 and S2-M2 to M1-M2), and
finally scale the circle by the maximum of the found scale factors.
Edit: This is the exact solution. However, a little thought can optimize this further for speed:
You only need to do this for the squares closest to 45° (if n is even) resp. 45° and 135° (if n is odd; actually, you might prove that only one of these is necessary).
For large n, the optimal spacing of the squares on the circle will quickly approach the length of a diagonal of a square. You could thus precompute the scaling factors for a few small n (up to a dozen or so), and then have a good enough approximation with the diagonal.

Resources