fork download
  1. import math
  2.  
  3. # --- problem setup ---
  4. A = (0.0, 0.0)
  5. B = (100.0, 0.0)
  6. L = [25.0, 15.0, 5.0, -5.0, -15.0, -25.0] # marsh‑boundary offsets
  7. speeds = [10.0, 9.0, 8.0, 7.0, 6.0, 5.0, 10.0] # segment speeds
  8.  
  9. def total_time(x_vec):
  10. # build crossing points
  11. pts = [A]
  12. for xi, Li in zip(x_vec, L):
  13. yi = xi - 50.0 + Li * math.sqrt(2)
  14. pts.append((xi, yi))
  15. pts.append(B)
  16. # sum segment times
  17. t = 0.0
  18. for i in range(len(speeds)):
  19. x0, y0 = pts[i]
  20. x1, y1 = pts[i+1]
  21. d = math.hypot(x1 - x0, y1 - y0)
  22. t += d / speeds[i]
  23. return t
  24.  
  25. # initial guess: direct route intersections
  26. x = [50.0 - Li * math.sqrt(2) for Li in L]
  27.  
  28. # gradient descent parameters
  29. alpha = 1.0
  30. eps = 1e-6
  31. tol = 1e-8
  32. max_iters = 10000
  33.  
  34. def numerical_grad(f, x):
  35. grad = [0.0]*len(x)
  36. for i in range(len(x)):
  37. x_eps_p = x.copy(); x_eps_p[i] += eps
  38. x_eps_m = x.copy(); x_eps_m[i] -= eps
  39. grad[i] = (f(x_eps_p) - f(x_eps_m)) / (2*eps)
  40. return grad
  41.  
  42. for _ in range(max_iters):
  43. g = numerical_grad(total_time, x)
  44. # compute new candidate
  45. x_new = [xi - alpha*gi for xi, gi in zip(x, g)]
  46. if total_time(x_new) < total_time(x):
  47. x = x_new
  48. else:
  49. alpha *= 0.5
  50. if math.sqrt(sum(gi*gi for gi in g)) < tol:
  51. break
  52.  
  53. opt_time = total_time(x)
  54. print(f"Optimal time: {opt_time:.10f} days")
Success #stdin #stdout 1.15s 14184KB
stdin
Standard input is empty
stdout
Optimal time: 13.1265108588 days