两个文字的析取范式的可满足性表示

本文介绍了一种在多项式时间内判断2DNF(析取范式)可满足性的算法,并通过实例展示了如何将2DNF转换为有向图进行分析。文章包含算法设计、程序功能说明以及具体代码实现,最终通过测试给出结果分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、参考资料及问题

     命题变元及其否定统称为文字。仅由有限个文字构成的析取式称为简单析取式。

     设p、q为二个命题变元

     p,q,p∨p,q∨q,¬p∨q, ¬q∨ ¬p,p∨q,p∨ ¬q 称为简单析取式

     由有限个简单合取式构成的析取式称为析取范式disjunctive normal form),简称DNF

给定一个2DNF,如:,找一个算法,使得它能在多项式时间里判定任一给定的2DNF是否可满足,如果可满足,给每一个变量(如上例中的,,,)一个真值指派(true或false),使得该2DNF的值为true。

二、程序功能说明

   允许用户以一种非常简单的形式输入一个2DNF来进行测试

   能够在多项式时间里判断一个2DNF是否可满足。

   能够在多项式时间里给出一个可满足的2DNF的真值指派。

三、算法的设计

   例如用2DNF 。2DNF可满足问题的多项式时间算法要借助于图论中的知识。下面的规则说明了如何把一个2DNF转化为一个有向图G=<V,E>:

1把2DNF的每个变量及这个变量的非都作为图G的顶点。显然若这个2DNF有3个变量,那么将有6个顶点。

2有从顶点 指向顶点的边当且仅当在这个2DNF字句中有子句。显然每个字句对应两条有向边:从顶点 指向顶点的有向边和从顶点指向的有向边。

如,对2DNF ,

画出有向图的步骤:

1) 对于在f中出现的变量xi,在G中构造两个顶点

两个顶点用一条边相连。

2) 若子句cj中有nj个文字,则在G中构造一个具有nj个顶点的团

3) 对于子句cj中出现的每一个文字所对应的顶点(),

连一条边到nj-团中的一个顶点(不同的文字必须连到不同的顶点,

故团中每一个顶点都有一条边连到某个文字顶点)。

4) 令k=n+(e.g. k=3+(3-1)+(2-1)=6)。

  以上四条显然可以在多项式时间内实现    

  与之对应的有向图为:

程序总共运用了四个函数计算的数值getMatrixIndex,求取二维数组getAdjacentMatrix的函数,图的遍历函数BFS,讨论是否满足可满足性的函数isSat。

程序代码:

#include <iostream>

#include <cmath>

#include <queue>

#include<windows.h>

using namespace std;

/**********计算赋值的函数***********/

int getMatrixIndex(int x, int varNum)

{

    int b = varNum/2;

    return  (int)abs((abs(x)/x - 1)/2 * b + x) - 1;

}

/****************给数组二维adjacentMatrix赋值****************/

bool ** getAdjacentMatrix(int inputArray[][2], int length, int varNum)

{

    bool **adjacentMatrix  = new bool *[varNum];

    for(int i = 0; i < varNum; i++)

    {

        adjacentMatrix[i] = new bool[varNum];

        for (int j = 0; j < varNum; j++)

        {

            adjacentMatrix[i][j] = false;

        }

    }

    for (int k = 0; k < length; k++)

    {

        int row1 = getMatrixIndex(-inputArray[k][0], varNum);

        int to1  = getMatrixIndex(inputArray[k][1], varNum);

        int row2 = getMatrixIndex(-inputArray[k][1], varNum);

        int to2  = getMatrixIndex(inputArray[k][0], varNum);

        adjacentMatrix[row1][to1] = true;

        adjacentMatrix[row2][to2] = true;

    }

        cout<<"与图有关的矩阵edges:"<<endl;

       for(int i = 0; i < varNum; i++)

         {

           for (int j = 0; j < varNum; j++)

           {

            cout<<" "<<adjacentMatrix[i][j];

           }

           cout<<endl;

         }

    return adjacentMatrix;

}

/**基于BFS来决定从节点from到节点to是否有一条有向路径,若有的话返回true,否则返回false**/

bool BFS(int from, int to, bool ** adjacentM, int length)

{

    bool **status  = new bool *[length];

    for(int s = 0; s < length; s++)

    {

        status[s] = new bool[length];

        for (int m = 0; m<length; m++)

        {

            status[s][m] = false;

        }

    }

    queue<int>myQue;

    myQue.push(from);

    while(!myQue.empty())

    {

        int beginning = myQue.front();

        myQue.pop();

        for (int n = 0; n < length; n++)

        {

            if (adjacentM[beginning][n] == true && status[beginning][n] == false)

            {

                if (n == to)return true;

                myQue.push(n);

            }

            status[beginning][n] = true;

        }

    }

    return false;

}

/**************判断一个2NF能否满足*****************/

bool isSat(bool **Matrix, int length)

{

    for (int l = 1; l<= length/2; l++)

    {

        if (BFS(getMatrixIndex(l, length), getMatrixIndex(-l, length), Matrix, length)

            && BFS(getMatrixIndex(-l, length), getMatrixIndex(l, length), Matrix, length))

        {

            return false;

        }

    }

    return true;

}

/*************主函数***************/

int main()

{

    system("color FC");

    int inputArray[][2] = {

                          { 1,  2},

                          {-1, -2},

                          {-4, -5},

                          {-2,  3},

                          { 3,  4},

                          {-3,  5},

                          { 4, -3}

                         } ;

  cout<<"输入数组为:"<<endl;

   for(int i=0;i<7;i++)

     {

       for(int j=0;j<2;j++)

       cout<<'/t'<<inputArray[i][j];

       cout<<endl;

     }

    bool **matrix = getAdjacentMatrix(inputArray, 7, 10);

    if (isSat(matrix, 10))

        cout<<endl<<"两个文字的析取范式是可满足"<<endl;

    else

        cout<<endl<<"两个文字的析取范式不可满足"<<endl;

    return 0;

}

结果分析:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值