I am trying to solve the following question which was part of a programming contest:
PROBLEM ID : CIELLAND
Chef Ciel develops a new island with her restaurants. In the island, Ciel intends to built N restaurants, and the coordinate of the i-th restaurant will be (xi, yi). In addition, Ciel is going to create K roads, whose location is not decided yet. Each road must be a infinitely long straight line.
Let di be the distance between the i-th restaurant and the nearest road from the i-th restaurant. Ciel would like to create K roads which minimize max(d1, d2, ..., dN). Your task is to calculate the minimal value of max(d1, d2, ..., dN).
Any ideas as to how I should approach it? Also, the contest editorial is out ( http://www.codechef.com/wiki/march-2012-cook-problem-editorials ) but I cannot understand the solution.
Any help regarding the approach to be followed would be much appreciated.
At a high level, they are reformulating the problem so that it is easier to solve. By casting in the light below, they limit the number of possible lines to consider.
Problem A: There are N circles. The center of the i-th circle is (xi,
yi) and all circles have the radii R. And let we can draw X lines such
that any circle intersects with at least one line. What is the minimal
X?
To explain further, lets rephrase the problem A in words: The restaurants are sticklers for rules and there is a rule that says all restaurants must agree on a single maximum distance from the road - this'll be R. The circle created by the restaurant and R represents the place where a line needs to intersect to satisfy this requirement. The new problem asks the minimum number of roads to do this.
If this is not possible in under K roads, then something has to change. We can't add roads per the original problem, but we can modify R. This is where binary search comes in, but we have to solve problem A first.
Now, let's consider solving Problem A. At first, the lines can be
limited to common tangents to two circles. Because if a line
intersects with some (at least 2) circles, we can move the line such
that a moved line intersects with the same circles, and the moved line
is one of common tangents. If a line intersects less than 2 circles,
it is useless (but be careful of the case N = 1). There are at most 4
lines that is common tangents to two circles, so we consider at most 2
* N * (N-1) lines.
The important part is this, we need to find lines that intersect more than one circle. At most four lines from each pair of circle need be considered, check the source codes for implementation.
The next big step is the dynamic programming which find the minimum number of lines to cover all the circles. The 'mask' is a bitmask indicating which circles have been hit as each line is considered.
This solves the problem, but now we have to convert back. Remember R? We can now binary search to find the minimum R such that X<=K. In terms of my reformulation of Problem A, its the smallest distance all restaurant will agree to and still be serviced by a road
Hope that helps, tricky, but interesting problem.
You should be able to solve it as k means clustering problem. Initially seed with a bunch of lines. Then iteratively update points assignment to lines and optimalline given points.
Related
I have a problem that looks almost like a classic CS problem of finding all intersection points of given line segments.
The slight modification is the fact that:
1. I need to split all the segments at their intersection points
2. The resulting split segments must have integer coordinates.
If I just apply standard sweepline algorithm to find all the intersection points, and than cast coordinates of these points to integers, I sometimes get new intersections caused by the moving of intersections points to the integer grid.
I may apply this algorithm repeatedly, and probably (I can't prove it), in limited number of steps reach a state where I find no new intersections.
But I'm convinced there must be a simpler, more elegant solution.
I was trying to find a paper about such algorithm, but somehow couldn't find one that would deal with exactly this problem.
Can you tell point me to such a pape, or a description of an algorithm used by graphics libraries (such as Boost Polygon Library)?
Thank you.
This is an interesting variation to Line-segment intersection problem. Original problem of finding co-ordinates of point of intersection of these segments can be done solved using Line Sweep algorithm.
Here is an in depth article talking about Line-Sweep technique implementation for above problem. With this, intersection can be found in O(n*logn) time.
Now, in order to find the integer co-ordinates, you can cast the intersection points. But here you need to make sure about the direction of casting (which will later help in convergence).
If C in an intersection point on line segment AB, then split it into AC and CB. In AC, you cast C in direction of A, while in CB you cast it in direction of B. (By direction, I don't mean along the line segment direction, but along the half plane containing another end point.) This ensures that length of line segment will be reduced after each intersection.
PROOF: Consider, M to be maximum length of an line segment. Every time an intersection point lies on it, the length of new line segment is reduced by at least one unit. So number of iterations is bounded by M
Thus, overall iterations of your algorithm cannot exceed M.
Complexity = O(M* n *logn)
I'm working with a really slow renderer, and I need to approximate polygons so that they look almost the same when confined to a screen area containing very few pixels. That is, I'd need an algorithm to go through a polygon and subtract/move a bunch of vertices until the end polygon has a good combination of shape preservation and economy of vertice usage.
I don't know if there's a formal name for these kind of problems, but if anyone knows what it is it would help me get started with my research.
My untested plan is to remove the vertices that change the polygon area the least, and protect the vertices that touch the bounding box from removal, until the difference in area from the original polygon to the proposed approximate one exceeds a tolerance I specify.
This would all be done only once, not in real time.
Any other ideas?
Thanks!
You're thinking about the problem in a slightly off way. If your goal is to reduce the number of vertices with a minimum of distortion, you should be defining your distortion in terms of those same vertices, which define the shape. There's a very simple solution here, which I believe would solve your problem:
Calculate distance between adjacent vertices
Choose a tolerance between vertices, below which the vertices are resolved into a single vertex
Replace all pairs of vertices with distances lower than your cutoff with a single vertex halfway between the two.
Repeat until no vertices are removed.
Since your area is ultimately decided by the vertex placement, this method preserves shape and minimizes shape distortion. The one drawback is that distance between vertices might be slightly less intuitive than polygon area, but the two are proportional. If you really wish, you could run through the change in area that would result from vertex removal, but that's a lot more work for questionable benefit imo.
As mentioned by Angus, if you want a direct solution for the change in area, it's not actually super difficult. Was originally going to leave this as an exercise to the reader, but it's totally possible to solve this exactly, though you need to include vertices on either side.
Assume you're looking at a window of vertices [A, B, C, D] that are connected in that order. In this example we're determining the "cost" of combining B and C.
Calculate the angle offset from collinearity from A toward C. Basically you just want to see how far from collinear the two points are. This is |sin(|arctan(B - A)| - |arctan(C - A)|)| Where pipes are absolute value, and differences are the sensical notion of difference.
Calculate the total distance over which the angle change will effectively be applied, this is just the euclidean distance from A to B times the euclidean distance from B to C.
Multiply the terms from 2 and 3 to get your first term
To get your second term, repeat steps 2 - 4 replacing A with D, B with C, and C with B (just going in the opposite direction)
Calculate the geometric mean of the two terms obtained.
The number that results in step 6 presents the full-picture minus a couple constants.
I tried my own plan first: Protect the vertices touching the bounding box, then remove the rest in the order that changes the resultant area the least, until you can't find a vertice to remove that keeps the new polygon area within X% of the original one. This is the result with X = 5%:
When the user zooms out really far these shapes fit the bill well enough for me. I haven't tried any of the other suggestions. The savings are quite astonishing, sometimes from 80-100 vertices down to 4 or 5.
I have been given a task where I have to connects all the points in the 2D plane.
There are four conditions to to be met:
Length of the all segments joined together has to be minimal.
One point can be a part of only one line segment.
Line segments cannot intersect
All points have to be used(one can't be left alone but only if it cannot be avoided)
Image to visualize the problem:
The wrong image connected points correctly, although the total length is bigger that the the one in on the left.
At first I thought about sorting the points and doing it with a sweeping line and building a tree of all possibilities, although it does seem like a way to complicated solution with huge complexity. Therefore I search better approaches. I would appreciate some hints what to do, or how could I approach the problem.
I would start with a Delaunay triangulation of the point set. This should already give you the nearest neighbor connections of each point without any intersections. In the next step I'd look at the triangles that result from the triangulation - the convenient property here is that based on your ruleset you can pick exactly one side from each triangle and remove the remaining two from the selection.
The problem that remains now is to pick those edges that give you the smallest total sum which of course will not always be the smallest side since that one might already have been blocked by a neighboring triangle. I'd start with a greedy approach, always picking the smallest remaining edge that has not been blocked by neighboring triangles yet.
Edit: In the next step you retrieve a list of all the edges in that triangulation and sort them by length. You also make another list in which you count the amount of connections each point has. Now you iterate through the edge list going from the longest edge to the shortest one and check the two points it connects in the connection count list: if each of the points has still more than 1 connection left, you can discard the edge and decrement the connection count for the two points involved. If at least one of the points has only one connection left, you have got yourself one of the edges you are looking for. You repeat the process until there are no edges left and this should hopefully give you the smallest possible edge sum.
If I am not mistaken this problem is loosely related to the knapsack problem which is NP-Hard so I am not sure if this solution really gives you the best possible one.
I'd say this is an extension to the well-known travelling salesman problem.
A good technique (if a little old-fashioned) is to use a simulated annealing optimisation technique.
You'll need to make adjustments to the cost (a.k.a. objective) function to miss out sections of the path. But given a candidate continuous path, it's reasonably trivial to decide which sections to miss out to minimise its length. (You'd first remove the longer of any intersecting lines).
Wow, that's a tricky one. That's a lot of conditions to meet.
I think from a programming standpoint, the "simplest" solution might actually be to just loop through, find all the possibilities that satisfy the last 3 conditions, and record the total length as you loop through, and just choose the one with the shortest length in the end - brute force, guess-and-check. I think this is what you were referring to in your OP when you mentioned a "sweeping line and building a tree of all possibilities". This approach is very computationally expensive, but if the code is written right, it should always work in the end.
If you want the "best" solution, where you want to just solve for the single final answer right away, I'm afraid my math skills aren't strong enough for that - I'm not even sure if there is any single analytical solution to that problem for any arbitrary collection of points. Maybe try checking with the people over at MathOverflow. If someone over there can explain you with the math behind that calculation, and you then you still need help to convert that math into code in a certain programming language, update your question here (maybe with a link to the answer they provide you) and I'm sure someone will be able to help you out from that point.
One of the possible solutions is to use graph theory.
Construct a bipartite graph G, such that each point has its copy in both parts. Now put the edges between the points i and j with the weight = i == j ? infinity : distance[i][j]. The minimal weight maximum matching in the graph will be your desired configuration.
Notice that since this is on a euclidean 2D plane, the resulting "edges" of the matching will not intersect. Let's say that edges AB and XY intersect for points A, B, X, Y. Then the matching is not of the minimum weight, because either AX, BY or AY, BX will produce a smaller total weight without an intersection (this comes from triangle inequality a+b > c)
In class we saw the followin problem but i didnt undestand the solution. Do anybody could explain me with more detail the procedure to solve this problem or give me a better solution?:
Assume that n points in the plane are given. Find a polygonal arc with n-1 sides whose vertices are given points, and whose sides do not intersect.(Adjacent sides may form a 180 angle). The number of operations shold be of order n log n.
The teacher solution was:
Sort all the points with respect to the x-coordinate; when x-coordinates are equal, take the y-coordinate into account, then connect all the vertices by line segments(in that order).
The solution of your teacher is (fortunately) good. I'll try to visualize this for you.
Just draw the points on a plot. Then you can draw a line from the leftmost point to the next point. This way, connect all points going to the right.
If all the points have different x-coordinates, that'll work out, and no lines will cross:
For the points with the same x-coordinates, we first go to the lowest (smallest y-coordinate) and then go up. No crossing there, either.
I came across this problem wherein there are a number of houses on a 2-D grid (their coordinates are given) and we essentially have to find which house can be used as a meeting point so that the distance traveled by everyone minimizes. Let us assume that a distance along the x or y-axis takes 1 unit and a distance to the diagonal neighbors takes (say) 1.2 units.
I cannot really think of a good optimization algorithm for this.
P.S: Not a homework problem. And I am only looking for an algorithm (not code) and if possible, its proof.
P.S #2: I am not looking for the Exhaustive solution. Believe it or not, that did strike me :)
As already pointed, in case of Manhattan distance the median gives a solution. This is an obvious conclusion from the well-known fact that median minimizes the mean of absolute deviation:
E|X-c| >= E|X-median(X)| for any constant c.
And here you can find an example of the proof for discrete case:
https://stats.stackexchange.com/questions/7307/mean-and-median-properties/7315#7315
This is probably really inefficient, but loop through all the houses, then loop through all the other houses. (nested for loops) Use the distance formula to find the distance between the 2 houses. Then you have the distance between every house. One quick and easy way to find which house is the closest distance is to add everyone's walking distance together for the given house. The house with the least total walking distance is the meeting area of choice.
I have been bugged by the same problem for some time now. The solution is the obvious consensus given in earlier posts: find the median (mx, my) independently and then find the point closest in the given N points and that is the meeting place. To see why this is actually the solution you should first consider the distance.
d = sum(|xi-x|) + sum(|yi-y|) over all 1<=i<=N,
which is independent in x and y. Hence we can solve the 1-D case for x and y. I will skip over the explanation given ^^ and hence conclude that (mx,my) is the best solution if we consider all possible points.The bigger challenge is to prove that we may move from (mx, my) to the closest (xi,yi) such that (xi, yi) is one of the given points, w/o changing(increasing) the distance. The proof goes:
Consider that we have sorted x-coordinates( for sake for proof ) and
that X1<X2<...<Xn. Also Xj<mx<X(j+1) where j = N/2, now let's move mx
one step to left, that is mx' <- mx-1.
Hence d' = |X1-mx+1| + .. + |Xj-mx+1| + |X(j+1)-mx+1| + .. + |Xn-mx+1|
We know that mx-1 will increase N/2 values( for k>=j+1 and decrease
for <=j ) hence the effect is the same. Thus (mx-1, my) gives the same
solution. It means that there is a space from Xj<mx<X(j+1) and
Yj<my<Y(j+1) where the distance does not change. Thus we can find the
closest such point which is the answer.
I have ignored the subtle case of even/odd nodes, but I hope the math works out itself when you realize the basic proof.
This is my first post, do help me improve my writing skills.
Your distance metric is weird. You'd expect that travelling on the diagonal should take at least sqrt(2) ~= 1.41 times the distance of travelling along a component direction, because that's how much further it is if travelling in a straight line along the diagonal by the Pythagorean theorem.
If you insisted on a manhattan distance (no diagonals allowed), then you'd want to pick the house closest to the median(x) + median(y) of the houses.
Consider the 1D case, you have a bunch of points on a line, and you want to pick the meeting spot. For concreteness/simplicity, let's say there are 5 houses, none duplicate.
Consider what happens as the meeting spot drifts away from the median to the right. For every unit away until you pass the 4th house left to right order, 3 people have to take an additional step to the right, and 2 people have to take one less step to the left, so the cost goes up by 1. Once you pass the 4th house, then 4 people have to taken an additional step to the right, and a single person has to take one less step to the left, so the cost increases by 3. An identical argument holds as you move the meeting spot to the left from the median. Moving away from the median always increases the cost.
The argument generalizes to any number of people, with or without duplicate houses, and even across to arbitrary number of dimensions, so long as you aren't allowed to use the diagonal.
Your problem is called Optimal Meeting Point Finding.
The following paper gives an efficient approximate algorithm
http://www.cse.ust.hk/~wilfred/paper/vldb11.pdf
Well, you could brute force it. Take each house and calculate the distance to each other house. Sum the distances up for each individual house. Then just grab the house that had the lowest sum.