View Javadoc

1   /*******************************************************************************
2    * SAT4J: a SATisfiability library for Java Copyright (C) 2004-2008 Daniel Le Berre
3    *
4    * All rights reserved. This program and the accompanying materials
5    * are made available under the terms of the Eclipse Public License v1.0
6    * which accompanies this distribution, and is available at
7    * http://www.eclipse.org/legal/epl-v10.html
8    *
9    * Alternatively, the contents of this file may be used under the terms of
10   * either the GNU Lesser General Public License Version 2.1 or later (the
11   * "LGPL"), in which case the provisions of the LGPL are applicable instead
12   * of those above. If you wish to allow use of your version of this file only
13   * under the terms of the LGPL, and not to allow others to use your version of
14   * this file under the terms of the EPL, indicate your decision by deleting
15   * the provisions above and replace them with the notice and other provisions
16   * required by the LGPL. If you do not delete the provisions above, a recipient
17   * may use your version of this file under the terms of the EPL or the LGPL.
18   * 
19   * Based on the original MiniSat specification from:
20   * 
21   * An extensible SAT solver. Niklas Een and Niklas Sorensson. Proceedings of the
22   * Sixth International Conference on Theory and Applications of Satisfiability
23   * Testing, LNCS 2919, pp 502-518, 2003.
24   *
25   * See www.minisat.se for the original solver in C++.
26   * 
27   *******************************************************************************/
28  package org.sat4j.minisat.restarts;
29  
30  import org.sat4j.minisat.core.RestartStrategy;
31  import org.sat4j.minisat.core.SearchParams;
32  
33  /**
34   * Luby series
35   */
36  public final class LubyRestarts implements RestartStrategy {
37  
38  	private static final int DEFAULT_LUBY_FACTOR = 32;
39  	private static final int PRECOMPUTED_VALUES_IN_POOL = 32;
40  	/**
41       * 
42       */
43  	private static final long serialVersionUID = 1L;
44  
45  	private static int[] cachedValues = new int[] { 0, 1, 1, 2 };
46  
47  	public static final int luby(int i) {
48  		if (i >= Integer.MAX_VALUE / 2) {
49  			throw new IllegalArgumentException("i is too big");
50  		}
51  		if (i >= cachedValues.length) {
52  			int oldsize = cachedValues.length;
53  			int newsize = i << 1;
54  			int[] newContent = new int[newsize + 1];
55  			System.arraycopy(cachedValues, 0, newContent, 0, oldsize);
56  			int nextPowerOfTwo = 1;
57  			while (nextPowerOfTwo <= oldsize) {
58  				nextPowerOfTwo <<= 1;
59  			}
60  			int lastPowerOfTwo = nextPowerOfTwo >> 1;
61  			for (int j = oldsize; j <= newsize; j++) {
62  				if (j + 1 == nextPowerOfTwo) {
63  					newContent[j] = lastPowerOfTwo;
64  					lastPowerOfTwo = nextPowerOfTwo;
65  					nextPowerOfTwo <<= 1;
66  				} else {
67  					newContent[j] = newContent[j - lastPowerOfTwo + 1];
68  				}
69  			}
70  			cachedValues = newContent;
71  
72  		}
73  		return cachedValues[i];
74  	}
75  
76  	static {
77  		luby(PRECOMPUTED_VALUES_IN_POOL);
78  	}
79  
80  	private int factor;
81  
82  	private int count;
83  
84  	public LubyRestarts() {
85  		this(DEFAULT_LUBY_FACTOR); // uses TiniSAT default
86  	}
87  
88  	/**
89  	 * @param factor
90  	 *            the factor used for the Luby series.
91  	 * @since 2.1
92  	 */
93  	public LubyRestarts(int factor) {
94  		setFactor(factor);
95  	}
96  
97  	public final void setFactor(int factor) {
98  		this.factor = factor;
99  	}
100 
101 	public int getFactor() {
102 		return factor;
103 	}
104 
105 	public void init(SearchParams params) {
106 		count = 1;
107 	}
108 
109 	public long nextRestartNumberOfConflict() {
110 		return luby(count) * factor;
111 	}
112 
113 	public void onRestart() {
114 		count++;
115 	}
116 
117 	@Override
118 	public String toString() {
119 		return "luby style (SATZ_rand, TiniSAT) restarts strategy with factor "
120 				+ factor;
121 	}
122 
123 }