Вам нужно найти какое-то ограничение для вашей системы и работать, чтобы удержать его в разумных пределах. Я провел несколько симуляций молекулярных столкновений, и в этих системах полная энергия сохраняется, поэтому каждый шаг я дважды проверяю общую энергию системы и, если она изменяется по некоторому порогу, то я знаю, что мой временной шаг был выбран неправильно (слишком большой или слишком маленький), и я выбираю новый временной шаг и перезапускаю его. Таким образом, я могу отслеживать, что происходит с системой в режиме реального времени.
Для этой симуляции я не знаю, какое у вас есть консервативное количество, но если оно у вас есть, вы можете попытаться сохранить его постоянным. Помните, что уменьшение вашего временного шага не всегда увеличивает точность, вам нужно оптимизировать размер шага с той точностью, которую вы имеете. Я провел численное моделирование в течение нескольких недель процессорного времени, и сохраненные величины всегда были в пределах 1 части в 10 ^ 8, так что возможно, вам просто нужно поэкспериментировать с некоторыми.
Кроме того, как сказал Томалак, возможно, старайтесь всегда ссылаться на вашу систему во время запуска, а не на предыдущий шаг. Поэтому вместо того, чтобы постоянно перемещать свои хромосомы, держите хромосомы на их начальном месте и сохраняйте с ними матрицу трансформации, которая приведет вас к текущему местоположению. Когда вы вычисляете свое новое вращение, просто измените матрицу преобразования. Это может показаться глупым, но иногда это работает хорошо, потому что ошибки в среднем равны 0.
Например, допустим, у меня есть частица, которая находится в точке (x, y), и на каждом шагу я вычисляю (dx, dy) и перемещаю частицу. Пошаговый способ сделал бы это
t0 (x0,y0)
t1 (x0,y0) + (dx,dy) -> (x1, y1)
t2 (x1,y1) + (dx,dy) -> (x2, y2)
t3 (x2,y2) + (dx,dy) -> (x3, y3)
t4 (x3,30) + (dx,dy) -> (x4, y4)
...
Если вы всегда ссылаетесь на t0, вы можете сделать это
t0 (x0, y0) (0, 0)
t1 (x0, y0) (0, 0) + (dx, dy) -> (x0, y0) (dx1, dy1)
t2 (x0, y0) (dx1, dy1) + (dx, dy) -> (x0, y0) (dx2, dy2)
t3 (x0, y0) (dx2, dy2) + (dx, dy) -> (x0, y0) (dx3, dy3)
Таким образом, в любое время, tn, чтобы получить реальную позицию, вы должны сделать (x0, y0) + (dxn, dyn)
Теперь для простого перевода, такого как мой пример, вы, вероятно, не очень выиграете. Но для ротации это может быть спасением. Просто сохраните матрицу с углами Эйлера, связанными с каждой хромосомой, и обновите ее, а не фактическое положение хромосомы. По крайней мере, так они не уплывут.