import numpy as np
from scipy.optimize import minimize
import math
def total_travel_time(d):
"""
Given an array d of 7 horizontal displacements (in leagues) for each segment,
compute the total travel time.
Each segment has a fixed vertical distance of 10 leagues. The travel distance in
segment i is L_i = sqrt(d_i^2 + 10^2). The speeds for the 7 segments are:
v0 = 10, v1 = 9, v2 = 8, v3 = 7, v4 = 6, v5 = 5, v6 = 10 (leagues/day).
The total time is:
T = sum_{i=0}^{6} L_i / v_i.
"""
speeds = [10, 9, 8, 7, 6, 5, 10]
T = 0.0
for i in range(7):
L = math.sqrt(d[i]**2 + 10**2)
T += L / speeds[i]
return T
def constraint_sum(d):
"""Constraint: sum of horizontal displacements must equal 100 leagues."""
return np.sum(d) - 100
# Initial guess: equally distribute 100 leagues among 7 segments.
d0 = np.full(7, 100/7)
# Set up the equality constraint and bounds (each d_i must be nonnegative)
cons = {'type': 'eq', 'fun': constraint_sum}
bnds = [(0, None) for _ in range(7)]
# Use SLSQP to minimize the total travel time
res = minimize(total_travel_time, d0, method='SLSQP', bounds=bnds, constraints=cons, options={'ftol': 1e-12})
if res.success:
optimal_d = res.x
T_opt = res.fun
# Recover the cumulative horizontal x–positions: x0 = 0, then x_i = sum_{j=1}^i d_j, and x7 = 100.
x_positions = np.concatenate(([0], np.cumsum(optimal_d), [100]))
print("Optimal horizontal displacements d_i (leagues):")
print(optimal_d)
print("\nCumulative x–positions:")
print(x_positions)
print("\nMinimum travel time = {:.13f} days".format(T_opt))
else:
print("Optimization did not converge.")
aW1wb3J0IG51bXB5IGFzIG5wCmZyb20gc2NpcHkub3B0aW1pemUgaW1wb3J0IG1pbmltaXplCmltcG9ydCBtYXRoCgpkZWYgdG90YWxfdHJhdmVsX3RpbWUoZCk6CiAgICAiIiIKICAgIEdpdmVuIGFuIGFycmF5IGQgb2YgNyBob3Jpem9udGFsIGRpc3BsYWNlbWVudHMgKGluIGxlYWd1ZXMpIGZvciBlYWNoIHNlZ21lbnQsCiAgICBjb21wdXRlIHRoZSB0b3RhbCB0cmF2ZWwgdGltZS4KICAgIAogICAgRWFjaCBzZWdtZW50IGhhcyBhIGZpeGVkIHZlcnRpY2FsIGRpc3RhbmNlIG9mIDEwIGxlYWd1ZXMuIFRoZSB0cmF2ZWwgZGlzdGFuY2UgaW4KICAgIHNlZ21lbnQgaSBpcyBMX2kgPSBzcXJ0KGRfaV4yICsgMTBeMikuIFRoZSBzcGVlZHMgZm9yIHRoZSA3IHNlZ21lbnRzIGFyZToKICAgICAgICB2MCA9IDEwLCB2MSA9IDksIHYyID0gOCwgdjMgPSA3LCB2NCA9IDYsIHY1ID0gNSwgdjYgPSAxMCAobGVhZ3Vlcy9kYXkpLgogICAgCiAgICBUaGUgdG90YWwgdGltZSBpczoKICAgICAgICBUID0gc3VtX3tpPTB9Xns2fSBMX2kgLyB2X2kuCiAgICAiIiIKICAgIHNwZWVkcyA9IFsxMCwgOSwgOCwgNywgNiwgNSwgMTBdCiAgICBUID0gMC4wCiAgICBmb3IgaSBpbiByYW5nZSg3KToKICAgICAgICBMID0gbWF0aC5zcXJ0KGRbaV0qKjIgKyAxMCoqMikKICAgICAgICBUICs9IEwgLyBzcGVlZHNbaV0KICAgIHJldHVybiBUCgpkZWYgY29uc3RyYWludF9zdW0oZCk6CiAgICAiIiJDb25zdHJhaW50OiBzdW0gb2YgaG9yaXpvbnRhbCBkaXNwbGFjZW1lbnRzIG11c3QgZXF1YWwgMTAwIGxlYWd1ZXMuIiIiCiAgICByZXR1cm4gbnAuc3VtKGQpIC0gMTAwCgojIEluaXRpYWwgZ3Vlc3M6IGVxdWFsbHkgZGlzdHJpYnV0ZSAxMDAgbGVhZ3VlcyBhbW9uZyA3IHNlZ21lbnRzLgpkMCA9IG5wLmZ1bGwoNywgMTAwLzcpCgojIFNldCB1cCB0aGUgZXF1YWxpdHkgY29uc3RyYWludCBhbmQgYm91bmRzIChlYWNoIGRfaSBtdXN0IGJlIG5vbm5lZ2F0aXZlKQpjb25zID0geyd0eXBlJzogJ2VxJywgJ2Z1bic6IGNvbnN0cmFpbnRfc3VtfQpibmRzID0gWygwLCBOb25lKSBmb3IgXyBpbiByYW5nZSg3KV0KCiMgVXNlIFNMU1FQIHRvIG1pbmltaXplIHRoZSB0b3RhbCB0cmF2ZWwgdGltZQpyZXMgPSBtaW5pbWl6ZSh0b3RhbF90cmF2ZWxfdGltZSwgZDAsIG1ldGhvZD0nU0xTUVAnLCBib3VuZHM9Ym5kcywgY29uc3RyYWludHM9Y29ucywgb3B0aW9ucz17J2Z0b2wnOiAxZS0xMn0pCgppZiByZXMuc3VjY2VzczoKICAgIG9wdGltYWxfZCA9IHJlcy54CiAgICBUX29wdCA9IHJlcy5mdW4KICAgICMgUmVjb3ZlciB0aGUgY3VtdWxhdGl2ZSBob3Jpem9udGFsIHjigJNwb3NpdGlvbnM6IHgwID0gMCwgdGhlbiB4X2kgPSBzdW1fe2o9MX1eaSBkX2osIGFuZCB4NyA9IDEwMC4KICAgIHhfcG9zaXRpb25zID0gbnAuY29uY2F0ZW5hdGUoKFswXSwgbnAuY3Vtc3VtKG9wdGltYWxfZCksIFsxMDBdKSkKICAgIAogICAgcHJpbnQoIk9wdGltYWwgaG9yaXpvbnRhbCBkaXNwbGFjZW1lbnRzIGRfaSAobGVhZ3Vlcyk6IikKICAgIHByaW50KG9wdGltYWxfZCkKICAgIHByaW50KCJcbkN1bXVsYXRpdmUgeOKAk3Bvc2l0aW9uczoiKQogICAgcHJpbnQoeF9wb3NpdGlvbnMpCiAgICBwcmludCgiXG5NaW5pbXVtIHRyYXZlbCB0aW1lID0gezouMTNmfSBkYXlzIi5mb3JtYXQoVF9vcHQpKQplbHNlOgogICAgcHJpbnQoIk9wdGltaXphdGlvbiBkaWQgbm90IGNvbnZlcmdlLiIp