【发布时间】:2020-09-07 04:04:16
【问题描述】:
我正在努力解决一个问题,我需要确定 Point 是否位于连接另外两个 Points 的线上。例如,如果我有Point a, b, c,我想确定c 是否在连接a 和b 的线段上。在我的代码中,我有一个点 me(示例中的 a)和两个点列表 hits(示例中的 b)和 reachable(示例中的 c)。对于命中中的每个点,我想确定在连接我和命中点的线段上是否有任何可到达的点。如果该线段上有一个点,则需要减少 numHits。这是我的代码:
Point me; //Point a from the example above
ArrayList<Point> hits = new ArrayList<>(); //a list of Point b's from the example above
ArrayList<Point> reachable = new ArrayList<>(); //a list of point c's from the example above
for(Point hit : hits) {
for(Point p : reachable) {
if(!hit.equals(p) && !me.equals(p)) {
//find the equation of a line from me to hit
if(hit.x - me.x == 0) { //if the line has an undefined slope... if the line is vertical
if( (((p.y <= hit.y) && (p.y >= me.y)) || ((p.y >= hit.y) && (p.y <= me.y))) && p.x - me.x == 0) { //if there is any occupied point on that line in between me and the hit, that point blocks the hit
numHits--;
break;
}
} else {
//create a line from me to the hit... if there is any occupied point on that line in between me and the hit, that point blocks the hit
double deltaY = hit.y - me.y;
double deltaX = hit.x - me.x;
double m = deltaY / deltaX; //slope
double b = me.y - (double)(m*me.x); //y intercept
if((double) p.y == ((double)(m * p.x) + b)) { //if this point is on the same line
if( ((p.x <= hit.x && p.x >= me.x) && (p.y <= hit.y && p.y >= me.y)) ||
((p.x <= hit.x && p.x >= me.x) && (p.y >= hit.y && p.y <= me.y)) ||
((p.x >= hit.x && p.x <= me.x) && (p.y >= hit.y && p.y <= me.y)) ||
((p.x >= hit.x && p.x <= me.x) && (p.y <= hit.y && p.y >= me.y))) { //if the point is in between me and the hit
numHits--;
break;
}
}
}
}
}
}
我的代码用于确定reachable 中的任何点在me 和hits 中的每个点之间是否存在任何点,它会变得非常慢,较大的hits 和reachable 得到。例如,如果 hits 的大小为 780,000,reachable 的大小为 1,500,000,则代码需要很长时间才能运行。我想知道如何优化它以更快地运行。我不确定瓶颈问题是出在循环本身还是出在循环内的代码中。非常感谢任何帮助或优化想法。谢谢!
【问题讨论】:
-
使用输入
780,000hits 和1,500,000reachables,这是 1 万亿次潜在迭代。我可以想象这需要很长时间。您是否需要一次性处理这么多数据?有什么方法可以重新设计您的系统以要求/处理更少的输入?也许您可以合并/展平输入中一些更一致的部分(例如线性运动序列)? -
@VinceEmigh 在大多数情况下,正在处理的数据量将远小于
780,000和1,500,000。但是,在极少数情况下,代码仍然需要能够处理与这些一样大的数字。 -
你是什么意思,
in between?。如果一个点是原点,另一个是10,10,那么5,5介于两者之间,3,7也是如此 或者您的意思是在由点a和b形成的同一个line segment上?跨度> -
@WJS 我想说一个点是否在原点和另一个点之间的线上。所以如果原点是
(0,0),另一点是(10,10),那么(5,5)在中间,(3,7)不在中间,(11,11)不在中间。我将更新问题以使这一点更清楚。 -
所以你的意思是
line segment
标签: java performance optimization time-complexity nested-loops