Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
D
dsprog
Manage
Activity
Members
Labels
Plan
Issues
0
Issue boards
Milestones
Wiki
Requirements
Code
Merge requests
0
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Container Registry
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Manuel Bucher
dsprog
Commits
9c683cb2
Commit
9c683cb2
authored
6 years ago
by
Manuel Bucher
Browse files
Options
Downloads
Patches
Plain Diff
fixed neighbor funcion
parent
15bc156b
Branches
Branches containing commit
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
loesung2.c
+41
-32
41 additions, 32 deletions
loesung2.c
with
41 additions
and
32 deletions
loesung2.c
+
41
−
32
View file @
9c683cb2
...
@@ -7,10 +7,6 @@
...
@@ -7,10 +7,6 @@
#define INF UINT32_MAX
#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 **********/
/********** Kachel definition **********/
typedef
struct
Tile
{
typedef
struct
Tile
{
uint32_t
x
;
uint32_t
x
;
...
@@ -18,7 +14,7 @@ typedef struct Tile {
...
@@ -18,7 +14,7 @@ typedef struct Tile {
uint32_t
neigh
[
4
];
// Nachbarn
uint32_t
neigh
[
4
];
// Nachbarn
struct
Tile
*
p_next
;
// queue
struct
Tile
*
p_next
;
// queue
uint32_t
pair
;
// matching partner
uint32_t
pair
;
// matching partner
uint32_t
dist
;
uint32_t
dist
;
// entfernung zu Knoten 0 im Schichtgraph
}
Tile
;
}
Tile
;
// initialisieren des Speichers von einem Tile
// initialisieren des Speichers von einem Tile
...
@@ -30,12 +26,12 @@ void tile_init(Tile *this) {
...
@@ -30,12 +26,12 @@ void tile_init(Tile *this) {
int
tile_compare
(
const
void
*
p
,
const
void
*
q
)
{
int
tile_compare
(
const
void
*
p
,
const
void
*
q
)
{
const
Tile
*
s
=
(
const
Tile
*
)
p
;
const
Tile
*
s
=
(
const
Tile
*
)
p
;
const
Tile
*
t
=
(
const
Tile
*
)
q
;
const
Tile
*
t
=
(
const
Tile
*
)
q
;
// als erstes nach y sortieren
// als erstes nach x sortieren
if
(
s
->
y
<
t
->
y
)
return
-
1
;
if
(
s
->
y
>
t
->
y
)
return
1
;
// danach nach x sortieren
if
(
s
->
x
<
t
->
x
)
return
-
1
;
if
(
s
->
x
<
t
->
x
)
return
-
1
;
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
return
0
;
// Elemente sind gleich
}
}
...
@@ -52,7 +48,6 @@ typedef struct Field {
...
@@ -52,7 +48,6 @@ typedef struct Field {
uint32_t
num_tiles
;
uint32_t
num_tiles
;
uint32_t
size
;
uint32_t
size
;
uint32_t
num_odd
;
uint32_t
num_odd
;
// TODO: Rechteck erkennen?
}
Field
;
}
Field
;
// returns 0 if successful, nonzero if failed
// returns 0 if successful, nonzero if failed
...
@@ -68,7 +63,7 @@ int field_init(Field *this) {
...
@@ -68,7 +63,7 @@ int field_init(Field *this) {
int
field_push
(
Field
*
this
,
Tile
*
p_tile
)
{
int
field_push
(
Field
*
this
,
Tile
*
p_tile
)
{
if
(
this
->
size
==
this
->
num_tiles
)
{
if
(
this
->
size
==
this
->
num_tiles
)
{
if
(
this
->
size
==
1u
<<
31
)
return
1
;
// catch overflow
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
));
Tile
*
new
=
realloc
(
this
->
tiles
,
this
->
size
*
sizeof
(
Tile
));
if
(
new
==
NULL
)
return
1
;
// catch failed realloc
if
(
new
==
NULL
)
return
1
;
// catch failed realloc
this
->
tiles
=
new
;
this
->
tiles
=
new
;
...
@@ -184,24 +179,24 @@ int field_neighbours(Field *this) {
...
@@ -184,24 +179,24 @@ int field_neighbours(Field *this) {
Tile
*
t
=
this
->
tiles
;
Tile
*
t
=
this
->
tiles
;
for
(
uint32_t
cur
=
2
;
cur
<
this
->
num_tiles
;
cur
++
)
{
for
(
uint32_t
cur
=
2
;
cur
<
this
->
num_tiles
;
cur
++
)
{
// ermitteln der ost/west-Beziehung
// ermitteln der ost/west-Beziehung
if
(
t
[
cur
].
y
==
t
[
cur
-
1
].
y
)
{
uint32_t
east
=
cur
-
1
;
if
(
t
[
cur
].
x
==
t
[
cur
-
1
].
x
)
{
if
(
t
[
cur
].
x
==
t
[
east
].
x
)
{
if
(
t
[
cur
].
y
==
t
[
east
].
y
)
{
return
1
;
// Doppelung
return
1
;
// Doppelung
}
}
else
if
(
t
[
cur
].
y
-
1
==
t
[
east
].
y
)
{
if
(
t
[
cur
].
x
==
t
[
cur
-
1
].
x
-
1
)
{
t
[
cur
].
neigh
[
1
]
=
east
;
t
[
cur
].
neigh
[
1
]
=
cur
-
1
;
t
[
east
].
neigh
[
3
]
=
cur
;
t
[
cur
-
1
].
neigh
[
3
]
=
cur
;
}
}
}
else
{
}
else
{
begin_line
=
cur
;
// neue Zeile
begin_line
=
cur
;
// neue Zeile
}
}
// ermitteln der nord/sued-Beziehung
// 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
top
=
begin_line
;
// Luecke zwischen zeilen
}
else
if
(
t
[
top
].
y
==
t
[
cur
].
y
-
1
)
{
}
else
if
(
t
[
top
].
x
==
t
[
cur
].
x
-
1
)
{
// finden, ob paar
existiert, zurzeit O(n)
.
// 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
++
);
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
[
top
].
neigh
[
2
]
=
cur
;
t
[
cur
].
neigh
[
0
]
=
top
;
t
[
cur
].
neigh
[
0
]
=
top
;
}
}
...
@@ -210,6 +205,14 @@ int field_neighbours(Field *this) {
...
@@ -210,6 +205,14 @@ int field_neighbours(Field *this) {
return
0
;
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 **********/
/********** Schlange von Tiles **********/
typedef
struct
Queue
{
typedef
struct
Queue
{
Tile
*
p_first
;
Tile
*
p_first
;
...
@@ -246,7 +249,7 @@ Tile *queue_pop(Queue* this) {
...
@@ -246,7 +249,7 @@ Tile *queue_pop(Queue* this) {
/********** Algorithmus von Hopcroft und Karp **********/
/********** Algorithmus von Hopcroft und Karp **********/
bool
hk_bfs
(
Field
*
this
)
{
bool
hk_bfs
(
Field
*
this
)
{
Queue
q
;
// Schlange von K
note
n
Queue
q
;
// Schlange von K
achel
n
queue_init
(
&
q
);
queue_init
(
&
q
);
Tile
*
t
=
this
->
tiles
;
Tile
*
t
=
this
->
tiles
;
for
(
int
i
=
1
;
i
<
this
->
num_tiles
;
i
++
)
{
for
(
int
i
=
1
;
i
<
this
->
num_tiles
;
i
++
)
{
...
@@ -285,12 +288,11 @@ bool hk_dfs(Field *this, uint32_t e) {
...
@@ -285,12 +288,11 @@ bool hk_dfs(Field *this, uint32_t e) {
Tile
*
p_even
=
&
t
[
e
];
Tile
*
p_even
=
&
t
[
e
];
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
// Benachbart zu e
// Benachbart zu e
uint32_t
o
=
p_even
->
neigh
[
i
];
// Nachbar, ungerade
s Tile
uint32_t
o
=
p_even
->
neigh
[
i
];
// Nachbar, ungerade
Kachel
Tile
*
p_odd
=
&
t
[
o
];
Tile
*
p_odd
=
&
t
[
o
];
if
(
t
[
p_odd
->
pair
].
dist
==
p_even
->
dist
+
1
)
{
if
(
t
[
p_odd
->
pair
].
dist
==
p_even
->
dist
+
1
)
{
// Augmentiere den Pfad, falls durch Tiefensuche gefunden
// Augmentiere den Pfad, falls durch Tiefensuche gefunden
if
(
hk_dfs
(
this
,
p_odd
->
pair
))
{
if
(
hk_dfs
(
this
,
p_odd
->
pair
))
{
printf
(
"%u %u
\n
"
,
e
,
o
);
p_even
->
pair
=
o
;
p_even
->
pair
=
o
;
p_odd
->
pair
=
e
;
p_odd
->
pair
=
e
;
return
true
;
return
true
;
...
@@ -303,19 +305,26 @@ bool hk_dfs(Field *this, uint32_t e) {
...
@@ -303,19 +305,26 @@ bool hk_dfs(Field *this, uint32_t e) {
}
}
void
hk_print
(
Field
*
this
)
{
void
hk_print
(
Field
*
this
)
{
Tile
*
t
=
this
->
tiles
;
for
(
uint32_t
i
=
1
;
i
<
this
->
num_tiles
;
i
++
)
{
for
(
uint32_t
i
=
1
;
i
<
this
->
num_tiles
;
i
++
)
{
printf
(
"%u
\n
"
,
i
);
//
printf("%u\n", i);
if
(
this
->
tiles
[
i
].
pair
==
0
)
{
if
(
this
->
tiles
[
i
].
pair
==
0
)
{
printf
(
"None
\n
"
);
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
)
{
void
hk
(
Field
*
this
)
{
uint32_t
result
=
0
;
uint32_t
result
=
0
;
while
(
hk_bfs
(
this
))
{
while
(
hk_bfs
(
this
))
{
for
(
int
i
=
1
;
i
<
this
->
num_tiles
;
i
++
)
{
for
(
u
int
32_t
i
=
1
;
i
<
this
->
num_tiles
;
i
++
)
{
if
(
tile_odd
(
&
this
->
tiles
[
i
]))
if
(
tile_odd
(
&
this
->
tiles
[
i
]))
continue
;
continue
;
if
(
this
->
tiles
[
i
].
pair
==
0
&&
hk_dfs
(
this
,
i
))
if
(
this
->
tiles
[
i
].
pair
==
0
&&
hk_dfs
(
this
,
i
))
...
@@ -346,11 +355,11 @@ int main() {
...
@@ -346,11 +355,11 @@ int main() {
result
=
EXIT_SUCCESS
;
result
=
EXIT_SUCCESS
;
break
;
break
;
case
ReadEof
:
result
=
EXIT_SUCCESS
;
break
;
case
ReadEof
:
result
=
EXIT_SUCCESS
;
break
;
case
ReadErrOverflow
:
fprintf
(
stderr
,
"%
d
: too big integer
\n
"
,
f
.
num_tiles
);
break
;
case
ReadErrOverflow
:
fprintf
(
stderr
,
"%
u
: too big integer
\n
"
,
f
.
num_tiles
);
break
;
case
ReadErrInvalidChar
:
fprintf
(
stderr
,
"%
d
: invalid character
\n
"
,
f
.
num_tiles
);
break
;
case
ReadErrInvalidChar
:
fprintf
(
stderr
,
"%
u
: invalid character
\n
"
,
f
.
num_tiles
);
break
;
case
ReadErrTooFewNumbers
:
fprintf
(
stderr
,
"%
d
: too few numbers
\n
"
,
f
.
num_tiles
);
break
;
case
ReadErrTooFewNumbers
:
fprintf
(
stderr
,
"%
u
: too few numbers
\n
"
,
f
.
num_tiles
);
break
;
case
ReadErrTooManyNumbers
:
fprintf
(
stderr
,
"%
d
: too many numbers
\n
"
,
f
.
num_tiles
);
break
;
case
ReadErrTooManyNumbers
:
fprintf
(
stderr
,
"%
u
: too many numbers
\n
"
,
f
.
num_tiles
);
break
;
case
ReadErrOutOfMemory
:
fprintf
(
stderr
,
"%
d
:
failed to allocate more
memory
\n
"
,
f
.
num_tiles
);
break
;
case
ReadErrOutOfMemory
:
fprintf
(
stderr
,
"%
u
:
not enough
memory
\n
"
,
f
.
num_tiles
);
break
;
}
}
free
(
f
.
tiles
);
free
(
f
.
tiles
);
return
result
;
return
result
;
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment