#java #loops #infinity
Вопрос:
Я хочу создать программу, которая будет вычислять линию наилучшего соответствия с помощью градиентного спуска. Это мой код:
import java.util.ArrayList;
import java.io.*;
import java.util.Scanner;
class Main {
public static double d0(double m, double b, ArrayList<Long> trueY) {
double res = 0;
for (int i = 0 ; i < trueY.size() ; i ) {
res =(m*i b)-trueY.get(i);
}
res = res/trueY.size();
return res;
}
public static double d1(double m, double b, ArrayList<Long> trueY) {
double res = 0;
for (int i = 0 ; i < trueY.size() ; i ) {
res =((m*i b)-trueY.get(i))*i;
}
res = res/trueY.size();
return res;
}
public static void main(String[] args) {
ArrayList<Long> trueY = new ArrayList<Long>();
try {
File myObj = new File("digdelnums.txt");
Scanner myReader = new Scanner(myObj);
while (myReader.hasNextLine()) {
long data = myReader.nextLong();
trueY.add(data);
}
myReader.close();
} catch (FileNotFoundException e) {
System.out.println("An error occurred.");
e.printStackTrace();
}
double alpha = 1;
double theta1 = 0, theta0 = 0;
double temp1 = theta1 - (alpha*d1(theta1, theta0, trueY));
double temp0 = theta0 - (alpha*d0(theta1, theta0, trueY));
/*
System.out.print(temp0);
System.out.print(" ");
System.out.println(temp1);
theta1 = temp1;
theta0 = temp0;
temp1 = theta1 - (alpha*d1(theta1, theta0, trueY));
temp0 = theta0 - (alpha*d0(theta1, theta0, trueY));
System.out.print(temp0);
System.out.print(" ");
System.out.println(temp1);
theta1 = temp1;
theta0 = temp0;
temp1 = theta1 - (alpha*d1(theta1, theta0, trueY));
temp0 = theta0 - (alpha*d0(theta1, theta0, trueY));
System.out.print(temp0);
System.out.print(" ");
System.out.println(temp1);
theta1 = temp1;
theta0 = temp0;
temp1 = theta1 - (alpha*d1(theta1, theta0, trueY));
temp0 = theta0 - (alpha*d0(theta1, theta0, trueY));
*/
while (!(theta0 == temp0 amp;amp; theta1 == temp1)) {
System.out.print(" temp0: ");
System.out.print(temp0);
System.out.print(" temp1: ");
System.out.println(temp1);
theta1 = temp1;
theta0 = temp0;
temp1 = alpha*d1(theta1, theta0, trueY);
temp0 = alpha*d0(theta1, theta0, trueY);
}
}
}
Единственная проблема в том, что после нескольких итераций цикла while temp1
начинается хранение Infinity
. Я понимаю, что было задано несколько вопросов о том, почему программа возвращает Бесконечность, но я не смог найти ответа. Я новичок в Java, поэтому буду признателен за любую помощь.
Ниже приведен вывод, который я получаю:
temp0: 3.316799084695052E8 temp1: 3.8386449054430206E11
temp0: 3.333863100377265E14 temp1: 3.861723799932096E17
temp0: 3.353910454100809E20 temp1: 3.884945309735452E23
temp0: 3.374078355415694E26 temp1: 3.9083064562814664E29
temp0: 3.3943675313588086E32 temp1: 3.931808079236908E35
temp0: 3.414778711184791E38 temp1: 3.9554510233215225E41
temp0: 3.4353126285334533E44 temp1: 3.979236138334556E47
temp0: 3.4559700214561855E50 temp1: 4.0031642791853155E53
temp0: 3.4767516324424656E56 temp1: 4.027236305923881E59
temp0: 3.497658208446524E62 temp1: 4.051453083772042E65
temp0: 3.518690500914227E68 temp1: 4.0758154831543767E71
temp0: 3.539849265810076E74 temp1: 4.1003243797295477E77
temp0: 3.5611352636443777E80 temp1: 4.1249806544217646E83
temp0: 3.582549259500566E86 temp1: 4.149785193452459E89
temp0: 3.604092023062723E92 temp1: 4.174738888372125E95
temp0: 3.625764328643213E98 temp1: 4.199842636092383E101
temp0: 3.647566955210562E104 temp1: 4.2250973389182087E107
temp0: 3.669500686417421E110 temp1: 4.250503904580352E113
temp0: 3.691566310628722E116 temp1: 4.276063246267989E119
temp0: 3.713764620950058E122 temp1: 4.30177628266152E125
temp0: 3.7360964152561505E128 temp1: 4.3276439379656014E131
temp0: 3.758562496219541E134 temp1: 4.353667141942356E137
temp0: 3.781163671339433E140 temp1: 4.379846829944819E143
temp0: 3.8039007529707466E146 temp1: 4.406183942950514E149
temp0: 3.8267745583532734E152 temp1: 4.432679427595307E155
temp0: 3.8497859096410823E158 temp1: 4.459334236207427E161
temp0: 3.872935633932059E164 temp1: 4.4861493268416895E167
temp0: 3.8962245632976413E170 temp1: 4.513125663313925E173
temp0: 3.919653534812707E176 temp1: 4.54026421523563E179
temp0: 3.943223390585679E182 temp1: 4.5675659580488296E185
temp0: 3.966934977788773E188 temp1: 4.595031873061107E191
temp0: 3.9907891486885487E194 temp1: 4.622662947480914E197
temp0: 4.014786760676322E200 temp1: 4.650460174453017E203
temp0: 4.038928676299206E206 temp1: 4.67842455309422E209
temp0: 4.063215763291015E212 temp1: 4.706557088529252E215
temp0: 4.08764889460342E218 temp1: 4.734858791926927E221
temp0: 4.1122289484374295E224 temp1: 4.763330680536456E227
temp0: 4.13695680827486E230 temp1: 4.791973777724022E233
temp0: 4.161833362910121E236 temp1: 4.820789113009571E239
temp0: 4.1868595064821813E242 temp1: 4.849777722103811E245
temp0: 4.212036138506666E248 temp1: 4.878940646945438E251
temp0: 4.2373641639082515E254 temp1: 4.90827893573858E257
temp0: 4.262844493053121E260 temp1: 4.9377936429904826E263
temp0: 4.2884780417817274E266 temp1: 4.967485829549406E269
temp0: 4.3142657314417016E272 temp1: 4.9973565626427493E275
temp0: 4.34020848892096E278 temp1: 5.027406915915427E281
temp0: 4.366307246681038E284 temp1: 5.0576379694684457E287
temp0: 4.392562942790594E290 temp1: 5.0880508098977176E293
temp0: 4.4189765209591106E296 temp1: 5.1186465303331416E299
temp0: 4.445548930570854E302 temp1: Infinity
temp0: NaN temp1: NaN
temp0: NaN temp1: NaN
temp0: NaN temp1: NaN
temp0: NaN temp1: NaN
temp0: NaN temp1: NaN
temp0: NaN temp1: NaN
temp0: NaN temp1: NaN
temp0: NaN temp1: NaN
temp0: NaN temp1: NaN
temp0: NaN temp1: NaN
temp0: NaN temp1: NaN
temp0: NaN temp1: NaN
temp0: NaN temp1: NaN
temp0: NaN temp1: NaN
temp0: NaN temp1: NaN
temp0: NaN temp1: NaN
temp0: NaN temp1: NaN
temp0: NaN temp1: NaN
temp0: NaN temp1: NaN
temp0: NaN temp1: NaN
temp0: NaN temp1: NaN
temp0: NaN temp1: NaN
temp0: NaN temp1: NaN
...
Комментарии:
1. Единственные места в программе, где я делю, — это строки 10 и 18, но
trueY.size()
они остаются постоянными (больше 1), поэтому я никогда не делюсь на ноль, верно?2.
res = res/(double) trueY.size();
3. Какая разница, что бы это значило @Darkman?
4. Какой метод возвращает бесконечность @okayatcp12? Очевидно, что у любого типа данных есть предел, поэтому, даже если вы не делите на ноль, вы можете получить бесконечность.
5. Я считаю, что метод, который возвращается
Infinity
, этоd1()
Ответ №1:
Тип double
данных в Java может соответствовать только Double.MAX_VALUE
(примерно 1.7E308
), и кажется, что вы довольно быстро поднимаетесь выше этого.
Вам следует заглянуть в BigDecimal
класс, если вам нужны большие значения.