SAT problem expands (2) [Next]
First, what kind of adaptation function we use. In fact, for the dyeing group, our good and bad evaluation is recorded by score. The following process naturally portrays our design: the design of the adaptive function:
Private Int GetScore (INT i)
{
int score = 0;
For (int J = 0; j For (int K = 0; K IF (int.pars [i] .tostring (). Substring (k, 1)) bsentence [J, K] == 2 // || int.parse (Satgenes [i] .tostring (). Substring (k, 1)) bsentence [j, k] == - 1) { SCORE ; Break; } Return score; } Public int sort () { INT IBEST = 0, iWorst = 0; Int bestscore = getScore (0); // Int Worstscore = GetScore (0); For (int i = 0; i { Score [I] = GetScore (i); IF (Score [I]> Bestscore { IBEST = I; Bestscore = score [i]; } Else IF (Score [i] { iWorst = i; Worstscore = score [i]; } } Best = New Stringbuilder (Satgenes [ibest] .tostring ()); Worst = New StringBuilder (Satgenes [iWorst] .tostring ()); Return Bestscore; } You noticed that the evolutionary strategy we have taken from the general genetic algorithm. Of course, use Best and Worst, so that the evolution is abnormal, but we are diverse to the design of the operator to avoid the appearance of early maturity. It is the most core part, the design of the genetic operator. In our algorithm, hybrid operators and variation operators are very diverse. Among them, the mutation operator makes a chromosome as follows: 1/3 of the case of a certain bit of retrore variation, or two consecutive retroform variations at 2/3. The hybrid operator is hybridized by the probability value of the PC, and the hybridization process is as follows: From a certain bit, the interchangeable string is performed with a random length, 2/3, and the case of 1/3 is different or hybridized. The process is as follows: Public void mutation () { Int muttype, start; String subgene; INT i = randnum.next (MAXNUM-1); RandNum.nextdouble () <= pm) { MUTTYPE = RandNum.next (0, 2); Switch (MUTTYPE) { Case 0: Start = randnum.next (0, VALNUM-1); SubGene = satgenes [i] .tostring (). Substring (start, 1); IF (SUBGENE == "0") Satgenes [i] .Replace ("0", "1", start, 1); Else Satgenes [I] .replace ("1", "0", Start, 1); Break; Case 1: Case 2: Start = randnum.next (0, VALNUM-2); SubGene = satgenes [i] .tostring (). Substring (start, 2); Switch (SUBGENE) { Case "00": Satgenes [i] .Replace ("00", "11", start, 2); Break; Case "01": Satgenes [i] .Replace ("01", "10", start, 2); Break; Case "10": Satgenes [i] .replace ("10", "01", start, 2); Break; Case "11": Satgenes [i] .Replace ("11", "00", start, 2); Break; } Break; DEFAULT: Break; } } } Public void crossover () { Int Crotype, Start, Length, I, J String i_subgene, j_subgene; Length = randnum.next (5) 1; START = RandNum.next (0, VALNUM-Length); i = randnum.next (maxnum-1); J = randnum.next (maxnum-1); I_SUBGENE = Satgenes [i] .tostring (). Substring (Start, Length); J_SUBGENE = Satgenes [J] .tostring (). Substring (Start, Length); Crotype = randnum.next (2); Switch (Crotype) { Case 0: Case 2: Satgenes [i] .replace (i_subgene, j_subgene, start, length); Satgenes [J] .replace (j_subgene, i_subgene, start, length); Break; Case 1: For (int K = 0; K { Switch (int.parse (i_subgene.substring (k, 1)) int.parse (j_subgene.substring (k, 1)))) { Case 0: Case 2: Satgenes [i] .replace (i_subgene.substring (k, 1), "1", start k, 1); Satgenes [J] .replace (j_subgene.substring (k, 1), "0", start k, 1); Break; Case 1: Satgenes [i] .replace (i_subgene.substring (k, 1), "0", start k, 1); Satgenes [J] .replace (j_subgene.substring (k, 1), "1", start k, 1); Break; } } Break; DEFAULT: Break; } } The above is the main part of the SAT class. The details of the algorithm have been implemented. Below is an algorithm process, as well as initialization processes and other interface processes, implemented in class Form1, and other modification of the evolutionary parameters. Here is the algorithm itself: Private void geneCompute () { INT Answer = 0, Oldanswer = 0; HH = datetime.now.hour; mm = datetime.now.minute; SS = datetime.now.second; MS = datetime.now.millisecond; SetTime (); Onesat.initgenes (); Oldanswer = answer = onesat.sort (); While (Answer { Onesat.mutation (); Onesat.crossover (); Answer = onesat.sort (); SPSCORE.TEXT = STRSCORE ANSWER.TOSTRING (); IF (Answer { Oldanswer = answer; ChlistboxString.Items.Add (OneSat.Best, True); } SetTime (); } ChlistboxString.clearselected (); ChlistboxString.Items.Add (OneSat.Best, True); SPSCORE.TEXT = STRSCORE ANSWER.TOSTRING (); } One of OneSat is an object of the SAT class, which is initialized as follows: Onesat = New Sat (MaxNum, Valnum, 0.8, 0.02); SetTime () is the tracking of the calculation algorithm execution time, and the detailed process can be seen appendix. The entire algorithm is implemented, we have newly created a thread computegene, the process is as follows: Private void threadGENECompute () { Computegene = New Thread (New ThreadStart (GeneCompute)); Computegene.start (); } Thus, in class Form1, we can control this thread computegene to perform numerical experiments in our algorithm. The parameter setting of the algorithm is as follows: l Logic variable scale: 200 and 300 L population scale: 30 L subsee quantity: 30 l hybrid probability: 0.8 l Variation probability: 0.02 l Algorithm export as the best chromosome fraction equal to the number of non-empty clauses We have selected 200 and 300 logical variables. Some experiments have been made. In addition to the instantaneous solution to the results, we randomly selected two subsections and their calculations, time. From: The number of logical variables is 200: First, the calculation results are: 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000-00 Time is: 13s 328ms Second, the calculation results are: 0000011110010000000001111000001100000000000000011010111000000000000110000001111100000000000100000000000000000000000000000010000000000000001100000000100000110000 0000000001000000000000000000000000000000000000001111100 Time is: 57s 563ms The number of logical variables is 300: First, the calculation results are: 00000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 Time is: 2S 625ms Second, the calculation results are: 00001000000000000000000000000000000000000000111000000000000000000000000000000000 000000000000000000-00- 000000000000000000-00- 000000000000000000-00- Time is: 28s 641ms The set of clauses is randomly generated, and we appendix in the back for reference. From the results of the answer, the complex clause requires more time, but corresponding to the problem of 2 ^ 200 and 2 ^ 300, the calculation speed is still considerable. Existence problem The algorithm is our last semester, and later don't make meticulous optimization work because of being busy with other things. So now it seems that the algorithm's improvement is still very much. Simply analyze the following, and more improvements, we hope to readers. If you are interested in the source code of the entire program, you can contact the author and give free. First, the evolutionary strategy is still monotonous. What we actually take is that a population, choosing a probability requirement and hybridization, then sort the worst. No other measures, such as good genes can be retained as a library. Here you can try it. The algorithm is in the process of execution, there is a small amount of case, the score is 1 point, but it is fast to restore. This indicates that the calculation is not always forward. Moreover, when the calculation results tend to be better, the calculation is also slow, and it should be desirable to accelerate and remedy. The biggest shortcoming is that we cannot determine if the collection is satisfied before the final result appears. We can only tell you that the current calculation results show that how many clauses have been met, and we hope that the situation is getting better and better. This is determined by the characteristics of evolution calculations, and improvements are difficult to implement. Operators can also try to take other solutions. But we think our operator design is still better. Reference: (1) Kangli Mountain, intelligent calculation and its application and lectures, internal Chinese geology, September 2002 (2) Harry R.Lewis / Christos H.Papadimitriou, Elements of the Theory of Computation, Tsinghua University Press (Capital), September 1999 (2)