首页 > 其他分享 >2-SAT学习笔记

2-SAT学习笔记

时间:2023-01-01 20:23:15浏览次数:36  
标签:cup int 笔记 stk 学习 low Leftrightarrow SAT rightarrow

\(SAT:satisfaction\)

\(SAT\)问题:若干问题\(x_1, x_2, ..., x_n\),另有\(m\)个需要满足条件,其中每个命题为真或假,求\(x_1, x_2, ..., x_n\)的一种取值。

一般\(k-SAT\)问题为\(NP\)完全问题,故只考虑\(O(n+m)\)的\(2-SAT\)问题

算法复习

拓扑排序

统计入度和出度,不再赘述。

code

bool topsort()
{
    int hh = 0, tt = -1;

    for (int i = 1; i <= n; i ++ )
        if (!d[i])
            q[ ++ tt] = i;

    while (hh <= tt)
    {
        int t = q[hh ++ ];

        for (int i = h[t]; i != -1; i = ne[i])
        {
            int j = e[i];
            if (-- d[j] == 0)
                q[ ++ tt] = j;
        }
    }

    return tt == n - 1;
}

\(Tarjan\)算法

求强连通分量,缩点,不再赘述.

code

int h[N], e[M], ne[M], idx;
int dfn[N], low[N], timestamp;
int stk[N], top;
bool in_stk[N];
int id[N], scc_cnt, Size[N];
int dout[N];

void add(int a, int b)
{
    e[idx] = b, ne[idx] = h[a], h[a] = idx ++ ;
}

void tarjan(int u)
{
    dfn[u] = low[u] = ++ timestamp;
    stk[ ++ top] = u, in_stk[u] = true;
    for (int i = h[u]; i != -1; i = ne[i])
    {
        int j = e[i];
        if (!dfn[j])
        {
            tarjan(j);
            low[u] = min(low[u], low[j]);
        }
        else if (in_stk[j]) low[u] = min(low[u], dfn[j]);
    }

    if (dfn[u] == low[u])
    {
        ++ scc_cnt;
        int y;
        do {
            y = stk[top -- ];
            in_stk[y] = false;
            id[y] = scc_cnt;
            Size[scc_cnt] ++ ;
        } while (y != u);
    }
}

\(a \rightarrow b \Leftrightarrow -a \cup b\)

\(a \cup b \Leftrightarrow -a \rightarrow b \Leftrightarrow -b \rightarrow a\)

\(\rightarrow\)可以视作\(a,b\)连一条有向边

原问题因此可以转化成图论问题。

  • 无解情况:\(x_1 \rightarrow ... \rightarrow -x_1 \quad or\quad x_1 \rightarrow ... \rightarrow -x_1\)
    (\(x_i\)与\(-x_i\)在同一个强连通分量中,即\(x_i\)既等于\(1\),又等于\(0\))

若上述条件不成立是否一定有解?

构造:按照任意顺序枚举所有\(x_i\)
用\(tarjan\)算法缩点成一个\(DAG\), 然后拓扑排序,在合法与非法中选择拓扑序编号更靠后的一个。

为什么此构造成立?

  • 对于每一个\(x_i\),只有一种值。
  • 对于每一个强联通分量,如果选了其中的一个点,则其中所有点都被选了,即要选都选,要不选都不选。还存在一个强连通分量与之所有成分都相反,成对出现。(原命题和逆否命题等价)
  • 对于条件\(a \cup b\),假设\(a = 0\),则\(a\)的拓扑序更靠前,则\(-a \rightarrow b\),故\(b\)所在强连通分量更靠后\(,b\)一定取\(1\),由对称性,反之亦成立。

故成立。

细节问题

满足需求不同形式的实现:

  • \(a \cup b \Leftrightarrow -a \rightarrow b \Leftrightarrow -b \rightarrow a\)

  • \(a \rightarrow b \Leftrightarrow -a \cup b\)

  • \(a = 1 \Leftrightarrow a \cup a\)

code

标签:cup,int,笔记,stk,学习,low,Leftrightarrow,SAT,rightarrow
From: https://www.cnblogs.com/sunruize/p/17018525.html

相关文章

  • 我的第一天学习-HelloWorld详解
    HelloWorld详解1.随便新建一个文件夹存放代码2.新建一个Java文件文件后缀名为.javaHello.java[注意]系统可能没有显示文件后缀名,需要我们手动打开,在文件查看中......
  • 狂神说Java(零基础)预科班笔记
    前言​以下笔记是根据B站up主遇见狂神说的Java零基础学习视频整理而成,视频链接点这里跳转(狂神说系列Java零基础版)。由于本人推崇费曼学习法,不想要写完一篇笔记之后就直......
  • 动手深度学习系列笔记
    动手学深度学习在线课程此系列文章为听课所敲代码+笔记,使用jupyternotebook展现目录​​3月20日​​​​3月21日​​​​3月27日​​​​3月28日​​​​4月10日​​​​4......
  • 【树模型与集成学习】(task6)梯度提升树GBDT+LR
    学习总结(1)不同问题的提升树学习算法,主要区别在于使用的损失函数不同,如用平方误差损失函数的回归问题、用指数损失函数的分类问题、用一般损失函数的一般决策问题等。(2)不管......
  • 操作系统OS笔记目录(清华大学)
    简介不得不说想自学学操作系统,清华大学慕课是个不错的选择,但难度比较大,特别是想把慕课的实验部分内容也完成的话。不过如果能把它的实验部分也完成的话,相信你会对操作系统......
  • nginx学习
    之前都只会照着网上的nginx配置和代码什么的直接拿过来用,但是没系统学习过,所以来系统学习一下nginx内容。1、nginx基本概念(1)nginx是什么,能做什么?Nginx是什么?Nginx介绍及......
  • 计算机网络个人学习经验
    目录学好这门课的必要性重要的专业基础各种考试很爱考课程学习的需要预期的学习效果学习方法书籍推荐《计算机网络:自顶向下方法》《计算机网络》(谢希仁)《TCP/IP详解卷1......
  • 学习机赛道加速:请“卷”产品,不要“卷”营销
    文|李永华毫无疑问,出于家长对中小学生教育重视等综合原因,在智能终端赛道上,学习机正在成为一匹黑马。而市面上的学习机产品到这个阶段究竟发展得如何,是很多人关心的问题。恰......
  • 《C++ —— 笔记》
      this指针在C++中成员变量和成员函数是分开存储的。每一个非静态成员函数只会诞生一份函数实例,也就是说多个同类型的对象会共用一块代码。那么问题是:这一块代码是......
  • 学习记录--利用LSTM实现预测时间序列(股票预测)
    nn.Linear的理解nn.Linear是pytorch中线性变换的一个库在实际应用中,nn.Linear往往用来初始化矩阵,供神经网络使用。view()方法我们经常会用到x.view()方法来进行数据......