具有更多解的线性方程组算法

时间:2013-03-22 12:32:07

标签: c algorithm math

有人能帮助我解决模运算中线性方程的算法(!)。我只需要“最小”的解决方案。最小的首先是按字典顺序排列。

我们有这个系统:
3X1 + 2×2 = 3
4X1 + 3×2 + 1×3 + 2×4 = 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&lt; 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

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

编辑:我在考虑如何确定哪些变量是参数。但无法搞清楚......

2 个答案:

答案 0 :(得分: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;
}

答案 1 :(得分:0)

您可以将此视为线性代数和高斯消除模型中的问题。

您正在尝试找到Mx = y mod p的解决方案。如果需要,通过添加0'x = 0的行来开始方形M.现在使用高斯消除模p将M尽可能地减少到上三角形。你最终得到了一个方程组,如

ax + by + cz = H

 dy + ez = G

但是在对角线上有一些零,要么是因为你已经用完了方程式,要么是因为所有方程在特定列上都为零。如果你有0z = 1或类似的东西没有解决方案。如果没有,你可以像往常一样通过自下而上的方法解决一个可能的解决方案中的一个,并且如果没有剩下的方程式,则在z = 0时放入z,对角线上的z具有非零系数。

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

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

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

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

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