From 9c683cb2c990bd33fe9fccacac36e4d90166e3d4 Mon Sep 17 00:00:00 2001 From: Manuel Bucher <manuel.bucher@hu-berlin.de> Date: Fri, 22 Jun 2018 14:17:03 +0200 Subject: [PATCH] fixed neighbor funcion --- loesung2.c | 73 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 41 insertions(+), 32 deletions(-) diff --git a/loesung2.c b/loesung2.c index a7ddbe3..f3049ac 100755 --- a/loesung2.c +++ b/loesung2.c @@ -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; -- GitLab