DfsSolver.hpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006 #ifndef DFSSOLVER_H
00007 #define DFSSOLVER_H
00008
00009 #include <boost/scoped_ptr.hpp>
00010
00011 #include "Hex.hpp"
00012 #include "HexBoard.hpp"
00013 #include "VC.hpp"
00014 #include "TransTable.hpp"
00015 #include "DfsData.hpp"
00016 #include "SolverDB.hpp"
00017 #include "StateDB.hpp"
00018 #include "HexEval.hpp"
00019
00020 _BEGIN_BENZENE_NAMESPACE_
00021
00022
00023
00024
00025 typedef TransTable<DfsData> DfsHashTable;
00026
00027
00028 class DfsDB : public StateDB<DfsData>
00029 {
00030 public:
00031 static const std::string DFS_DB_VERSION;
00032
00033 DfsDB(const std::string& filename)
00034 : StateDB<DfsData>(filename, DFS_DB_VERSION)
00035 { }
00036 };
00037
00038
00039 typedef SolverDB<DfsHashTable, DfsDB, DfsData> DfsStates;
00040
00041
00042
00043
00044 struct DfsBranchStatistics
00045 {
00046
00047 unsigned total_states;
00048
00049
00050 unsigned explored_states;
00051
00052
00053 unsigned expanded_states;
00054
00055
00056
00057 unsigned minimal_explored;
00058
00059
00060
00061 unsigned decompositions;
00062
00063
00064 unsigned decompositions_won;
00065
00066
00067
00068
00069 unsigned moves_to_consider;
00070
00071
00072 unsigned winning_expanded;
00073
00074
00075 unsigned branches_to_win;
00076
00077
00078 unsigned pruned;
00079
00080
00081 unsigned shrunk;
00082
00083
00084
00085 unsigned cells_removed;
00086
00087 DfsBranchStatistics();
00088
00089 void operator+=(const DfsBranchStatistics& o);
00090 };
00091
00092 inline DfsBranchStatistics::DfsBranchStatistics()
00093 : total_states(0),
00094 explored_states(0),
00095 expanded_states(0),
00096 minimal_explored(0),
00097 decompositions(0),
00098 decompositions_won(0),
00099 moves_to_consider(0),
00100 winning_expanded(0),
00101 branches_to_win(0),
00102 pruned(0),
00103 shrunk(0),
00104 cells_removed(0)
00105 {
00106 }
00107
00108 inline void DfsBranchStatistics::operator+=(const DfsBranchStatistics& o)
00109 {
00110 total_states += o.total_states;
00111 explored_states += o.explored_states;
00112 expanded_states += o.expanded_states;
00113 minimal_explored += o.minimal_explored;
00114 decompositions += o.decompositions;
00115 decompositions_won += o.decompositions_won;
00116 moves_to_consider += o.moves_to_consider;
00117 winning_expanded += o.winning_expanded;
00118 branches_to_win += o.branches_to_win;
00119 pruned += o.pruned;
00120 shrunk += o.shrunk;
00121 cells_removed += o.cells_removed;
00122 }
00123
00124
00125
00126
00127 struct DfsHistogram
00128 {
00129
00130 typedef std::map<int, std::size_t> StatsMap;
00131
00132
00133 StatsMap terminal;
00134
00135
00136 StatsMap states;
00137
00138
00139 StatsMap winning;
00140
00141 StatsMap size_of_winning_states;
00142
00143 StatsMap size_of_losing_states;
00144
00145
00146 StatsMap branches;
00147
00148
00149 StatsMap mustplay;
00150
00151
00152 StatsMap states_under_losing;
00153
00154
00155 StatsMap tthits;
00156
00157
00158 std::string Write();
00159 };
00160
00161
00162
00163
00164 struct DfsSolutionSet
00165 {
00166 bitset_t proof;
00167
00168 int m_numMoves;
00169
00170 PointSequence pv;
00171
00172 DfsBranchStatistics stats;
00173
00174 DfsSolutionSet();
00175
00176 void SetPV(HexPoint cell);
00177
00178 void SetPV(HexPoint cell, const PointSequence& pv);
00179 };
00180
00181 inline DfsSolutionSet::DfsSolutionSet()
00182 : m_numMoves(0)
00183 {
00184 }
00185
00186 inline void DfsSolutionSet::SetPV(HexPoint cell)
00187 {
00188 pv.clear();
00189 pv.push_back(cell);
00190 }
00191
00192 inline void DfsSolutionSet::SetPV(HexPoint cell, const PointSequence& old)
00193 {
00194 pv.clear();
00195 pv.push_back(cell);
00196 pv.insert(pv.end(), old.begin(), old.end());
00197 }
00198
00199
00200
00201 namespace DfsMoveOrderFlags
00202 {
00203
00204
00205
00206
00207
00208
00209 static const int WITH_MUSTPLAY = 1;
00210
00211
00212
00213 static const int WITH_RESIST = 2;
00214
00215
00216
00217 static const int FROM_CENTER = 4;
00218 }
00219
00220
00221
00222
00223
00224
00225
00226 class DfsSolver
00227 {
00228 public:
00229 DfsSolver();
00230
00231 ~DfsSolver();
00232
00233
00234
00235
00236
00237
00238
00239 HexColor Solve(const HexState& state, HexBoard& board,
00240 DfsSolutionSet& solution,
00241 DfsStates& positions, int depthLimit = -1,
00242 double timeLimit = -1.0);
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252 bool UseDecompositions() const;
00253
00254
00255 void SetUseDecompositions(bool enable);
00256
00257
00258 int ProgressDepth() const;
00259
00260
00261 void SetProgressDepth(int depth);
00262
00263
00264 int UpdateDepth() const;
00265
00266
00267 void SetUpdateDepth(int depth);
00268
00269
00270 bool ShrinkProofs() const;
00271
00272
00273 void SetShrinkProofs(bool enable);
00274
00275
00276
00277 bool BackupIceInfo() const;
00278
00279
00280 void SetBackupIceInfo(bool enable);
00281
00282 bool UseGuiFx() const;
00283
00284
00285 void SetUseGuiFx(bool enable);
00286
00287
00288 int MoveOrdering() const;
00289
00290
00291 void SetMoveOrdering(int flags);
00292
00293
00294
00295
00296
00297
00298
00299 void DumpStats(const DfsSolutionSet& solution) const;
00300
00301
00302 DfsHistogram Histogram() const;
00303
00304 private:
00305
00306
00307
00308
00309 struct GlobalStatistics
00310 {
00311
00312 unsigned played;
00313
00314 GlobalStatistics()
00315 : played(0)
00316 { }
00317 };
00318
00319
00320
00321 DfsStates* m_positions;
00322
00323 HexBoard* m_workBrd;
00324
00325 double m_start_time;
00326
00327 double m_end_time;
00328
00329 std::vector<std::pair<int, int> > m_completed;
00330
00331 bool m_aborted;
00332
00333 mutable DfsHistogram m_histogram;
00334
00335 mutable GlobalStatistics m_statistics;
00336
00337 boost::scoped_ptr<HexState> m_state;
00338
00339
00340 bool m_use_decompositions;
00341
00342
00343 int m_update_depth;
00344
00345
00346 bool m_shrink_proofs;
00347
00348
00349 bool m_backup_ice_info;
00350
00351
00352 bool m_use_guifx;
00353
00354
00355 int m_move_ordering;
00356
00357 unsigned m_last_histogram_dump;
00358
00359 int m_depthLimit;
00360
00361 double m_timeLimit;
00362
00363
00364
00365 void PlayMove(HexPoint cell);
00366
00367 void UndoMove(HexPoint cell);
00368
00369 bool CheckTransposition(DfsData& state) const;
00370
00371 void StoreState(const DfsData& state, const bitset_t& proof);
00372
00373 bool CheckAbort();
00374
00375 bool HandleLeafNode(DfsData& state, bitset_t& proof) const;
00376
00377 bool HandleTerminalNode(DfsData& state, bitset_t& proof) const;
00378
00379 bool OrderMoves(bitset_t& mustplay, DfsSolutionSet& solution,
00380 std::vector<HexMoveValue>& moves);
00381
00382 bool SolveState(PointSequence& variation, DfsSolutionSet& solution);
00383
00384 bool SolveDecomposition(PointSequence& variation,
00385 DfsSolutionSet& solution, HexPoint group);
00386
00387 bool SolveInteriorState(PointSequence& variation,
00388 DfsSolutionSet& solution);
00389
00390 void HandleProof(const PointSequence& variation,
00391 bool winning_state, DfsSolutionSet& solution);
00392 };
00393
00394
00395
00396 inline bool DfsSolver::UseDecompositions() const
00397 {
00398 return m_use_decompositions;
00399 }
00400
00401 inline void DfsSolver::SetUseDecompositions(bool enable)
00402 {
00403 m_use_decompositions = enable;
00404 }
00405
00406 inline int DfsSolver::UpdateDepth() const
00407 {
00408 return m_update_depth;
00409 }
00410
00411 inline void DfsSolver::SetUpdateDepth(int depth)
00412 {
00413 m_update_depth = depth;
00414 }
00415
00416 inline bool DfsSolver::ShrinkProofs() const
00417 {
00418 return m_shrink_proofs;
00419 }
00420
00421 inline void DfsSolver::SetShrinkProofs(bool enable)
00422 {
00423 m_shrink_proofs = enable;
00424 }
00425
00426 inline bool DfsSolver::BackupIceInfo() const
00427 {
00428 return m_backup_ice_info;
00429 }
00430
00431 inline void DfsSolver::SetBackupIceInfo(bool enable)
00432 {
00433 m_backup_ice_info = enable;
00434 }
00435
00436 inline bool DfsSolver::UseGuiFx() const
00437 {
00438 return m_use_guifx;
00439 }
00440
00441 inline void DfsSolver::SetUseGuiFx(bool enable)
00442 {
00443 m_use_guifx = enable;
00444 }
00445
00446 inline int DfsSolver::MoveOrdering() const
00447 {
00448 return m_move_ordering;
00449 }
00450
00451 inline void DfsSolver::SetMoveOrdering(int flags)
00452 {
00453 m_move_ordering = flags;
00454 }
00455
00456 inline DfsHistogram DfsSolver::Histogram() const
00457 {
00458 return m_histogram;
00459 }
00460
00461
00462
00463
00464 namespace DfsSolverUtil
00465 {
00466
00467 int DistanceFromCenter(const ConstBoard& brd, HexPoint p);
00468 }
00469
00470
00471
00472 _END_BENZENE_NAMESPACE_
00473
00474 #endif // DFSSOLVER_H