1

有人可以帮助我解决模算术(!)中的线性方程组的算法。我只需要“最小”的解决方案。最小的意思是按字典顺序排列。

让我们有这个系统:
3x1+2x2=3
4x1+3x2+1x3+2x4=4
x 旁边的数字是索引。

我们使用模 5(0<=x<=p,其中 p 是我们的模)的系统的矩阵是
3 2 0 0 0 | 3
4 3 1 2 0 | 4

最小的解决方案是 (0,4,0,1,0)。我必须编写一个算法来给我那个解决方案。我在考虑蛮力,因为 p<1000。但我不知道该怎么做,因为在这种情况下,在第一行我必须 x1=0 ... p-1 ,然后解决 x2,在第二行我必须选择 x3= 0 ... p-1。并解决 x4。我必须这样做,直到该方程组成立。如果我从 0 .. p-1 开始,那么我得到的第一个解决方案将是最小的解决方案。

PS:矩阵可以有很多种形式,比如:
3 2 4 0 0 | 3
4 3 1 2 1 | 4


1 2 0 0 0 | 3
3 0 3 0 0 | 3
4 3 1 2 3 | 4

对不起我的英语,我来自亚洲。

编辑:我在考虑如何确定哪些变量是参数。但是想不通....

4

2 回答 2

1

啊好吧,到底是什么,为什么不呢,给你

#include <stdio.h>

#define L 2
#define N 5
#define MOD 5

static int M[L][N] =
{       { 3, 2, 0, 0, 0 }
,       { 4, 3, 1, 2, 0 }
};

static int S[L] =
{       3, 4
};

static void init(int * s)
{
        int     i;
        for (i = 0; i < N; i++)
        {
                s[i] = 0;
        }
}

static int next(int * s)
{
        int     i, c;
        c = 1;
        for (i = N-1; i >= 0 && c > 0; i--)
        if ( (++s[i]) == MOD)
        {
                s[i] = 0;
        }
        else
        {
                c = 0;
        }
        return c == 0;
}

static int is_solution(int * s)
{
        int     i, j, sum;

        for (i = 0; i < L; i++)
        {
                sum = 0;
                for (j = 0; j < N; j++)
                {
                        sum += M[i][j]*s[j];
                }
                if (sum % MOD != S[i])
                {
                        return 0;
                }
        }
        return 1;
}

int main(void)
{
        int     s[N];

        init(s);
        do
        {
                if (is_solution(s))
                {
                        int     i;
                        for (i = 0; i < N; i++)
                        {
                                printf(" %d", s[i]);
                        }
                        printf("\n");
                        break;
                }
        } while (next(s));
        return 0;
}
于 2013-03-22T14:40:48.187 回答
0

您可以将其视为线性代数和高斯消元 mod p 中的问题。

您正在尝试找到 Mx = y mod p 的解决方案。如有必要,通过添加 0'x = 0 的行从正方形 M 开始。现在使用高斯消去 mod p 将 M 尽可能地减少为上三角形式。您最终会得到一个方程组,例如

ax + by + cz = H

 dy + ez = G

但是对角线上有一些零,要么是因为你用完了方程,要么是因为所有方程在特定列上都为零。如果您有 0z = 1 或类似的内容,则没有解决方案。如果不是,您可以像往常一样通过自下而上求解来找出可能的多种解决方案之一,如果没有剩下的方程在对角线上的 z 系数为非零,则输入 z=0。

我认为如果最重要的未知数对应于向量的底部,这将产生字典上最小的答案。下面显示了如何采用任意解决方案并使其按字典顺序最小,我认为您会发现它不会修改如上生成的解决方案。

现在看看http://en.wikipedia.org/wiki/Kernel_%28matrix%29。存在向量 n 的线性空间,使得 Mn = 0,并且方程的所有解的形式为 x + n,其中 n 是该空间中的向量 - 零空间 - 而 x 是特定解,例如作为你已经解决的那个。

您可以通过找到 Mn = 0 的解来计算零空间的基础,就像您找到 x 一样。找到对角线上没有非零条目的列,转到该列的对角线所在的行,将该列的未知数设置为 1,然后从那里向上移动矩阵,选择其他未知数你有一个 Mn = 0 的解。

请注意,您从中获得的所有向量在该向量的某个位置都有 1,在该向量下方有 0,并且在上方可能有非零条目。这意味着,如果您将它们的倍数添加到解决方案中,从最下方 1 的向量开始,后面的向量将永远不会干扰您之前添加的解决方案的分量,因为后面的向量总是为零那里。

因此,如果您想找到字典上最小的解决方案,您可以安排一些事情,以便您首先使用具有字典上最大条目的空空间的基础。从任意解开始,并尽可能按字典顺序添加零空间向量,以减少解向量。您最终应该得到字典上最小的解向量 - 通过从零空间添加基向量的组合,可以从任何其他解中生成任何解,并且您可以从上述过程中看到它产生字典上最小的此类结果 -在每个阶段,最重要的组件都尽可能地小,任何替代品都必须在字典上更大。

于 2013-03-22T21:18:54.180 回答