C#,布尔可满足性问题(Boolean Satisfiability Problem)算法与源代码

本文主要是介绍C#,布尔可满足性问题(Boolean Satisfiability Problem)算法与源代码,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1 布尔可满足性问题

布尔可满足性问题

布尔可满足性或简单的SAT是确定布尔公式是可满足还是不可满足的问题。


可满足:如果布尔变量可以赋值,使得公式为真,那么我们说公式是可满足的。

不可满足:如果无法指定此类值,则我们称公式不可满足。

2 合取范式(CNF)或也称为和积(POS)

为了更好地理解这一点,首先让我们看看什么是合取范式(CNF)或也称为和积(POS)。

CNF:CNF是子句的连词(AND),其中每个子句都是析取(OR)。

现在,2-SAT将SAT问题限制为仅表示为CNF的布尔公式,每个子句只有2个项(也称为2-CNF)。

示例:F=(A\u 1\vee B\u 1)\wedge(A\u 2\vee B\u 2)\wedge(A\u 3\vee B\u 3)\wedge。。。。。。。\楔块(A\u m\vee B\u m)

因此,2-可满足性问题可以表述为:

给定每个子句只有2个项的CNF,是否可以将这些值分配给变量,以使CNF为真?

3 源代码

using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;namespace Legalsoft.Truffer.Algorithm
{public static class NP_Complete_Problem{private static int MAX { get; set; } = 100000;private static List<List<int>> adj { get; set; }private static List<List<int>> adjInv { get; set; }private static bool[] visited { get; set; } = new bool[MAX];private static bool[] visitedInv { get; set; } = new bool[MAX];private static Stack<int> stack { get; set; } = new Stack<int>();private static int[] scc { get; set; } = new int[MAX];private static int counter { get; set; } = 1;public static void Initialize(int n = 5, int m = 7){for (int i = 0; i < MAX; i++){adj.Add(new List<int>());adjInv.Add(new List<int>());}}private static void Add_Edge(int a, int b){adj[a].Add(b);}private static void Add_Edges_Inverse(int a, int b){adjInv[b].Add(a);}private static void DFS_First(int u){if (visited[u]){return;}visited[u] = true;for (int i = 0; i < adj[u].Count; i++){DFS_First(adj[u][i]);}stack.Push(u);}private static void DFS_Second(int u){if (visitedInv[u]){return;}visitedInv[u] = true;for (int i = 0; i < adjInv[u].Count; i++){DFS_Second(adjInv[u][i]);}scc[u] = counter;}public static bool Is_2_Satisfiable(int n, int m, int[] a, int[] b){for (int i = 0; i < m; i++){if (a[i] > 0 && b[i] > 0){Add_Edge(a[i] + n, b[i]);Add_Edges_Inverse(a[i] + n, b[i]);Add_Edge(b[i] + n, a[i]);Add_Edges_Inverse(b[i] + n, a[i]);}else if (a[i] > 0 && b[i] < 0){Add_Edge(a[i] + n, n - b[i]);Add_Edges_Inverse(a[i] + n, n - b[i]);Add_Edge(-b[i], a[i]);Add_Edges_Inverse(-b[i], a[i]);}else if (a[i] < 0 && b[i] > 0){Add_Edge(-a[i], b[i]);Add_Edges_Inverse(-a[i], b[i]);Add_Edge(b[i] + n, n - a[i]);Add_Edges_Inverse(b[i] + n, n - a[i]);}else{Add_Edge(-a[i], n - b[i]);Add_Edges_Inverse(-a[i], n - b[i]);Add_Edge(-b[i], n - a[i]);Add_Edges_Inverse(-b[i], n - a[i]);}}for (int i = 1; i <= 2 * n; i++){if (!visited[i]){DFS_First(i);}}while (stack.Count != 0){int top = stack.Peek();stack.Pop();if (!visitedInv[top]){DFS_Second(top);counter++;}}for (int i = 1; i <= n; i++){if (scc[i] == scc[i + n]){return false;}}return true;}}
}

POWER BY TRUFFER.CN

4 源程序

using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;

namespace Legalsoft.Truffer.Algorithm
{
    public static class NP_Complete_Problem
    {
        private static int MAX { get; set; } = 100000;
        private static List<List<int>> adj { get; set; }
        private static List<List<int>> adjInv { get; set; }
        private static bool[] visited { get; set; } = new bool[MAX];
        private static bool[] visitedInv { get; set; } = new bool[MAX];
        private static Stack<int> stack { get; set; } = new Stack<int>();
        private static int[] scc { get; set; } = new int[MAX];
        private static int counter { get; set; } = 1;

        public static void Initialize(int n = 5, int m = 7)
        {
            for (int i = 0; i < MAX; i++)
            {
                adj.Add(new List<int>());
                adjInv.Add(new List<int>());
            }
        }

        private static void Add_Edge(int a, int b)
        {
            adj[a].Add(b);
        }

        private static void Add_Edges_Inverse(int a, int b)
        {
            adjInv[b].Add(a);
        }

        private static void DFS_First(int u)
        {
            if (visited[u])
            {
                return;
            }
            visited[u] = true;

            for (int i = 0; i < adj[u].Count; i++)
            {
                DFS_First(adj[u][i]);
            }
            stack.Push(u);
        }

        private static void DFS_Second(int u)
        {
            if (visitedInv[u])
            {
                return;
            }
            visitedInv[u] = true;

            for (int i = 0; i < adjInv[u].Count; i++)
            {
                DFS_Second(adjInv[u][i]);
            }
            scc[u] = counter;
        }

        public static bool Is_2_Satisfiable(int n, int m, int[] a, int[] b)
        {
            for (int i = 0; i < m; i++)
            {
                if (a[i] > 0 && b[i] > 0)
                {
                    Add_Edge(a[i] + n, b[i]);
                    Add_Edges_Inverse(a[i] + n, b[i]);
                    Add_Edge(b[i] + n, a[i]);
                    Add_Edges_Inverse(b[i] + n, a[i]);
                }
                else if (a[i] > 0 && b[i] < 0)
                {
                    Add_Edge(a[i] + n, n - b[i]);
                    Add_Edges_Inverse(a[i] + n, n - b[i]);
                    Add_Edge(-b[i], a[i]);
                    Add_Edges_Inverse(-b[i], a[i]);
                }
                else if (a[i] < 0 && b[i] > 0)
                {
                    Add_Edge(-a[i], b[i]);
                    Add_Edges_Inverse(-a[i], b[i]);
                    Add_Edge(b[i] + n, n - a[i]);
                    Add_Edges_Inverse(b[i] + n, n - a[i]);
                }
                else
                {
                    Add_Edge(-a[i], n - b[i]);
                    Add_Edges_Inverse(-a[i], n - b[i]);
                    Add_Edge(-b[i], n - a[i]);
                    Add_Edges_Inverse(-b[i], n - a[i]);
                }
            }

            for (int i = 1; i <= 2 * n; i++)
            {
                if (!visited[i])
                {
                    DFS_First(i);
                }
            }

            while (stack.Count != 0)
            {
                int top = stack.Peek();
                stack.Pop();

                if (!visitedInv[top])
                {
                    DFS_Second(top);
                    counter++;
                }
            }

            for (int i = 1; i <= n; i++)
            {
                if (scc[i] == scc[i + n])
                {
                    return false;
                }
            }

            return true;
        }
    }
}
 

这篇关于C#,布尔可满足性问题(Boolean Satisfiability Problem)算法与源代码的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/782796

相关文章

SpringBoot应用中出现的Full GC问题的场景与解决

《SpringBoot应用中出现的FullGC问题的场景与解决》这篇文章主要为大家详细介绍了SpringBoot应用中出现的FullGC问题的场景与解决方法,文中的示例代码讲解详细,感兴趣的小伙伴可... 目录Full GC的原理与触发条件原理触发条件对Spring Boot应用的影响示例代码优化建议结论F

C#中DrawCurve的用法小结

《C#中DrawCurve的用法小结》本文主要介绍了C#中DrawCurve的用法小结,通常用于绘制一条平滑的曲线通过一系列给定的点,具有一定的参考价值,感兴趣的可以了解一下... 目录1. 如何使用 DrawCurve 方法(不带弯曲程度)2. 如何使用 DrawCurve 方法(带弯曲程度)3.使用Dr

openCV中KNN算法的实现

《openCV中KNN算法的实现》KNN算法是一种简单且常用的分类算法,本文主要介绍了openCV中KNN算法的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的... 目录KNN算法流程使用OpenCV实现KNNOpenCV 是一个开源的跨平台计算机视觉库,它提供了各

MySQL 中查询 VARCHAR 类型 JSON 数据的问题记录

《MySQL中查询VARCHAR类型JSON数据的问题记录》在数据库设计中,有时我们会将JSON数据存储在VARCHAR或TEXT类型字段中,本文将详细介绍如何在MySQL中有效查询存储为V... 目录一、问题背景二、mysql jsON 函数2.1 常用 JSON 函数三、查询示例3.1 基本查询3.2

Pyserial设置缓冲区大小失败的问题解决

《Pyserial设置缓冲区大小失败的问题解决》本文主要介绍了Pyserial设置缓冲区大小失败的问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录问题描述原因分析解决方案问题描述使用set_buffer_size()设置缓冲区大小后,buf

resultMap如何处理复杂映射问题

《resultMap如何处理复杂映射问题》:本文主要介绍resultMap如何处理复杂映射问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录resultMap复杂映射问题Ⅰ 多对一查询:学生——老师Ⅱ 一对多查询:老师——学生总结resultMap复杂映射问题

java实现延迟/超时/定时问题

《java实现延迟/超时/定时问题》:本文主要介绍java实现延迟/超时/定时问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java实现延迟/超时/定时java 每间隔5秒执行一次,一共执行5次然后结束scheduleAtFixedRate 和 schedu

如何解决mmcv无法安装或安装之后报错问题

《如何解决mmcv无法安装或安装之后报错问题》:本文主要介绍如何解决mmcv无法安装或安装之后报错问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录mmcv无法安装或安装之后报错问题1.当我们运行YOwww.chinasem.cnLO时遇到2.找到下图所示这里3.

浅谈配置MMCV环境,解决报错,版本不匹配问题

《浅谈配置MMCV环境,解决报错,版本不匹配问题》:本文主要介绍浅谈配置MMCV环境,解决报错,版本不匹配问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录配置MMCV环境,解决报错,版本不匹配错误示例正确示例总结配置MMCV环境,解决报错,版本不匹配在col

Vue3使用router,params传参为空问题

《Vue3使用router,params传参为空问题》:本文主要介绍Vue3使用router,params传参为空问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录vue3使用China编程router,params传参为空1.使用query方式传参2.使用 Histo