【问题标题】:A fast algorithm to minimize a pseudo Diophantine equation一种最小化伪丢番图方程的快速算法
【发布时间】:2023-03-29 00:51:02
【问题描述】:

我们正在寻找一种算法来在 O(N) 内解决这个问题。

给定两个实数 a 和 b(不失一般性,您可以假设它们都在 0 和 1 之间) 求一个介于 -N 和 N 之间的整数 n,使表达式最小化:

|a n - b - 圆形(a n - b)|

我们认为欧几里得算法可能适用于此,但无法弄清楚。看起来应该有比通过对整数 n 进行详尽搜索更快的方法来做到这一点。

注意:在我们的情况下,a 和 b 可能会经常变化,因此可以将 a 和 b 固定为查找表,因为 N 也可以变化,所以它有点难看。尚未详细查看查找表,看看我们可以将它作为 N 的函数得到多小。

【问题讨论】:

  • 如果您计划测试 k 个不同的 ns,那么我可以提供一个解决方案,保证 |a n - b - round(a n - b)|
  • 我们正在搜索所有 n 个整数,使得 |n|

标签: algorithm minimum number-theory


【解决方案1】:

听起来您可能正在寻找类似continued fractions...

它们有什么关系?假设你可以用有理数 b1/b2 代替 b。现在您正在寻找整数 n 和 m,使得 an-b1/b2 大约为 m。换句话说,你正在寻找 n 和 m 使得 (m+(b1/b2))/n = (mb2+b1)/nb1,一个有理数,大约是 a。设置 a1 = mb2+b1 和 a2 = nb1。从连分式逼近中找出 a1 和 a2 的值并求解 n 和 m。

另一种方法可能是这样的:

  1. 为 a 和 b 找到一个好的有理近似值:a ~ a1/a2 和 b ~ b1/b2。
  2. 对 n 和 m 求解 n(a1/a2)-(b1/b2) = m。

我不太确定它是否会起作用。 a 所需的精度取决于 n 和 b。

【讨论】:

  • 我确信他知道什么是连分数,但这究竟有什么帮助呢?
  • 您看不到与寻找实数有理近似值的相似之处吗?我太累了,现在无法提出一个像样的论点。
  • @JoniSalonen 在这里找到有理逼近!= 解决方案。即使 x/y 约等于 a,|ya-round(ya)|可能仍然很高。例如:a= 0.1111111110874642873287.... x=1, y=9 是一个很好的近似值。但是|9*a - 圆(9*a)|大约等于 1。
  • 编辑了答案以使想法更清晰。 @ElKamina 不会 |9*a - round(9*a)|更像 .0000000002128214140417 而不是 1?
【解决方案2】:

您正在有效地搜索使表达式aN - b 尽可能接近整数的整数N。 ab 是固定的吗?如果是,您可以预先计算一个查找表并拥有 O(1) :-)

如果不考虑寻找使所有整数IaN 接近I + b 的N。

【讨论】:

  • a 和 b 不幸的是没有修复。我们已经想到了。我们曾考虑为 N small 建立 N 个查找表,但这是用 O(N) 空间换取 O(1) 速度,我们通常不喜欢这种方法,但这是我们的后备立场。
  • 您是否尝试绘制方程式并尝试一些启发式方法?
  • 不,对这个启发式方法不太感兴趣。
  • 这至少可以提供一些见解。 ab 是精度有限的实数还是浮点整数?
  • 可能浮动,可能翻倍。这是要在计算机上实现的东西。
【解决方案3】:

您可以计算比率 a/b 的连分数。当分母大于N,或者当您的近似值足够好时,您可以停止。

// Initialize:
double ratio = a / b;
int ak = (int)(ratio);
double remainder = ratio - ak;

int n0 = 1;
int d0 = 0;

int n1 = ak;
int d1 = 1;

do {
    ratio = 1 / remainder;
    ak = (int)ratio;
    int n2 = ak * n1 + n0;
    int d2 = ak * d1 + d0;
    n0 = n1;
    d0 = d1;
    n1 = n2;
    d1 = d2;
    remainder = ratio - ak;
} while (d1 < N);

您要查找的n 的值是d0(或d1,如果它仍然小于N)。

这不一定给你最小的解决方案,但它可能是一个非常好的近似值。

【讨论】:

  • 需要最低限度。为什么我要查找的数字是 d0 或 d1?
【解决方案4】:

首先,让我们考虑一个更简单的情况,其中 b=0 且 0

令 step_size = 1

Step 1. Let v=a
Step 2. Let period size p = upper_round( 1/v ).
Step 3. Now, for n=1..p, there must be a number i such that F(v,i) < v.
Step 4. v = F(v,i), step_size = stepsize * i
Step 5. Go to step 2

如您所见,您可以将 F(v, *) 降低到您想要的任何级别。最终解 n = step_size。

【讨论】:

  • 如果 b = 0,则令 n = 0(n 介于 -N 和 N 之间),我们得到表达式为零。我假设您正在查看 n 介于 1 和 N 之间的子问题?你能描述一下你的算法在做什么吗?看起来像是某种连分数表达式?
  • @John 这给出了一个介于 1 和无穷大之间的解决方案。现在我详细看到了你的问题,是的,它对你的问题不起作用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-12
相关资源
最近更新 更多