類比退火演算法解決3SAT問題(C++實現代碼)

來源:互聯網
上載者:User

標籤:類比退火演算法   3sat   c++   進階演算法   代碼   

轉載請註明出處:http://blog.csdn.net/zhoubin1992/article/details/46453761

1 SAT問題描述

命題邏輯中合取範式 (CNF)的可滿足性問題 (SAT)是當代理論電腦科學的核心問題,是一典型的NP完全問題.在定義可滿足性問題SAT之前,先引進一些邏輯符號。


2  類比退火演算法

類比退火演算法來源於固體退火原理,將固體加溫至充分高,再讓其徐徐冷卻,加溫時,固體內部粒子隨溫升變為無序狀,內能增大,而徐徐冷卻時粒子漸趨有序,在每個溫度都達到平衡態,最後在常溫時達到基態,內能減為最小。用固體退火類比組合最佳化問題,將內能E類比為目標函數值f,溫度T演化成控制參數t,即得到解組合最佳化問題的類比退火演算法:由初始解i和控制參數初值t開始,對當前解重複“產生新解→計算目標函數差→接受或捨棄”的迭代,並逐步衰減t值,演算法終止時的當前解即為所得近似最優解,這是基於蒙特卡羅迭代求解法的一種啟發學習法隨機搜尋過程。

類比退火演算法可以分解為解空間、目標函數和初始解3部分。其基本思想是:

(1)初始化:初始溫度T(充分大),初始解狀態s(是演算法迭代的起點),每個T值的迭代次數L(Markov鏈長),衰減準則α,停止準則。

(2)對k=1,……,L做第(3)至第(6)步;

(3)產生新解s′;

(4)計算增量cost=cost(s′)-cost(s),其中cost(s)為評價函數;

(5)若t′<0則接受s′作為新的當前解,否則以機率exp(-t′/T)接受s′作為新的當前解;

(6)如果滿足終止條件則輸出當前解作為最優解,結束程式。否則T逐漸減少,並轉第2步運算。

    類比退火演算法虛擬碼如下:

<span style="font-size:14px;">choose an initial solution X0  randomly    //隨機的選擇一個初始解X0give an initial temperature T0 , X ← X0, T ← T0    //初始化溫度T0while the stop criterion is not yet satisfied do    //停止準則不滿足則  {   for i ← 1 to  L do                          //Markov 鏈的長度 L       { pick a solution  X'∈N(X) randomly  //隨機播放臨域內一個解X'         Δf ← f(X')-f(X)                                                            if Δf<0  then  X ← X'         else  X ← X' with  probability exp(- Δf/T)  }  // 以exp(- Δf/T)的接受機率接受X' T← g(T)    //generally, T ← aT    }      //溫度下降 return X</span>
3 C++實現代碼

<span style="font-size:14px;">// SA3Sat.cpp : 定義控制台應用程式的進入點。//#include "stdafx.h"#include <iostream>#include <time.h>#include <fstream>#include <math.h>using namespace std;#define ANSSIZE 100int ans[ANSSIZE]; int new_ans[ANSSIZE];int **x;int n=100;int m=430;int randomi(int a, int b){int c=rand()%(b-a+1)+a;return c;}double randomf(double a, double b){double c = (double)(rand()%((int)b-(int)a)) + a + (double)(rand()/(RAND_MAX + 1.0));return c;}void Johnson(int n){for (int i = 0 ; i<n ; i++){if ((double)rand()/(RAND_MAX)>0.5){ans[i] = 1;}else{ans[i] = 0;}}}int satisfied_ans(int m){int count = 0;int i,j;for (i = 0 ; i<m ; i++){for (j = 0 ; j<3 ; j++){if (x[i][j]<0){int temp= (-1)*x[i][j];if (ans[temp-1]==0){count++;break;}}else if (x[i][j]>0){if (ans[x[i][j]-1]==1){count++;break;}}}}return count;}int satisfied_new_ans(int m){int count = 0;int i,j;for (i = 0 ; i<m ; i++){for (j = 0 ; j<3 ; j++){if (x[i][j]<0){int temp= (-1)*x[i][j];if (new_ans[temp-1]==0){count++;break;}}else if (x[i][j]>0){if (new_ans[x[i][j]-1]==1){count++;break;}}}}return count;}void disturb(int n){for (int j = 0 ; j<n ;j++){new_ans[j] = ans[j];}int i = rand()%n;new_ans[i] = 1-new_ans[i];}bool accept(int deta,float T){if (deta>0){return 1;} else if(((deta<0)&&(exp(deta/T)>randomf(0,1)))){return 1;}return 0;}void SA3Sat(int n,int m){int i;Johnson(n);   //初始解float T = 1000;  //初始溫度int L = 100*n;    float T_time=0.001;while(T>T_time&&satisfied_ans(m)!=m){for (i= 0 ; i<L ; i++){disturb(n);// for (i = 0 ; i<n ; i++)// {// cout<<ans[i]<<" ";// }int deta = satisfied_new_ans(m)-satisfied_ans(m);if (accept(deta,T)){for (int j = 0 ; j<n ; j++){ans[j] = new_ans[j];}}}T = 0.98*T;}}int _tmain(int argc, _TCHAR* argv[]){// int n,m,i,j;// cin>>n>>m;     //3SAT問題 // x = new int*[m];// for (i = 0 ; i<m ; i++)// {// x[i] = new int[3];// }// for (i = 0 ; i<m ; i++)   //子句 // {// for (j = 0 ; j<3 ; j++)// {// cin>>x[i][j];// }// }double run_time = 0.0; //執行時間time_t start,end;start = clock();ifstream fin;fin.open("10.txt");int i,j,t;    x = new int*[m];for (i = 0 ; i<m ; i++){x[i] = new int[3];}for (i = 0 ; i<m ; i++)   {for (j = 0 ; j<3 ; j++){fin>>x[i][j];}fin>>t;}fin.close();srand((unsigned)time(NULL)); SA3Sat(n,m); cout<<"可滿足的子句個數:"<<satisfied_ans(m)<<endl; cout<<"變元的最終取值為:"; for (i = 0 ; i<n ; i++) { cout<<ans[i]<<" "; }// if (satisfied_ans(m)==m)// {// cout<<"Yes";// }// else// {// cout<<"No";// }end = clock();run_time = (end - start)/CLOCKS_PER_SEC;printf("已耗用時間為 : %f\n", run_time);system("pause");return 0;}</span>


4  實驗結果

4.1參數設定

控制參數初值:t0=1000;

停止準則:溫度達到設定的下限時即停止演算法運行或達到最大可滿足子句條件。

冷卻進度表中的控制參數t的衰減函數:a(t)=0.98*t;

Mapkob鏈長:定長100*m。

4.2實驗結果

測試案例(1.txt):http://download.csdn.net/detail/zhoubin1992/8794893

樣本為1.txt,變元個數n=30,子句個數m=129時,可滿足的子句數為128,已耗用時間為19.0000秒,結果如下:


參考文獻

[1]  張德富.演算法設計與分析(進階教程)[M].國防工業出版社,2007.


類比退火演算法解決3SAT問題(C++實現代碼)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.