Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 5103c56

Browse files
committed
improve text and add images
1 parent ecbb9f1 commit 5103c56

File tree

5 files changed

+43
-4
lines changed

5 files changed

+43
-4
lines changed

src/geometry/manhattan-distance.md

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ $d(p,q) = |p.x - q.x| + |p.y - q.y|$
1212

1313
This is informally know as the [Manhattan distance, or taxicab geometry](https://en.wikipedia.org/wiki/Taxicab_geometry), because we can think of the points as being intersections in a well designed city, like manhattan, where you can only move on the streets, as shown in the image below:
1414

15+
![Manhattan Distance](https://upload.wikimedia.org/wikipedia/commons/thumb/0/08/Manhattan_distance.svg/220px-Manhattan_distance.svg.png)
16+
1517
This images show some of the smallest paths from one black point to the other, all of them with distance $12$.
1618

1719
There are some interseting tricks and algorithms that can be done with this distance, and we will show some of them here.
@@ -31,7 +33,26 @@ Notice that we can extend this idea further for 2 (or more!) dimensions. For $d$
3133

3234
$max_{p, q \in P} (p.x + (-q.x)) + (p.y + (-q.y)) = max_{p \in P}(p.x + p.y) + max_{q \in P}(-q.x - q.y)$.
3335

34-
As we made $p$ and $q$ independent, it is now easy to find the $p$ and $q$ that maximize the expression.
36+
As we made $p$ and $q$ independent, it is now easy to find the $p$ and $q$ that maximize the expression.
37+
38+
The code below generalizes this to $d$ dimensions and runs in $O(n \cdot 2^d \cdot d)$.
39+
40+
```cpp
41+
long long ans = 0;
42+
for(int msk=0;msk < (1<<d);msk++){
43+
long long mx = LLONG_MIN, mn = LLONG_MAX;
44+
for(int i=0;i<n;i++){
45+
long long cur = 0;
46+
for(int j=0;j<d;j++){
47+
if(msk & (1<<j)) cur += p[i][j];
48+
else cur -= p[i][j];
49+
}
50+
mx = max(mx, cur);
51+
mn = min(mn, cur);
52+
}
53+
ans = max(ans, mx - mn);
54+
}
55+
```
3556

3657
## Rotating the points and Chebyshev distance
3758

@@ -42,17 +63,31 @@ As we made $p$ and $q$ independent, it is now easy to find the $p$ and $q$ that
4263
The Manhattan MST problem consists of, given some points in the plane, find the edges that connect all the points and have a minimum total sum of weights. The weight of an edge that connects two points is their Manhattan distance. For simplicity, we assume that all points have different locations.
4364
Here we show a way of finding the MST in $O(n \log{n})$ by finding for each point its nearest neighbor in each octant, as represented by the image below. This will give us $O(n)$ candidate edges, which will guarantee that they contain the MST. The final step is then using some standard MST, for example, [Kruskal algorithm using disjoint set union](https://cp-algorithms.com/graph/mst_kruskal_with_dsu.html).
4465

66+
![8 octants picture](manhattan-mst-octants.png)
67+
*The 8 octants relative to a point S*
68+
4569
The algorithm show here was first presented in a paper from [H. Zhou, N. Shenoy, and W. Nichollos (2002)](https://ieeexplore.ieee.org/document/913303). There is also another know algorithm that uses a Divide and conquer approach by [J. Stolfi](https://www.academia.edu/15667173/On_computing_all_north_east_nearest_neighbors_in_the_L1_metric), which is also very interesting and only differ in the way they find the nearest neighbor in each octant. They both have the same complexity, but the one presented here is easier to implement and has a lower constant factor.
4670

47-
First, let's understand why it is enough to consider only the nearest neighbor in each octant. The idea is to show that for a point $s$ and any two other points $p$ and $q$ in the same octant, $dist(p, q) < max(dist(s, p), dist(s, q))$. This is important, because it shows that if there was a MST where $s$ is connected to both $p$ and $q$, we could erase one of these edges and add the edge $(p,q)$, which would decrease the total cost. To prove this, we assume without loss of generality that $p$ and $q$ are in the octanct $R_1$, which is defined by: $x_s \leq x$ and $x_s - y_s > x - y$, and then do some casework. The images below give some intuition on why this is true.
71+
First, let's understand why it is enough to consider only the nearest neighbor in each octant. The idea is to show that for a point $s$ and any two other points $p$ and $q$ in the same octant, $dist(p, q) < max(dist(s, p), dist(s, q))$. This is important, because it shows that if there was a MST where $s$ is connected to both $p$ and $q$, we could erase one of these edges and add the edge $(p,q)$, which would decrease the total cost. To prove this, we assume without loss of generality that $p$ and $q$ are in the octanct $R_1$, which is defined by: $x_s \leq x$ and $x_s - y_s > x - y$, and then do some casework. The image below give some intuition on why this is true.
72+
73+
![unique nearest neighbor](manhattan-mst-uniqueness.png)
74+
*We can build some intuition that limitation of the octant make it impossible that $s$ is closer to both $p$ and $q$ then each other*
75+
4876

4977
Therefore, the main question is how to find the nearest neighbor in each octant for every single of the $n$ points.
5078

5179
## Nearest Neighbor in each Octant in $O(n\log{n})$
5280

5381
For simplicity we focus on the north-east octant. All other directions can be found with the same algorithm by rotating the input.
5482

55-
We will use a sweep-line approach. We process the points from south-west to north-east, that is, by non-decreasing $x + y$. We also keep a set of points which don't have their nearest neighbor yet, which we call "active set".
83+
We will use a sweep-line approach. We process the points from south-west to north-east, that is, by non-decreasing $x + y$. We also keep a set of points which don't have their nearest neighbor yet, which we call "active set". We add the images below to help visualize the algorithm.
84+
85+
![manhattan-mst-sweep](manhattan-mst-sweep-line-1.png)
86+
87+
*In black with an arrow you can see the direction of the line-sweep. All the points below this lines are in the active set, and the points above are still not processed. In green we see the points which are in the octant of the processed point. In red the points that are not in the searched octant.*
88+
89+
![manhattan-mst-sweep](manhattan-mst-sweep-line-2.png)
90+
*In this image we see the active set after processing the point $p$. Note that the $2$ green points of the previous image had $p$ in its north-north-east octant and are not in the active set anymore, because they already found their nearest neighbor.*
5691

5792
When we add a new point point $p$, for every point $s$ that has it in it's octant we can safely assign $p$ as the nearest neighbor. This is true because their distance is $d(p,s) = |x_p - x_s| + |y_p - y_s| = (x_p + y_p) - (x_s + y_s)$, because $p$ is in the north-east octant. As all the next points will not have a smaller value of $x + y$ because of the sorting step, $p$ is guaranteed to have the smaller distance. We can then remove all such points from the active set, and finally add $p$ to the active set.
5893

@@ -61,7 +96,9 @@ The next question is how to efficiently find which points $s$ have $p$ in the no
6196
- $x_s \leq x_p$
6297
- $x_p - y_p < x_s - y_s$
6398

64-
Because no points in the active set are in the R_1 of another, we also have that for two points $q_1$ and $q_2$ in the active set, $x_{q_1} \neq x_{q_2}$ and $x_{q_1} < x_{q_2} \implies x_{q_1} - y_{q_1} \leq x_{q_2} - y_{q_2}$.
99+
Because no points in the active set are in the $R_1$ of another, we also have that for two points $q_1$ and $q_2$ in the active set, $x_{q_1} \neq x_{q_2}$ and $x_{q_1} < x_{q_2} \implies x_{q_1} - y_{q_1} \leq x_{q_2} - y_{q_2}$.
100+
101+
You can try to visualize this on the images above by thinking of the ordering of $x - y$ as a "sweep-line" that goes from the north-west to the south-east, so perpendicular to the one that is drawn.
65102

66103
This means that if we keep the active set ordered by $x$ the candidates $s$ are consecutively placed. We can then find the largest $x_s \leq x_p$ and process the points in decreasing order of $x$ until the second condition $x_p - y_p < x_s - y_s$ breaks (we can actually allow that $x_p - y_p = x_s - y_s$ and that deals with the case of points with equal coordinates). Notice that because we remove from the set right after processing, this will have an amortized complexity of $O(n \log(n))$.
67104
Now that we have the nearest point in the north-east direction, we rotate the points and repeat. It is possible to show that actually we also find this way the nearest point in the south-west direction, so we can repeat only 4 times, instead of 8.
@@ -77,6 +114,8 @@ In summary we:
77114
Below you can find a implementation, based on the one from [KACTL](https://github.com/kth-competitive-programming/kactl/blob/main/content/geometry/ManhattanMST.h).
78115

79116
```{.cpp file=manhattan_mst.cpp}
117+
// Returns a list of edges in the format (weight, u, v).
118+
// Passing this list to Kruskal algorithm will give the Manhattan MST.
80119
vector<tuple<long long,int,int> > manhattan_mst_edges(vector<point> ps){
81120
vector<int> ids(ps.size());
82121
iota(ids.begin(), ids.end(), 0);
31.8 KB
Loading
83.1 KB
Loading
67.7 KB
Loading
15.9 KB
Loading

0 commit comments

Comments
 (0)