如果有人可以帮我解决这个问题,那我很想知道:我正在尝试创建一段Java代码,找到距离点最近的2个点。以下是我到目前为止的情况:
import java.util.Random;
public class Main {
static int distance(int x1, int x2) {
return Math.round((x2 - x1) * (x2 - x1));
// Math.sqrt is the square root of the 2 co-ordinates
}
public static void main(String[] args) {
Random randomGenerator = new Random();
int x2, x1; // The Points
int distance;// The Math to work out distance
int randomInt2 = randomGenerator.nextInt(10) + 1;// For Length of array
int[] distances = new int[randomInt2];// The Array
int store;
x1 = 0;// used to calculate distance from original point to current point
System.out.println("Distance Generated for Point 1 : 0");// For First Point
int origin = 1;// increment which point start from
int range = 0;// Amount of Points
int point = 2;// Counts the number of points
while (range < randomInt2) {
int randomInt3 = randomGenerator.nextInt(10) + 2;// Distance for all points besides first
x2 = randomInt3;
distance = distance(x1, x2); // System.out.println("The distance between point 1 and point " +point+ " is " + distance + " .");
System.out.println("Distance from Point " + origin + " to Point " + point + " is distance = " + distance);
store = distance;// stores the distance to be put into array
point++;// increments the point number each time
distances[range] = store;
// System.out.println(" ,from Point " +point+" to Point "+origin+" = " + distance);
origin++;// Increments Original Point
range++;// increments amount of points each time
}
/*
* for (int val : distances) { System.out.println(val); }
*/
}
}
到目前为止,它创建了具有随机距离的点,并且我能够找到距离前一点的每个点的最近点。但是我试图让它成为一种树形结构,其中每个点都有2个最接近它的点。对不起,如果我没有说清楚,但如果有人能给我任何提示,他们将不胜感激。
答案 0 :(得分:2)
很难猜出你想做什么。从我如何阅读你的问题,你想在一条线上创建一些点(即一维点),并找到每个点最接近的两个点。
---------甲----------- ---------乙C-d-E -----------
对于线上的这些点A-E,这应该会产生如下结果:
A的邻居是B和C.
B的邻居是A和C.
C的邻居是D和E.
D的邻居是C和E.
E的邻居是C和D.
但是您的代码的结果如下:
A与B的距离为d
B与C的距离为d
C与D的距离为d
D与E的距离为d。
关于如何改进代码已有一些建议,我现在将添加这些建议,并列举其他几个。
我们现在只能猜测,因为您的代码与您的问题所做的完全不同。再考虑一下,并尝试提出一些更清晰的问题。
已经提到:最好有一些课程,至少例如Point
的一个类。将distance
方法放入另一个类,也许是某种数学库可能会很好
还要考虑可见性。包可见性(distance()
方法使用的内容)通常不是您的想法。
使用类可以使代码更加结构化,并且通常更容易扩展或增加一些可重用性。
我们很难猜到range
,randomInt2
和store
的含义。如果你有一个正确的上下文,一个好的缩进和一些有意义的名字,我们可以更容易地猜测它的作用,即使评论较少。
您遇到的另一个问题是您一次又一次地重复使用x2。最终你有一些距离,存储在距离数组中,但不知道它们属于哪一点 - 因为这些点不再存在。
好的,虽然你的问题不是最有帮助的,但我会尝试解决问题。
首先想到一个Point类。我决定将其称为Point1D
,以表明它可以轻松扩展到Point2D
之后或Point3D
。
package sto;
public class Point1D {
private final double x; // this could also be a good public variable
private final String name;
public Point1D(double x, String name) {
this.x = x;
this.name = name;
}
public double distanceTo(Point1D other) {
return Math.abs(other.x - this.x);
}
}
这可能是一个简单的Point1D
课程,可满足您的需求。它包含String name
,值(此处为double x
)以及计算此Point1D
与另一个public double distanceTo(Point1D other)
之间距离的方法:Main
。
在你的package sto;
import java.util.Random;
public class Main {
public static void main(String[] args) {
Random rng = new Random();
// generate points
int numberOfPoints = rng.nextInt(10) + 1;
Point1D[] points = new Point1D[numberOfPoints];
for(int i = 0; i < numberOfPoints; ++i) {
points[i] = new Point1D(rng.nextDouble() * 10.0d, "Point " + i);
}
}
}
中,您现在可以创建一个可重复使用的随机数量的点:
Point1D[] points
这将在numberOfPoints
数组中创建1-10个点。请注意命名:randomInt2
比 public static double distance(Point1D p1, Point1D p2) {
return p1.distanceTo(p2);
}
更有意义。
由于你在main中有一个距离函数,我们也可以添加它。请注意,我们现在使用公共可见性执行此操作,以便可以从任何位置访问它:
MathUtil
将这样的方法移到单独的类中会更好,例如distanceTo(Point1D)
。因为我已经创建了 for(int i = 0; i < numberOfPoints; ++i) {
Point1D currentPoint = points[i];
Point1D closestPoint = null;
Point1D secondClosestPoint = null;
for(int j = 0; j < numberOfPoints; ++j) {
if(i == j) continue;
if(closestPoint == null || currentPoint.distanceTo(points[j]) < currentPoint.distanceTo(closestPoint)) {
secondClosestPoint = closestPoint;
closestPoint = points[j];
} else if(secondClosestPoint == null || currentPoint.distanceTo(points[j]) < currentPoint.distanceTo(secondClosestPoint)) {
secondClosestPoint = points[j];
}
}
currentPoint.setNeighbors(closestPoint, secondClosestPoint);
}
,所以现在还不需要它。
现在您想要找到每个点的两个最近点。可能有比这更好的方法,但这个方法做得很好:
null
首先,我们定义最近和第二个最近的点并用null初始化它们。然后我们比较当前点和其他点之间的距离,每当距离比当前最近点更近时,我们分配它。否则我们检查第二个最近的点。注意points[0]
检查,这是为了避免空指针异常和(如果你说:嘿,我可以一直用points[j]
或currentPoint
初始化它)你比较距离为零的情况(如果points[0]
等于currentPoint
或points[j]
等于null
),或者您最近和最接近的距离设置为距离最近的点。
另请注意,只有1或2个生成点,一个或两个邻居将为currentPoint.setNeighbors(closestPoint, secondClosestPoint);
。
最后一个方法调用Point1D
对您来说是新手。不知何故,你想存储邻居。而不是真正的树结构(您应该能够使用此答案后的内容构建)我只是决定将邻居存储在Point1D
对象本身中。为此, /* extensions for your special case: two neighbors */
private Point1D neighbor1 = null;
private Point1D neighbor2 = null;
public void setNeighbors(Point1D p1, Point1D p2) {
neighbor1 = p1;
neighbor2 = p2;
}
public String toString() {
return "Point1D \"" + name + "\" at " + x + ", "
+ "Neighbors: " + (neighbor1 != null? neighbor1.name + " (" + distanceTo(neighbor1) + "), " : "")
+ (neighbor2 != null? neighbor2.name + " (" + distanceTo(neighbor2) + ")" : "");
}
类被改变了一点:
public String toString()
Point1D有两个简单的成员和一个setter。当然,您可以轻松地修改它,并使用getter等扩展它。我还重载Point1D
以便能够轻松打印package sto;
import java.util.Random;
public class Main {
// better into a seperate MathLibrary
public static double distance(Point1D p1, Point1D p2) {
return p1.distanceTo(p2);
}
public static void main(String[] args) {
Random rng = new Random();
// generate points
int numberOfPoints = rng.nextInt(10) + 1;
Point1D[] points = new Point1D[numberOfPoints];
for(int i = 0; i < numberOfPoints; ++i) {
points[i] = new Point1D(rng.nextDouble() * 10.0d, "Point " + i);
}
for(int i = 0; i < numberOfPoints; ++i) {
Point1D currentPoint = points[i];
Point1D closestPoint = null;
Point1D secondClosestPoint = null;
for(int j = 0; j < numberOfPoints; ++j) {
if(i == j) continue;
if(closestPoint == null || currentPoint.distanceTo(points[j]) < currentPoint.distanceTo(closestPoint)) {
secondClosestPoint = closestPoint;
closestPoint = points[j];
} else if(secondClosestPoint == null || currentPoint.distanceTo(points[j]) < currentPoint.distanceTo(secondClosestPoint)) {
secondClosestPoint = points[j];
}
}
currentPoint.setNeighbors(closestPoint, secondClosestPoint);
}
for(int i = 0; i < numberOfPoints; ++i)
System.out.println(points[i]);
}
}
。
毕竟我们只需要打印它们,这只是另一个非常简单的循环。
Main.java
package sto;
public class Point1D {
private final double x; // this could also be a good public variable
private final String name;
public Point1D(double x, String name) {
this.x = x;
this.name = name;
}
public double distanceTo(Point1D other) {
return Math.abs(other.x - this.x);
}
/* extensions for your special things: 2 neighbors */
private Point1D neighbor1 = null;
private Point1D neighbor2 = null;
public String toString() {
return "Point1D \"" + name + "\" at " + x + ", "
+ "Neighbors: " + (neighbor1 != null? neighbor1.name + " (" + distanceTo(neighbor1) + "), " : "")
+ (neighbor2 != null? neighbor2.name + " (" + distanceTo(neighbor2) + ")" : "");
}
public void setNeighbors(Point1D p1, Point1D p2) {
neighbor1 = p1;
neighbor2 = p2;
}
}
Point1D.java
Point1D "Point 0" at 6.420136069230588, Neighbors:
生成1点:
Point1D "Point 0" at 5.944088209230237, Neighbors: Point 1 (0.43915003704614364),
Point1D "Point 1" at 6.383238246276381, Neighbors: Point 0 (0.43915003704614364),
有2个生成点:
Point1D "Point 0" at 8.843803983191671, Neighbors: Point 8 (1.1272536955360408), Point 3 (1.561097922588882)
Point1D "Point 1" at 5.769064395124087, Neighbors: Point 9 (0.2901718634798556), Point 3 (1.5136416654787022)
Point1D "Point 2" at 3.1745401994446834, Neighbors: Point 7 (0.23098459949774464), Point 5 (0.2711748146393602)
Point1D "Point 3" at 7.28270606060279, Neighbors: Point 9 (1.2234698019988466), Point 1 (1.5136416654787022)
Point1D "Point 4" at 1.3174388168729179, Neighbors: Point 5 (1.5859265679324053), Point 7 (1.6261167830740209)
Point1D "Point 5" at 2.903365384805323, Neighbors: Point 7 (0.04019021514161558), Point 2 (0.2711748146393602)
Point1D "Point 6" at 3.8143932773804448, Neighbors: Point 2 (0.6398530779357614), Point 7 (0.870837677433506)
Point1D "Point 7" at 2.9435555999469387, Neighbors: Point 5 (0.04019021514161558), Point 2 (0.23098459949774464)
Point1D "Point 8" at 9.971057678727712, Neighbors: Point 0 (1.1272536955360408), Point 3 (2.6883516181249227)
Point1D "Point 9" at 6.059236258603943, Neighbors: Point 1 (0.2901718634798556), Point 3 (1.2234698019988466)
超过2分:
public static double distance(PointND p1, PointND p2)
尝试为Point2D和Point3D实现此功能,在单独的MathUtil.java
中使用{{1}}。