Browse Source

Ajout prog utilsant EMA

Arthur Brandao 6 years ago
parent
commit
ba84cb26da

+ 171 - 0
BanditEMA/ControlBandit.cpp

@@ -0,0 +1,171 @@
+#include <unistd.h>
+#include "ControlBandit.hpp"
+
+/* --- Public --- */
+
+ControlBandit::ControlBandit() {
+	//Initialisation de la queue pour les 1er passes
+	for(int i = 0; i < 2; i++) {
+		//2 tours pour les 2 passe initiale
+		for(int f = 2; f < 6; f++) {
+			for(int h = 0; h < 7; h++) {
+				fillAndHeuristic fah;
+				fah.fill = f;
+				fah.heuristic = h;
+				queue.push_back(fah);
+			}
+		}
+	}
+	//Remplissage tableau moyenne
+	for(int f = 0; f < NB_FILL; f++) {
+		favg[f] = 0;
+	}
+	for(int h = 0; h < NB_HEURISTIC; h++){
+		havg[h] = 0;
+	}
+	//Ini method
+	alphaStatic = true;
+	alpha = 0.5;
+	method = MT_EMA;
+	epsilon = 10;
+	//Ini random
+	srand(getpid());
+}
+
+ControlBandit::~ControlBandit() {
+
+}
+
+void ControlBandit::setMethod(int cstMethod, bool statique) {
+	if(statique) {
+		alphaStatic = true;
+		alpha = 0.5;
+	} else {
+		alphaStatic = false;
+		alpha = 0.4;
+	}
+	method = cstMethod;
+}
+
+void ControlBandit::setEpsilon(double newEpsilon) {
+	if(newEpsilon >= 0 && newEpsilon <= 1) {
+		epsilon = (int) (newEpsilon * 100);
+	}
+}
+
+bool ControlBandit::queueIsEmpty() {
+	bool res;
+	mutex.lock();
+	res = queue.size() == 0;
+	mutex.unlock();
+	return res;
+}
+
+fillAndHeuristic ControlBandit::next() {
+	fillAndHeuristic fah;
+	mutex.lock();
+	if(queue.size() == 0) {
+		switch(method) {
+			case MT_EPS:
+				fah = this->methodEps();
+				break;
+			default:
+				fah = this->methodEma();
+		}
+	} else {
+		fah = queue[0];
+		queue.erase(queue.begin());
+	}
+	mutex.unlock();
+	return fah;
+}
+
+void ControlBandit::addFill(int num, int score) {
+	num -= 2;
+	//Recup la valeur d'alpha
+	double localAlpha;
+	if(alphaStatic) {
+		localAlpha = alpha;
+	} else {
+		//Increment la valeur
+		mutex.lock();
+		alpha += ALPHA_STEP;
+		localAlpha = alpha;
+		mutex.unlock();
+	}
+	//Met a jour la moyenne
+	mutexFill.lock();
+	favg[num] = (1 - localAlpha) * favg[num] + localAlpha * score;
+	mutexFill.unlock();
+}
+
+void ControlBandit::addHeuristic(int num, int score) {
+	//Recup la valeur d'alpha
+	double localAlpha;
+	if(alphaStatic) {
+		localAlpha = alpha;
+	} else {
+		//Increment la valeur
+		mutex.lock();
+		alpha += ALPHA_STEP;
+		localAlpha = alpha;
+		mutex.unlock();
+	}
+	mutexHeuristic.lock();
+	havg[num] = (1 - localAlpha) * havg[num] + localAlpha * score;
+	mutexHeuristic.unlock();
+}
+
+/* --- Private --- */
+
+fillAndHeuristic ControlBandit::methodEma() {
+	fillAndHeuristic fah;
+	fah.fill = this->getBestFill();
+	fah.heuristic = this->getBestHeuristic();
+	return fah;
+}
+
+fillAndHeuristic ControlBandit::methodEps() {
+	fillAndHeuristic fah;
+	//Tirage au sort pour savoir si on prend la meilleur moyenne ou non
+	int random = rand() % 100;
+	if(random < epsilon) {
+		//Tirage au sort de fill et heuristic
+		fah.fill = this->getRandomFill();
+		fah.heuristic = this->getRandomHeuristic();
+		//printf("=== Random === : %d %d\n", fah.fill, fah.heuristic);
+	} else {
+		//Utilisation des meilleurs fill et heuristic
+		fah.fill = this->getBestFill();
+		fah.heuristic = this->getBestHeuristic();
+	}
+	return fah;
+}
+
+int ControlBandit::getBestFill() {
+	int max = 0;
+	int fill = 0;
+	mutexFill.lock();
+	for(int i = 0; i < NB_FILL; i++) {
+		if(favg[i] > max) {
+			max = favg[i];
+			fill = i;
+		}
+	}
+	mutexFill.unlock();
+	return fill + 2;
+}
+
+int ControlBandit::getBestHeuristic() {
+	int max = 0;
+	int h = 0;
+	mutexHeuristic.lock();
+	for(int i = 0; i < NB_HEURISTIC; i++) {
+		if(havg[i] > max) {
+			max = havg[i];
+			h = i;
+		}
+	}
+	mutexHeuristic.unlock();
+	return h;
+}

+ 58 - 0
BanditEMA/ControlBandit.hpp

@@ -0,0 +1,58 @@
+#ifndef CONTROLBANDIT_HPP
+#define CONTROLBANDIT_HPP 
+
+/* --- Include --- */
+#include <mutex>
+#include <vector>
+#include <stdlib.h>
+
+/* --- Define --- */
+#define NB_FILL 4
+#define NB_HEURISTIC 7
+#define MT_EMA 0
+#define MT_EPS 1
+#define ALPHA_STEP 0.001
+
+/* --- Structure --- */
+typedef struct {
+	int fill;
+	int heuristic;
+}fillAndHeuristic;
+
+class ControlBandit {
+	public:
+		ControlBandit();
+		~ControlBandit();
+
+		void setMethod(int, bool);
+		void setEpsilon(double);
+
+		bool queueIsEmpty();
+		fillAndHeuristic next();
+
+		void addFill(int, int);
+		void addHeuristic(int, int);
+
+	private:
+		int method;
+		int epsilon;
+		std::mutex mutex;
+		std::mutex mutexFill;
+		std::mutex mutexHeuristic;
+		std::vector<fillAndHeuristic> queue;
+		bool alphaStatic;
+		double alpha;
+		double favg[NB_FILL];
+		double havg[NB_HEURISTIC];
+
+		fillAndHeuristic methodEma();
+		fillAndHeuristic methodEps();
+
+		int getBestFill();
+		int getBestHeuristic();
+		inline int getRandomFill() {return rand() % 4 + 2;}
+		inline int getRandomHeuristic() {return rand() % 7;}
+
+};
+
+#endif

+ 120 - 0
BanditEMA/GSAT/ArrayFiller.cpp

@@ -0,0 +1,120 @@
+/*
+ * ArrayFiller.cpp
+ *
+ *  Created on: Oct 1, 2016
+ *      Author: Sina M.Baharlou
+ *      The class for filling 1-D boolean array
+ */
+
+
+#include "ArrayFiller.hpp"
+
+ArrayFiller::ArrayFiller(bool* bArray,unsigned int arrSize):
+arrSize(arrSize),
+stepSize(DEFAULT_STEP_SIZE),
+currStep(DEFAULT_CURR_STEP),
+tRate(0),
+pArray(NULL)
+{
+
+	// -- Initialize boolean array if it has not been initialized
+
+	if (bArray==NULL)
+		this->bArray=new bool[arrSize];
+	else
+		this->bArray=bArray;
+
+	// -- Initializing sampling distribution --
+
+	this->rndReal=std::uniform_real_distribution<float>(0.0,1.0);
+
+	// -- Init random engine --
+
+	struct timespec ts;
+	unsigned theTick = 0U;
+	clock_gettime( CLOCK_REALTIME, &ts );
+	theTick  = ts.tv_nsec / 1000000;
+	theTick += ts.tv_sec * 1000;
+	this->rndEngine.seed(theTick);
+}
+
+
+bool* ArrayFiller::getArray()
+{
+	return this->bArray;
+}
+
+void ArrayFiller::setPortionArray(float* pArray)
+{
+	this->pArray=pArray;
+}
+
+void ArrayFiller::setPortionRate(float rate)
+{
+	this->tRate=rate;
+}
+
+
+bool* ArrayFiller::fillArray(FillMethod method)
+{
+
+
+	switch (method)
+	{
+
+	case ZEROS_FILL:	// -- fills with zeros (false)
+		memset(this->bArray,0,this->arrSize*sizeof(bool));
+		break;
+
+	case ONES_FILL: // -- fills with ones (true)
+		memset(this->bArray,1,this->arrSize*sizeof(bool));
+		break;
+
+	case UNIFORM_FILL: // -- uniformly fills with zeros and ones
+		for (unsigned int i=0;i<this->arrSize;i++)
+		{
+			float rnd=this->rndReal(this->rndEngine);
+			this->bArray[i]=(rnd<UNIFORM_RATIO);
+		}
+		break;
+
+	case STEP_FILL:	// -- fills with step method
+		for (unsigned int i=0;i<this->arrSize;i++)
+		{
+			float rnd=this->rndReal(this->rndEngine);
+			this->bArray[i]=(rnd < this->currStep);
+		}
+
+		this->currStep+=this->stepSize; // -- increase the step size ( probability of having true value)
+		if (this->currStep>1) this->currStep=0;
+		break;
+
+	case PORTION_FILL: // -- fills proportionally
+		for (unsigned int i=0;i<this->arrSize;i++)
+		{
+			float rnd=this->rndReal(this->rndEngine);
+			this->bArray[i]=(rnd < this->tRate);
+		}
+		break;
+
+	case PORTION_EL_FILL: // -- fills each element proportionally
+
+		if (this->pArray==NULL)
+			break;
+
+
+		for (unsigned int i=0;i<this->arrSize;i++)
+		{
+			float rnd=this->rndReal(this->rndEngine);
+			this->bArray[i]=(rnd < this->pArray[i]);
+		}
+		break;
+
+	}
+
+	return this->bArray;
+
+}
+
+
+

+ 61 - 0
BanditEMA/GSAT/ArrayFiller.hpp

@@ -0,0 +1,61 @@
+/*
+ * ArrayFiller.hpp
+ *
+ *  Created on: Oct 1, 2016
+ *      Author: Sina M.Baharlou
+ *      The class for filling 1-D boolean array
+ */
+
+#ifndef ARRAYFILLER_HPP_
+#define ARRAYFILLER_HPP_
+
+#include <iostream>
+#include <string.h>
+#include <string>
+#include <stdio.h>
+#include <stdlib.h>
+#include <vector>
+#include <set>
+#include <fstream>
+#include <random>
+#include <math.h>
+#include "FillMethod.hpp"
+
+#define DEFAULT_STEP_SIZE	0.05
+#define DEFAULT_CURR_STEP	0.05
+
+using namespace std;
+
+class ArrayFiller
+{
+private :
+	bool *bArray ;					// -- pointer to the boolean array
+	unsigned int arrSize;			// -- array size
+	float stepSize;					// -- STEP_FILL, step size
+	float currStep;					// -- STEP_FILL, current step
+	float tRate;					// -- PORTION_FILL, true-rate
+	float* pArray;					// -- PORTION_EL_FILL array
+
+	std::uniform_real_distribution<float> rndReal;	// -- sampling from real uniform  distribution
+	std::default_random_engine rndEngine;			// -- sampling engine
+
+
+public:
+
+	// -- Vector Filler constructor
+	ArrayFiller(bool* bArray,unsigned int arrSize);
+
+	// -- property methods --
+	bool* getArray();
+
+	void setPortionArray(float* pArray);
+
+	void setPortionRate(float rate);
+
+	// -- Fill array randomly with the given method --
+	bool* fillArray(FillMethod method);
+
+};
+
+
+#endif /* ARRAYFILLER_HPP_ */

+ 675 - 0
BanditEMA/GSAT/CFormula.cpp

@@ -0,0 +1,675 @@
+/*
+ * CFormula.cpp
+ *
+ *  Created on: Oct 1, 2016
+ *      Author: Sina M.Baharlou
+ */
+
+#include "CFormula.hpp"
+
+CFormula::CFormula():
+nVars(0),
+nClauses(0),
+fStats{0,0,0},
+fVars(NULL),
+fPortions(NULL),
+tPortion(0),
+nLit(NULL),
+evalArray(NULL),
+
+evalClause(NULL),
+varMap(NULL),
+
+clCounter(0),
+
+greedyFactor(DEFAULT_GREEDY_FACTOR),
+arrayFiller(NULL),
+nbSatisfiedClausesFill(0),
+nbSatisfiedClausesSolve(0),
+lastFillMethod(0),
+lastHeuristic(0),
+ite(0)
+{
+
+	this->fType.clear();
+	this->fComments.clear();
+
+	// -- Initializing distribution variables --
+
+	rndReal=std::uniform_real_distribution<float>(0.0,1.0);
+	rndMethod=std::uniform_int_distribution<int>(FIRST_FILL_METHOD,LAST_FILL_METHOD);
+	rndHeuristic=std::uniform_int_distribution<int>(FIRST_H_METHOD,LAST_H_METHOD);
+
+	// -- Init random engine --
+
+	struct timespec ts;
+	unsigned theTick = 0U;
+	clock_gettime( CLOCK_REALTIME, &ts );
+	theTick  = ts.tv_nsec / 1000000;
+	theTick += ts.tv_sec * 1000;
+	rndEngine.seed(theTick);
+}
+
+
+
+
+bool CFormula::initFormula(const char* filename)
+{
+
+	// -- Initialize variables --
+
+	this->cFormula.empty();
+	this->fComments.empty();
+	this->fType.empty();
+	this->fStats={0,0,0};
+	this->clCounter=0;
+	bool fReached=false;
+
+
+	// -- Free previously allocated variables --
+
+	if (this->fVars) free(this->fVars);
+	if (this->fPortions) free(this->fPortions);
+	if (this->nLit) free(this->nLit);
+	if (this->evalArray) free(this->evalArray);
+	if (this->arrayFiller) free(this->arrayFiller);
+	if (this->varMap) free(this->varMap);
+	if (this->evalClause) free(this->evalClause);
+
+	// -- Open input file --
+
+	ifstream input_file;
+	input_file.open(filename);
+
+	if (!input_file.is_open())
+	{
+		printf("STD Error: cannot open '%s'.",filename);
+		return false;
+	}
+
+
+	// -- Parse the provided file --
+
+	std::string line;
+	while (std::getline(input_file, line))
+	{
+		// -- get the flag (can be 'c' or 'p') --
+		char flag=line[0];
+		std::vector<string> tokens;
+
+		switch (flag)
+		{
+
+		case COMMENT_FLAG:	// -- Comment line has reached --
+
+			// -- Add to comment string --
+			this->fComments.append(&line[1]);
+			this->fComments.append("\n");
+			break;
+
+
+		case PROBLEM_FLAG:	// -- Problem line has reached --
+
+			// -- Tokenize current line --
+			tokens.empty();
+			tokens=tokenize(&line[1]," ");
+
+			// -- Check if the syntax if correct in order to parse the parameters --
+			if (tokens.size()<3)
+			{
+				printf("There is a syntax error in the problem definition.");
+				return false;
+			}
+
+			// -- Assign the variables --
+			this->fType=tokens[0];
+			this->nVars=stoi(tokens[1])+1;		// -- starts from 1
+			this->nClauses=stoi(tokens[2]);
+			fReached=true;
+
+			// -- allocate the arrays
+			this->fVars=new bool[this->nVars];
+			this->fPortions= new float[this->nVars];
+			this->nLit=new int[this->nVars];
+			this->evalArray=new int[this->nVars];
+			this->evalClause=new bool[this->nClauses];
+			this->varMap=new std::vector<int>[this->nVars];
+
+			// -- initialize the arrays
+			memset(this->fVars,0,this->nVars*sizeof(bool));
+			memset(this->fPortions,0,this->nVars*sizeof(float));
+			memset(this->nLit,0,this->nVars*sizeof(int));
+			memset(this->evalArray,0,this->nVars*sizeof(int));
+			memset(this->evalClause,0,this->nClauses*sizeof(bool));
+
+			// -- Instantiate the arrayFiller class
+			this->arrayFiller=new ArrayFiller(this->fVars,this->nVars);
+
+			break;
+
+
+		case END_FLAG: // -- End of the formula has reached --
+			input_file.close();
+
+			// -- Ppdate stats --
+			this->tPortion=(float)this->fStats.nPosLits/this->fStats.nLits;
+			for (unsigned int i=1;i<this->nVars;i++)
+				this->fPortions[i]/=(float)this->nLit[i];
+
+			// -- Init random filler --
+			this->arrayFiller->setPortionRate(this->tPortion);
+			this->arrayFiller->setPortionArray(this->fPortions);
+			this->arrayFiller->fillArray(PORTION_EL_FILL);
+			return true;
+			break;
+
+		default:	// -- Clause line has reached--
+			if (!fReached)
+				continue;
+			this->cFormula.push_back(parseClause(&line[0]," "));
+			break;
+		}
+
+	}
+
+	return true;
+}
+
+
+
+
+bool CFormula::evalFormulaQ(unsigned int varIndex,int& clNum)
+{
+
+	bool fEval=true;
+	clNum=0;
+
+	// -- check through the modified clauses --
+	for (unsigned int i=0;i<this->varMap[varIndex].size();i++)
+	{
+		// -- get the clause --
+		int cIndex=this->varMap[varIndex].at(i);
+		Clause cl=this->cFormula[cIndex];
+
+		// -- for each literal
+		for (unsigned int j=0;j<cl.size();j++)
+		{
+
+			Literal lit=cl[j];
+
+			// -- get the index and sign
+			bool neg=(lit<0);
+			int index=abs(lit);
+			// -- evaluate the literal
+			bool litEval=neg^this->fVars[index];
+			this->evalClause[cIndex]=litEval; // -- update clause truth list
+
+			// -- if positive -> clause will be evaluated as positive
+			if (litEval)
+				break;
+
+		}
+
+	}
+
+
+	// -- evaluate the whole formula --
+
+	for (unsigned int i=0;i<this->cFormula.size();i++)
+	{
+		bool evalClause=this->evalClause[i];
+		fEval&=evalClause;
+		if (evalClause)clNum++;
+	}
+	return fEval;
+}
+
+
+bool CFormula::evalFormula(int& clNum)
+{
+
+
+	bool fEval=true;
+	clNum=0;
+
+
+	for (unsigned int i=0;i<this->cFormula.size();i++)
+	{
+
+		// -- get the clause --
+		Clause cl=this->cFormula[i];
+		bool clEval=false;
+
+		// -- for each literal
+		for (unsigned int j=0;j<cl.size();j++)
+		{
+
+			Literal lit=cl[j];
+
+			// -- get the index and sign
+			bool neg=(lit<0);
+			int index=abs(lit);
+			// -- evaluate the literal
+			bool litEval=neg^this->fVars[index];
+
+			this->evalClause[i]=litEval;
+
+			// -- if positive -> clause will be evaluated as positive
+			if (litEval)
+			{
+				clEval=true;
+				clNum++;
+				break;
+			}
+		}
+
+		// -- and it with current evaluation of formula
+		fEval&=clEval;
+
+	}
+
+	return fEval;
+}
+
+
+
+bool CFormula::startGSAT(int iterations,int maxTry,int fillMethod,int hMethod)
+{
+	float initGuessMean=0;	// -- initial guess average
+	float negClauseMean=0;	// -- average number of negative clauses
+	float elaborateMean=0; 	// -- averate number of elaboration
+	bool fEval=false;
+	int i;
+
+	for (i=0;i<iterations;i++)
+	{
+		int initGuess=0;
+		int clNum=0;
+		fEval=false;
+
+		// -- randomly select the filler method --
+		FillMethod fMethod;
+		if (fillMethod==-1)
+			fMethod=getRandomMethod();
+		else
+			fMethod=(FillMethod)fillMethod;
+		lastFillMethod=fMethod;
+		ite++;
+		// -- randomly select the heuristic method --
+		HeuristicMethod heuristic;
+		if (hMethod==-1)
+			heuristic=getRandomHeuristic();
+		else
+			heuristic=(HeuristicMethod)hMethod;
+		lastHeuristic=heuristic;
+		
+		this->arrayFiller->fillArray(fMethod);
+
+		// -- evaluate the function
+		fEval=this->evalFormula(clNum);
+		initGuess=clNum;
+		nbSatisfiedClausesFill=initGuess;
+		initGuessMean+=initGuess;
+
+		// -- return if already found the solution
+		if (fEval)
+			break;
+
+
+		for (int j=0;j<maxTry;j++)
+		{
+			int choice=0;
+
+
+			// -- select the choice with the given heuristics --
+
+			switch (heuristic)
+			{
+
+			case FIRST_BEST:
+				choice=this->getBestChoice(true);
+				break;
+
+			case RND_BEST:
+				choice=this->getBestChoice();
+				break;
+
+			case RND_DIST:
+				choice=this->getRndBest();
+				break;
+
+			case RND:
+				choice=(int)(rndReal(rndEngine)*this->nVars);
+				break;
+
+			case RND_GREEDY:
+				if (this->takeBestChoice())
+					choice=this->getBestChoice();
+				else
+					choice=this->getRndBest();
+				break;
+
+			case WALK_SAT:
+				choice=this->walkSatChoice();
+				break;
+
+			case GSAT_WSAT:
+				if (this->takeGW())
+					choice=this->getBestChoice();
+				else
+					choice=this->walkSatChoice();
+				break;
+
+			}
+
+
+			toggle(this->fVars[choice]);
+			fEval=this->evalFormulaQ(choice,clNum);//this->evalFormula(clNum);
+
+			if (fEval)
+				break;
+
+
+		}
+
+
+		negClauseMean+=this->nClauses-clNum;
+		elaborateMean+=clNum-initGuess;
+		nbSatisfiedClausesSolve=clNum;
+
+		//printf("[iteration %d, fill :%d, heuristic :%d] - init Guess :%d - final Guess :%d - model found :%d\n",i,fMethod,heuristic,initGuess,clNum,fEval);
+
+		if (fEval)
+			break;
+	}
+
+
+	/*printf("Elaborate mean :%f\n",elaborateMean/(float)i);
+	printf("Initial guess mean :%f\n",initGuessMean/(float)i);
+	printf("Neg clause mean :%f\n",negClauseMean/(float)i);*/
+
+
+
+	return fEval;
+
+}
+
+
+void CFormula::setGreedyFactor(float factor)
+{
+	this->greedyFactor=factor;
+}
+
+void CFormula::setGWFactor(float factor)
+{
+	this->gwFactor=factor;
+}
+
+std::vector<string> CFormula::tokenize(char*input,const char*split)
+{
+	char * token;
+	std::vector<string> token_vec;
+
+	token = strtok (input,split);
+	while (token != NULL)
+	{
+		token_vec.push_back(string(token));
+		token = strtok (NULL, " ");
+	}
+	return token_vec;
+}
+
+Clause CFormula::parseClause(char*input,const char*split)
+{
+	char * token;
+	Clause cl;
+
+	token = strtok (input,split);
+	while (token != NULL)
+	{
+		Literal lit=stoi(token);
+		if (lit!=0)
+		{
+			int index=abs(lit);
+			// -- update the stats
+
+			this->varMap[index].push_back(clCounter);
+
+			if (lit>0)
+			{
+				this->fStats.nPosLits++;
+				this->fPortions[index]+=1;
+			}
+			else this->fStats.nNegLits++;
+			fStats.nLits++;
+			this->nLit[index]++;
+			// --
+
+			cl.push_back(lit);
+		}
+		token = strtok (NULL, " ");
+	}
+
+	this->clCounter++;
+
+	return cl;
+}
+
+
+
+
+FillMethod CFormula::getRandomMethod()
+{
+	return (FillMethod)rndMethod(rndEngine);
+}
+
+
+HeuristicMethod CFormula::getRandomHeuristic()
+{
+	return (HeuristicMethod)rndHeuristic(rndEngine);
+}
+
+
+
+bool CFormula::takeBestChoice()
+{
+
+	double random=rndReal(rndEngine);	// -- Get a double random number between 0 and 1
+
+	// -- Check if GSAT should take a best action
+	if (random<=this->greedyFactor)
+		return true;
+	return false;
+}
+
+bool CFormula::takeGW()
+{
+
+	double random=rndReal(rndEngine);	// -- Get a double random number between 0 and 1
+
+	// -- Check if GSAT should take a best action
+	if (random<=this->gwFactor)
+		return true;
+	return false;
+}
+
+
+void CFormula::evalMove(int&min,int&max)
+{
+	min=std::numeric_limits<int>::max();
+	max=0;
+
+	for (unsigned int i=1;i<this->nVars;i++)
+	{
+		int clNum=0;
+		int temp=0;
+		toggle(this->fVars[i]);
+
+		this->evalFormulaQ(i,clNum);	//this->evalFormula(clNum);
+		toggle(this->fVars[i]);
+		this->evalFormulaQ(i,temp);
+
+		this->evalArray[i]=clNum;
+		if (clNum>max) max=clNum;
+		if (clNum<min) min=clNum;
+
+	}
+}
+
+std::vector<int> CFormula::evalUnsatClause(int clIndex,int&min,int&max)
+{
+	min=std::numeric_limits<int>::max();
+	max=0;
+
+	Clause cl=this->cFormula[clIndex];
+	std::vector<int> evalArray;
+
+	for (unsigned int i=0;i<cl.size();i++)
+	{
+		Literal lit=cl[i];
+		int index=abs(lit);
+
+		int clNum=0;
+		int temp=0;
+
+		// -- evaluate the positive clauses
+		toggle(this->fVars[index]);
+		this->evalFormulaQ(index,clNum);	//this->evalFormula(clNum);
+		toggle(this->fVars[index]);
+		this->evalFormulaQ(index,temp);
+		// --
+
+		evalArray.push_back(clNum);
+		if (clNum>max) max=clNum;
+		if (clNum<min) min=clNum;
+
+	}
+
+	return evalArray;
+}
+
+int CFormula::getBestChoice(bool retFirst)
+{
+	int min,max;
+	this->evalMove(min,max);
+	int bestCount=0;
+	std::vector<int> bestArray;
+
+	for (unsigned int i=1;i<this->nVars;i++)
+	{
+		if (this->evalArray[i]==max)
+		{
+			if (retFirst) return i;	// -- return immediately the first choice
+
+			bestArray.push_back(i);
+			bestCount++;
+		}
+	}
+
+	if (bestCount==1)
+		return bestArray[0];
+
+	// -- randomly select the best choice
+	int rndIndex=(int)(rndReal(rndEngine)*bestCount);
+	return bestArray[rndIndex];
+
+}
+
+
+int CFormula::walkSatChoice(bool retFirst)
+{
+
+	// -- Randomly get one unsatisfied clause
+	int clIndex=this->getUnsatClause(retFirst);
+
+	int min,max;
+
+	// -- List the best choices
+	std::vector<int> evalArray=evalUnsatClause( clIndex,min,max);
+
+	// -- select randomly from the best choices
+	int bestCount=0;
+	std::vector<int> bestArray;
+
+	for (unsigned int i=0;i<evalArray.size();i++)
+	{
+		if (evalArray[i]==max)
+		{
+			if (retFirst) return i;	// -- return immediately the first choice
+
+			bestArray.push_back(i);
+			bestCount++;
+		}
+	}
+
+	if (bestCount==1)
+		return abs(this->cFormula[clIndex].at(bestArray[0]));
+
+	// -- randomly select the best choice
+	int rndIndex=(int)(rndReal(rndEngine)*bestCount);
+
+	return abs(this->cFormula[clIndex].at(bestArray[rndIndex]));
+}
+
+int CFormula::getUnsatClause(bool retFirst)
+{
+
+	int clCount=0;
+	std::vector<int> clArray;
+
+	for (unsigned int i=0;i<this->nClauses;i++)
+	{
+		if (!this->evalClause[i])
+		{
+			if (retFirst) return i;	// -- return immediately the first choice
+
+			clArray.push_back(i);
+			clCount++;
+		}
+	}
+
+	if (clCount==1)
+		return clArray[0];
+
+	// -- randomly select the best choice
+	int rndIndex=(int)(rndReal(rndEngine)*clCount);
+	return clArray[rndIndex];
+
+}
+
+int CFormula::getRndBest(bool exponential)
+{
+	int min,max;
+	float cum=0;
+	this->evalMove(min,max);
+	float normalizer=0;
+
+	// -- calculate the discrete probability distribution --
+	float  probs[this->nVars];
+	float rnd =rndReal(rndEngine);
+
+	for (unsigned int i=1;i<this->nVars;i++)
+	{
+
+		probs[i]=(float)(this->evalArray[i]-min+DEFAULT_BIAS);
+
+		if (exponential)probs[i]=exp(probs[i]);
+		normalizer+=probs[i];
+	}
+
+	// -- sample from the distribution --
+	for (unsigned int i=1;i<this->nVars;i++)
+	{
+		cum+=probs[i]/normalizer;
+
+		if (cum>rnd)
+			return i;
+
+	}
+
+	return 0;
+}
+
+
+
+

+ 140 - 0
BanditEMA/GSAT/CFormula.hpp

@@ -0,0 +1,140 @@
+/*
+ * CFormula.hpp
+ *
+ *  Created on: Oct 1, 2016
+ *      Author: Sina M.Baharlou
+ */
+
+#ifndef CFORMULA_HPP_
+#define CFORMULA_HPP_
+
+#include <iostream>
+#include <string.h>
+#include <string>
+#include <stdio.h>
+#include <stdlib.h>
+#include <vector>
+#include <set>
+#include <fstream>
+#include <random>
+#include <math.h>
+#include "FillMethod.hpp"
+#include "ArrayFiller.hpp"
+#include "HeuristicMethod.hpp"
+
+using namespace std;
+
+
+typedef int Literal;
+typedef std::vector<Literal> Clause;
+typedef std::vector<Clause> Formulae;
+
+
+
+#define COMMENT_FLAG 'c'
+#define PROBLEM_FLAG 'p'
+#define END_FLAG '%'
+#define toggle(x) (x=x^1)
+#define DEFAULT_BIAS 1
+#define DEFAULT_ITERATIONS 1000
+#define DEFAULT_MAX_TRY 255
+#define DEFAULT_GREEDY_FACTOR 0.8
+#define DEFAULT_GW_FACTOR 0.5
+
+class CFormula
+{
+public :
+	string fType;			// -- formula type (in this case should be 'cnf')
+	string fComments;		// -- formula comments
+	unsigned int nVars;		// -- number of variables
+	unsigned int nClauses;	// -- number of clauses
+	struct
+	{
+		unsigned int nPosLits;		// -- number of positive literals
+		unsigned int nNegLits;		// -- number of negative literals
+		unsigned int nLits;			// -- total literls
+	}fStats;
+
+public :
+  bool * fVars;				// -- formula variables
+  float * fPortions;			// -- variables' proportions
+  float tPortion;				// -- total positive to negative literal proportion
+  int * nLit	;				// -- total occurrence of specific literal in formula
+  int * evalArray;			// -- flip evaluation array
+  bool * evalClause;		    // -- evaluation of clauses  // ADDED
+  std::vector<int>* varMap;	// -- mapping between variables and clauses //ADDED
+  unsigned int clCounter;		// -- clause counter variable
+  float greedyFactor;			// -- GSAT greedy factor
+  float gwFactor;				// -- GSAT or WSAT select probability
+
+  Formulae cFormula;				// -- canonical formula jagged array(vector)
+  ArrayFiller* arrayFiller;		//-- array filler class
+  std::default_random_engine rndEngine;
+  std::uniform_real_distribution<float> rndReal;	// -- sampling from real uniform  distribution
+  std::uniform_int_distribution<int> rndMethod;   // -- sampling from int uniform  distribution
+  std::uniform_int_distribution<int> rndHeuristic;// -- sampling from int uniform  distribution
+  unsigned int nbSatisfiedClausesFill;
+  unsigned int nbSatisfiedClausesSolve;
+  unsigned int lastFillMethod;
+  unsigned int lastHeuristic;
+  unsigned int ite;
+  
+public:
+  CFormula();
+  
+  bool initFormula(const char* filename);
+
+  bool evalFormulaQ(unsigned int varIndex,int& clNum);	// -- faster version of evalFormula (just check the modified clauses)
+
+  bool evalFormula(int& clNum);
+
+  bool startGSAT(int iterations=DEFAULT_ITERATIONS,int maxTry=DEFAULT_MAX_TRY,int fillMethod=-1,int hMethod=-1);
+
+  void setGreedyFactor(float factor);
+
+  void setGWFactor(float factor);
+
+  inline unsigned int getNbClauses(){return nClauses;}
+  inline unsigned int getNbVariables(){return nVars;}
+
+  inline unsigned int getNbSatisfiedClausesFill(){return nbSatisfiedClausesFill;}
+  inline unsigned int getNbSatisfiedClausesSolve(){return nbSatisfiedClausesSolve;}
+  
+  inline unsigned int getHeuristicFill(){return lastFillMethod;}
+  inline unsigned int getHeuristicSolve(){return lastHeuristic;}
+  inline unsigned int getNbIterations(){return ite;}
+
+  
+private:
+	std::vector<string> tokenize(char*input,const char*split);
+
+	Clause parseClause(char*input,const char*split);
+
+	// -- randomly select the filler method --
+	FillMethod getRandomMethod();
+
+	// -- randomly select the heuristic method --
+	HeuristicMethod getRandomHeuristic();
+
+	// -- If GSAT should take a best action
+	bool takeBestChoice();
+
+	bool takeGW();
+
+	void evalMove(int&min,int&max);
+
+	std::vector<int> evalUnsatClause(int clIndex,int&min,int&max);
+
+	int getBestChoice(bool retFirst=false);
+
+	int walkSatChoice(bool retFirst=false);
+
+	int getUnsatClause(bool retFirst=false);
+
+	int getRndBest(bool exponential=true);	// -- randomly select the choice according to each move's reward
+
+
+};
+
+
+#endif /* CFORMULA_HPP_ */

+ 28 - 0
BanditEMA/GSAT/FillMethod.hpp

@@ -0,0 +1,28 @@
+/*
+ * FillMethod.hpp
+ *
+ *  Created on: Oct 1, 2016
+ *      Author: Sina M.Baharlou
+ *      The methods for filling 1-D boolean array
+ */
+
+#ifndef FILLMETHOD_HPP_
+#define FILLMETHOD_HPP_
+
+
+enum FillMethod
+{
+	ZEROS_FILL,
+	ONES_FILL,
+	UNIFORM_FILL,
+	STEP_FILL,
+	PORTION_FILL,
+	PORTION_EL_FILL
+};
+
+#define METHOD_COUNT 6
+#define FIRST_FILL_METHOD 	UNIFORM_FILL
+#define LAST_FILL_METHOD 	PORTION_EL_FILL
+#define UNIFORM_RATIO	0.5
+
+#endif /* FILLMETHOD_HPP_ */

+ 144 - 0
BanditEMA/GSAT/GSAT.cpp

@@ -0,0 +1,144 @@
+//============================================================================
+// Name        : GSAT.cpp
+// Author      : Sina M.Baharlou
+// Version     : 1
+// Description : GSAT Solver
+//============================================================================
+
+
+
+#include <iostream>
+#include <string.h>
+#include <string>
+#include <stdio.h>
+#include <stdlib.h>
+#include <vector>
+#include <set>
+#include <fstream>
+#include <random>
+#include <math.h>
+#include <sys/time.h>
+
+#include "GSAT.hpp"
+
+using namespace std;
+
+#include <algorithm>
+
+
+char* getCmdOption(char ** begin, char ** end, const std::string & option)
+{
+	char ** itr = std::find(begin, end, option);
+	if (itr != end && ++itr != end)
+	{
+		return *itr;
+	}
+	return 0;
+}
+
+bool cmdOptionExists(char** begin, char** end, const std::string& option)
+{
+	return std::find(begin, end, option) != end;
+}
+
+
+
+void printHelp()
+{
+	const char *help = "\n\n// --  GSAT simple solver -- // \n"
+			"// --  By Sina M.Baharlou -- // \n"
+			"// --  Oct  2016 \n\n"
+			"GSAT -i [input_file] <options> \n"
+			"Available options are : \n"
+			"\t--iterations [number of iterations] \n"
+			"\t--flip_max [number of maximum flips per iterations]\n"
+			"\t--greedy_factor [greedy factor] \n"
+			"\t--gw_factor [gsat/wsat factor] \n"
+			"\t--heuristic [heuristic_method]\n"
+			"\t\t-1- randomly select the heuristic method\n"
+			"\t\t 0- select the first best choice\n"
+			"\t\t 1- select randomly among the best choices\n"
+			"\t\t 2- select according to the cost distribution\n"
+			"\t\t 3- select randomly among all the choices\n"
+			"\t\t 4- combination of 1 and 2 according to the greedy factor\n"
+			"\t\t 5- WALKSAT\n"
+			"\t\t 6- randomly select between GSAT or WALKSAT\n"
+			"\t--rnd_method [rnd_method] \n"
+			"\t\t-1-randomly select the method\n"
+			"\t\t0-fill with zeros\n"
+			"\t\t1-fill with ones\n"
+			"\t\t2-fill uniformly\n"
+			"\t\t3-STEP method\n"
+			"\t\t4-PORTION method\n"
+			"\t\t5-PORTION_EL method\n";
+
+
+	printf("%s",help);
+}
+
+void GSAT::initialize(){
+  formula=new CFormula();
+  formula->initFormula(options->filename);
+  formula->setGreedyFactor(options->greedyFactor);
+  formula->setGWFactor(options->gwFactor);
+}
+
+bool GSAT::start(int fill,int heuristic){
+  return formula->startGSAT(1,options->maxTry,fill,heuristic);
+}
+
+Options* GSAT::setParameters(int argc,char* argv[]){
+  options = new Options();
+  // -- default variables --
+  options->iterations=DEFAULT_ITERATIONS;
+  options->maxTry=DEFAULT_MAX_TRY;
+  options->greedyFactor=DEFAULT_GREEDY_FACTOR;
+  options->gwFactor=DEFAULT_GW_FACTOR;
+  options->rndMethod=DEFAULT_RND_METHOD;
+  options->hMethod=DEFAULT_H_METHOD;
+  // --
+
+
+  if (argc<2)
+    {
+      printHelp();
+      exit(0);
+    }
+
+  if (!cmdOptionExists(argv, argv+argc, "-i"))
+    {
+      printHelp();
+      printf("STD Error : no input file has been provided.\n\n");
+      exit(0);
+    }
+
+  options->filename = getCmdOption(argv, argv + argc, "-i");
+
+  if (options->filename==NULL)
+    {
+      printf("STD Error : not input file has been provided.\n\n");
+      exit(0);
+    }
+
+  if (cmdOptionExists(argv, argv+argc, "--iterations"))
+    options->iterations=stoi(getCmdOption(argv, argv + argc, "--iterations"));
+
+
+
+  if (cmdOptionExists(argv, argv+argc, "--flip_max"))
+    options->maxTry=stoi(getCmdOption(argv, argv + argc, "--flip_max"));
+
+
+  if (cmdOptionExists(argv, argv+argc, "--greedy_factor"))
+    options->greedyFactor=stof(getCmdOption(argv, argv + argc, "--greedy_factor"));
+
+  if (cmdOptionExists(argv, argv+argc, "--gw_factor"))
+    options->gwFactor=stof(getCmdOption(argv, argv + argc, "--gw_factor"));
+
+  if (cmdOptionExists(argv, argv+argc, "--rnd_method"))
+    options->rndMethod=stoi(getCmdOption(argv, argv + argc, "--rnd_method"));
+
+  if (cmdOptionExists(argv, argv+argc, "--heuristic"))
+    options->hMethod=stoi(getCmdOption(argv, argv + argc, "--heuristic"));
+  return options;
+}

+ 71 - 0
BanditEMA/GSAT/GSAT.hpp

@@ -0,0 +1,71 @@
+
+#ifndef GSAT_HPP_
+#define GSAT_HPP_
+
+
+#include "FillMethod.hpp"
+#include "ArrayFiller.hpp"
+#include "CFormula.hpp"
+#include <iostream>
+#include <string.h>
+#include <string>
+#include <stdio.h>
+#include <stdlib.h>
+#include <vector>
+#include <set>
+#include <string> 
+#include <fstream>
+#include <random>
+#include <math.h>
+#include <sys/time.h>
+
+#define DEFAULT_ITERATIONS 1000
+#define DEFAULT_MAX_TRY 255
+#define DEFAULT_GREEDY_FACTOR 0.8
+#define DEFAULT_GW_FACTOR 0.5
+#define DEFAULT_RND_METHOD -1
+#define DEFAULT_H_METHOD -1
+
+class Options{
+public:
+  int iterations;
+  int maxTry;
+  float greedyFactor;
+  float gwFactor;
+  int rndMethod;
+  int hMethod;
+  char* filename;
+};
+
+char* getCmdOption(char ** begin, char ** end, const std::string & option);
+bool cmdOptionExists(char** begin, char** end, const std::string& option);
+void printHelp();
+
+class GSAT{
+public:
+  CFormula* formula;
+  Options* options;
+
+  Options* setParameters(int argc,char* argv[]);
+  void initialize();
+  bool start(int fill=DEFAULT_RND_METHOD,int heuristic=DEFAULT_H_METHOD);
+  inline double realTime() {
+    struct timeval tv;
+    gettimeofday(&tv, NULL);
+    return (double)tv.tv_sec + (double) tv.tv_usec / 1000000;
+  }
+
+  inline unsigned int getNbClauses(){return formula->getNbClauses();}
+  inline unsigned int getNbVariables(){return formula->getNbVariables();}
+
+  inline unsigned int getNbSatisfiedClausesFill(){return formula->getNbSatisfiedClausesFill();}
+  inline unsigned int getNbSatisfiedClausesSolve(){return formula->getNbSatisfiedClausesSolve();}
+  
+  inline unsigned int getHeuristicFill(){return formula->getHeuristicFill();}
+  inline unsigned int getHeuristicSolve(){return formula->getHeuristicSolve();}
+  inline unsigned int getNbIterations(){return formula->getNbIterations();}
+};
+
+
+
+#endif

+ 30 - 0
BanditEMA/GSAT/HeuristicMethod.hpp

@@ -0,0 +1,30 @@
+/*
+ * HeuristicMethod.hpp
+ *
+ *  Created on: Oct 3, 2016
+ *      Author: sina
+ */
+
+#ifndef HEURISTICMETHOD_HPP_
+#define HEURISTICMETHOD_HPP_
+
+
+enum HeuristicMethod
+{
+	FIRST_BEST,
+	RND_BEST,
+	RND_DIST,
+	RND,
+	RND_GREEDY,
+	WALK_SAT,
+	GSAT_WSAT,
+
+};
+
+#define FIRST_H_METHOD 	FIRST_BEST
+#define LAST_H_METHOD 	GSAT_WSAT
+
+
+
+
+#endif /* HEURISTICMETHOD_HPP_ */

+ 176 - 0
BanditEMA/GSATThread.cpp

@@ -0,0 +1,176 @@
+#include <iostream>
+#include <stdlib.h>
+#include <stdio.h>
+#include "GSATThread.hpp"
+#include "color.h"
+
+/* --- Public --- */
+
+GSATThread::GSATThread(int _nbThread, int argc, char** argv) {
+	nbThread = _nbThread;
+	gsat = std::vector<GSAT*>(_nbThread);
+	time = std::vector<double>(_nbThread);
+	threads = std::vector<std::thread>(_nbThread);
+	for(int i = 0; i < _nbThread; i++) {
+		gsat[i] = new GSAT();
+		gsat[i]->setParameters(argc,argv);
+  		gsat[i]->initialize();
+  		time[i] = 0;
+	}
+}
+
+GSATThread::~GSATThread() {
+	for(int i = 0; i < nbThread; i++) {
+		delete gsat[i];
+	}
+}
+
+void GSATThread::useEmaMethod(bool statique) {
+	cb.setMethod(MT_EMA, statique);
+}
+
+void GSATThread::useEpsilonMethod(double epsilon, bool statique) {
+	cb.setMethod(MT_EPS, statique);
+	cb.setEpsilon(epsilon);
+}
+
+bool GSATThread::solve() {
+	return this->solve(true);
+}
+
+bool GSATThread::solve(bool verbose) {
+	end = false;
+	calcTime = 0;
+	//Lance Initialise
+	printf("--- Initialize ---------------------------------------------------------------------------\n");
+	this->initBandit(verbose);
+	//Si la reponse n'a pas été trouvé durant l'initialisation
+	if(!end) {
+		//Lance les bandit avec la méthode choisit
+		printf("--- Search -------------------------------------------------------------------------------\n");
+		this->runBandit(verbose);
+	}
+	//Resultat
+	if(verbose) {
+		printf("--- Result -------------------------------------------------------------------------------\n");
+		this->printResult();
+	}
+  	return end;
+}
+
+void GSATThread::printResult() {
+	if(end) {
+		printf(GREEN "s SATISFIABLE\n" RESET);
+	} else {
+		printf(RED "NOT FOUND\n" RESET);
+	}
+	//printf("s %s\n",end?"SATISFIABLE":"NOT FOUND");
+	if(!end && calcTime == 0) {
+		//Si on à pas trouver
+		calcTime = gsat[0]->realTime() - time[0];
+	}
+	printf(YELLOW);
+	if(end) {
+		printf("c [thread:%2d][iteration:%5d][fill:%d][heuristic:%d]Satisfied clauses (begin: %d)(end:%d)\n",
+			result.threadId,
+			result.nbIteration,
+			result.heuristicFill,
+			result.heuristicSolve,
+			result.nbSatisfiedClausesFill,
+			result.nbSatisfiedClausesSolve);
+	}
+  	printf("c real time : %.4f seconds\n", calcTime);
+  	printf(RESET);
+}
+
+/* --- Private --- */
+
+void GSATThread::initBandit(bool verbose) {
+	threads.clear();
+	//Lance thread
+	for(int i = 0; i < nbThread; i++) {
+		time[i] = gsat[i]->realTime();
+		threads[i] = std::thread(&GSATThread::initThread, this, i, verbose);
+	}
+	//Attend resultat
+	for(int i = 0; i < nbThread; i++){
+		threads[i].join();
+	}
+}
+
+void GSATThread::runBandit(bool verbose) {
+	threads.clear();
+	//Lance thread
+	for(int i = 0; i < nbThread; i++) {
+		threads[i] = std::thread(&GSATThread::runThread, this, i, verbose);
+	}
+	//Attend resultat
+	for(int i = 0; i < nbThread; i++){
+		threads[i].join();
+	}
+}
+
+void GSATThread::initThread(int id, bool verbose) {
+	//Les threads vont jouer les bandits pour etablir les moyennes
+	bool solve = false;
+	while(!end && !solve && !cb.queueIsEmpty()){
+		solve = this->calc(id, verbose);
+	}
+	//Si 1er arreter
+	if(!end && solve) {
+		end = true;
+		calcTime = gsat[id]->realTime() - time[id];
+		result.threadId = id;
+		result.nbIteration = gsat[id]->getNbIterations();
+		result.heuristicFill = gsat[id]->getHeuristicFill();
+		result.heuristicSolve = gsat[id]->getHeuristicSolve();
+		result.nbSatisfiedClausesFill = gsat[id]->getNbSatisfiedClausesFill();
+		result.nbSatisfiedClausesSolve = gsat[id]->getNbSatisfiedClausesSolve();
+	}
+}
+
+void GSATThread::runThread(int id, bool verbose) {
+	//Les threads vont jouer les bandits avec la méthode choisit
+	bool solve = false;
+	while(!end && !solve){
+		solve = this->calc(id, verbose);
+	}
+	//Si 1er arreter
+	if(!end && solve) {
+		end = true;
+		calcTime = gsat[id]->realTime() - time[id];
+		result.threadId = id;
+		result.nbIteration = gsat[id]->getNbIterations();
+		result.heuristicFill = gsat[id]->getHeuristicFill();
+		result.heuristicSolve = gsat[id]->getHeuristicSolve();
+		result.nbSatisfiedClausesFill = gsat[id]->getNbSatisfiedClausesFill();
+		result.nbSatisfiedClausesSolve = gsat[id]->getNbSatisfiedClausesSolve();
+	}
+}
+
+bool GSATThread::calc(int id, bool verbose) {
+	//Recup le prochaine fill et heuristic à tester
+	fillAndHeuristic fah = cb.next();
+	//Calcul
+	bool solve = gsat[id]->start(fah.fill, fah.heuristic);
+	//Affiche
+	if(verbose) {
+		if(solve) {
+			printf(CYAN);
+		}
+		printf("c [thread:%2d][iteration:%5d][fill:%d][heuristic:%d]Satisfied clauses (begin: %d)(end:%d)\n",
+			id,
+		   	gsat[id]->getNbIterations(),
+		   	gsat[id]->getHeuristicFill(),
+		   	gsat[id]->getHeuristicSolve(),
+		   	gsat[id]->getNbSatisfiedClausesFill(),
+		   	gsat[id]->getNbSatisfiedClausesSolve());
+		if(solve) {
+			printf(RESET);
+		}
+	}
+	//Ajoute le resultat aux moyenne
+	cb.addFill(fah.fill, gsat[id]->getNbSatisfiedClausesFill());
+	cb.addHeuristic(fah.heuristic, gsat[id]->getNbSatisfiedClausesSolve());
+	return solve;
+}

+ 57 - 0
BanditEMA/GSATThread.hpp

@@ -0,0 +1,57 @@
+#ifndef GSATTHREAD_HPP 
+#define GSATTHREAD_HPP 
+
+/* --- Include --- */
+#include <vector>
+#include <thread>
+#include "GSAT/GSAT.hpp"
+#include "ControlBandit.hpp"
+
+/* --- Constante --- */
+#define DEFAULT_NB_THREAD 4
+
+/* --- Structure --- */
+typedef struct {
+	int threadId;
+	unsigned int nbIteration;
+	unsigned int heuristicFill;
+	unsigned int heuristicSolve;
+	unsigned int nbSatisfiedClausesFill;
+	unsigned int nbSatisfiedClausesSolve;
+}GSATResult;
+
+class GSATThread {
+	public:
+		GSATThread(int, int, char**);
+		~GSATThread();
+
+		void useEmaMethod(bool);
+		void useEpsilonMethod(double, bool);
+
+		bool solve();
+		bool solve(bool);
+		void printResult();
+
+		/* --- Getter --- */
+		inline unsigned int getNbVariables() {return gsat[0]->getNbVariables();}
+		inline unsigned int getNbClauses() {return gsat[0]->getNbClauses();}
+
+	private:
+		ControlBandit cb;
+		bool end;
+		double calcTime;
+		int nbThread;
+		std::vector<GSAT*> gsat;
+		std::vector<double> time;
+		std::vector<std::thread> threads;
+		GSATResult result;
+
+		void initBandit(bool);
+		void runBandit(bool);
+
+		void initThread(int, bool);
+		void runThread(int, bool);
+		bool calc(int, bool);
+};
+
+#endif

+ 79 - 0
BanditEMA/Main.cpp

@@ -0,0 +1,79 @@
+#include "GSAT/GSAT.hpp"
+#include "GSATThread.hpp"
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+using namespace std;
+
+void help(char* prog) {
+    fprintf(stderr, "usage: %s -i file.cnf [-t int] [-s] [-e double] [-d]\n\t-t Number of threads to use\n\t-s Silent mode\n\t-e Use epsilon greedy method with the value (0 <= value <= 1)\n\t-d Use dynamic alpha (default is static alpha = 0.5)\n", prog);
+    exit(1);
+}
+
+int main(int argc, char* argv[]) {
+
+    extern char * optarg; 
+    int nbThread = DEFAULT_NB_THREAD;
+    bool verbose = true;
+    int opt;
+    bool optI = false;
+    bool optE = false;
+    double epsilon = 0.1;
+    bool optD = false;
+
+    char** gsatArg = (char**) malloc(sizeof(char*) * 3);
+    gsatArg[0] = (char*) malloc(sizeof(char) * strlen(argv[0]) + 1);
+    memset(gsatArg[0], 0, strlen(argv[0]) + 1);
+    strncpy(gsatArg[0], argv[0], strlen(argv[0]));
+
+    while((opt = getopt(argc, argv, "si:t:e:d")) != -1) {
+        switch(opt) {
+            case 'i':
+                optI = true;
+                gsatArg[1] = (char*) malloc(sizeof(char) * 3);
+                memset(gsatArg[1], 0, 3);
+                strncpy(gsatArg[1], "-i", 2);
+                gsatArg[2] = (char*) malloc(sizeof(char) * strlen(optarg) + 1);
+                memset(gsatArg[2], 0, strlen(optarg) + 1);
+                strncpy(gsatArg[2], optarg, strlen(optarg));
+                break;
+            case 't':
+                nbThread = atoi(optarg);
+                break;
+            case 's':
+                verbose = false;
+                break;
+            case 'e':
+                optE = true;
+                epsilon = strtod(optarg, NULL);
+                break;
+            case 'd':
+                optD = true;
+                break;
+            case '?':
+                help(argv[0]); 
+        }
+    }
+
+    if(!optI) {
+        help(argv[0]);
+    }
+  
+    GSATThread* gsat = new GSATThread(nbThread, 3, gsatArg);
+    if(optE) {
+        gsat->useEpsilonMethod(epsilon, !optD);
+    } else {
+        gsat->useEmaMethod(!optD);
+    }
+    printf("c nbThreads: %d\n", nbThread);
+    printf("c nbVariables: %d\n", gsat->getNbVariables());
+    printf("c nbClauses: %d\n", gsat->getNbClauses());
+    bool result = gsat->solve(verbose);
+    if(!verbose) {
+        printf("s %s\n", result?"SATISFIABLE":"NOT FOUND");
+    }
+    
+
+}

+ 29 - 0
BanditEMA/Makefile

@@ -0,0 +1,29 @@
+CXXFLAGS = -std=c++0x -O2 -g -Wall -fmessage-length=0 -Wreorder -Wwrite-strings -Wsign-compare
+
+OBJS = Main.o GSATThread.o ControlBandit.o GSAT/GSAT.o GSAT/ArrayFiller.o GSAT/CFormula.o
+
+LIBS = -lpthread
+
+TARGET = GSATSolver
+
+$(TARGET):	$(OBJS)
+	$(CXX) -o $(TARGET) $(OBJS) $(LIBS)
+
+all:	$(TARGET)
+
+clean:
+	rm -f $(OBJS) $(TARGET)
+	rm -rf *.*~
+	rm -rf *~
+
+run:
+	./GSATSolver -i ../benchmarks/uf150/uf150-099.cnf -t 4
+
+epsilon:
+	./GSATSolver -i ../benchmarks/uf150/uf150-099.cnf -t 4 -e 0.2
+
+dynamic:
+	./GSATSolver -i ../benchmarks/uf150/uf150-099.cnf -t 4 -d
+
+exec:
+	./GSATSolver -i ../benchmarks/uf150/uf150-099.cnf -t 4 -d -e 0.2

+ 3 - 0
BanditEMA/README.txt

@@ -0,0 +1,3 @@
+
+make -j
+./GSAT -i ../benchmarks/uf150/uf150-099.cnf

+ 7 - 0
BanditEMA/color.h

@@ -0,0 +1,7 @@
+#define RED     "\x1b[31m"
+#define GREEN   "\x1b[32m"
+#define YELLOW  "\x1b[33m"
+#define BLUE    "\x1b[34m"
+#define MAGENTA "\x1b[35m"
+#define CYAN    "\x1b[36m"
+#define RESET   "\x1b[0m"