Skip to content
Snippets Groups Projects
Commit 9c683cb2 authored by Manuel Bucher's avatar Manuel Bucher
Browse files

fixed neighbor funcion

parent 15bc156b
Branches
No related merge requests found
......@@ -7,10 +7,6 @@
#define INF UINT32_MAX
/** Min-Max funktionen fuer uint32_t */
inline uint32_t min(uint32_t a, uint32_t b) { return a < b ? a : b; }
inline uint32_t max(uint32_t a, uint32_t b) { return a > b ? a : b; }
/********** Kachel definition **********/
typedef struct Tile {
uint32_t x;
......@@ -18,7 +14,7 @@ typedef struct Tile {
uint32_t neigh[4]; // Nachbarn
struct Tile *p_next; // queue
uint32_t pair; // matching partner
uint32_t dist;
uint32_t dist; // entfernung zu Knoten 0 im Schichtgraph
} Tile;
// initialisieren des Speichers von einem Tile
......@@ -30,12 +26,12 @@ void tile_init(Tile *this) {
int tile_compare(const void *p, const void *q) {
const Tile *s = (const Tile*) p;
const Tile *t = (const Tile*) q;
// als erstes nach y sortieren
if (s->y < t->y) return -1;
if (s->y > t->y) return 1;
// danach nach x sortieren
// als erstes nach x sortieren
if (s->x < t->x) return -1;
if (s->x > t->x) return 1;
// danach nach y sortieren
if (s->y < t->y) return -1;
if (s->y > t->y) return 1;
return 0; // Elemente sind gleich
}
......@@ -52,7 +48,6 @@ typedef struct Field {
uint32_t num_tiles;
uint32_t size;
uint32_t num_odd;
// TODO: Rechteck erkennen?
} Field;
// returns 0 if successful, nonzero if failed
......@@ -68,7 +63,7 @@ int field_init(Field *this) {
int field_push(Field *this, Tile *p_tile) {
if (this->size == this->num_tiles) {
if (this->size == 1u<<31) return 1; // catch overflow
this->size *= 2;
this->size *= 2; // Armortisiert O(1)
Tile *new = realloc(this->tiles, this->size*sizeof(Tile));
if (new == NULL) return 1; // catch failed realloc
this->tiles = new;
......@@ -184,24 +179,24 @@ int field_neighbours(Field *this) {
Tile *t = this->tiles;
for (uint32_t cur = 2; cur < this->num_tiles; cur++) {
// ermitteln der ost/west-Beziehung
if (t[cur].y == t[cur-1].y) {
if (t[cur].x == t[cur-1].x) {
uint32_t east = cur-1;
if (t[cur].x == t[east].x) {
if (t[cur].y == t[east].y) {
return 1; // Doppelung
}
if (t[cur].x == t[cur-1].x - 1) {
t[cur].neigh[1] = cur-1;
t[cur-1].neigh[3] = cur;
} else if (t[cur].y-1 == t[east].y) {
t[cur].neigh[1] = east;
t[east].neigh[3] = cur;
}
} else {
begin_line = cur; // neue Zeile
}
// ermitteln der nord/sued-Beziehung
if (t[top].y < t[cur].y - 1) {
if (t[top].x < t[cur].x - 1) {
top = begin_line; // Luecke zwischen zeilen
} else if (t[top].y == t[cur].y - 1) {
// finden, ob paar existiert, zurzeit O(n).
} else if (t[top].x == t[cur].x - 1) {
// finden, ob paar nach oben existiert O(n) fuer alle Nachbarn nach oben/unten.
for(;t[top].y < t[cur].y && top < begin_line; top++);
if (t[top].x == t[cur].x) {
if (t[top].y == t[cur].y) {
t[top].neigh[2] = cur;
t[cur].neigh[0] = top;
}
......@@ -210,6 +205,14 @@ int field_neighbours(Field *this) {
return 0;
}
void field_print(Field *this) {
printf("[\n");
for (uint32_t i = 1; i < this->num_tiles; i++){
printf("\t(%u %u)\n", this->tiles[i].x, this->tiles[i].y);
}
printf("]\n");
}
/********** Schlange von Tiles **********/
typedef struct Queue {
Tile *p_first;
......@@ -246,7 +249,7 @@ Tile *queue_pop(Queue* this) {
/********** Algorithmus von Hopcroft und Karp **********/
bool hk_bfs(Field *this) {
Queue q; // Schlange von Knoten
Queue q; // Schlange von Kacheln
queue_init(&q);
Tile *t = this->tiles;
for (int i = 1; i < this->num_tiles; i++) {
......@@ -285,12 +288,11 @@ bool hk_dfs(Field *this, uint32_t e) {
Tile *p_even = &t[e];
for (int i = 0; i < 4; i++) {
// Benachbart zu e
uint32_t o = p_even->neigh[i]; // Nachbar, ungerades Tile
uint32_t o = p_even->neigh[i]; // Nachbar, ungerade Kachel
Tile* p_odd = &t[o];
if (t[p_odd->pair].dist == p_even->dist+1) {
// Augmentiere den Pfad, falls durch Tiefensuche gefunden
if (hk_dfs(this, p_odd->pair)) {
printf("%u %u\n", e, o);
p_even->pair = o;
p_odd->pair = e;
return true;
......@@ -303,19 +305,26 @@ bool hk_dfs(Field *this, uint32_t e) {
}
void hk_print(Field *this) {
Tile *t = this->tiles;
for (uint32_t i = 1; i < this->num_tiles; i++) {
printf("%u\n", i);
//printf("%u\n", i);
if (this->tiles[i].pair == 0) {
printf("None\n");
return; // Kein Belegung existiert
return;
}
}
for (uint32_t i = 1; i < this->num_tiles; i++) {
if (tile_odd(&t[i]))
continue;
uint32_t p = t[i].pair;
printf("%u %u;%u %u\n", t[i].x, t[i].y, t[p].x, t[p].y);
}
}
void hk(Field *this) {
uint32_t result = 0;
while(hk_bfs(this)) {
for (int i = 1; i < this->num_tiles; i++) {
for (uint32_t i = 1; i < this->num_tiles; i++) {
if (tile_odd(&this->tiles[i]))
continue;
if (this->tiles[i].pair == 0 && hk_dfs(this, i))
......@@ -346,11 +355,11 @@ int main() {
result = EXIT_SUCCESS;
break;
case ReadEof: result = EXIT_SUCCESS; break;
case ReadErrOverflow: fprintf(stderr, "%d: too big integer\n", f.num_tiles); break;
case ReadErrInvalidChar: fprintf(stderr, "%d: invalid character\n", f.num_tiles); break;
case ReadErrTooFewNumbers: fprintf(stderr, "%d: too few numbers\n", f.num_tiles); break;
case ReadErrTooManyNumbers: fprintf(stderr, "%d: too many numbers\n", f.num_tiles); break;
case ReadErrOutOfMemory: fprintf(stderr, "%d: failed to allocate more memory\n", f.num_tiles); break;
case ReadErrOverflow: fprintf(stderr, "%u: too big integer\n", f.num_tiles); break;
case ReadErrInvalidChar: fprintf(stderr, "%u: invalid character\n", f.num_tiles); break;
case ReadErrTooFewNumbers: fprintf(stderr, "%u: too few numbers\n", f.num_tiles); break;
case ReadErrTooManyNumbers: fprintf(stderr, "%u: too many numbers\n", f.num_tiles); break;
case ReadErrOutOfMemory: fprintf(stderr, "%u: not enough memory\n", f.num_tiles); break;
}
free(f.tiles);
return result;
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment