C 多解线性方程组的算法

C 多解线性方程组的算法,c,algorithm,math,C,Algorithm,Math,有人能帮我用模运算(!)解线性方程组的算法吗。我只需要“最小”的解决方案。最小的意思是先按词典编纂 让我们使用这个系统: 3x1+2x2=3 4x1+3x2+1x3+2x4=4 x旁边的数字是索引 这个系统的矩阵,我们使用模5(0啊,见鬼,为什么不呢,给你 #include <stdio.h> #define L 2 #define N 5 #define MOD 5 static int M[L][N] = { { 3, 2, 0, 0, 0 } , {

有人能帮我用模运算(!)解线性方程组的算法吗。我只需要“最小”的解决方案。最小的意思是先按词典编纂

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


这个系统的矩阵,我们使用模5(0啊,见鬼,为什么不呢,给你

#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;
}
#包括
#定义L2
#定义n5
#定义MOD 5
静态整数M[L][N]=
{       { 3, 2, 0, 0, 0 }
,       { 4, 3, 1, 2, 0 }
};
静态整数S[L]=
{       3, 4
};
静态void init(int*s)
{
int i;
对于(i=0;i=0&&c>0;i--)
如果(++s[i])==MOD)
{
s[i]=0;
}
其他的
{
c=0;
}
返回c==0;
}
静态int是_解决方案(int*s)
{
int i,j,和;
对于(i=0;i
啊,好吧,见鬼,为什么不呢,给你

#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;
}
#包括
#定义L2
#定义n5
#定义MOD 5
静态整数M[L][N]=
{       { 3, 2, 0, 0, 0 }
,       { 4, 3, 1, 2, 0 }
};
静态整数S[L]=
{       3, 4
};
静态void init(int*s)
{
int i;
对于(i=0;i=0&&c>0;i--)
如果(++s[i])==MOD)
{
s[i]=0;
}
其他的
{
c=0;
}
返回c==0;
}
静态int是_解决方案(int*s)
{
int i,j,和;
对于(i=0;i
您可以将其视为线性代数和高斯消去模p中的一个问题

您试图找到Mx=y mod p的解。如果需要,从一个平方M开始,添加0'x=0的行。现在使用高斯消去mod p尽可能将M减少为上三角形式。您最终得到一个方程组,如

ax+by+cz=H

 dy + ez = G
但是对角线上有一些零,或者是因为你的方程已经用完了,或者是因为所有的方程在某一列上都有零。如果你有一些表示0z=1或类似的东西,那么就没有解。如果没有,你可以像往常一样,通过自下而上求解,并在有解的情况下输入z=0,来计算出许多解中的一个没有留下在对角线上z的非零系数的方程

我认为,如果最重要的未知对应于向量的底部,那么这将产生字典最小的答案。下面展示了如何获取任意解,并使其字典最小,我认为您将发现它不会修改如上所述生成的解

现在看,有一个向量n的线性空间,Mn=0,方程的所有解都是x+n的形式,其中n是这个空间中的一个向量-零空间-x是一个特殊的解,比如你已经计算出来的

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

请注意,由此得到的所有向量在该向量的某个位置都有1,在该向量下方有0,在该向量上方可能有非零项。这意味着,如果将它们的倍数添加到一个解决方案中,从最下方有1的向量开始,后面的向量将永远不会干扰到解决方案中以前存在的部分在向量中加上一个下限,因为后面的向量总是有零

因此,如果你想找到字典最小的解决方案,你可以安排一些事情,这样你就可以先用字典最大的条目作为零空间的基础。从一个任意的解决方案开始,尽可能按字典顺序添加零空间向量,以减少解向量。你应该以Exichographical最小解向量-任何解都可以通过从零空间添加基向量的组合从任何其他解生成,并且