Javascript 两个相关函数的收敛算法

Javascript 两个相关函数的收敛算法,javascript,algorithm,convergence,Javascript,Algorithm,Convergence,我目前正在使用的javascript应用程序有问题。这是一种用于计算游艇船体静水力学数据的船只设计工具。 我遇到的问题是,我有两个相互关联的函数,它们都需要得到一个特定的结果 为了澄清,用户输入设计位移,船体向上或向下移动,直到浸没体积等于设计位移 用户还输入重心的纵向位置,并倾斜船体,直到浮力中心的纵向位置(浸没体积的质心)与重心对齐 然而,俯仰船体将改变位移,向上或向下移动船体将改变浮力中心的位置 我当前所做的(伪代码) function raiseAndPitch 而a

我目前正在使用的javascript应用程序有问题。这是一种用于计算游艇船体静水力学数据的船只设计工具。 我遇到的问题是,我有两个相互关联的函数,它们都需要得到一个特定的结果

为了澄清,用户输入设计位移,船体向上或向下移动,直到浸没体积等于设计位移

用户还输入重心的纵向位置,并倾斜船体,直到浮力中心的纵向位置(浸没体积的质心)与重心对齐

然而,俯仰船体将改变位移,向上或向下移动船体将改变浮力中心的位置

我当前所做的(伪代码)

function raiseAndPitch
而adesignVolume,则为else
上船
其他的
完成
a++
而bdesignCG.x
把船向前倾
否则,如果boat.cg.x
我有一个最大数量的递归。 然而,当一个或另一个参数的微小移动造成位移体积或浮力中心位置的巨大变化时,即使这两个参数有大量递归,有时也无法收敛

伪代码中未显示的是我收敛于值的方式,请指出它是否与我的问题相关,我将添加它


有没有更好的方法可以确保两个参数同时达到所需的值?

我会选择一些“损失函数”,比如(cur\u volume-desired\u volume)^2+(cur\u cg-desired\u cg)^2,它将等于0以获得完美的拟合。(加权任一项使其更重要。)然后,您可以搜索2元素增量(更新)向量(深度差、角度差),以减少损失函数;迭代选择一个好的向量:如果你有连续的函数来描述体积和重心,它们都是深度和角度的函数,你可以使用导数,否则只需对方向进行一些猜测。无论哪种方式,确保增量向量的大小较小。谢谢@j_random_hacker。这同样有效,但在某些情况下,它对俯仰或深度的极小变化非常敏感,因此增量向量应该非常小,从而大幅增加迭代次数。我使用了某种增量或减量的增量或减量,取决于它收敛或偏离解的速度。我保留了我原来的算法,并添加了你的算法作为后备算法。如果两者都不能正确收敛,我就从一个或另一个中选取最佳解。我想我应该读一下梯度下降算法。那有帮助吗?那可能会有帮助——恐怕我不是专家!但我发现其中一个参数的微小变化会导致结果的巨大变化。结果似乎是你需要非常精确的工具来建造这样一艘船;即使在船头的顶端插上一根羽毛,也能把一切都抛在脑后!这让我想知道你是否正确地计算了体积和重心(或者这种灵敏度在这种设计中是一个已知的困难吗?)。我会选择一些“损失函数”,比如(cur_volume-desired_volume)^2+(cur_CG-desired_CG)^2,它将等于0以获得完美的拟合。(加权任一项使其更重要。)然后,您可以搜索2元素增量(更新)向量(深度差、角度差),以减少损失函数;迭代选择一个好的向量:如果你有连续的函数来描述体积和重心,它们都是深度和角度的函数,你可以使用导数,否则只需对方向进行一些猜测。无论哪种方式,确保增量向量的大小较小。谢谢@j_random_hacker。这同样有效,但在某些情况下,它对俯仰或深度的极小变化非常敏感,因此增量向量应该非常小,从而大幅增加迭代次数。我使用了某种增量或减量的增量或减量,取决于它收敛或偏离解的速度。我保留了我原来的算法,并添加了你的算法作为后备算法。如果两者都不能正确收敛,我就从一个或另一个中选取最佳解。我想我应该读一下梯度下降算法。那有帮助吗?那可能会有帮助——恐怕我不是专家!但我发现其中一个参数的微小变化会导致结果的巨大变化。结果似乎是你需要非常精确的工具来建造这样一艘船;即使在船头的顶端插上一根羽毛,也能把一切都抛在脑后!这让我想知道你是否正确计算了体积和重心(或者这种设计中的灵敏度是已知的困难?)。
function raiseAndPitch
  while a < maxIterations
    if boat.volume < designVolume
      move boat down
    else if boat.volume > designVolume
      move boat up
    else
      done
    a++
  while b < maxIterations
    if boat.cg.x > designCG.x
      pitch boat forward
    else if boat.cg.x < designCG.x
      pitch boat aft
    else
      done
    b++

  if boat.cg.x == designCG.x && boat.volume == designVolume
    return data
  else
    raiseAndPitch