ruby-minisat 1.14.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +24 -0
- data/LICENSE +21 -0
- data/README.rdoc +56 -0
- data/Rakefile +48 -0
- data/VERSION +1 -0
- data/examples/compat18.rb +65 -0
- data/examples/example.rb +26 -0
- data/examples/example2.rb +60 -0
- data/examples/kakuro.rb +178 -0
- data/examples/kakuro.sample +13 -0
- data/examples/lonely7.rb +302 -0
- data/examples/nonogram.rb +254 -0
- data/examples/nonogram.sample +26 -0
- data/examples/numberlink.rb +489 -0
- data/examples/numberlink.sample +11 -0
- data/examples/shikaku.rb +190 -0
- data/examples/shikaku.sample +11 -0
- data/examples/slitherlink.rb +279 -0
- data/examples/slitherlink.sample +11 -0
- data/examples/sudoku.rb +216 -0
- data/examples/sudoku.sample +11 -0
- data/ext/minisat/extconf.rb +9 -0
- data/ext/minisat/minisat-wrap.cpp +88 -0
- data/ext/minisat/minisat.c +497 -0
- data/ext/minisat/minisat.h +53 -0
- data/minisat/MiniSat_v1.14.2006-Aug-29.src.zip +0 -0
- data/minisat/MiniSat_v1.14/Global.h +274 -0
- data/minisat/MiniSat_v1.14/Heap.h +100 -0
- data/minisat/MiniSat_v1.14/LICENSE +20 -0
- data/minisat/MiniSat_v1.14/Main.C +244 -0
- data/minisat/MiniSat_v1.14/Makefile +88 -0
- data/minisat/MiniSat_v1.14/README +30 -0
- data/minisat/MiniSat_v1.14/Solver.C +781 -0
- data/minisat/MiniSat_v1.14/Solver.h +206 -0
- data/minisat/MiniSat_v1.14/Solver.o +0 -0
- data/minisat/MiniSat_v1.14/SolverTypes.h +130 -0
- data/minisat/MiniSat_v1.14/Sort.h +131 -0
- data/minisat/MiniSat_v1.14/TODO +73 -0
- data/minisat/MiniSat_v1.14/VarOrder.h +96 -0
- data/test/test_minisat.rb +143 -0
- metadata +114 -0
@@ -0,0 +1,206 @@
|
|
1
|
+
/****************************************************************************************[Solver.h]
|
2
|
+
MiniSat -- Copyright (c) 2003-2005, Niklas Een, Niklas Sorensson
|
3
|
+
|
4
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
5
|
+
associated documentation files (the "Software"), to deal in the Software without restriction,
|
6
|
+
including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
7
|
+
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in all copies or
|
11
|
+
substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
14
|
+
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
15
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
16
|
+
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
17
|
+
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
18
|
+
**************************************************************************************************/
|
19
|
+
|
20
|
+
#ifndef Solver_h
|
21
|
+
#define Solver_h
|
22
|
+
|
23
|
+
#include "SolverTypes.h"
|
24
|
+
#include "VarOrder.h"
|
25
|
+
|
26
|
+
// Redfine if you want output to go somewhere else:
|
27
|
+
#define reportf(format, args...) ( printf(format , ## args), fflush(stdout) )
|
28
|
+
|
29
|
+
|
30
|
+
//=================================================================================================
|
31
|
+
// Solver -- the main class:
|
32
|
+
|
33
|
+
|
34
|
+
struct SolverStats {
|
35
|
+
int64 starts, decisions, propagations, conflicts;
|
36
|
+
int64 clauses_literals, learnts_literals, max_literals, tot_literals;
|
37
|
+
SolverStats() : starts(0), decisions(0), propagations(0), conflicts(0)
|
38
|
+
, clauses_literals(0), learnts_literals(0), max_literals(0), tot_literals(0) { }
|
39
|
+
};
|
40
|
+
|
41
|
+
|
42
|
+
struct SearchParams {
|
43
|
+
double var_decay, clause_decay, random_var_freq; // (reasonable values are: 0.95, 0.999, 0.02)
|
44
|
+
SearchParams(double v = 1, double c = 1, double r = 0) : var_decay(v), clause_decay(c), random_var_freq(r) { }
|
45
|
+
};
|
46
|
+
|
47
|
+
|
48
|
+
|
49
|
+
class Solver {
|
50
|
+
protected:
|
51
|
+
// Solver state:
|
52
|
+
//
|
53
|
+
bool ok; // If FALSE, the constraints are already unsatisfiable. No part of the solver state may be used!
|
54
|
+
vec<Clause*> clauses; // List of problem clauses.
|
55
|
+
vec<Clause*> learnts; // List of learnt clauses.
|
56
|
+
int n_bin_clauses; // Keep track of number of binary clauses "inlined" into the watcher lists (we do this primarily to get identical behavior to the version without the binary clauses trick).
|
57
|
+
double cla_inc; // Amount to bump next clause with.
|
58
|
+
double cla_decay; // INVERSE decay factor for clause activity: stores 1/decay.
|
59
|
+
|
60
|
+
vec<double> activity; // A heuristic measurement of the activity of a variable.
|
61
|
+
double var_inc; // Amount to bump next variable with.
|
62
|
+
double var_decay; // INVERSE decay factor for variable activity: stores 1/decay. Use negative value for static variable order.
|
63
|
+
VarOrder order; // Keeps track of the decision variable order.
|
64
|
+
|
65
|
+
vec<vec<GClause> > watches; // 'watches[lit]' is a list of constraints watching 'lit' (will go there if literal becomes true).
|
66
|
+
vec<char> assigns; // The current assignments (lbool:s stored as char:s).
|
67
|
+
vec<Lit> trail; // Assignment stack; stores all assigments made in the order they were made.
|
68
|
+
vec<int> trail_lim; // Separator indices for different decision levels in 'trail'.
|
69
|
+
vec<GClause> reason; // 'reason[var]' is the clause that implied the variables current value, or 'NULL' if none.
|
70
|
+
vec<int> level; // 'level[var]' is the decision level at which assignment was made.
|
71
|
+
int root_level; // Level of first proper decision.
|
72
|
+
int qhead; // Head of queue (as index into the trail -- no more explicit propagation queue in MiniSat).
|
73
|
+
int simpDB_assigns; // Number of top-level assignments since last execution of 'simplifyDB()'.
|
74
|
+
int64 simpDB_props; // Remaining number of propagations that must be made before next execution of 'simplifyDB()'.
|
75
|
+
|
76
|
+
// Temporaries (to reduce allocation overhead). Each variable is prefixed by the method in which is used:
|
77
|
+
//
|
78
|
+
vec<char> analyze_seen;
|
79
|
+
vec<Lit> analyze_stack;
|
80
|
+
vec<Lit> analyze_toclear;
|
81
|
+
Clause* propagate_tmpbin;
|
82
|
+
Clause* analyze_tmpbin;
|
83
|
+
Clause* solve_tmpunit;
|
84
|
+
vec<Lit> addBinary_tmp;
|
85
|
+
vec<Lit> addTernary_tmp;
|
86
|
+
|
87
|
+
// Main internal methods:
|
88
|
+
//
|
89
|
+
bool assume (Lit p);
|
90
|
+
void cancelUntil (int level);
|
91
|
+
void record (const vec<Lit>& clause);
|
92
|
+
|
93
|
+
void analyze (Clause* confl, vec<Lit>& out_learnt, int& out_btlevel); // (bt = backtrack)
|
94
|
+
bool analyze_removable(Lit p, uint min_level); // (helper method for 'analyze()')
|
95
|
+
void analyzeFinal (Clause* confl, bool skip_first = false);
|
96
|
+
bool enqueue (Lit fact, GClause from = GClause_new((Clause*)NULL));
|
97
|
+
Clause* propagate ();
|
98
|
+
void reduceDB ();
|
99
|
+
Lit pickBranchLit (const SearchParams& params);
|
100
|
+
lbool search (int nof_conflicts, int nof_learnts, const SearchParams& params);
|
101
|
+
double progressEstimate ();
|
102
|
+
|
103
|
+
// Activity:
|
104
|
+
//
|
105
|
+
void varBumpActivity(Lit p) {
|
106
|
+
if (var_decay < 0) return; // (negative decay means static variable order -- don't bump)
|
107
|
+
if ( (activity[var(p)] += var_inc) > 1e100 ) varRescaleActivity();
|
108
|
+
order.update(var(p)); }
|
109
|
+
void varDecayActivity () { if (var_decay >= 0) var_inc *= var_decay; }
|
110
|
+
void varRescaleActivity();
|
111
|
+
void claDecayActivity () { cla_inc *= cla_decay; }
|
112
|
+
void claRescaleActivity();
|
113
|
+
|
114
|
+
// Operations on clauses:
|
115
|
+
//
|
116
|
+
void newClause(const vec<Lit>& ps, bool learnt = false);
|
117
|
+
void claBumpActivity (Clause* c) { if ( (c->activity() += cla_inc) > 1e20 ) claRescaleActivity(); }
|
118
|
+
void remove (Clause* c, bool just_dealloc = false);
|
119
|
+
bool locked (const Clause* c) const { GClause r = reason[var((*c)[0])]; return !r.isLit() && r.clause() == c; }
|
120
|
+
bool simplify (Clause* c) const;
|
121
|
+
|
122
|
+
int decisionLevel() const { return trail_lim.size(); }
|
123
|
+
|
124
|
+
public:
|
125
|
+
Solver() : ok (true)
|
126
|
+
, n_bin_clauses (0)
|
127
|
+
, cla_inc (1)
|
128
|
+
, cla_decay (1)
|
129
|
+
, var_inc (1)
|
130
|
+
, var_decay (1)
|
131
|
+
, order (assigns, activity)
|
132
|
+
, qhead (0)
|
133
|
+
, simpDB_assigns (0)
|
134
|
+
, simpDB_props (0)
|
135
|
+
, default_params (SearchParams(0.95, 0.999, 0.02))
|
136
|
+
, expensive_ccmin (true)
|
137
|
+
, verbosity (0)
|
138
|
+
, progress_estimate(0)
|
139
|
+
{
|
140
|
+
vec<Lit> dummy(2,lit_Undef);
|
141
|
+
propagate_tmpbin = Clause_new(false, dummy);
|
142
|
+
analyze_tmpbin = Clause_new(false, dummy);
|
143
|
+
dummy.pop();
|
144
|
+
solve_tmpunit = Clause_new(false, dummy);
|
145
|
+
addBinary_tmp .growTo(2);
|
146
|
+
addTernary_tmp.growTo(3);
|
147
|
+
}
|
148
|
+
|
149
|
+
~Solver() {
|
150
|
+
for (int i = 0; i < learnts.size(); i++) remove(learnts[i], true);
|
151
|
+
for (int i = 0; i < clauses.size(); i++) if (clauses[i] != NULL) remove(clauses[i], true); }
|
152
|
+
|
153
|
+
// Helpers: (semi-internal)
|
154
|
+
//
|
155
|
+
lbool value(Var x) const { return toLbool(assigns[x]); }
|
156
|
+
lbool value(Lit p) const { return sign(p) ? ~toLbool(assigns[var(p)]) : toLbool(assigns[var(p)]); }
|
157
|
+
|
158
|
+
int nAssigns() { return trail.size(); }
|
159
|
+
int nClauses() { return clauses.size() + n_bin_clauses; } // (minor difference from MiniSat without the GClause trick: learnt binary clauses will be counted as original clauses)
|
160
|
+
int nLearnts() { return learnts.size(); }
|
161
|
+
|
162
|
+
// Statistics: (read-only member variable)
|
163
|
+
//
|
164
|
+
SolverStats stats;
|
165
|
+
|
166
|
+
// Mode of operation:
|
167
|
+
//
|
168
|
+
SearchParams default_params; // Restart frequency etc.
|
169
|
+
bool expensive_ccmin; // Controls conflict clause minimization. TRUE by default.
|
170
|
+
int verbosity; // Verbosity level. 0=silent, 1=some progress report, 2=everything
|
171
|
+
|
172
|
+
// Problem specification:
|
173
|
+
//
|
174
|
+
Var newVar ();
|
175
|
+
int nVars () { return assigns.size(); }
|
176
|
+
void addUnit (Lit p) { if (ok) ok = enqueue(p); }
|
177
|
+
void addBinary (Lit p, Lit q) { addBinary_tmp [0] = p; addBinary_tmp [1] = q; addClause(addBinary_tmp); }
|
178
|
+
void addTernary(Lit p, Lit q, Lit r) { addTernary_tmp[0] = p; addTernary_tmp[1] = q; addTernary_tmp[2] = r; addClause(addTernary_tmp); }
|
179
|
+
void addClause (const vec<Lit>& ps) { newClause(ps); } // (used to be a difference between internal and external method...)
|
180
|
+
|
181
|
+
// Solving:
|
182
|
+
//
|
183
|
+
bool okay() { return ok; } // FALSE means solver is in an conflicting state (must never be used again!)
|
184
|
+
void simplifyDB();
|
185
|
+
bool solve(const vec<Lit>& assumps);
|
186
|
+
bool solve() { vec<Lit> tmp; return solve(tmp); }
|
187
|
+
|
188
|
+
double progress_estimate; // Set by 'search()'.
|
189
|
+
vec<lbool> model; // If problem is satisfiable, this vector contains the model (if any).
|
190
|
+
vec<Lit> conflict; // If problem is unsatisfiable (possibly under assumptions), this vector represent the conflict clause expressed in the assumptions.
|
191
|
+
};
|
192
|
+
|
193
|
+
|
194
|
+
//=================================================================================================
|
195
|
+
// Debug:
|
196
|
+
|
197
|
+
|
198
|
+
#define L_LIT "%sx%d"
|
199
|
+
#define L_lit(p) sign(p)?"~":"", var(p)
|
200
|
+
|
201
|
+
// Just like 'assert()' but expression will be evaluated in the release version as well.
|
202
|
+
inline void check(bool expr) { assert(expr); }
|
203
|
+
|
204
|
+
|
205
|
+
//=================================================================================================
|
206
|
+
#endif
|
Binary file
|
@@ -0,0 +1,130 @@
|
|
1
|
+
/***********************************************************************************[SolverTypes.h]
|
2
|
+
MiniSat -- Copyright (c) 2003-2005, Niklas Een, Niklas Sorensson
|
3
|
+
|
4
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
5
|
+
associated documentation files (the "Software"), to deal in the Software without restriction,
|
6
|
+
including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
7
|
+
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in all copies or
|
11
|
+
substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
14
|
+
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
15
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
16
|
+
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
17
|
+
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
18
|
+
**************************************************************************************************/
|
19
|
+
|
20
|
+
|
21
|
+
#ifndef SolverTypes_h
|
22
|
+
#define SolverTypes_h
|
23
|
+
|
24
|
+
#ifndef Global_h
|
25
|
+
#include "Global.h"
|
26
|
+
#endif
|
27
|
+
|
28
|
+
|
29
|
+
//=================================================================================================
|
30
|
+
// Variables, literals, clause IDs:
|
31
|
+
|
32
|
+
|
33
|
+
// NOTE! Variables are just integers. No abstraction here. They should be chosen from 0..N,
|
34
|
+
// so that they can be used as array indices.
|
35
|
+
|
36
|
+
typedef int Var;
|
37
|
+
#define var_Undef (-1)
|
38
|
+
|
39
|
+
|
40
|
+
class Lit {
|
41
|
+
int x;
|
42
|
+
public:
|
43
|
+
Lit() : x(2*var_Undef) {} // (lit_Undef)
|
44
|
+
explicit Lit(Var var, bool sgn = false) : x((var+var) + (int)sgn) {}
|
45
|
+
friend Lit operator ~ (Lit p);
|
46
|
+
|
47
|
+
friend bool sign (Lit p);
|
48
|
+
friend int var (Lit p);
|
49
|
+
friend int index (Lit p);
|
50
|
+
friend Lit toLit (int i);
|
51
|
+
friend Lit unsign(Lit p);
|
52
|
+
friend Lit id (Lit p, bool sgn);
|
53
|
+
|
54
|
+
friend bool operator == (Lit p, Lit q);
|
55
|
+
friend bool operator < (Lit p, Lit q);
|
56
|
+
|
57
|
+
uint hash() const { return (uint)x; }
|
58
|
+
};
|
59
|
+
inline Lit operator ~ (Lit p) { Lit q; q.x = p.x ^ 1; return q; }
|
60
|
+
inline bool sign (Lit p) { return p.x & 1; }
|
61
|
+
inline int var (Lit p) { return p.x >> 1; }
|
62
|
+
inline int index (Lit p) { return p.x; } // A "toInt" method that guarantees small, positive integers suitable for array indexing.
|
63
|
+
inline Lit toLit (int i) { Lit p; p.x = i; return p; } // Inverse of 'index()'.
|
64
|
+
inline Lit unsign(Lit p) { Lit q; q.x = p.x & ~1; return q; }
|
65
|
+
inline Lit id (Lit p, bool sgn) { Lit q; q.x = p.x ^ (int)sgn; return q; }
|
66
|
+
inline bool operator == (Lit p, Lit q) { return index(p) == index(q); }
|
67
|
+
inline bool operator < (Lit p, Lit q) { return index(p) < index(q); } // '<' guarantees that p, ~p are adjacent in the ordering.
|
68
|
+
|
69
|
+
const Lit lit_Undef(var_Undef, false); // }- Useful special constants.
|
70
|
+
const Lit lit_Error(var_Undef, true ); // }
|
71
|
+
|
72
|
+
inline int toDimacs(Lit p) { return sign(p) ? -var(p) - 1 : var(p) + 1; }
|
73
|
+
|
74
|
+
|
75
|
+
//=================================================================================================
|
76
|
+
// Clause -- a simple class for representing a clause:
|
77
|
+
|
78
|
+
|
79
|
+
class Clause {
|
80
|
+
uint size_learnt;
|
81
|
+
Lit data[1];
|
82
|
+
public:
|
83
|
+
// NOTE: This constructor cannot be used directly (doesn't allocate enough memory).
|
84
|
+
Clause(bool learnt, const vec<Lit>& ps) {
|
85
|
+
size_learnt = (ps.size() << 1) | (int)learnt;
|
86
|
+
for (int i = 0; i < ps.size(); i++) data[i] = ps[i];
|
87
|
+
if (learnt) activity() = 0; }
|
88
|
+
|
89
|
+
// -- use this function instead:
|
90
|
+
friend Clause* Clause_new(bool learnt, const vec<Lit>& ps);
|
91
|
+
|
92
|
+
int size () const { return size_learnt >> 1; }
|
93
|
+
bool learnt () const { return size_learnt & 1; }
|
94
|
+
Lit operator [] (int i) const { return data[i]; }
|
95
|
+
Lit& operator [] (int i) { return data[i]; }
|
96
|
+
float& activity () const { return *((float*)&data[size()]); }
|
97
|
+
};
|
98
|
+
inline Clause* Clause_new(bool learnt, const vec<Lit>& ps) {
|
99
|
+
assert(sizeof(Lit) == sizeof(uint));
|
100
|
+
assert(sizeof(float) == sizeof(uint));
|
101
|
+
void* mem = xmalloc<char>(sizeof(Clause) - sizeof(Lit) + sizeof(uint)*(ps.size() + (int)learnt));
|
102
|
+
return new (mem) Clause(learnt, ps); }
|
103
|
+
|
104
|
+
|
105
|
+
//=================================================================================================
|
106
|
+
// GClause -- Generalize clause:
|
107
|
+
|
108
|
+
|
109
|
+
// Either a pointer to a clause or a literal.
|
110
|
+
class GClause {
|
111
|
+
void* data;
|
112
|
+
GClause(void* d) : data(d) {}
|
113
|
+
public:
|
114
|
+
friend GClause GClause_new(Lit p);
|
115
|
+
friend GClause GClause_new(Clause* c);
|
116
|
+
|
117
|
+
bool isLit () const { return ((uintp)data & 1) == 1; }
|
118
|
+
Lit lit () const { return toLit(((intp)data) >> 1); }
|
119
|
+
Clause* clause () const { return (Clause*)data; }
|
120
|
+
bool operator == (GClause c) const { return data == c.data; }
|
121
|
+
bool operator != (GClause c) const { return data != c.data; }
|
122
|
+
};
|
123
|
+
inline GClause GClause_new(Lit p) { return GClause((void*)(((intp)index(p) << 1) + 1)); }
|
124
|
+
inline GClause GClause_new(Clause* c) { assert(((uintp)c & 1) == 0); return GClause((void*)c); }
|
125
|
+
|
126
|
+
#define GClause_NULL GClause_new((Clause*)NULL)
|
127
|
+
|
128
|
+
|
129
|
+
//=================================================================================================
|
130
|
+
#endif
|
@@ -0,0 +1,131 @@
|
|
1
|
+
/******************************************************************************************[Sort.h]
|
2
|
+
MiniSat -- Copyright (c) 2003-2005, Niklas Een, Niklas Sorensson
|
3
|
+
|
4
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
5
|
+
associated documentation files (the "Software"), to deal in the Software without restriction,
|
6
|
+
including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
7
|
+
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in all copies or
|
11
|
+
substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
14
|
+
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
15
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
16
|
+
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
17
|
+
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
18
|
+
**************************************************************************************************/
|
19
|
+
|
20
|
+
#ifndef Sort_h
|
21
|
+
#define Sort_h
|
22
|
+
|
23
|
+
|
24
|
+
//=================================================================================================
|
25
|
+
|
26
|
+
|
27
|
+
template<class T>
|
28
|
+
struct LessThan_default {
|
29
|
+
bool operator () (T x, T y) { return x < y; }
|
30
|
+
};
|
31
|
+
|
32
|
+
|
33
|
+
//=================================================================================================
|
34
|
+
|
35
|
+
|
36
|
+
template <class T, class LessThan>
|
37
|
+
void selectionSort(T* array, int size, LessThan lt)
|
38
|
+
{
|
39
|
+
int i, j, best_i;
|
40
|
+
T tmp;
|
41
|
+
|
42
|
+
for (i = 0; i < size-1; i++){
|
43
|
+
best_i = i;
|
44
|
+
for (j = i+1; j < size; j++){
|
45
|
+
if (lt(array[j], array[best_i]))
|
46
|
+
best_i = j;
|
47
|
+
}
|
48
|
+
tmp = array[i]; array[i] = array[best_i]; array[best_i] = tmp;
|
49
|
+
}
|
50
|
+
}
|
51
|
+
template <class T> static inline void selectionSort(T* array, int size) {
|
52
|
+
selectionSort(array, size, LessThan_default<T>()); }
|
53
|
+
|
54
|
+
|
55
|
+
template <class T, class LessThan>
|
56
|
+
void sort(T* array, int size, LessThan lt, double& seed)
|
57
|
+
{
|
58
|
+
if (size <= 15)
|
59
|
+
selectionSort(array, size, lt);
|
60
|
+
|
61
|
+
else{
|
62
|
+
T pivot = array[irand(seed, size)];
|
63
|
+
T tmp;
|
64
|
+
int i = -1;
|
65
|
+
int j = size;
|
66
|
+
|
67
|
+
for(;;){
|
68
|
+
do i++; while(lt(array[i], pivot));
|
69
|
+
do j--; while(lt(pivot, array[j]));
|
70
|
+
|
71
|
+
if (i >= j) break;
|
72
|
+
|
73
|
+
tmp = array[i]; array[i] = array[j]; array[j] = tmp;
|
74
|
+
}
|
75
|
+
|
76
|
+
sort(array , i , lt, seed);
|
77
|
+
sort(&array[i], size-i, lt, seed);
|
78
|
+
}
|
79
|
+
}
|
80
|
+
template <class T, class LessThan> void sort(T* array, int size, LessThan lt) {
|
81
|
+
double seed = 91648253; sort(array, size, lt, seed); }
|
82
|
+
template <class T> static inline void sort(T* array, int size) {
|
83
|
+
sort(array, size, LessThan_default<T>()); }
|
84
|
+
|
85
|
+
|
86
|
+
template <class T, class LessThan>
|
87
|
+
void sortUnique(T* array, int& size, LessThan lt)
|
88
|
+
{
|
89
|
+
int i, j;
|
90
|
+
T last;
|
91
|
+
|
92
|
+
if (size == 0) return;
|
93
|
+
|
94
|
+
sort(array, size, lt);
|
95
|
+
|
96
|
+
i = 1;
|
97
|
+
last = array[0];
|
98
|
+
for (j = 1; j < size; j++){
|
99
|
+
if (lt(last, array[j])){
|
100
|
+
last = array[i] = array[j];
|
101
|
+
i++; }
|
102
|
+
}
|
103
|
+
|
104
|
+
size = i;
|
105
|
+
}
|
106
|
+
template <class T> static inline void sortUnique(T* array, int& size) {
|
107
|
+
sortUnique(array, size, LessThan_default<T>()); }
|
108
|
+
|
109
|
+
|
110
|
+
//=================================================================================================
|
111
|
+
// For 'vec's:
|
112
|
+
|
113
|
+
|
114
|
+
template <class T, class LessThan> void sort(vec<T>& v, LessThan lt) {
|
115
|
+
sort((T*)v, v.size(), lt); }
|
116
|
+
template <class T> void sort(vec<T>& v) {
|
117
|
+
sort(v, LessThan_default<T>()); }
|
118
|
+
|
119
|
+
|
120
|
+
template <class T, class LessThan> void sortUnique(vec<T>& v, LessThan lt) {
|
121
|
+
int size = v.size();
|
122
|
+
T* data = v.release();
|
123
|
+
sortUnique(data, size, lt);
|
124
|
+
v.~vec<T>();
|
125
|
+
new (&v) vec<T>(data, size); }
|
126
|
+
template <class T> void sortUnique(vec<T>& v) {
|
127
|
+
sortUnique(v, LessThan_default<T>()); }
|
128
|
+
|
129
|
+
|
130
|
+
//=================================================================================================
|
131
|
+
#endif
|