Lasvegas算法解决3SAT问题(C++实现代码)

转载请注明出处:http://blog.csdn.net/zhoubin1992/article/details/46469557


1.SAT问题描述

命题逻辑中合取范式 (CNF) 的可满足性问题 (SAT)是当代理论计算机科学的核心问题, 是一典型的NP 完全问题.在定义可满足性问题SAT之前,先引进一些逻辑符号。

一个 SAT 问题是指: 对于给定的 CNF 是否存在一组关于命题变元的真值指派使得A 为真. 显然, 如果A 为真, 则 CNF 的每个子句中必有一个命题变元为 1 (真) 。


2.Las Vegas算法

Las Vegas 算法是利用随机值做出随机选择的一种概率算法,并且不会产生不正确的答案。在计算过程中所做出的随机选择,可能使算法比其他算法更快地得到所要求的解。

拉斯维加斯算法不会得到不正确的解。一旦用拉斯维加斯算法找到一个解,这个解就一定是正确解。但有时用拉斯维加斯算法找不到解。与蒙特卡罗算法类似,拉斯维加斯算法找到正确解的概率随着它所用的计算时间的增加而提高。对于所求解问题的任一实例,用同一拉斯维加斯算法反复对该实例求解足够多次,可使求解失败的概率任意小。

Las Vegas 算法用来搜索包含目标结点的解空间。它用一些随机选择来移动,而不需要在每个结点都计算一个新的结点。如果成功结点的比例在解空间中相当高,则找到目标结点的概率可能很高。当下一个结点的计算比较困难或者系统化地搜索没有什么必要时,采用Las Vegas 算法,会提高计算的效率。当然,下一个结点的随机选择有可能导致找不到成功的结点,但是我们可以重复多次运行,来提高目标结点的效率。拉斯维加斯算法的一个显著特征是它所作的随机性决策有可能导致算法找不到所需的解,但是通过重复多次运行来克服,在求解NP难问题时,用它往往会收到奇效。


3.C++实现代码

#include
#include
#include 

const int n=250;
int M[n][3];
int sign[3*n+1];
int x[101],y[101];
int ok[2];
bool Place( int k)
{
    //memset(y,1,101);
    int t;
    /*for( int j = 1; j k)
                t = t+1;
            else
                t = t+!(sign[i*3+j]^x[M[i][j]] );
        }
        if(t 100000)
            {
                printf("failed!\n");
                break;
            }
        }
        end = clock();
        run_num = k;
        run_time += (end - start)/CLOCKS_PER_SEC;
        if(k // lasvegas3SAT.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <iostream>

const int n=250;
int M[n][3];
int sign[3*n+1];
int x[101],y[101];
int ok[2];
bool Place( int k)
{
    //memset(y,1,101);
    int t;
    /*for( int j = 1; j <= k - 1; j++)
    {
        y[j]=~x[j];
    }*/
    for(int i = 0; i < n; i++)
    {
        t=0;
        for(int j = 0; j < 3; j++)
        {
            if(M[i][j]>k)
                t = t+1;
            else
                t = t+!(sign[i*3+j]^x[M[i][j]] );
        }
        if(t<1)
            return false;
    }
    return true;
}
bool SAT_True(int x[])
{
    int k = 1;
    int count = 0;
    int i;
    while( k <= 100 )
    {
        count = 0;
        for( i = 0; i <= 1 ; i++ )
        {
            x[k] = i;
            if( Place(k))
            {
                ok[count] = i;
                count ++;
            }
        }
        if( count == 0 ) return false;
        i = ok[rand() % count];
        x[k] = i;
        k++;
    }
    return true;
}

int _tmain(int argc, _TCHAR* argv[])
{       //重复执行20次
    //int ncase = 20;
    double run_time = 0.0; //执行时间
    double run_num = 0.0; //执行次数
    time_t start,end;
    srand(time(0));
    //while(ncase--)
    //{
        start = clock();
        for(int i=0;i<n;i++)
            for(int j=0;j<3;j++)
                M[i][j] = rand()%100+1;
        for(int i=1;i<=3*n;i++)
            sign[i] = rand()%2;

        memset(x,0,101*sizeof(int));
        int k=1;
         while(!SAT_True(x) )
        {
            k++;
            if(k > 100000)
            {
                printf("failed!\n");
                break;
            }
        }
        end = clock();
        run_num = k;
        run_time += (end - start)/CLOCKS_PER_SEC;
        if(k <= 100000)
            std::cout << "执行了" << run_num << "次" << std::endl;
    //}

    printf("the running time is : %f\n", run_time);
    system("pause");
    return 0;
}


4.实验结果及分析

为了测试Las Vegas 的计算效果, 我们用随机产生的3-SAT 模型(每个子句的长度 l= 3, 且子句里的变元两两不同) 做实例。每种取值执行20次,考虑有可能找不到解的情况,当搜索次数超过十万次,认为此样例不可满足。得到的结果为:



参考文献

[1] 张德富.算法设计与分析(高级教程)[M].国防工业出版社,2007.

时间: 2024-07-29 18:08:56

Lasvegas算法解决3SAT问题(C++实现代码)的相关文章

模拟退火算法解决3SAT问题(C++实现代码)

转载请注明出处:http://blog.csdn.net/zhoubin1992/article/details/46453761 1 SAT问题描述 命题逻辑中合取范式 (CNF)的可满足性问题 (SAT)是当代理论计算机科学的核心问题,是一典型的NP完全问题.在定义可满足性问题SAT之前,先引进一些逻辑符号. 2  模拟退火算法 模拟退火算法来源于固体退火原理,将固体加温至充分高,再让其徐徐冷却,加温时,固体内部粒子随温升变为无序状,内能增大,而徐徐冷却时粒子渐趋有序,在每个温度都达到平衡态

Lasvegas+回溯算法解决3SAT问题(C++实现代码)

转载请注明出处:http://blog.csdn.net/zhoubin1992/article/details/46507919 1.SAT问题描述 命题逻辑中合取范式 (CNF) 的可满足性问题 (SAT)是当代理论计算机科学的核心问题, 是一典型的NP 完全问题.在定义可满足性问题SAT之前,先引进一些逻辑符号. 一个 SAT 问题是指: 对于给定的 CNF 是否存在一组关于命题变元的真值指派使得A 为真. 显然, 如果A 为真, 则 CNF 的每个子句中必有一个命题变元为 1 (真) .

【先进的算法】Lasvegas算法3SAT问题(C++实现代码)

转载请注明出处:http://blog.csdn.net/zhoubin1992/article/details/46469557 1.SAT问题描写叙述 命题逻辑中合取范式 (CNF) 的可满足性问题 (SAT)是当代理论计算机科学的核心问题, 是一典型的NP 全然问题.在定义可满足性问题SAT之前.先引进一些逻辑符号. 一个 SAT 问题是指: 对于给定的 CNF 是否存在一组关于命题变元的真值指派使得A 为真. 显然, 假设A 为真, 则 CNF 的每一个子句中必有一个命题变元为 1 (真

【高级算法】遗传算法解决3SAT问题(C++实现)

转载请注明出处:http://blog.csdn.net/zhoubin1992/article/details/46910079 1 SAT问题描写叙述 命题逻辑中合取范式 (CNF) 的可满足性问题 (SAT)是当代理论计算机科学的核心问题, 是一典型的NP 全然问题.在定义可满足性问题SAT之前,先引进一些逻辑符号. 一个 SAT 问题是指: 对于给定的 CNF 是否存在一组关于命题变元的真值指派使A为真. 显然,如A为真,则CNF的每一个子句中必有一个命题变元为1(真). 2 遗传算法

遗传算法解决3SAT问题(C++实现代码)

1 SAT问题描述 命题逻辑中合取范式 (CNF) 的可满足性问题 (SAT)是当代理论计算机科学的核心问题, 是一典型的NP 完全问题.在定义可满足性问题SAT之前,先引进一些逻辑符号. 一个 SAT 问题是指: 对于给定的 CNF 是否存在一组关于命题变元的真值指派使A为真. 显然,如A为真,则CNF的每个子句中必有一个命题变元为1(真). 2 遗传算法 遗传算法类似于自然进化,通过作用于染色体上的基因寻找好的染色体来求解问题.与自然界相似,遗传算法对求解问题的本身一无所知,它所需要的仅是对

【高级算法】禁忌搜索算法解决3SAT问题(C++实现)

转载请注明出处:http://blog.csdn.net/zhoubin1992/article/details/46440389 近期梳理,翻出了当年高级算法课程做的题目.禁忌搜索算法解决3SAT问题. 吐槽:数学符号怎样在编辑器里打出来啊,为了保留符号,我直接截图了. 1 SAT问题描写叙述 定理4.4.1: 赋值v为使CNF可满足的充要条件是f(x1,x2,-,xm)达到最小值0. 2  禁忌搜索算法 禁忌搜索算法是在局部搜索的过程中引进了贪心选择机制.并利用禁忌表改动邻域,通过构造的候选

禁忌搜索算法解决3SAT问题(C++代码实现)

最近梳理,翻出了当年高级算法课程做的题目,禁忌搜索. 吐槽:数学符号如何在编辑器里打出来啊,为了保留符号,我直接截图了. 1 SAT问题描述 定理4.4.1: 赋值v为使CNF可满足的充要条件是f(x1,x2,-,xm)达到最小值0. 2  禁忌搜索算法 禁忌搜索算法是在局部搜索的过程中引进了贪心选择机制,并利用禁忌表修改邻域,通过构造的候选邻域来控制解得选择和接受过程.在搜索的过程中,禁忌搜索算法从上一步计算解的候选邻域里选择一个最好的解,即使这个解比上一步得到的解还差,也接受它,同时修改禁忌

基本算法思想Java实现的详细代码

基本算法思想Java实现的详细代码 算法是一个程序的灵魂,一个好的算法往往可以化繁为简,高效的求解问题.在程序设计中算法是独立于语言的,无论使用哪一种语言都可以使用这些算法,本文笔者将以Java语言为例介绍一些常用的算法思想. 分类 穷举算法思想 递推算法思想 递归算法思想 分治算法思想 概率算法思想  穷举算法思想 穷举算法的基本思想 从所有可能情况中搜索正确答案 1. 对于一种可能情况,计算其结果. 2. 判断结果是否满足,如不能满足者执行第一步来搜索下一个可能的情况:如满足则表示选找到一个

Operation System - Peterson&amp;#39;s Solution算法 解决多线程冲突

Person's solution 是用来一种基于软件的解决关键区域问题的算法(critical-section). 它并不是完美的,有可能不对地工作.并且是限制解决两个进程同步的问题. 可是它非常easy,非常原始,学习起来也是非常轻松的. 代码例如以下: do { flag[i] = true; turn = j; while (flag[j] && turn == j); critical section flag[i] = false; remainder section } wh