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 @@
#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 K
note
n
Queue
q
;
// Schlange von K
achel
n
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, ungerade
s 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
(
u
int
32_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
;
...
...
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