确定线性丢番图方程非负值解存在性的算法

发布于 2024-08-05 09:15:33 字数 567 浏览 3 评论 0 原文

我正在寻找一种方法来确定方程是否有解,例如: 3n1+4n2+5n3=456,其中n1,n2,n3为正整数。

或者更一般地说:是否存在零或正整数n1,n2,n3...可以解方程k1n1+k2n2+k3n3...=m< /em> 其中 k1,k2,k3... 和 m 是已知的正整数。

我不需要找到解决方案 - 只需确定解决方案是否存在。

编辑:

关于该算法的实际使用:

在通信库中,我想在处理消息之前根据其大小确定给定消息是否有效。 例如:我知道一条消息包含零个或多个 3 字节元素、零个或多个 4 字节元素以及零个或多个 5 字节元素。我收到一条 456 字节的消息,我想在进一步检查其内容之前确定其有效性。 当然,消息的标头包含每种类型的元素数量,但我想通过传递诸如 pair 这样的内容来在通信库级别进行首次检查。 >

I am looking for a method to determine if there is a solution to equations such as:
3n1+4n2+5n3=456, where n1,n2,n3 are positive integers.

Or more general: are there zero or positive integers n1,n2,n3... that solves the equation k1n1+k2n2+k3n3...=m where k1,k2,k3... and m are known positive integers.

I don't need to find a solution - just to determine if a solution exist.

Edit:

Concerning the practical use of this algorithm:

In a communication library, I want to decide if a given message is valid according to its size, before handling the message.
For example: I know that a message contains zero-or-more 3-bytes elements, zero-or-more 4-bytes elements, and zero-or-more 5-bytes elements. I received a message of 456 bytes, and I want to determine its validity before further inspecting its content.
Of course the header of the message contains the number of elements of each type, but I want to make a first-inspection in the communication-library level by passing something like pair<MsgType,vector<3,4,5>>.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

猫弦 2024-08-12 09:15:33

您询问正则表达式

(xxx|xxxx|xxxxx)*

是否匹配 xx...x,其中 x 出现了 456 次。

这是 O(n+a^2) 的解决方案,其中 a 是左侧数字中最小的(在本例中为 3)。

假设你的数字是 6、7、15。我将用 6x+7y+15z 形式表示的数字称为“可用”。您要检查给定的号码是否可用。

如果你能够得到一些数字 n,那么你肯定能够得到 n+6、n+12、n+18 - 一般来说,对于所有 k >= 0,n+6k。另一方面,如果你无法得到某个数字n,那么n-6肯定也无法得到(如果你能得到(n-6),那么(n-6)+6=n将可用),这意味着n-12 、n-18、n-6k 也没有。

假设您确定 15 可用,但 9 不可用。在我们的例子中,15=6*0+7*0+15*1,但无论如何都无法得到 9。因此,根据我们之前的推理,15+6k 对于所有 k >= 0 可用,而 9-6k 对于所有 k >= 0 则不可用。如果你有一些数字除以 6 得到 3 作为余数(3、9、15、21,...),你可以快速回答:数字 <= 9 不可用,数字 >= 15 可用。

对于除以 6 的所有可能余数(即 0,1,2,3,4,5),确定可用的最小数是多少就足够了。 (我刚刚已经证明余数 3 的这个数字是 15)。

操作方法:创建一个包含顶点 0,1,2,3,4,5 的图。对于给定的所有数字 k (7,15 - 我们忽略 6),添加一条从 x 到 (x + k) mod 6 的边。赋予它权重 (x + k) div 6。使用 Dijkstra 算法 使用 0 作为初始节点。算法找到的距离将正是我们正在搜索的数字。

在我们的例子中 (6,7,15),数字 7 产生 0 -> 0。 1(权重1),1→ 2(权重1),2→ 3(权重1),...,5→ 0(权重1)和数字15给出0->; 3(权重2),1→ 4(权重2),...,5→ 1(重量2)。从 0 到 3 的最短路径有一条边 - 其权重为 2。因此 6*2 + 3 = 15 是余数为 3 的最小数。 6*1 + 3 = 9 不可用(好吧,我们之前手动检查过)。

与正则表达式有什么联系?好吧,每个正则表达式都有一个等效的有限自动机,我构建了其中一个。

这个问题,允许多个查询,出现在 波兰奥林匹克竞赛,我翻译了解决方案。现在,如果你听到有人说计算机科学对真正的程序员没有用,那就打他的脸。

You're asking if the regular expression

(xxx|xxxx|xxxxx)*

matches xx...x, where x occurs 456 times.

Here's a solution in O(n+a^2), where a is the smallest of the numbers on the left side (in this case 3).

Suppose your numbers are 6,7,15. I'll call a number expressible in the form 6x+7y+15z "available". You are to check if a given number is available.

If you're able to get some number n, then surely you will be able to get n+6, n+12, n+18 - in general, n+6k for all k >= 0. On the other side, if you are unable to get some number n, then n-6 is surely not available too (if you could get (n-6), then (n-6)+6=n would be available), this means n-12, n-18, n-6k are not available neither.

Suppose you have determined that 15 is available but 9 is not. In our case, 15=6*0+7*0+15*1 but won't be able to get 9 in any way. So, by our previous reasoning, 15+6k is available for all k >= 0 and 9-6k for all k >= 0 is not. If you've got some number that divided by 6 gives 3 as remainder (3, 9, 15, 21, ...) you can quickly answer: numbers <= 9 are not available, numbers >= 15 are.

It is enough to determine for all possible remainders of division by 6 (that is 0,1,2,3,4,5) what is the smallest number that is available. (I just have shown that this number for the remainder 3 is 15).

How to do it: Create a graph with vertices 0,1,2,3,4,5. For all numbers k that you are given (7,15 - we disregard 6) add an edge from x to (x + k) mod 6. Give it weight (x + k) div 6. Use Dijkstra's algorithm using 0 as the initial node. The distances found by the algorithm will be exactly those numbers we are searching for.

In our case (6,7,15) the number 7 gives rise to 0 -> 1 (weight 1), 1 -> 2 (weight 1), 2 -> 3 (weight 1), ..., 5 -> 0 (weight 1) and the number 15 gives 0 -> 3 (weight 2), 1 -> 4 (weight 2), ..., 5 -> 1 (weight 2). The shortest path from 0 to 3 has one edge - its weight is 2. So 6*2 + 3 = 15 is the smallest number that gives 3 as remainder. 6*1 + 3 = 9 is not available (well, we checked that previously by hand).

And what is the connection to regular expressions? Well, every regular expression has an equivalent finite automaton, and I constructed one of them.

This problem, with multiple queries allowed, appeared on the Polish Olympiad and I translated the solution. Now, if you hear now a person saying computer science is not useful for real programmers, punch him in face.

楠木可依 2024-08-12 09:15:33

根据,如果 {n1, n2, n3, . ..} 不是 m 的约数,那么你就没有解。此页面仅显示 {n1, n2} 的示例,但它可以扩展到更大的系统。新问题是编写一个算法来查找最大公因数,但这对于原始问题来说是微不足道的。

所以你的算法的一部分会找到 gcf({n1,n2,...}) 然后看看它是否是 m 的一个因子。如果不是,则不存在解决方案。这并不能完全表明存在解决方案,但它可以快速向您表明不存在解决方案,这仍然很有用。

According to this, if the greatest common factor of {n1, n2, n3, ...} is not a divisor of m then you have no solution. This page shows an example of just {n1, n2} but it extends to larger systems. The new problem is writing an algorithm for finding the greatest common factor, but that's trivial in light of the original problem.

So part of your algorithm would find the gcf({n1,n2,...}) then see if it's a factor of m. If it isn't, then no solution exists. This doesn't fully show that a solution exists, but it can quickly show you that none exists, which is still useful.

烙印 2024-08-12 09:15:33

看起来您正在谈论具有整数约束的不等式系统。现实情况是您正在解决这个系统:

k1n1+k2n2+k3n3...=m
n1 >= 0
n2 >= 0
n3 >= 0

以及 n1、n2、n3 是整数的附加约束。这是一个线性规划问题。不幸的是,使用 整数约束解决此类系统的一般情况是 NP 完全的。但是,有许多算法可以为您解决这个问题。

Looks like you're talking about a system of inequalities with integer constraints. The reality is you're solving for this system:

k1n1+k2n2+k3n3...=m
n1 >= 0
n2 >= 0
n3 >= 0

And the additional constraint that n1, n2, n3 are integers. That's a linear programming problem. Unfortunately for you, the general case of solving such a system with integer constraints is NP-complete. However, there are many algorithms that will solve it for you.

埋情葬爱 2024-08-12 09:15:33

这与Frobenius coin问题有关,该问题对于n>3尚未解决。

This is related to the Frobenius coin problem, which hasn't been solved for n>3.

你丑哭了我 2024-08-12 09:15:33

暴力方法(伪代码):

def a = 3
def b = 4
def c = 5
def x = 456

for n1 = a to int(x / a) + 1 step a
  for n2 =b to int(x / b) + 1 step b
    for n3 = c to int(x / c) + 1 step c
      if a * n1 + b * n2 + c * n3 = x then
        print n1, n2, n3

另请参见 http:// /mail.python.org/pipermail/python-list/2000-April/031714.html

编辑: 在通信库中,这没有任何意义,因为它需要立即工作。在OP的应用程序中,我可能会使用某种哈希,但他的方法听起来很有趣。

A brute-force approach (pseudocode):

def a = 3
def b = 4
def c = 5
def x = 456

for n1 = a to int(x / a) + 1 step a
  for n2 =b to int(x / b) + 1 step b
    for n3 = c to int(x / c) + 1 step c
      if a * n1 + b * n2 + c * n3 = x then
        print n1, n2, n3

See also http://mail.python.org/pipermail/python-list/2000-April/031714.html

EDIT: In a communications library this would make no sense, since it needs to work immediately. In the OP's application I would probably use some sort of hash, but his approach sounds interesting.

臻嫒无言 2024-08-12 09:15:33

这是关于 2 号案例的一些内容。我还没有弄清楚如何缩放它:

给定 2 个相对素数 x 和 y,存在正整数 a 和 b,使得所有 c>= 的 ax+by=c (x-1)(y-1)

基本上,这是有效的,因为如果您假设 x,您可以用 (0, y, 2y, 3y , ..., (x-1)y)。现在,通过添加 x 的一些正倍数,您可以达到 [(x-1)(y-1),(x-1)y] 之间的所有整数,因为 (x-1)(y- 之间的所有整数1) 和 (x-1)y-1 之前已经表达过。

  1. GCD(x,y)。如果 c 不是倍数,则返回 false。
  2. 如果 GCD(x,y) > 1,将 x,y,c 除以 GCD
  3. 如果 c > (x-1)(y-1), 返回 true
  4. 否则暴力破解

对于暴力破解:

if int(c/y) >= c*y^(-1) mod x, return true, 
else return false

Here's something on the 2 number case. I haven't figured out yet how to scale it:

Given 2 relatively prime integers x and y, there exist positive integers a and b such that ax+by=c for all c>=(x-1)(y-1)

Basically, this works because, if you assume x<y, you can express all integers mod x with (0, y, 2y, 3y, ..., (x-1)y). Now, by adding some positive multiple of x, you can reach all integers between [(x-1)(y-1),(x-1)y], as all of the integers between (x-1)(y-1) and (x-1)y-1 had been expressed previously.

  1. GCD(x,y). If c is not a multiple, return false.
  2. if GCD(x,y) > 1, divide x,y,c by GCD
  3. If c > (x-1)(y-1), return true
  4. Else brute force

And for the brute force:

if int(c/y) >= c*y^(-1) mod x, return true, 
else return false
情独悲 2024-08-12 09:15:33

也许以下信息是无关紧要的,因为它不能处理一般情况,但是...

如果问题是确定给定的正整数 K 是否可以形成和 3*n1 + 4*n2 + 5*n3,对于非负整数n1,n2,n3,那么答案是“是”,对于K>=3。Rosen

的著名教科书离散数学及其应用, p。第六版的第 287 号,利用归纳法证明“只需 4 分和 5 分邮票即可形成 12 分或以上的每笔邮资”。

基本步骤是用3张4美分的邮票可以形成12美分的邮资。

归纳步骤认为,如果使用四美分邮票 P(k) 为真,则只需用五美分邮票替换四美分邮票即可表明 P(k+1) 为真。
如果不使用四美分邮票 P(k) 为真,那么,因为 k>=12,所以我们至少需要 3 个五美分邮票来形成总和,并且 3 个五美分邮票可以用 4 个四美分邮票代替邮票实现k+1。

要扩展该问题的上述解决方案,只需要考虑更多的情况。

Perhaps the following info is irrelevant, because it doesn't handle the general situation, but...

If the problem is to determine whether a given positive integer K can be formed as a sum 3*n1 + 4*n2 + 5*n3, for nonnegative integers n1, n2, n3, then the answer is "yes", for K >= 3.

Rosen's well-known textbook Discrete Mathematics and its Applications, p. 287 of the sixth edition, proves that "every amount of postage of 12 cents or more can be formed using just 4-cent and 5-cent stamps," using induction.

The basis step is that postage of 12 cents can be formed with 3 four-cent stamps.

The induction step considers that if P(k) is true using four-cent stamps, then simply substitute a four-cent stamp with a five-cent stamp to show that P(k+1) is true.
If P(k) is true using no four-cent stamps, then, because k>=12, we need at least 3 five-cent stamps to form our sum, and 3 five-cent stamps can be replaced with 4 four-cent stamps to achieve k+1.

To extend the above solution for this problem requires just considering just a few more cases.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文