Skip to content

Commit 96ad920

Browse files
authored
Addition of the Skyline Algorithm
Implementation of the skyline algorithm
1 parent d55d1e4 commit 96ad920

File tree

1 file changed

+190
-0
lines changed

1 file changed

+190
-0
lines changed

divideconquer/SkylineAlgorithm.java

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
package skylinealgorithm;
2+
3+
import java.util.ArrayList;
4+
import java.util.Comparator;
5+
6+
/**
7+
*
8+
* @author dimgrichr
9+
*
10+
* Space complexity: O(n)
11+
* Time complexity: O(nlogn), because it is a divide and conquer algorithm
12+
*/
13+
public class SkylineAlgorithm {
14+
private ArrayList<Point> points;
15+
16+
17+
/**
18+
* Main constructor of the application.
19+
* ArrayList points gets created, which represents the sum of all edges.
20+
*/
21+
public SkylineAlgorithm(){
22+
points = new ArrayList<>();
23+
}
24+
25+
26+
/**
27+
* @return points, the ArrayList that includes all points.
28+
*/
29+
public ArrayList<Point> getPoints(){
30+
return points;
31+
}
32+
33+
34+
/**
35+
* The main divide and conquer, and also recursive algorithm.
36+
* It gets an ArrayList full of points as an argument.
37+
* If the size of that ArrayList is 1 or 2,
38+
* the ArrayList is returned as it is, or with one less point
39+
* (if the initial size is 2 and one of it's points, is dominated by the other one).
40+
* On the other hand, if the ArrayList's size is bigger than 2,
41+
* the function is called again, twice,
42+
* with arguments the corresponding half of the initial ArrayList each time.
43+
* Once the flashback has ended, the function produceFinalSkyLine gets called,
44+
* in order to produce the final skyline, and return it.
45+
* @param list, the initial list of points
46+
* @return leftSkyLine, the combination of first half's and second half's skyline
47+
* @see Point
48+
* @see produceFinalSkyLine
49+
*/
50+
public ArrayList<Point> produceSubSkyLines(ArrayList<Point> list){
51+
52+
//part where function exits flashback
53+
int size = list.size();
54+
if(size == 1){
55+
return list;
56+
}
57+
else if(size==2){
58+
if(list.get(0).dominates(list.get(1))){
59+
list.remove(1);
60+
}
61+
else{
62+
if(list.get(1).dominates(list.get(0))){
63+
list.remove(0);
64+
}
65+
}
66+
return list;
67+
}
68+
69+
//recursive part of the function
70+
ArrayList<Point> leftHalf=new ArrayList<>();
71+
ArrayList<Point> rightHalf=new ArrayList<>();
72+
for (int i=0;i<list.size();i++){
73+
if(i<list.size()/2){
74+
leftHalf.add(list.get(i));
75+
}
76+
else{
77+
rightHalf.add(list.get(i));
78+
}
79+
}
80+
ArrayList<Point> leftSubSkyLine=new ArrayList<>();
81+
ArrayList<Point> rightSubSkyLine=new ArrayList<>();
82+
leftSubSkyLine=produceSubSkyLines(leftHalf);
83+
rightSubSkyLine=produceSubSkyLines(rightHalf);
84+
85+
//skyline is produced
86+
return produceFinalSkyLine(leftSubSkyLine,rightSubSkyLine);
87+
}
88+
89+
90+
/**
91+
* The first half's skyline gets cleared
92+
* from some points that are not part of the final skyline
93+
* (Points with same x-value and different y=values. The point with the smallest y-value is kept).
94+
* Then, the minimum y-value of the points of first half's skyline is found.
95+
* That helps us to clear the second half's skyline, because, the points
96+
* of second half's skyline that have greater y-value of the minimum y-value that we found before,
97+
* are dominated, so they are not part of the final skyline.
98+
* Finally, the "cleaned" first half's and second half's skylines, are combined,
99+
* producing the final skyline, which is returned.
100+
* @param left the skyline of the left part of points
101+
* @param right the skyline of the right part of points
102+
* @return left the final skyline
103+
*/
104+
public ArrayList<Point> produceFinalSkyLine(ArrayList<Point> left, ArrayList<Point> right){
105+
106+
//dominated points of ArrayList left are removed
107+
for(int i=0;i<left.size()-1;i++){
108+
if(left.get(i).x==left.get(i+1).x && left.get(i).y>left.get(i+1).y){
109+
left.remove(i);
110+
i--;
111+
}
112+
}
113+
114+
//minimum y-value is found
115+
int min=left.get(0).y;
116+
for(int i=1;i<left.size();i++){
117+
if(min>left.get(i).y){
118+
min = left.get(i).y;
119+
if(min==1){
120+
i=left.size();
121+
}
122+
}
123+
}
124+
125+
//dominated points of ArrayList right are removed
126+
for(int i=0;i<right.size();i++){
127+
if(right.get(i).y>=min){
128+
right.remove(i);
129+
i--;
130+
}
131+
}
132+
133+
//final skyline found and returned
134+
left.addAll(right);
135+
return left;
136+
}
137+
138+
139+
140+
public static class Point{
141+
private int x;
142+
private int y;
143+
/**
144+
* The main constructor of Point Class, used to represent the 2 Dimension points.
145+
* @param x the point's x-value.
146+
* @param y the point's y-value.
147+
*/
148+
public Point(int x, int y){
149+
this.x=x;
150+
this.y=y;
151+
}
152+
/**
153+
* @return x, the x-value
154+
*/
155+
public int getX(){
156+
return x;
157+
}
158+
/**
159+
* @return y, the y-value
160+
*/
161+
public int getY(){
162+
return y;
163+
}
164+
/**
165+
* Based on the skyline theory,
166+
* it checks if the point that calls the function dominates the argument point.
167+
* @param p1 the point that is compared
168+
* @return true if the point wich calls the function dominates p1
169+
* false otherwise.
170+
*/
171+
public boolean dominates(Point p1){
172+
173+
//checks if p1 is dominated
174+
if((this.x<p1.x && this.y<=p1.y) || (this.x<=p1.x && this.y<p1.y)){
175+
return true;
176+
}
177+
return false;
178+
}
179+
}
180+
/**
181+
* It is used to compare the 2 Dimension points,
182+
* based on their x-values, in order get sorted later.
183+
*/
184+
class XComparator implements Comparator<Point> {
185+
@Override
186+
public int compare(Point a, Point b) {
187+
return a.x < b.x ? -1 : a.x == b.x ? 0 : 1;
188+
}
189+
}
190+
}

0 commit comments

Comments
 (0)