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
dfd743f5
Commit
dfd743f5
authored
5 years ago
by
Lukas Garbas
Browse files
Options
Downloads
Patches
Plain Diff
multiple sources and sinks
parent
38ef3f65
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
bnb/edmonds_karp.cpp
+47
-31
47 additions, 31 deletions
bnb/edmonds_karp.cpp
include/gp-bnb/edmonds_karp.hpp
+6
-6
6 additions, 6 deletions
include/gp-bnb/edmonds_karp.hpp
with
53 additions
and
37 deletions
bnb/edmonds_karp.cpp
+
47
−
31
View file @
dfd743f5
#include
<limits>
#include
<limits>
#include
<queue>
#include
<queue>
#include
<cassert>
#include
<cassert>
#include
<algorithm>
#include
<gp-bnb/edmonds_karp.hpp>
#include
<gp-bnb/edmonds_karp.hpp>
edmonds_karp
::
edmonds_karp
(
const
graph
&
g
,
node_id
source
,
node_id
sink
)
edmonds_karp
::
edmonds_karp
(
const
graph
&
g
,
std
::
vector
<
node_id
>
sources
,
std
::
vector
<
node_id
>
sinks
)
:
g_
(
g
),
source_
(
source
),
sink_
(
sink
)
{
:
g_
(
g
),
sources_
(
sources
),
sinks_
(
sinks
)
{
assert
(
source_
>
0
);
// Nodes have ids: 1, .., n
assert
(
source_
<=
g
.
num_nodes
());
};
};
/* Indexes edges of the graph
/* Indexes edges of the graph
...
@@ -37,24 +36,29 @@ void edmonds_karp::index_edges() {
...
@@ -37,24 +36,29 @@ void edmonds_karp::index_edges() {
}
}
}
}
/* Breadth-first search in the graph from source to sink
/* Breadth-first search in the graph from source nodes to sink nodes */
When the sink is reached gain is added to gain[sink] */
std
::
pair
<
int
,
node_id
>
edmonds_karp
::
bfs
(
std
::
vector
<
int
>
&
resid_flow
,
std
::
vector
<
unsigned
int
>
&
pred
)
const
{
int
edmonds_karp
::
bfs
(
std
::
vector
<
int
>
&
resid_flow
,
std
::
vector
<
unsigned
int
>
&
pred
)
const
{
pred
.
clear
();
pred
.
clear
();
pred
.
resize
(
g_
.
num_nodes
()
+
1
,
-
1
);
// undiscovered nodes are marked with -1
pred
.
resize
(
g_
.
num_nodes
()
+
1
,
-
1
);
// undiscovered nodes are marked with -1
std
::
vector
<
int
>
gain
(
g_
.
num_nodes
(),
0.0
);
std
::
vector
<
int
>
gain
(
g_
.
num_nodes
(),
0
);
bool
sink_reached
=
false
;
node_id
sink
;
// Push all source nodes to the queue
std
::
queue
<
node_id
>
q
;
std
::
queue
<
node_id
>
q
;
q
.
push
(
source_
);
for
(
node_id
s
:
sources_
)
{
pred
[
source_
]
=
source_
;
q
.
push
(
s
);
gain
[
source_
]
=
std
::
numeric_limits
<
int
>::
max
();
pred
[
s
]
=
s
;
while
(
!
q
.
empty
())
{
gain
[
s
]
=
std
::
numeric_limits
<
int
>::
max
();
}
// Perform BFS from each source node and stop when the sink was reached
// or there was no path found from the source to the sink
while
(
!
q
.
empty
()
&&
!
sink_reached
)
{
node_id
u
=
q
.
front
();
node_id
u
=
q
.
front
();
q
.
pop
();
q
.
pop
();
bool
sink_reached
=
false
;
std
::
vector
<
node_id
>
neighbors
=
g_
.
get_adjacency
(
u
);
std
::
vector
<
node_id
>
neighbors
=
g_
.
get_adjacency
(
u
);
// iterate through neighbors of u
// iterate through neighbors of u
...
@@ -67,19 +71,23 @@ int edmonds_karp::bfs(std::vector<int> &resid_flow, std::vector<unsigned int> &p
...
@@ -67,19 +71,23 @@ int edmonds_karp::bfs(std::vector<int> &resid_flow, std::vector<unsigned int> &p
&&
pred
[
v
]
==
(
unsigned
int
)
-
1
)
{
// only add those neighbors with rest capacity and which were not discovered yet
&&
pred
[
v
]
==
(
unsigned
int
)
-
1
)
{
// only add those neighbors with rest capacity and which were not discovered yet
pred
[
v
]
=
u
;
pred
[
v
]
=
u
;
gain
[
v
]
=
std
::
min
(
gain
[
u
],
edge_weight
-
(
u
>=
v
?
flow_
[
edge_id
]
:
resid_flow
[
edge_id
]));
gain
[
v
]
=
std
::
min
(
gain
[
u
],
edge_weight
-
(
u
>=
v
?
flow_
[
edge_id
]
:
resid_flow
[
edge_id
]));
if
(
v
!=
sink_
&&
!
sink_reached
)
{
if
(
!
sink_reached
)
{
q
.
push
(
v
);
q
.
push
(
v
);
}
else
{
sink
=
v
;
sink_reached
=
true
;
}
}
// Check if any of the sink nodes are reached
for
(
node_id
t
:
sinks_
)
if
(
v
==
t
)
sink_reached
=
true
;
}
}
}
}
if
(
sink_reached
)
{
if
(
sink_reached
)
return
gain
[
sink
_
];
return
std
::
make_pair
(
gain
[
sink
]
,
sink
)
;
}
}
}
return
0.0
;
return
std
::
make_pair
(
0.0
,
sink
);
};
};
...
@@ -91,31 +99,36 @@ Step 2: Perform BFS that returns max gain from source to sink in one path
...
@@ -91,31 +99,36 @@ Step 2: Perform BFS that returns max gain from source to sink in one path
Step 3: Add gain that was calculated during BFS to the flow value. Break from the loop if gain was 0
Step 3: Add gain that was calculated during BFS to the flow value. Break from the loop if gain was 0
Step 4: Update flow and residual flow values for each node */
Step 4: Update flow and residual flow values for each node */
void
edmonds_karp
::
run
()
{
void
edmonds_karp
::
run
()
{
index_edges
();
index_edges
();
int
num_edges
=
indexed_edges_
.
size
()
/
2
;
int
num_edges
=
indexed_edges_
.
size
()
/
2
;
flow_
.
clear
();
flow_
.
clear
();
flow_
.
resize
(
num_edges
,
0.
0
);
flow_
.
resize
(
num_edges
,
0
);
std
::
vector
<
int
>
resid_flow
(
num_edges
,
0.
0
);
std
::
vector
<
int
>
resid_flow
(
num_edges
,
0
);
flow_value_
=
0
;
flow_value_
=
0
;
while
(
true
)
{
while
(
true
)
{
std
::
vector
<
node_id
>
pred
;
std
::
vector
<
node_id
>
pred
;
// Perform BFS that returns max gain from source to sink in one path
int
gain
=
bfs
(
resid_flow
,
pred
);
// If gain == 0.0 that means there exist no more paths from source to sink
// BFS from source nodes to sink nodes
auto
bfs_result
=
bfs
(
resid_flow
,
pred
);
int
gain
=
bfs_result
.
first
;
node_id
v
=
bfs_result
.
second
;
if
(
gain
==
0
)
break
;
if
(
gain
==
0
)
break
;
// Add gain that was calculated during BFS to the flow value
// Add gain that was calculated during BFS to the flow value
flow_value_
+=
gain
;
flow_value_
+=
gain
;
node_id
v
=
sink_
;
// Update flow and residual flow values for each edge
// Update flow and residual flow values for each edge
while
(
v
!=
source_
)
{
// in the path from the sink node to the source node
bool
source_reached
=
false
;
while
(
!
source_reached
)
{
node_id
u
=
pred
[
v
];
node_id
u
=
pred
[
v
];
int
edge_id
=
indexed_edges_
[
std
::
make_pair
(
u
,
v
)];
int
edge_id
=
indexed_edges_
[
std
::
make_pair
(
u
,
v
)];
if
(
u
>=
v
)
{
if
(
u
>=
v
)
{
flow_
[
edge_id
]
+=
gain
;
flow_
[
edge_id
]
+=
gain
;
resid_flow
[
edge_id
]
-=
gain
;
resid_flow
[
edge_id
]
-=
gain
;
...
@@ -123,9 +136,12 @@ void edmonds_karp::run() {
...
@@ -123,9 +136,12 @@ void edmonds_karp::run() {
flow_
[
edge_id
]
-=
gain
;
flow_
[
edge_id
]
-=
gain
;
resid_flow
[
edge_id
]
+=
gain
;
resid_flow
[
edge_id
]
+=
gain
;
}
}
v
=
u
;
v
=
u
;
source_reached
=
std
::
find
(
sources_
.
begin
(),
sources_
.
end
(),
v
)
!=
sources_
.
end
();
}
}
}
}
};
};
int
edmonds_karp
::
get_max_flow
()
const
{
int
edmonds_karp
::
get_max_flow
()
const
{
...
...
This diff is collapsed.
Click to expand it.
include/gp-bnb/edmonds_karp.hpp
+
6
−
6
View file @
dfd743f5
#ifndef EDMONDSKARP_H_
#ifndef EDMONDSKARP_H_
#define EDMONDSKARP_H_
#define EDMONDSKARP_H_
#include
"graph.hpp"
#include
<vector>
#include
<vector>
#include
<map>
#include
<map>
#include
<gp-bnb/graph.hpp>
class
edmonds_karp
{
class
edmonds_karp
{
private:
private:
...
@@ -11,8 +11,8 @@ private:
...
@@ -11,8 +11,8 @@ private:
std
::
map
<
std
::
pair
<
node_id
,
node_id
>
,
unsigned
int
>
indexed_edges_
;
std
::
map
<
std
::
pair
<
node_id
,
node_id
>
,
unsigned
int
>
indexed_edges_
;
node_id
source_
;
std
::
vector
<
node_id
>
source
s
_
;
node_id
sink_
;
std
::
vector
<
node_id
>
sink
s
_
;
int
flow_value_
;
int
flow_value_
;
std
::
vector
<
int
>
flow_
;
std
::
vector
<
int
>
flow_
;
...
@@ -26,9 +26,9 @@ private:
...
@@ -26,9 +26,9 @@ private:
* Performs a breadth-first search on the graph from the source node to find an augmenting path to the sink node respecting the flow values
* Performs a breadth-first search on the graph from the source node to find an augmenting path to the sink node respecting the flow values
* @param residFlow The residual flow in the network.
* @param residFlow The residual flow in the network.
* @param pred Used to store the path from the source to the sink.
* @param pred Used to store the path from the source to the sink.
* @return The gain in terms of flow.
* @return The gain in terms of flow
and id of the sink node
.
*/
*/
int
bfs
(
std
::
vector
<
int
>
&
resid_flow
,
std
::
vector
<
unsigned
int
>
&
pred
)
const
;
std
::
pair
<
int
,
node_id
>
bfs
(
std
::
vector
<
int
>
&
resid_flow
,
std
::
vector
<
unsigned
int
>
&
pred
)
const
;
public:
public:
/**
/**
...
@@ -37,7 +37,7 @@ public:
...
@@ -37,7 +37,7 @@ public:
* @param source The source node.
* @param source The source node.
* @param sink The sink node.
* @param sink The sink node.
*/
*/
edmonds_karp
(
const
graph
&
g
,
node_id
source
,
node_id
sink
);
edmonds_karp
(
const
graph
&
g
,
std
::
vector
<
node_id
>
source
s
,
std
::
vector
<
node_id
>
sink
s
);
/**
/**
* Computes the maximum flow, executes the EdmondsKarp algorithm.
* Computes the maximum flow, executes the EdmondsKarp algorithm.
...
...
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