fork download
  1. class Smooth {
  2. public static void main(String[] args) {
  3. testar(0.05, 10, 40, 50, 20, 35);
  4. testar(0.34, 22, 18);
  5. testar(0.25, 260, 350, 430, 280, 640, 650, 240, 430, 320, 585, 385, 450, 760, 690, 400);
  6. testar(null, 128, 180, 96, 108, 130, 150, 165, 139, 140, 165, 290, 190, 210, 240, 235);
  7. testar(null, 36, 48, 26, 31, 57, 42, 26, 23, 18, 25, 18, 36, 41, 18, 22);
  8. }
  9.  
  10. private static void testar(Double a, double... d) {
  11. System.out.println("Valores: " + java.util.Arrays.toString(d));
  12. if (a != null) {
  13. double r = smooth(a, d);
  14. System.out.println("Taxa: " + a + " - resultado: " + r);
  15. double b = smoothRatio(r, d);
  16. System.out.println("Taxa (prova real): " + b);
  17. }
  18. double p = bestSmooth(d);
  19. System.out.println("Melhor taxa: " + p + " - resultado: " + smooth(p, d));
  20. System.out.println();
  21. }
  22.  
  23. public static double smooth(double a, double... d) {
  24. double soma = 0.0;
  25. double potencia = 1.0;
  26. for (int i = d.length - 1; i >= 0; i--) {
  27. soma += a * potencia * d[i];
  28. potencia *= 1.0 - a;
  29. }
  30. return soma;
  31. }
  32.  
  33. public static double bestSmooth(double... d) {
  34. double v1 = 0.0;
  35. double v5 = 1.0;
  36. while (true) {
  37. double v3 = (v1 + v5) / 2;
  38. if (v3 == v1 || v3 == v5) return v3;
  39. double s1 = smooth(v1, d);
  40. double s3 = smooth(v3, d);
  41. double s5 = smooth(v5, d);
  42. if (s5 >= s3 && s5 >= s1) {
  43. v1 = v3;
  44. } else if (s1 >= s3 && s1 >= s5) {
  45. v5 = v3;
  46. } else {
  47. double v2 = (v1 + v3) / 2;
  48. double v4 = (v3 + v5) / 2;
  49. double s2 = smooth(v2, d);
  50. double s4 = smooth(v4, d);
  51. if (s4 >= s3 && s4 >= s5) {
  52. v1 = v3;
  53. v3 = v4;
  54. } else if (s2 >= s3 && s2 >= s1) {
  55. v5 = v3;
  56. v3 = v2;
  57. } else if (s3 >= s2 && s3 >= s4) {
  58. v1 = v2;
  59. v5 = v4;
  60. }
  61. }
  62. }
  63. }
  64.  
  65. private static boolean ordered(double a, double b, double c) {
  66. return (a <= b && b <= c) || (c <= b && b <= a);
  67. }
  68.  
  69. public static double smoothRatio(double total, double... d) {
  70. double minA = 0.0;
  71. double maxA = bestSmooth(d);
  72. double smoothMin = smooth(minA, d);
  73. double smoothMax = smooth(maxA, d);
  74. if (!ordered(smoothMin, total, smoothMax)) {
  75. throw new IllegalArgumentException(total + " " + smoothMin + " " + smoothMax + " " + minA + " " + maxA);
  76. }
  77.  
  78. while (true) {
  79. if (total == smoothMin) return minA;
  80. if (total == smoothMax) return maxA;
  81. double mid = minA + (maxA - minA) / 2;
  82. if (mid == minA) return smoothMin;
  83. if (mid == maxA) return smoothMax;
  84. double smoothMid = smooth(mid, d);
  85. if (ordered(smoothMid, total, smoothMax)) {
  86. minA = mid;
  87. smoothMin = smoothMid;
  88. } else if (ordered(smoothMid, total, smoothMin)) {
  89. maxA = mid;
  90. smoothMax = smoothMid;
  91. }
  92. }
  93. }
  94. }
Success #stdin #stdout 0.05s 4386816KB
stdin
Standard input is empty
stdout
Valores: [10.0, 40.0, 50.0, 20.0, 35.0]
Taxa: 0.05 - resultado: 7.078253125000002
Taxa (prova real): 0.05
Melhor taxa: 1.0 - resultado: 35.0

Valores: [22.0, 18.0]
Taxa: 0.34 - resultado: 11.056799999999999
Taxa (prova real): 0.33999999999999997
Melhor taxa: 0.9090909212827682 - resultado: 18.18181818181818

Valores: [260.0, 350.0, 430.0, 280.0, 640.0, 650.0, 240.0, 430.0, 320.0, 585.0, 385.0, 450.0, 760.0, 690.0, 400.0]
Taxa: 0.25 - resultado: 514.275442045182
Taxa (prova real): 0.24999999999999967
Melhor taxa: 0.3844731971623787 - resultado: 529.8357007856109

Valores: [128.0, 180.0, 96.0, 108.0, 130.0, 150.0, 165.0, 139.0, 140.0, 165.0, 290.0, 190.0, 210.0, 240.0, 235.0]
Melhor taxa: 0.9200836578384042 - resultado: 235.20144008802336

Valores: [36.0, 48.0, 26.0, 31.0, 57.0, 42.0, 26.0, 23.0, 18.0, 25.0, 18.0, 36.0, 41.0, 18.0, 22.0]
Melhor taxa: 0.21615071594715118 - resultado: 26.222890515272397