Better table algorithm for visited table implementing a very simple hashset
This commit is contained in:
parent
c0a0639105
commit
f1a0bd9614
1 changed files with 69 additions and 10 deletions
|
@ -255,20 +255,79 @@ unsigned int decreasing_path_len(const struct chessboard* c,
|
||||||
return hops - 1;
|
return hops - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void visit(bool* visited, unsigned columns, unsigned column, unsigned row) {
|
struct row_list {
|
||||||
visited[column * columns + row] = true;
|
unsigned row;
|
||||||
|
unsigned column;
|
||||||
|
struct row_list* next;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct row_list* visit_table;
|
||||||
|
unsigned long alloc = 0;
|
||||||
|
|
||||||
|
unsigned long table_total_size(const struct chessboard*);
|
||||||
|
unsigned long table_hash(const struct chessboard*, unsigned, unsigned);
|
||||||
|
|
||||||
|
inline unsigned long table_total_size(const struct chessboard* c) {
|
||||||
|
return 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool visited(bool* visited, unsigned columns, unsigned column, unsigned row) {
|
inline unsigned long table_hash(const struct chessboard* c, unsigned col,
|
||||||
return visited[column * columns + row];
|
unsigned row) {
|
||||||
|
return (value_at(c, col, row) ^ 0xDEADBEEF) % table_total_size(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
visit_table* table_new(const struct chessboard* c) {
|
||||||
|
unsigned long table_size = table_total_size(c);
|
||||||
|
alloc += sizeof(struct row_list*) * table_size;
|
||||||
|
return calloc(table_size, sizeof(struct row_list*));
|
||||||
|
}
|
||||||
|
|
||||||
|
void table_visit(const struct chessboard* c, visit_table* visited,
|
||||||
|
unsigned column, unsigned row) {
|
||||||
|
|
||||||
|
unsigned long hash = table_hash(c, column, row);
|
||||||
|
struct row_list* prev = hash[visited];
|
||||||
|
alloc += sizeof(struct row_list);
|
||||||
|
hash[visited] = malloc(sizeof(struct row_list));
|
||||||
|
assert(hash[visited] != NULL);
|
||||||
|
hash[visited]->row = row;
|
||||||
|
hash[visited]->column = column;
|
||||||
|
hash[visited]->next = prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool table_visited(const struct chessboard* c, visit_table* visited,
|
||||||
|
unsigned column, unsigned row) {
|
||||||
|
|
||||||
|
unsigned long hash = table_hash(c, column, row);
|
||||||
|
for (struct row_list* i = hash[visited]; i != NULL; i = i->next) {
|
||||||
|
if (i->row == row && i->column == column) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void table_destroy(const struct chessboard* c, visit_table* visited) {
|
||||||
|
|
||||||
|
unsigned long table_size = table_total_size(c);
|
||||||
|
for (unsigned e = 0; e < table_size; e++) {
|
||||||
|
for (struct row_list* i = e[visited], *j; i != NULL;) {
|
||||||
|
j = i->next;
|
||||||
|
free(i);
|
||||||
|
i = j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("alloc = %lu\n", alloc);
|
||||||
|
alloc = 0;
|
||||||
|
|
||||||
|
free(visited);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int simple_path_len(const struct chessboard* c,
|
unsigned int simple_path_len(const struct chessboard* c,
|
||||||
struct piece_position* p) {
|
struct piece_position* p) {
|
||||||
|
|
||||||
const unsigned int CC = columns(c);
|
visit_table* v = table_new(c);
|
||||||
bool* v = calloc(rows(c) * CC, sizeof(unsigned));
|
table_visit(c, v, p->column, p->row);
|
||||||
visit(v, CC, p->column, p->row);
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
print_visited(c, v);
|
print_visited(c, v);
|
||||||
#endif
|
#endif
|
||||||
|
@ -287,7 +346,7 @@ unsigned int simple_path_len(const struct chessboard* c,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
while(poss != NULL) {
|
while(poss != NULL) {
|
||||||
if (!visited(v, CC, poss->column, poss->row)) {
|
if (!table_visited(c, v, poss->column, poss->row)) {
|
||||||
next_v = value_at(c, poss->column, poss->row);
|
next_v = value_at(c, poss->column, poss->row);
|
||||||
if (!has_next || next_v > base_v) {
|
if (!has_next || next_v > base_v) {
|
||||||
has_next = true;
|
has_next = true;
|
||||||
|
@ -301,14 +360,14 @@ unsigned int simple_path_len(const struct chessboard* c,
|
||||||
free(del);
|
free(del);
|
||||||
}
|
}
|
||||||
|
|
||||||
visit(v, CC, p->column, p->row);
|
table_visit(c, v, p->column, p->row);
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
print_visited(c, v);
|
print_visited(c, v);
|
||||||
#endif
|
#endif
|
||||||
hops++;
|
hops++;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(v);
|
table_destroy(c, v);
|
||||||
return hops - 1;
|
return hops - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Reference in a new issue