本项目的目的是生成一个交互式物流地图。用户可以单击所生成的图片,在这一点上放大图片。
这是逻辑映射方程:

这是我的节目:
public class LogisticMap {
public static double returnLogisticEquation(double x, double r) {
return r * x * (1 - x);
}
public static double ignoreFirstIterations(int numberOfIterations, double x, double r) {
for (int i = 0; i < numberOfIterations; i++) {
x = returnLogisticEquation(x, r);
}
return x;
}
public static void drawLogisticMap(int numberOfHorizontalPoints, int numberOfVerticalPoints, double leftOfRInterval, double rightOfRInterval, double x) {
StdDraw.setYscale(0, 1);
StdDraw.enableDoubleBuffering();
double subintervalLength = (rightOfRInterval - leftOfRInterval) / numberOfHorizontalPoints;
int numberOfIterations = 1000;
for (double r = leftOfRInterval; r < rightOfRInterval; r += subintervalLength) {
x = ignoreFirstIterations(numberOfIterations, x, r);
for (int p = 0; p < numberOfVerticalPoints; p++) {
x = returnLogisticEquation(x, r);
StdDraw.point(r, x);
}
}
StdDraw.show();
}
public static void interactiveLogisticMap(int numberOfHorizontalPoints, int numberOfVerticalPoints, double leftOfRInterval, double rightOfRInterval, double x) {
StdDraw.setXscale(leftOfRInterval, rightOfRInterval);
drawLogisticMap(numberOfHorizontalPoints, numberOfVerticalPoints, leftOfRInterval, rightOfRInterval, x);
double r = 0;
double y = 0;
double scale = 0.05;
while (true) {
if (StdDraw.isMousePressed()) {
r = StdDraw.mouseX();
y = StdDraw.mouseY();
double newLeftOfRInterval = r - scale;
double newRightOfRInterval = r + scale;
double belowRInterval = y - scale;
double aboveRInterval = y + scale;
StdDraw.setXscale(newLeftOfRInterval, newRightOfRInterval);
StdDraw.setYscale(belowRInterval, aboveRInterval);
StdDraw.clear();
drawLogisticMap(numberOfHorizontalPoints, numberOfVerticalPoints, newLeftOfRInterval, newRightOfRInterval, x);
scale /= 10;
}
}
}
public static void main(String[] args) {
StdDraw.setCanvasSize(850, 850);
int numberOfHorizontalPoints = 800;
int numberOfVerticalPoints = 1000;
double leftOfRInterval = 2.4;
double rightOfRInterval = 4;
double x = Math.random();
interactiveLogisticMap(numberOfHorizontalPoints, numberOfVerticalPoints, leftOfRInterval, rightOfRInterval, x);
}
}StdDraw是由“计算机科学”( Computer )一书的作者编写的一种简单的API。我检查了我的程序就行了。这就是其中的一个例子。
产出(实际上是一系列产出):


有什么办法可以改进我的计划吗?
感谢您的关注。
发布于 2020-10-25 19:58:19
public static double returnLogisticEquation(double x, double r) {这个名称并不完全正确,因为它返回的是方程的结果,而不是方程本身,所以更像calculateLogisticEquation。
public static double returnLogisticEquation(double x, double r) {
return r * x * (1 - x);
}我对这件事很感兴趣。通常,我说你只允许在处理维度时使用单字母变量(是的,这也不允许"i“、"j”、"k“)。然而,在实现数学函数时,可能有一个使用它们的理由。然而,使用长名称可能仍然是一个改进:
public static double returnLogisticEquation(double populationRatio, double reproductionate) {
return reproductionRate * populationRatio * (1 - populationRatio);
}for (int i = 0; i < numberOfIterations; i++) {这就是我的意思:
for (int counter = 0; counter < numberOfIterations; counter++) {public static double ignoreFirstIterations(int numberOfIterations, double x, double r) {我不确定这里的名称,也许forward(int numberOfIterations, ...)会是一个更好的名称,通常,我不会假设函数忽略了返回某项内容的内容。
public static double ignoreFirstIterations(int numberOfIterations, double x, double r) {
for (int i = 0; i < numberOfIterations; i++) {
x = returnLogisticEquation(x, r);
}
return x;
}为参数赋值是错误的样式。尽管你可以把它看作是另一个声明,但它可能会导致混乱。例如,如果您有一个对象作为参数,并且下面的行是:
thisIsAParameter.setValue("value");如果您有分配参数的习惯,那么现在需要检查在函数调用之前是否有不同的对象分配给参数。理想情况下,参数将是final,但这是相当嘈杂的。威胁他们为final。
int numberOfIterations = 1000;这不是迭代的次数,而是被忽略的迭代的次数。
r += subintervalLength记录在案:+=和其他速记操作符不是a = a + b的缩写,而是a = (TYPE_A)(a+b)的缩写,这可能会产生意想不到的结果。例如,intA = intA + 5.5d将产生一个错误,即double被截断为int。intA += 5.5d不会产生这样的错误。
public static void drawLogisticMap(int numberOfHorizontalPoints, int numberOfVerticalPoints, double leftOfRInterval, double rightOfRInterval, double x) {
StdDraw.setYscale(0, 1);
StdDraw.enableDoubleBuffering();
double subintervalLength = (rightOfRInterval - leftOfRInterval) / numberOfHorizontalPoints;
int numberOfIterations = 1000;
for (double r = leftOfRInterval; r < rightOfRInterval; r += subintervalLength) {
x = ignoreFirstIterations(numberOfIterations, x, r);
for (int p = 0; p < numberOfVerticalPoints; p++) {
x = returnLogisticEquation(x, r);
StdDraw.point(r, x);
}
}
StdDraw.show();
}再用几行空行来分组逻辑会很好(就像在其他函数中所做的那样)。
public static void drawLogisticMap(int numberOfHorizontalPoints, int numberOfVerticalPoints, double leftOfRInterval, double rightOfRInterval, double x) {
StdDraw.setYscale(0, 1);
StdDraw.enableDoubleBuffering();
double subintervalLength = (rightOfRInterval - leftOfRInterval) / numberOfHorizontalPoints;
int numberOfIterations = 1000;
for (double r = leftOfRInterval; r < rightOfRInterval; r += subintervalLength) {
x = ignoreFirstIterations(numberOfIterations, x, r);
for (int p = 0; p < numberOfVerticalPoints; p++) {
x = returnLogisticEquation(x, r);
StdDraw.point(r, x);
}
}
StdDraw.show();
}while (true) {如果可以包含动态中断条件,请这样做(比如侦听ESC)。
double r = 0;
double y = 0;声明使用它们的变量,以限制它们存在的范围以限制可能的错误。
double r = StdDraw.mouseX();
double y = StdDraw.mouseY();double scale = 0.05;这似乎更像是一个参数,或者是一个类级常量。
我还没有测试您的代码,也没有验证数学的正确性,但到目前为止看起来还不错。
https://codereview.stackexchange.com/questions/251135
复制相似问题