WalkSATlm2013是一个随机局部搜索的典型求解器,包含了主要的求解框架和技术实现方法。下面就代码组成做解读。
第一部分:库、宏、函数指针、全局变量
//1.1 头文件
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <cmath>
using namespace std;
/* limits on the size of the problem. */
#define MAX_VARS 4000010
#define MAX_CLAUSES 17000000
#define pop(stack) stack[--stack ## _fill_pointer]
#define push(item, stack) stack[stack ## _fill_pointer++] = item
//1.2自定义结构体类型表示文字类型
// Define a data structure for a literal in clauses
struct lit {
//int clause_num; //clause num, begin with 0
int var_num; //variable num, begin with 1
bool sense; //is 1 for positive literals, 0 for negative literals.
};
//1.3宏定义——指明求解器适用求解样例的规模
/* limits on the size of the problem. */
#define MAX_VARS 4000010
#define MAX_CLAUSES 17000000
#define pop(stack) stack[--stack ## _fill_pointer]
#define push(item, stack) stack[stack ## _fill_pointer++] = item
//注意:上面两个宏定义实现函数功能,其中[ ]中的写法很是“高明”,需要重点参悟。pop(unsat_stack); 相当于unsat_stack[--unsat_stack _fill_pointer];
//可以参见:Cardiac.TJ的博文 https://blog.csdn.net/weixin_41892460/article/details/82735451
//1.4函数指针
void (* flip)(int flipvar); //通过将不同的翻转函数名(也是函数指针)赋给指针flip,可以调用不同的翻转函数
//备选的有 void flip_simp(int flipvar); || void flip_update(int flipvar);
int (*pick) (); //计算并挑选出翻转变元。针对不同问题可以有多个函数备选。
//1.5全局变量
/*parameters of the instance*/
int num_vars; //var index from 1 to num_vars
int num_clauses; //clause index from 0 to num_clauses-1
int max_clause_len;
int min_clause_len;
double ratio; //clause to variable ratio
/* literal arrays */
int* var_poslit[MAX_VARS]; //var_lit[v][j]: the clause number of the clause that the j'th positive literal of v occurs in.
int* var_neglit[MAX_VARS]; //这是两个二维向量,其元素一维向量 var_poslit[v] 联合var_neglit[v]可以表示全部包含有变元v(以正负两种文字出现)的子句。
int var_poslit_count[MAX_VARS];
int var_neglit_count[MAX_VARS];
lit* clause_lit[MAX_CLAUSES]; // clause_lit[i][j] means the j'th literal of clause i. 注意子句和子句中的文字都是从0开始编号
int clause_lit_count[MAX_CLAUSES]; // amount of literals in each clause
/* Information about the variables. */
int bbreak[MAX_VARS]; //break(x), the smaller the better
//int gmake[MAX_VARS]; //combination of make(x) and pmake(x)
/* Information about the clauses */
int sat_count[MAX_CLAUSES];
int sat_var[MAX_CLAUSES];
//unsat clauses stack
int unsat_stack[MAX_CLAUSES]; //store the unsat clause number
int unsat_stack_fill_pointer;
int index_in_unsat_stack[MAX_CLAUSES]; //which position is a clause in the unsat_stack
/* Information about solution */
bool cur_soln[MAX_VARS]; //the current solution, with 1's for True variables, and 0's for False variables
//cutoff
int max_tries = 100000;
unsigned int max_flips = 4000000000u;
unsigned int step;
const int MY_RAND_MAX_INT = 10000000;
const float BASIC_SCALE = 0.0000001; //1.0f/MY_RAND_MAX_FLOAT; //以上这两个量在pick系列函数中被使用,参与计算得到的值用于与wp(噪声水平)想比较。
double wp; // the noise parameter