HOG2
TopSpinGraph.cpp
Go to the documentation of this file.
1 /*
2  * TopSpinGraph.cpp
3  * hog2
4  *
5  * Created by Nathan Sturtevant on 4/1/08.
6  * Copyright 2008 __MyCompanyName__. All rights reserved.
7  *
8  */
9 
10 #include "TopSpinGraph.h"
11 #include <string.h>
12 
14 
16 :GraphEnvironment(new Graph(), tsh)
17 {
18  length = mm;
19  flipSize = k;
20  directed = false;
21 
22  std::vector<int> config(mm);
23  for (unsigned int x = 0; x < config.size(); x++)
24  config[x] = x;
25  GetState(config);
26 }
27 
30 {
31  length = mm;
32  flipSize = k;
33  directed = false;
34 
35  std::vector<int> config(mm);
36  for (unsigned int x = 0; x < config.size(); x++)
37  config[x] = x;
38  GetState(config);
39 }
40 
42 {
43 }
44 
45 void TopSpinGraph::GetSuccessors(const graphState &stateID, std::vector<graphState> &neighbors) const
46 {
47  if (!data[stateID].expanded)
48  {
49  // add neighbors to graph
50  ExpandNode(stateID);
51  }
52  return GraphEnvironment::GetSuccessors(stateID, neighbors);
53 }
54 
55 void TopSpinGraph::GetActions(const graphState &stateID, std::vector<graphMove> &actions) const
56 {
57  if (!data[stateID].expanded)
58  {
59  // add neighbors to graph
60  ExpandNode(stateID);
61  }
62  return GraphEnvironment::GetActions(stateID, actions);
63 }
64 
65 bool TopSpinGraph::GoalTest(const graphState &state, const graphState &goal) const
66 {
67  return (state == goal);
68 }
69 
70 std::vector<int> &TopSpinGraph::GetState(graphState gs) const
71 {
72  return data[gs].config;
73 }
74 
75 graphState TopSpinGraph::GetState(const std::vector<int> &configuration) const
76 {
77  int zeroLoc = -1;
78  for (unsigned int x = 0; x < configuration.size(); x++)
79  {
80  if (configuration[x] == 0)
81  {
82  zeroLoc = x;
83  break;
84  }
85  }
86  return GetState(configuration, zeroLoc);
87 }
88 
89 graphState TopSpinGraph::GetState(const std::vector<int> &configuration, int zeroLoc) const
90 {
91  static std::vector<int> config(configuration.size());
92  config.resize(configuration.size());
93 
94  assert(zeroLoc != -1);
95  for (unsigned int x = 0; x < config.size(); x++)
96  config[x] = configuration[(zeroLoc+x)%configuration.size()];
97 
98  uint64_t hash = GetStateHash(config);
99  if (hashTable.find(hash) != hashTable.end())
100  return hashTable[hash];
101  node *n;
102  g2 = g;
103  g2->AddNode(n = new node(""));
104  data.resize(n->GetNum()+1);
105  data[n->GetNum()].config = config;
106  data[n->GetNum()].hashKey = hash;
107  data[n->GetNum()].expanded = false;
108  hashTable[hash] = n->GetNum();
109  //printf("Added item %lld; hash table size is now %d\n", hash, hashTable.size());
110  return n->GetNum();
111 }
112 
113 void TopSpinGraph::ExpandNode(const graphState &stateID) const
114 {
115  g2 = g;
116  //printf("Expanding %lu\n", stateID);
117  for (int x = 0; x < length; x++)
118  {
119  Flip(data[stateID].config, x, flipSize);
120  // will create the state if it doesn't exist already!
121  graphState s = GetState(data[stateID].config);
122  Flip(data[stateID].config, x, flipSize);
123  if (!g->FindEdge(s, stateID))
124  g2->AddEdge(new edge(s, stateID, 1));
125  }
126  data[stateID].expanded = true;
127 }
128 
129 void TopSpinGraph::Flip(std::vector<int> &arrangement, int index, int radius) const
130 {
131  while (radius > 1)
132  {
133  int tmp = arrangement[index];
134  int otherSide = (index+radius-1)%arrangement.size();
135  arrangement[index] = arrangement[otherSide];
136  arrangement[otherSide] = tmp;
137  radius-=2;
138  index = (index+1)%arrangement.size();
139  }
140 }
141 
142 uint64_t TopSpinGraph::GetStateHash(const graphState &state) const
143 {
144 // if (!data[state].expanded)
145 // ExpandNode(state);
146  return data[state].hashKey;
147 }
148 
150 {
151  if ( s == 0) return 0;
152 
153  std::vector<int> cfg = data[s].config;
154  std::vector<int> dualCfg = cfg;
155  for (unsigned int x=0;x<cfg.size();x++) {
156  dualCfg[cfg[x]] = x;
157  }
158 
159  return GetState(dualCfg); // it seems that we can't avoid storing the dual (for now) !
160 }
161 
162 uint64_t TopSpinGraph::GetStateHash(const std::vector<int> &config) const
163 {
164  return GetStateHash(&config[0], config.size());
165 }
166 
167 uint64_t TopSpinGraph::GetStateHash(const int *config, int config_size) const
168 {
169  // need to handle rotation!
170 
171 // static pdb_rank_t pdb_index( const int8_t *pdbpos, const int num_tiles,
172 // const int pdb_size )
173 // {
174  uint64_t rank;
175  int i, end;
176  int MAX_TILES = config_size;
177  int num_tiles = config_size;
178  int8_t tiles[ MAX_TILES ], loc[ MAX_TILES ];
179 
180  //memset( loc, pdb_size, num_tiles );
181  i = 0;
182  do {
183  loc[ tiles[ i ] = config[ i ] ] = i;
184  } while( ++i != num_tiles );
185 
186  rank = tiles[ i = 0 ];
187  end = num_tiles - 1;
188  while( i != num_tiles - 1 )
189  {
190  tiles[ loc[ end ] ] = tiles[ i ];
191  loc[ tiles[ i ] ] = loc[ end ];
192  i++; end--;
193 
194  rank = rank * ( num_tiles - i ) + tiles[ i ];
195  }
196 
197  return rank;
198 // }
199 }
200 
201 uint64_t TopSpinGraph::GetPDBHash(const graphState &state, int pdb_size) const
202 {
203  return GetPDBHash(GetState(state), pdb_size);
204 }
205 
206 uint64_t TopSpinGraph::GetPDBHash(const std::vector<int> &config, int pdb_size) const
207 {
208  std::vector<int> pdb_pos(config.size());
209  for (unsigned int x = 0; x < config.size(); x++)
210  pdb_pos[config[x]] = x;
211 
212  int MAX_TILES = config.size();
213  uint64_t rank;
214  int num_tiles = config.size();
215  int i, end;
216  int8_t tiles[ MAX_TILES ], loc[ MAX_TILES ];
217 
218  memset( loc, pdb_size, num_tiles );
219  i = 0;
220  do {
221  //loc[ tiles[ i ] = config[ i ] ] = i;
222  loc[ tiles[ i ] = pdb_pos[ i ] ] = i;
223  } while( ++i != pdb_size );
224 
225  rank = tiles[ i = 0 ];
226  end = num_tiles - 1;
227  while( i != pdb_size - 1 ) {
228  tiles[ loc[ end ] ] = tiles[ i ];
229  loc[ tiles[ i ] ] = loc[ end ];
230  i++; end--;
231 
232  rank = rank * ( num_tiles - i ) + tiles[ i ];
233  }
234 
235  return rank;
236 }
237 
238 uint64_t TopSpinGraph::GetPDBSize(int puzzleSize, int pdb_size) const
239 {
240  pdb_size--;
241  uint64_t size;
242  int i;
243 
244  size = 1;
245  for ( i = puzzleSize - pdb_size; i < puzzleSize; i++ ) {
246  size *= i;
247  }
248  return size;
249 }
250 
252 :ts(0), pdb(-1)
253 {
254 }
255 
256 TopSpinGraphHeuristic::TopSpinGraphHeuristic(int psize, int spin, int pdbStates)
257 :ts(0), pdb(pdbStates)
258 {
259  char filename[256];
260  sprintf(filename, "TS_%d_%d_%d.db", psize, spin, pdb);
261  FILE *f = fopen(filename, "r");
262  if (!f)
263  {
264  printf("Can't load PDB!\n");
265  exit(0);
266  }
267 
268  DB.resize(ts->GetPDBSize(psize, pdb));
269  fread(&(DB[0]), sizeof(uint8_t), ts->GetPDBSize(psize, pdb), f);
270  fclose(f);
271 }
272 
273 
274 double TopSpinGraphHeuristic::HCost(const graphState &s1, const graphState &s2) const
275 {
276  graphState sd;
277 
278  if (ts == 0)
279  return 0;
280  if ((s1 != 0) && (s2 != 0))
281  {
282  printf("Error -- one state must be canonical goal state\n");
283  exit(0);
284  }
285  if (s1 == 0)
286  {
287  //return DB[ts->GetPDBHash(s2, pdb)];
288  if (THmode == 0)
289  sd = s2;
290  else
291  sd = ts->Dual(s2);
292 
293  //printf("Returning heur value!: %d\n", DB[ts->GetPDBHash(sd, pdb)]);
294  return DB[ts->GetPDBHash(sd, pdb)];
295  }
296  // printf("Returning heur value!: %d\n", DB[ts->GetPDBHash(s1, pdb)]);
297  //return DB[ts->GetPDBHash(s1, pdb)];
298  if (THmode == 0)
299  sd = s1;
300  else
301  sd = ts->Dual(s1);
302  //printf("Returning heur value!: %d\n", DB[ts->GetPDBHash(sd, pdb)]);
303  return DB[ts->GetPDBHash(sd, pdb)];
304 }
305 
306 
307 //void switch_to_dual( const game_t *game, state_t state )
308 //{
309 //#if 1
310 // int i;
311 // int8_t t;
312 //
313 // for ( i = 0; i != game->num_tiles; i++ ) {
314 // t = state[ i ];
315 // state[ i ] = state[ i + game->num_tiles ];
316 // state[ i + game->num_tiles ] = t;
317 // }
318 //#else
TopSpinGraphHeuristic
Definition: TopSpinGraph.h:19
Graph::AddNode
int AddNode(node *)
Definition: Graph.cpp:136
TopSpinGraph::GetStateHash
uint64_t GetStateHash(const graphState &state) const
Definition: TopSpinGraph.cpp:142
TopSpinGraph::hashTable
TopSpinHashTable hashTable
Definition: TopSpinGraph.h:71
Graph::FindEdge
edge * FindEdge(unsigned int from, unsigned int to)
Finds an edge between nodes with ids from and to, no matter which direction.
Definition: Graph.cpp:230
TopSpinGraphHeuristic::HCost
virtual double HCost(const graphState &state1, const graphState &state2) const
Definition: TopSpinGraph.cpp:274
graphState
unsigned long graphState
Definition: GraphEnvironment.h:32
TopSpinGraph::flipSize
int flipSize
Definition: TopSpinGraph.h:73
TopSpinGraphHeuristic::pdb
int pdb
Definition: TopSpinGraph.h:31
TopSpinGraph::GetPDBSize
uint64_t GetPDBSize(int puzzle_size, int pdb_size) const
Definition: TopSpinGraph.cpp:238
TopSpinGraph::Dual
graphState Dual(graphState s)
Definition: TopSpinGraph.cpp:149
Graph::AddEdge
void AddEdge(edge *)
Definition: Graph.cpp:170
GraphEnvironment::GetSuccessors
virtual void GetSuccessors(const graphState &stateID, std::vector< graphState > &neighbors) const
Definition: GraphEnvironment.cpp:75
TopSpinGraphHeuristic::DB
std::vector< uint8_t > DB
Definition: TopSpinGraph.h:32
TopSpinGraph.h
Graph
A generic Graph class.
Definition: Graph.h:66
GraphEnvironment::g
Graph * g
Definition: GraphEnvironment.h:360
TopSpinGraph::length
int length
Definition: TopSpinGraph.h:73
TopSpinGraphHeuristic::ts
TopSpinGraph * ts
Definition: TopSpinGraph.h:30
TopSpinGraph::GetPDBHash
uint64_t GetPDBHash(const std::vector< int > &config, int pdb_size) const
Definition: TopSpinGraph.cpp:206
loc
Definition: MapGenerators.cpp:296
TopSpinGraph::data
std::vector< TopSpinGraphData > data
Definition: TopSpinGraph.h:72
GraphEnvironment::directed
bool directed
Definition: GraphEnvironment.h:358
TopSpinGraph::ExpandNode
void ExpandNode(const graphState &stateID) const
Definition: TopSpinGraph.cpp:113
TopSpinGraphHeuristic::TopSpinGraphHeuristic
TopSpinGraphHeuristic()
Definition: TopSpinGraph.cpp:251
TopSpinGraph::~TopSpinGraph
~TopSpinGraph()
Definition: TopSpinGraph.cpp:41
TopSpinGraph::GetState
graphState GetState(const std::vector< int > &configuration) const
Definition: TopSpinGraph.cpp:75
node::GetNum
unsigned int GetNum() const
Definition: Graph.h:176
TopSpinGraph::TopSpinGraph
TopSpinGraph(int m, int k, TopSpinGraphHeuristic *tsh)
Definition: TopSpinGraph.cpp:15
TopSpinGraph::GoalTest
bool GoalTest(const graphState &state, const graphState &goal) const
Definition: TopSpinGraph.cpp:65
TopSpinGraph::Flip
void Flip(std::vector< int > &arrangement, int index, int radius) const
Definition: TopSpinGraph.cpp:129
GraphEnvironment::GetActions
virtual void GetActions(const graphState &stateID, std::vector< graphMove > &actions) const
Definition: GraphEnvironment.cpp:105
TopSpinGraphHeuristic::THmode
static int THmode
Definition: TopSpinGraph.h:28
TopSpinGraph::g2
Graph * g2
Definition: TopSpinGraph.h:70
GraphEnvironment
Definition: GraphEnvironment.h:291
node
Nodes to be stored within a Graph.
Definition: Graph.h:170
TopSpinGraph::GetSuccessors
void GetSuccessors(const graphState &stateID, std::vector< graphState > &neighbors) const
Definition: TopSpinGraph.cpp:45
TopSpinGraph::GetActions
void GetActions(const graphState &stateID, std::vector< graphMove > &actions) const
Definition: TopSpinGraph.cpp:55
edge
Edge class for connections between node in a Graph.
Definition: Graph.h:129