提交 bd901895 编写于 作者: 三月三net's avatar 三月三net

Python超人-宇宙模拟器

上级 2342b5c6
import numpy as np
from common.consts import AU
from sim_scenes.solar_system.halley_comet_lib import HalleyCometParams
from sim_lab.halley_comet_research_calc import calc_simulator
def target_function(x, y, z):
params = HalleyCometParams(
start_time='1982-09-24 00:00:00',
# init_velocity=[-2.836 + (x / 1000), 4.705 + (y / 1000), 8.85 + (z / 1000)],
init_velocity=[x, y, z],
init_position=[0, -5 * AU, -10 * AU]
)
return calc_simulator(params)
def loss_function(a, b, c):
# 0.586AU, 35.1AU, 13817天
target_a = 0.586
target_b = 35.1
target_c = 13817.0
loss_a = (a - target_a) ** 2
loss_b = (b - target_b) ** 2
loss_c = (c - target_c) ** 2
total_loss = loss_a + loss_b + loss_c
return total_loss
def compute_gradients(x, y, z, epsilon=1e-5):
# 数值方法计算梯度
grad_x = (loss_function(*target_function(x + epsilon, y, z)) - loss_function(*target_function(x, y, z))) / epsilon
grad_y = (loss_function(*target_function(x, y + epsilon, z)) - loss_function(*target_function(x, y, z))) / epsilon
grad_z = (loss_function(*target_function(x, y, z + epsilon)) - loss_function(*target_function(x, y, z))) / epsilon
return grad_x, grad_y, grad_z
def adaptive_learning_rate(iteration):
# 自适应学习率调整
return 0.01 / np.sqrt(iteration + 1)
def gradient_descent(init_velocity, iterations):
x, y, z = init_velocity
for i in range(1, iterations + 1): # 从1开始,避免除以0
a, b, c = target_function(x, y, z)
loss = loss_function(a, b, c)
# 计算梯度
grad_x, grad_y, grad_z = compute_gradients(x, y, z)
# 自适应学习率调整
learning_rate = adaptive_learning_rate(i)
# 更新参数
x = x - learning_rate * grad_x
y = y - learning_rate * grad_y
z = z - learning_rate * grad_z
# 打印当前迭代的结果
if i % 100 == 0:
print(f"Iteration {i}: Loss = {loss}, a = {a}, b = {b}, c = {c}")
return x, y, z
# 设置初始值
init_velocity = [-2.816, 4.725, 8.87] # 请替换为实际的初始值
iterations = 1000
# 运行梯度下降算法
final_x, final_y, final_z = gradient_descent(init_velocity, iterations)
# 打印最终结果
final_a, final_b, final_c = target_function(final_x, final_y, final_z)
print(f"Final Result: a = {final_a}, b = {final_b}, c = {final_c}")
此差异已折叠。
import numpy as np
from common.consts import AU
from sim_scenes.solar_system.halley_comet_lib import HalleyCometParams
from sim_lab.halley_comet_research_calc import calc_simulator
def f(x, y, z):
params = HalleyCometParams(
start_time='1982-09-24 00:00:00',
# init_velocity=[-2.836 + (x / 1000), 4.705 + (y / 1000), 8.85 + (z / 1000)],
init_velocity=[x, y, z],
init_position=[0, -5 * AU, -10 * AU]
)
return calc_simulator(params)
from scipy.optimize import minimize
import numpy as np
# 定义损失函数
def loss_function(x, target):
# 定义损失函数,这里使用简单的平方差,并调整权重
weights = np.array([10, 1, 0.1]) # 调整权重,使近日点和远日点的偏差对最终结果的影响更大
return np.sum(weights * (x - target) ** 2)
# 定义目标函数
def target_function(v):
vx, vy, vz = v
result = f(vx, vy, vz)
# 计算损失函数,这里假设目标是 [0.586, 35.1, 13817]
target = np.array([0.586, 35.1, 13817])
loss = loss_function(result, target)
return loss
# 设置初始速度
initial_velocity = [-2.816, 4.725, 8.87] # 请替换为实际的初始值
# 设置初始速度时添加随机扰动
initial_velocity = [-2.816 + np.random.uniform(-1, 1), 4.725 + np.random.uniform(-1, 1), 8.87 + np.random.uniform(-1, 1)]
# 运行优化算法
result = minimize(target_function, initial_velocity, method='trust-constr', options={'maxiter': 10000, 'disp': True},
bounds=[(-100, 100), (-100, 100), (-100, 100)])
# 打印最终结果
final_velocity = result.x
print(f"Optimal Velocity: {final_velocity}")
#
# # # 定义目标函数
# # def f(vx, vy, vz):
# # # 这里需要根据你的实际情况定义哈雷彗星轨道的计算
# # # 返回近日点距离(单位:AU)、远日点距离(单位:AU)、以及哈雷彗星近日点到远日点花了多长时间(单位:天)
# # # 这里使用一个简单的示例,你需要根据实际情况修改
# # return np.array([0.586, 35.1, 13817])
#
# # 定义损失函数
# def loss_function(x, target):
# # 定义损失函数,这里使用简单的平方差
# return (x - target) ** 2
#
#
# # 定义目标函数
# def target_function(v):
# vx, vy, vz = v
# result = f(vx, vy, vz)
# # 计算损失函数,这里假设目标是 [0.586, 35.1, 13817]
# target = np.array([0.586, 35.1, 13817])
# loss = np.sum([loss_function(result[i], target[i]) for i in range(len(result))])
# return loss
#
#
# # 设置初始速度
# initial_velocity = [-2.816, 4.725, 8.87] # 请替换为实际的初始值
#
# # 运行优化算法
# # result = minimize(target_function, initial_velocity, method='BFGS',
# # options={'maxiter': 1000, 'disp': True}) # 使用BFGS优化算法,你可以尝试其他算法
#
# # 运行优化算法
# # result = minimize(target_function, initial_velocity, method='L-BFGS-B', options={'maxiter': 10000, 'disp': True})
#
# # 运行优化算法
# result = minimize(target_function, initial_velocity, method='trust-constr', options={'maxiter': 10000, 'disp': True},
# bounds=[(-100, 100), (-100, 100), (-100, 100)])
#
# # 打印最终结果
# final_velocity = result.x
# print(f"Optimal Velocity: {final_velocity}")
import numpy as np
import matplotlib.pyplot as plt
from common.consts import AU
from sim_scenes.solar_system.halley_comet_lib import HalleyCometParams
from sim_lab.halley_comet_research_calc import calc_simulator, target_function
# 支持中文
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
def plt_draw_3d():
# idx = 0
r = 1
xs = []
ys = []
zs = []
a_s = []
b_s = []
c_s = []
for xi in range(-r, r + 1):
for yi in range(-r, r + 1):
for zi in range(-r, r + 1):
x, y, z = -2.47 + (xi / 100), 5.1 + (yi / 100), 8.73 + (zi / 100)
xs.append(x)
ys.append(y)
zs.append(z)
a, b, c = target_function(x, y, z)
# a,b,c = x,y,z
a_s.append(a)
b_s.append(b)
c_s.append(c)
# 把 x y z 和 结果 a b c 进行可视化,完成代码,方便查看 x y z 和 结果 a b c 之间的关系
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot(xs, ys, zs, label="IN")
ax.plot(a_s, b_s, c_s, label="OUT")
# ax.scatter(xs, ys, zs, c='r', marker='o') # 绘制三维散点图,使用红色标记,可以根据需要更改颜色和标记类型
# ax.scatter(a_s, b_s, c_s, c='b', marker='o') # 在同样的图上,使用蓝色标记绘制函数的结果点
ax.legend()
plt.show()
import matplotlib.pyplot as plt
def plot_twin(t, _y1, _y2, _y3, xlabel, _ylabel1, _ylabel2, _ylabel3):
fig, ax1 = plt.subplots()
color = 'tab:blue'
ax1.set_xlabel(xlabel)
ax1.set_ylabel(_ylabel1, color=color)
ax1.plot(t, _y1, color=color)
ax1.tick_params(axis='y', labelcolor=color)
ax2 = ax1.twinx() # 创建共用x轴的第二个y轴
color = 'tab:red'
ax2.set_ylabel(_ylabel2, color=color)
ax2.plot(t, _y2, color=color)
ax2.tick_params(axis='y', labelcolor=color)
ax3 = ax1.twinx() # 创建共用x轴的第二个y轴
color = 'tab:green'
ax3.set_ylabel(_ylabel3, color=color)
ax3.plot(t, _y3, color=color)
ax3.tick_params(axis='y', labelcolor=color)
# fig.tight_layout()
plt.show()
def plt_draw_2d():
import numpy as np
t = np.array([1, 2, 3])
# 创建模拟数据
data1 = np.array([35.032, 35.033, 35.034])
data2 = np.array([0.477, 0.477, 0.477])
data3 = np.array([13615, 13615, 13615])
plot_twin(t, data1, data2, data3, 'exp', 'sine', 'year')
# target_function(-2.835, 4.71, 8.86) # 远日点:35.243 AU, 近日点:0.584 AU, 天数: 13809
# target_function(-2.835, 4.73, 8.85) # OK 远日点:35.251 AU, 近日点:0.585 AU, 天数: 13815
R = 3
X, Y, Z = -2.835, 4.73, 8.85
X, Y, Z = -2.835, 4.72, 8.847
# [-2.816, 4.725, 8.84]
def plt_draw_x():
x_s = []
a_s = []
b_s = []
c_s = []
for x in range(-R, R + 1):
x, y, z = X + (x / 100), Y, Z
x_s.append(x)
a, b, c = target_function(x, y, z)
a_s.append(a)
b_s.append(b)
c_s.append(c)
plot_twin(x_s, a_s, b_s, c_s, 'X', '远日点', '近日点', '天数')
def plt_draw_y():
y_s = []
a_s = []
b_s = []
c_s = []
for y in range(-R, R + 1):
x, y, z = X, Y + (y / 100), Z
y_s.append(y)
a, b, c = target_function(x, y, z)
a_s.append(a)
b_s.append(b)
c_s.append(c)
plot_twin(y_s, a_s, b_s, c_s, 'Y', '远日点', '近日点', '天数')
def plt_draw_z():
z_s = []
a_s = []
b_s = []
c_s = []
for z in range(-R, R + 1):
x, y, z = X, Y, Z + (z / 100)
z_s.append(z)
a, b, c = target_function(x, y, z)
a_s.append(a)
b_s.append(b)
c_s.append(c)
plot_twin(z_s, a_s, b_s, c_s, 'Z', '远日点', '近日点', '天数')
if __name__ == '__main__':
plt_draw_x()
plt_draw_y()
plt_draw_z()
...@@ -5,7 +5,18 @@ ...@@ -5,7 +5,18 @@
# date :2023-11-16 # date :2023-11-16
# link :https://gitcode.net/pythoncr/ # link :https://gitcode.net/pythoncr/
# python_version :3.9 # python_version :3.9
# ChatGPT
# ============================================================================== # ==============================================================================
"""
我把我的详细需求写给你,你帮我分析用什么方法。我要计算哈雷彗星在太阳系中某个位置上面的初始速度(vx, vy, vz) ,
通过万有引力的计算,哈雷彗星会在一个轨道上有2个点,近日点和远日点。哈雷彗星从近日点和远日点花了多长时间。
我现在定义了一个函数,f(vx,vy,vz) 参数就是初始速度(vx, vy, vz),
这个函数f返回3个值,分别是 近日点距离(单位:AU)、远日点距离(单位:AU)、以及哈雷彗星近日点到远日点花了多长时间(单位:天)。
我现在就是希望如果函数f返回值是 0.586AU, 35.1AU, 13817天,那么 vx,vy,vz的值是多少? 以上的需求,我用什么算法可以实现。
"""
import threading
from bodies import Body, Sun, Earth, Moon from bodies import Body, Sun, Earth, Moon
from objs import Obj, Satellite, Satellite2 from objs import Obj, Satellite, Satellite2
from common.consts import SECONDS_PER_HOUR, SECONDS_PER_DAY, SECONDS_PER_WEEK, SECONDS_PER_MONTH from common.consts import SECONDS_PER_HOUR, SECONDS_PER_DAY, SECONDS_PER_WEEK, SECONDS_PER_MONTH
...@@ -110,6 +121,8 @@ def calc_simulator(params): ...@@ -110,6 +121,8 @@ def calc_simulator(params):
sim.total_times = 0 sim.total_times = 0
sim.build() sim.build()
sim.result = None
def on_ready(context: CalcContext): def on_ready(context: CalcContext):
# for body in sim.bodies: # for body in sim.bodies:
# body.reset() # body.reset()
...@@ -198,8 +211,8 @@ def calc_simulator(params): ...@@ -198,8 +211,8 @@ def calc_simulator(params):
2023年12月9日 - 1986年2月9日 = 13817 2023年12月9日 - 1986年2月9日 = 13817
35.1AU 0.586AU 35.1AU 0.586AU
""" """
if abs(comet_peri - 0.586) < 0.01 and abs(comet_aphel - 35.1) < 0.1 and (diff_days - 13817) < 2: if abs(comet_peri - 0.586) < 0.01 and abs(comet_aphel - 35.1) < 0.1 and abs(diff_days - 13817) < 2:
print("OK ......",comet_peri,comet_aphel,diff_days) print("OK ......", comet_peri, comet_aphel, diff_days)
# print("year days:", time_data.years, time_data.days) # print("year days:", time_data.years, time_data.days)
# print("远日点: %.3f AU(%s)" % (sim.comet_aphel / AU, sim.comet_aphel_dt)) # print("远日点: %.3f AU(%s)" % (sim.comet_aphel / AU, sim.comet_aphel_dt))
# print("近日点: %.3f AU(%s)" % (sim.comet_peri / AU, sim.comet_peri_dt)) # print("近日点: %.3f AU(%s)" % (sim.comet_peri / AU, sim.comet_peri_dt))
...@@ -207,9 +220,14 @@ def calc_simulator(params): ...@@ -207,9 +220,14 @@ def calc_simulator(params):
# print("远\近日天数: %i 天 " % (sim.comet_aphel_dt[2] - sim.comet_peri_dt[2])) # print("远\近日天数: %i 天 " % (sim.comet_aphel_dt[2] - sim.comet_peri_dt[2]))
def on_finished(context: CalcContext): def on_finished(context: CalcContext):
global result
# print("on_finished", context) # print("on_finished", context)
time_data = context.get_param("time_data") time_data = context.get_param("time_data")
log(time_data) log(time_data)
comet_aphel = sim.comet_aphel / AU
comet_peri = sim.comet_peri / AU
diff_days = sim.comet_aphel_dt[2] - sim.comet_peri_dt[2]
sim.result = (comet_aphel, comet_peri, float(diff_days))
CalcSimulator.on_ready_subscription(on_ready) CalcSimulator.on_ready_subscription(on_ready)
CalcSimulator.on_after_evolve_subscription(after_evolve) CalcSimulator.on_after_evolve_subscription(after_evolve)
...@@ -218,13 +236,58 @@ def calc_simulator(params): ...@@ -218,13 +236,58 @@ def calc_simulator(params):
calc_run(sim.bodies, SECONDS_PER_YEAR, evolve_next=evolve_next) calc_run(sim.bodies, SECONDS_PER_YEAR, evolve_next=evolve_next)
return sim.result
if __name__ == '__main__':
def target_function(x, y, z):
params = HalleyCometParams( params = HalleyCometParams(
start_time='1982-09-24 00:00:00', start_time='1982-09-24 00:00:00',
init_velocity=[-2.836, 4.705, 8.85], # init_velocity=[-2.836 + (x / 1000), 4.705 + (y / 1000), 8.85 + (z / 1000)],
init_velocity=[x, y, z],
init_position=[0, -5 * AU, -10 * AU] init_position=[0, -5 * AU, -10 * AU]
) )
return calc_simulator(params)
if __name__ == '__main__':
pass
# 2023年12月9日 - 1986年2月9日 = 13817
# 35.1AU 0.586AU
# target_function(-2.836, 4.705, 8.85)
# target_function(-2.816, 4.725, 8.86) # 远日点:35.276 AU, 近日点:0.576 AU, 天数: 13821
# target_function(-2.816, 4.725, 8.855) # 远日点:35.212 AU, 近日点:0.576 AU, 天数: 13785
# target_function(-2.816, 4.725, 8.857) # 远日点:35.237 AU, 近日点:0.576 AU, 天数: 13797
# target_function(-2.816, 4.725, 8.858) # 远日点:35.251 AU, 近日点:0.576 AU, 天数: 13809
# target_function(-2.81, 4.725, 8.858) # 远日点:35.230 AU, 近日点:0.573 AU, 天数: 13791
# target_function(-2.81, 4.735, 8.858) # 远日点:35.297 AU, 近日点:0.573 AU, 天数: 13834
# target_function(-2.81, 4.73, 8.858) # 远日点:35.264 AU, 近日点:0.573 AU, 天数: 13815
# target_function(-2.820, 4.73, 8.858) # 远日点:35.298 AU, 近日点:0.578 AU, 天数: 13834
# target_function(-2.820, 4.73, 8.85) # 远日点:35.196 AU, 近日点:0.578 AU, 天数: 13779
# target_function(-2.825, 4.73, 8.85) # 远日点:35.215 AU, 近日点:0.581 AU, 天数: 13791
# target_function(-2.825, 4.73, 8.848) # 远日点:35.190 AU, 近日点:0.581 AU, 天数: 13773
# x, y, z => a, b, c
# x=a,b,c
# y=a,c
# z=a,c
# target_function(-2.835, 4.72, 8.847) # 远日点:35.144 AU, 近日点:0.586 AU, 天数: 13748
# target_function(-2.835, 4.71, 8.86) # 远日点:35.243 AU, 近日点:0.584 AU, 天数: 13809
# target_function(-2.835, 4.73, 8.85) # OK 远日点:35.251 AU, 近日点:0.585 AU, 天数: 13815
a, b, c = target_function(-2.47, 5.13, 8.73)
# [-2.5, 5.02, 8.763] 远日点:35.032 AU, 近日点:0.477 AU, 天数: 13615
# [-2.835, 4.81, 8.8] 远日点:35.161 AU, 近日点:0.591 AU, 天数: 13754
# [-2.835, 4.8, 8.81] 远日点:35.220 AU, 近日点:0.590 AU, 天数: 13797
# [-2.835, 4.8, 8.8], 远日点:35.092 AU, 近日点:0.590 AU, 天数: 13718
# [-2.835, 4.83, 8.8] 远日点:35.299 AU, 近日点:0.592 AU, 天数: 13846
# [-2.835, 4.75, 8.83] 远日点:35.132 AU, 近日点:0.588 AU, 天数: 13742
# [-2.835, 4.74, 8.84] 远日点:35.191 AU, 近日点:0.587 AU, 天数: 13779
# [-2.835, 4.79, 8.8] 远日点:35.025 AU, 近日点:0.589 AU, 天数: 13682
# params = HalleyCometParams(
# start_time='1982-09-24 00:00:00',
# init_velocity=[-2.836, 4.705, 8.85],
# init_position=[0, -5 * AU, -10 * AU]
# )
# year days: 42 6 # year days: 42 6
# 远日点: 35.086 AU((40, 346, 14946.8522)) # 远日点: 35.086 AU((40, 346, 14946.8522))
# 近日点: 0.586 AU((3, 133, 1228.3418)) # 近日点: 0.586 AU((3, 133, 1228.3418))
...@@ -233,16 +296,16 @@ if __name__ == '__main__': ...@@ -233,16 +296,16 @@ if __name__ == '__main__':
# for x in range(-2,2): # for x in range(-2,2):
# for y in range(-2, 2): # for y in range(-2, 2):
# for z in range(-2, 2): # for z in range(-2, 2):
idx = 0
r = 2 # def t():
for x in range(-r, r+1): # global idx
for y in range(-r, r+1): # params = HalleyCometParams(
for z in range(-r, r+1): # start_time='1982-09-24 00:00:00',
params = HalleyCometParams( # init_velocity=[-2.836 + (x / 100), 4.705 + (y / 100), 8.85 + (z / 100)],
start_time='1982-09-24 00:00:00', # init_position=[0, -5 * AU, -10 * AU]
init_velocity=[-2.836 + (x / 100), 4.705 + (y / 100), 8.85 + (z / 100)], # )
init_position=[0, -5 * AU, -10 * AU] # idx += 1
) # print(f"Index:{idx} ---------------------------")
idx += 1 # calc_simulator(params)
print(f"Index:{idx} ---------------------------") # # threading.Thread(target=t).start()
calc_simulator(params) # t()
...@@ -227,7 +227,8 @@ if __name__ == '__main__': ...@@ -227,7 +227,8 @@ if __name__ == '__main__':
# 2019年5月6日 34.772 # 2019年5月6日 34.772
params = HalleyCometParams( params = HalleyCometParams(
start_time='1982-09-24 00:00:00', start_time='1982-09-24 00:00:00',
init_velocity=[-2.836, 4.705, 8.85], init_velocity=[-2.835, 4.72, 8.847],
# init_velocity=[-2.836, 4.705, 8.85],
init_position=[0, -5 * AU, -10 * AU] init_position=[0, -5 * AU, -10 * AU]
) )
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册