Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
P
psco-2019-gp
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
Florian Heinrichs
psco-2019-gp
Commits
f45fd830
Commit
f45fd830
authored
5 years ago
by
p-hamann
Browse files
Options
Downloads
Patches
Plain Diff
Refactor bnb
parent
d49018a6
Branches
Branches containing commit
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
bnb/bnb.cpp
+18
-60
18 additions, 60 deletions
bnb/bnb.cpp
include/gp-bnb/bnb.hpp
+18
-61
18 additions, 61 deletions
include/gp-bnb/bnb.hpp
with
36 additions
and
121 deletions
bnb/bnb.cpp
+
18
−
60
View file @
f45fd830
...
...
@@ -7,46 +7,11 @@ static constexpr bool verbose = false;
namespace
gp_bnb
{
// --------------------------------------------------------------------------------------
// assignment_state implementation.
// --------------------------------------------------------------------------------------
void
assignment_state
::
resize_nodes
(
size_t
count
)
{
assigned_partition_
.
resize
(
count
,
illegal_partition
);
//fill_state_.resize(count);
}
void
assignment_state
::
assign
(
vertex_id
node
,
partition_index
p
,
std
::
vector
<
unsigned
int
>
neighbors
)
{
assert
(
assigned_partition_
[
node
]
==
illegal_partition
);
assert
(
p
>=
0
);
assigned_partition_
[
node
]
=
p
;
//for each neighbor of node in other partitions: current_objective++
for
(
auto
neighbor
:
neighbors
){
if
(
assigned_partition_
[
neighbor
]
==
(
p
xor
1
))
current_objective_
++
;
}
node_count
[
p
]
++
;
}
void
assignment_state
::
unassign
(
vertex_id
node
,
std
::
vector
<
unsigned
int
>
neighbors
)
{
assert
(
assigned_partition_
[
node
]
!=
illegal_partition
);
auto
p
=
assigned_partition_
[
node
];
assigned_partition_
[
node
]
=
illegal_partition
;
//for each neighbor of node in other partitions: current_objective--
for
(
vertex_id
neighbor
:
neighbors
){
if
(
assigned_partition_
[
neighbor
]
==
(
p
xor
1
))
current_objective_
--
;
}
node_count
[
p
]
--
;
}
// --------------------------------------------------------------------------------------
// trail_state implementation.
// --------------------------------------------------------------------------------------
void
trail_state
::
push_node
(
vertex_id
node
,
partition_index
alt
)
{
void
trail_state
::
push_node
(
vertex_id
node
,
subgraph
alt
)
{
stack_
.
push_back
({
node
,
alt
});
}
...
...
@@ -58,14 +23,7 @@ void trail_state::pop() {
// solver implementation.
// --------------------------------------------------------------------------------------
void
solver
::
resize_nodes
(
size_t
count
)
{
//nodes_.resize_nodes(count);
assignment_
.
resize_nodes
(
count
);
}
void
solver
::
define_graph
(
graph
&
g
){
nodes_
=
g
;
solver
::
solver
(
graph
&
g
)
:
nodes_
(
g
),
partition_
(
partition
{
g
})
{
}
void
solver
::
solve
()
{
...
...
@@ -79,13 +37,13 @@ void solver::solve() {
while
(
true
)
{
//falls current sol schlechter als obere grenze:
//zähle schritte bis zur nächsten alternative und
if
(
assignment
_
.
current_objective
()
>=
best_objective_
)
{
if
(
partition
_
.
current_objective
()
>=
best_objective_
)
{
int
i
=
trail_
.
length
()
-
1
;
while
(
true
)
{
if
(
i
<
0
)
return
;
// Only backtrack to assignments that have an alternative.
if
(
trail_
.
alternative_at
(
i
)
!=
illegal_partiti
on
)
if
(
trail_
.
alternative_at
(
i
)
!=
subgraph
::
n
on
e
)
break
;
i
--
;
}
...
...
@@ -103,30 +61,30 @@ void solver::solve() {
// Memorize the new solution.
best_solution_
.
resize
(
nodes_
.
num_vertices
());
for
(
vertex_id
node
=
0
;
node
<
nodes_
.
num_vertices
();
node
++
){
best_solution_
[
node
]
=
assignment
_
.
assigned_
partition
_of
(
node
);
best_solution_
[
node
]
=
partition
_
.
assigned_
subgraph
_of
(
node
);
}
best_objective_
=
assignment
_
.
current_objective
();
best_objective_
=
partition
_
.
current_objective
();
std
::
cerr
<<
"Solution improved to k = "
<<
best_objective_
<<
std
::
endl
;
}
else
{
//sonst expandiere suchbaum weiter
int
node
=
trail_
.
length
();
expand
(
node
,
next_possible_
partition
(
node
,
0
));
expand
(
node
,
next_possible_
subgraph
(
node
,
subgraph
::
sg_a
));
}
}
}
void
solver
::
expand
(
vertex_id
node
,
partition_index
p
)
{
void
solver
::
expand
(
vertex_id
node
,
subgraph
sg
)
{
// Search for an alternative BEFORE assigning the node.
// Because the node is not assigned, this calculation is easy.
auto
alt
=
next_possible_
partition
(
node
,
p
+
1
);
auto
alt
=
next_possible_
subgraph
(
node
,
static_cast
<
subgraph
>
(
-
sg
)
);
if
(
verbose
)
{
std
::
cerr
<<
"Assign node "
<<
node
<<
" to
partition
"
<<
p
<<
std
::
endl
;
std
::
cerr
<<
"Assign node "
<<
node
<<
" to
subgraph
"
<<
sg
<<
std
::
endl
;
std
::
cerr
<<
" Alternative "
<<
alt
<<
std
::
endl
;
}
std
::
vector
<
unsigned
int
>
neighbors
=
nodes_
.
get_adjacency
(
node
);
assignment_
.
assign
(
node
,
p
,
neighbors
);
partition_
.
assign_vertex
(
node
,
sg
);
trail_
.
push_node
(
node
,
alt
);
}
...
...
@@ -138,23 +96,23 @@ void solver::backtrack() {
std
::
cout
<<
"Unassign node "
<<
node
<<
std
::
endl
;
trail_
.
pop
();
assignment_
.
unassign
(
node
,
nodes_
.
get_adjacency
(
node
)
)
;
partition_
.
unassign_vertex
(
node
);
}
// Finds the next partition in which the given node can be placed.
partition_index
solver
::
next_possible_
partition
(
vertex_id
node
,
partition_index
m
)
{
subgraph
solver
::
next_possible_
subgraph
(
vertex_id
node
,
subgraph
m
)
{
// This function is only correct if the node is not assigned yet.
assert
(
assignment
_
.
assigned_
partition
_of
(
node
)
==
illegal_partiti
on
);
assert
(
partition
_
.
assigned_
subgraph
_of
(
node
)
==
subgraph
::
n
on
e
);
// partition_count_: Index+1 of last partition that we will try.
partition_index
p
=
m
;
subgraph
sg
=
m
;
//falls in einer partition schon die hälfte der knoten: nicht als alt wählen
if
((
assignment_
.
node_count
_of
(
p
)
*
2
)
<
nodes_
.
num_vertices
()){
return
p
;
if
((
partition_
.
num_vertices
_of
(
sg
)
*
2
)
<
nodes_
.
num_vertices
()){
return
sg
;
}
else
{
return
(
p
xor
1
)
;
return
subgraph
::
none
;
}
}
...
...
This diff is collapsed.
Click to expand it.
include/gp-bnb/bnb.hpp
+
18
−
61
View file @
f45fd830
...
...
@@ -5,53 +5,11 @@
#pragma once
#include
<gp-bnb/graph.hpp>
#include
<gp-bnb/partition.hpp>
namespace
gp_bnb
{
using
partition_index
=
unsigned
int
;
// We use (-1) as an indicator for non-existing (or otherwise illegal) partition.
// Note that because this is cast to unsigned int, it becomes 0xFFFF... (i.e., the highest
// possible number). We do not use zero as that is a valid partition index.
static
constexpr
partition_index
illegal_partition
=
static_cast
<
partition_index
>
(
-
1
);
// Represents a partial assignment.
struct
assignment_state
{
// Change the number of existing nodes.
void
resize_nodes
(
size_t
count
);
// Assigns an node to a partition.
void
assign
(
vertex_id
node
,
partition_index
p
,
std
::
vector
<
unsigned
int
>
neighbors
);
// Unassigns an node from its partition.
void
unassign
(
vertex_id
node
,
std
::
vector
<
unsigned
int
>
neigbors
);
partition_index
assigned_partition_of
(
vertex_id
node
)
const
{
return
assigned_partition_
[
node
];
}
unsigned
int
node_count_of
(
partition_index
p
)
const
{
return
node_count
[
p
];
}
int
current_objective
()
const
{
return
current_objective_
;
}
private
:
// For each node: index of the partition it is placed into.
std
::
vector
<
partition_index
>
assigned_partition_
;
// Value of objective function for current partial solution.
int
current_objective_
=
0
;
//for each partition: fill count
std
::
vector
<
unsigned
int
>
node_count
;
//number of partitions
int
partition_count_
=
2
;
};
using
subgraph
=
partition
::
subgraph
;
// Represents the current path throught the search tree.
struct
trail_state
{
...
...
@@ -60,18 +18,18 @@ private:
// Index of node that is assigned at a certain level of the search tree.
vertex_id
node
;
// Next alternative (or
illegal_partiti
on if no alternative exists).
partition_index
alt
;
// Next alternative (or
n
on
e
if no alternative exists).
subgraph
alt
;
};
public
:
// Extends the current path by adding another node.
void
push_node
(
vertex_id
node
,
partition_index
alt
);
void
push_node
(
vertex_id
node
,
subgraph
alt
);
// Reduces the current path by removing the last node.
void
pop
();
int
length
()
const
{
unsigned
int
length
()
const
{
return
stack_
.
size
();
}
...
...
@@ -79,7 +37,7 @@ public:
return
stack_
[
n
].
node
;
}
partition_index
alternative_at
(
size_t
n
)
const
{
subgraph
alternative_at
(
size_t
n
)
const
{
return
stack_
[
n
].
alt
;
}
...
...
@@ -90,24 +48,22 @@ private:
// Main solver structure. Puts everything together.
struct
solver
{
// Constructor
solver
(
graph
&
g
);
// Read-only access to the nodes.
const
graph
&
nodes
()
const
{
return
nodes_
;
}
// Read-only access to the optimal solution.
const
std
::
vector
<
partition_index
>
&
best_solution
()
const
{
const
std
::
vector
<
subgraph
>
&
best_solution
()
const
{
return
best_solution_
;
}
// Change the number of existing nodes.
void
resize_nodes
(
size_t
count
);
// Expand a search tree node, i.e., assigns an node to a partition and update all data structures.
void
expand
(
vertex_id
node
,
partition_index
p
);
//associates graph with the solver
void
define_graph
(
graph
&
g
);
void
expand
(
vertex_id
node
,
subgraph
sg
);
// Performs backtracking after the solver ran into a dead end,
// i.e., the current branch has been pruned.
...
...
@@ -117,15 +73,16 @@ struct solver {
void
solve
();
private
:
partition_index
next_possible_
partition
(
vertex_id
node
,
partition_index
p
);
subgraph
next_possible_
subgraph
(
vertex_id
node
,
subgraph
sg
);
graph
nodes_
;
assignment_state
assignment_
;
partition
partition_
;
trail_state
trail_
;
// Value of best solution seen so far.
std
::
vector
<
partition_index
>
best_solution_
;
int
best_objective_
=
0
;
std
::
vector
<
subgraph
>
best_solution_
;
unsigned
int
best_objective_
=
0
;
};
}
// namespace gp_bnb
...
...
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