Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Emmanuel Hebrard
SchedCL
Commits
7e025138
Commit
7e025138
authored
Feb 02, 2022
by
ehebrard
Browse files
menage
parent
d8cd18ad
Changes
12
Expand all
Hide whitespace changes
Inline
Side-by-side
src/cpp/Global.cpp
View file @
7e025138
...
...
@@ -29,3 +29,16 @@ unsigned long schedcl::random(void) { // period 2^96-1
return
z
;
}
// 0 is for the origin event, 1 is for the completion event
task
schedcl
::
TASK
(
event
x
)
{
return
x
/
2
-
1
;
}
event
schedcl
::
START
(
task
x
)
{
return
2
*
x
+
2
;
}
event
schedcl
::
END
(
task
x
)
{
return
2
*
x
+
3
;
}
src/cpp/Graph.cpp
0 → 100644
View file @
7e025138
#include
"Graph.hpp"
using
namespace
schedcl
;
// declare a new time point in the graph
Graph
::
Graph
()
:
ReversibleObject
()
{}
void
Graph
::
addArc
(
const
int
u
,
const
int
v
)
{
if
(
edges
.
newArc
(
u
,
v
))
{
ReversibleObject
::
save
();
trail
.
push_back
(
u
);
trail
.
push_back
(
v
);
add
(
Arc
(
u
,
v
));
#ifdef DEBUG_SG
// cout << *this << endl;
verify
(
"add arc"
);
#endif
}
}
void
Graph
::
add
(
Arc
a
)
{
for
(
auto
l
{
SUCCESSOR
};
l
<=
PREDECESSOR
;
++
l
)
{
neighbor_rank
[
l
][
a
[
l
]].
push_back
(
static_cast
<
int
>
(
neighbor
[
1
-
l
][
a
[
1
-
l
]].
size
()));
}
for
(
auto
l
{
SUCCESSOR
};
l
<=
PREDECESSOR
;
++
l
)
{
neighbor
[
l
][
a
[
l
]].
push_back
(
a
[
1
-
l
]);
// ++numArc;
}
++
numArc
;
}
bool
Graph
::
has
(
const
int
u
,
const
int
v
)
const
{
return
edges
.
has
(
u
,
v
);
}
void
Graph
::
removeVertex
(
const
int
u
)
{
ReversibleObject
::
save
();
trail
.
push_back
(
u
);
for
(
auto
l
{
SUCCESSOR
};
l
<=
PREDECESSOR
;
++
l
)
{
for
(
auto
i
{
neighbor
[
l
][
u
].
size
()};
i
--
>
0
;)
{
removeIthNeighbor
(
u
,
l
,
i
);
--
numArc
;
}
}
vertices
.
remove_back
(
u
);
// cout << "removed " << u << endl << *this << endl;
#ifdef DEBUG_SG
// cout << *this << endl;
verify
(
"remove vertex"
);
#endif
}
void
Graph
::
removeIthNeighbor
(
const
int
u
,
const
int
l
,
const
int
ith
)
{
auto
v
{
neighbor
[
l
][
u
][
ith
]};
auto
kth
{
neighbor_rank
[
l
][
u
][
ith
]};
// u appears at rank r in v's neighbors
assert
(
ith
==
neighbor_rank
[
1
-
l
][
v
][
kth
]);
assert
(
u
==
neighbor
[
1
-
l
][
v
][
kth
]);
auto
w
{
neighbor
[
1
-
l
][
v
].
back
()};
auto
jth
{
neighbor_rank
[
1
-
l
][
v
].
back
()};
// w is the last neighbor of v
assert
(
neighbor_rank
[
l
][
w
][
jth
]
==
neighbor
[
1
-
l
][
v
].
size
()
-
1
);
neighbor
[
1
-
l
][
v
][
kth
]
=
w
;
neighbor_rank
[
1
-
l
][
v
][
kth
]
=
jth
;
neighbor_rank
[
l
][
w
][
jth
]
=
kth
;
neighbor
[
1
-
l
][
v
].
pop_back
();
neighbor_rank
[
1
-
l
][
v
].
pop_back
();
}
void
Graph
::
addIthNeighbor
(
const
int
u
,
const
int
l
,
const
int
ith
)
{
// int k;
auto
v
{
neighbor
[
l
][
u
][
ith
]};
// k = 0;
// for (auto z : neighbor[SUCCESSOR][v]) {
// cout << " " << z << "@" << neighbor_rank[SUCCESSOR][v][k++];
// }
// cout << " /";
// k = 0;
// for (auto z : neighbor[PREDECESSOR][v]) {
// cout << " " << z << "@" << neighbor_rank[PREDECESSOR][v][k++];
// }
// cout << endl;
// k = 0;
// for (auto z : neighbor[SUCCESSOR][5]) {
// cout << " " << z << "@" << neighbor_rank[SUCCESSOR][5][k++];
// }
// cout << " /";
// k = 0;
// for (auto z : neighbor[PREDECESSOR][5]) {
// cout << " " << z << "@" << neighbor_rank[PREDECESSOR][5][k++];
// }
// cout << endl;
auto
kth
{
neighbor_rank
[
l
][
u
][
ith
]};
// cout << " - in " << v << "'s list @" << kth << endl;
if
(
kth
<
neighbor
[
1
-
l
][
v
].
size
())
{
auto
w
{
neighbor
[
1
-
l
][
v
][
kth
]};
auto
jth
{
neighbor_rank
[
1
-
l
][
v
][
kth
]};
// cout << "add " << u << " as " << kth << "-th " << (l ? "suc" : "prede")
// << "cessor of " << v << " in place of " << w << endl;
assert
(
neighbor_rank
[
l
][
w
][
jth
]
==
kth
);
assert
(
neighbor
[
l
][
w
][
jth
]
==
v
);
neighbor_rank
[
l
][
w
][
jth
]
=
static_cast
<
int
>
(
neighbor
[
1
-
l
][
v
].
size
());
neighbor
[
1
-
l
][
v
].
push_back
(
w
);
neighbor_rank
[
1
-
l
][
v
].
push_back
(
jth
);
neighbor
[
1
-
l
][
v
][
kth
]
=
u
;
neighbor_rank
[
1
-
l
][
v
][
kth
]
=
ith
;
}
else
{
assert
(
kth
==
neighbor
[
1
-
l
][
v
].
size
());
// cout << "add " << u << " as last " << (l ? "suc" : "prede")
// << "cessor of " << v << endl;
neighbor
[
1
-
l
][
v
].
push_back
(
u
);
neighbor_rank
[
1
-
l
][
v
].
push_back
(
ith
);
}
// cout << " (in place of " << w << ")\n";
//
// k = 0;
// for (auto z : neighbor[SUCCESSOR][v]) {
// cout << " " << z << "@" << neighbor_rank[SUCCESSOR][v][k++];
// }
// cout << " /";
// k = 0;
// for (auto z : neighbor[PREDECESSOR][v]) {
// cout << " " << z << "@" << neighbor_rank[PREDECESSOR][v][k++];
// }
// cout << endl;
// k = 0;
// for (auto z : neighbor[SUCCESSOR][5]) {
// cout << " " << z << "@" << neighbor_rank[SUCCESSOR][5][k++];
// }
// cout << " /";
// k = 0;
// for (auto z : neighbor[PREDECESSOR][5]) {
// cout << " " << z << "@" << neighbor_rank[PREDECESSOR][5][k++];
// }
// cout << endl;
}
void
Graph
::
recall
(
const
int
u
)
{
for
(
auto
l
{
PREDECESSOR
};
l
>=
SUCCESSOR
;
--
l
)
{
// cout << (l ? "prede" : "suc") << "cessors\n";
int
n
{
static_cast
<
int
>
(
neighbor
[
l
][
u
].
size
())};
for
(
int
ith
{
0
};
ith
<
n
;
++
ith
)
{
// cout << "add " << u << " as " << neighbor_rank[l][u][ith]
// << "-th " << (l ? "suc" : "prede") << "cessors of "
// << neighbor[l][u][ith] << endl;
addIthNeighbor
(
u
,
l
,
ith
);
++
numArc
;
}
}
vertices
.
add
(
u
);
// exit(1);
// // for()
//
//
// auto f{neighbor[l][z][i]};
// neighbor[1 - l][f.neighbor()][f.rank].rank =
// static_cast<int>(neighbor[l][z].size());
// neighbor[l][z].push_back(f);
// neighbor[l][z][i] = e;
#ifdef DEBUG_SG
verify
(
"recall"
);
#endif
}
void
Graph
::
undo
(
Arc
a
)
{
for
(
auto
l
{
SUCCESSOR
};
l
<=
PREDECESSOR
;
++
l
)
{
assert
(
neighbor
[
l
][
a
[
l
]].
back
()
==
a
[
1
-
l
]);
neighbor
[
l
][
a
[
l
]].
pop_back
();
neighbor_rank
[
l
][
a
[
l
]].
pop_back
();
}
edges
.
remove
(
a
);
--
numArc
;
}
void
Graph
::
resize
(
const
int
n
)
{
if
(
n
>
0
)
{
buffer
.
resize
(
n
,
0
);
neighbor
[
PREDECESSOR
].
resize
(
n
);
neighbor
[
SUCCESSOR
].
resize
(
n
);
neighbor_rank
[
PREDECESSOR
].
resize
(
n
);
neighbor_rank
[
SUCCESSOR
].
resize
(
n
);
vertices
.
reserve
(
n
);
vertices
.
fill
();
edges
.
resize
(
this
->
vertices
,
this
->
neighbor
[
SUCCESSOR
]);
}
#ifdef DEBUG_SG
// cout << *this << endl;
verify
(
"init"
);
#endif
}
size_t
Graph
::
arcCount
()
const
{
return
numArc
;
}
size_t
Graph
::
vertexCount
()
const
{
return
vertices
.
count
();
}
size_t
Graph
::
size
()
const
{
return
vertices
.
capacity
();
}
//
void
Graph
::
merge
(
const
int
u
,
const
int
v
)
{
// cout << *this << "\nMERGE " << v << " TO " << u << endl;
removeVertex
(
v
);
// cout << "1/ REMOVE " << v << ":\n" << *this << endl;
// for (auto l{SUCCESSOR}; l <= PREDECESSOR; ++l) {
//
// // cout << (l+2) << "/ COMPLETE " <<
//
//
//
// buffer.set(u);
// for (auto w : neighbor[l][u]) {
// assert(w >= 0);
// assert(w < buffer.size());
// buffer.set(w);
// }
//
// for (auto w : neighbor[l][v]) {
// if (not buffer[w]) {
// addArc(u, w);
// }
// }
// }
// cout << "2/ FILL " << u << "'s successors:\n";
buffer
.
reset
();
buffer
.
set
(
u
);
for
(
auto
w
:
neighbor
[
SUCCESSOR
][
u
])
{
assert
(
w
>=
0
);
assert
(
w
<
buffer
.
size
());
buffer
.
set
(
w
);
}
for
(
auto
w
:
neighbor
[
SUCCESSOR
][
v
])
{
if
(
not
buffer
[
w
])
{
// cout << " -" << w << endl;
addArc
(
u
,
w
);
}
}
// cout << *this << "\n2/ FILL " << u << "'s predecessors:\n";
buffer
.
reset
();
buffer
.
set
(
u
);
for
(
auto
w
:
neighbor
[
PREDECESSOR
][
u
])
{
assert
(
w
>=
0
);
assert
(
w
<
buffer
.
size
());
buffer
.
set
(
w
);
}
for
(
auto
w
:
neighbor
[
PREDECESSOR
][
v
])
{
if
(
not
buffer
[
w
])
{
// cout << " -" << w << endl;
addArc
(
w
,
u
);
}
}
// cout << *this << endl;
}
// restore to the last saved state
void
Graph
::
undo
()
{
auto
v
{
trail
.
back
()};
trail
.
pop_back
();
if
(
vertices
.
has
(
v
))
{
// undo an addArc(u, v)
auto
u
{
trail
.
back
()};
trail
.
pop_back
();
undo
(
Arc
(
u
,
v
));
}
else
{
// cout << "undo rm " << v << endl << *this << endl;
// undo a removeVertex
recall
(
v
);
}
#ifdef DEBUG_SG
// cout << *this << endl;
verify
(
"undo"
);
#endif
}
ostream
&
Graph
::
display
(
ostream
&
os
)
const
{
for
(
auto
i
{
0
};
i
<
size
();
++
i
)
{
os
<<
setw
(
3
)
<<
i
<<
":"
;
// if (not vertices.has(i)) {
// os << endl;
// } else {
int
k
{
0
};
for
(
auto
v
:
neighbor
[
SUCCESSOR
][
i
])
{
os
<<
" "
<<
v
#ifdef DEBUG_SG
<<
"@"
<<
neighbor_rank
[
SUCCESSOR
][
i
][
k
++
]
#endif
;
}
os
<<
" /"
;
k
=
0
;
for
(
auto
v
:
neighbor
[
PREDECESSOR
][
i
])
{
os
<<
" "
<<
v
#ifdef DEBUG_SG
<<
"@"
<<
neighbor_rank
[
PREDECESSOR
][
i
][
k
++
]
#endif
;
}
os
<<
endl
;
// }
}
return
os
;
}
#ifdef DEBUG_SG
void
Graph
::
verify
(
const
char
*
msg
)
{
// cout << msg << endl ;
for
(
auto
l
{
SUCCESSOR
};
l
<=
PREDECESSOR
;
++
l
)
{
int
count
=
0
;
for
(
auto
x
:
vertices
)
{
int
rank
=
0
;
for
(
auto
ith
{
0
};
ith
<
neighbor
[
l
][
x
].
size
();
++
ith
)
{
auto
y
{
neighbor
[
l
][
x
][
ith
]};
if
(
y
==
x
)
{
cout
<<
msg
<<
": error, there is a loop on "
<<
x
<<
endl
;
exit
(
1
);
}
auto
jth
{
neighbor_rank
[
l
][
x
][
ith
]};
if
(
neighbor_rank
[
1
-
l
][
y
][
jth
]
!=
ith
or
neighbor
[
1
-
l
][
y
][
jth
]
!=
x
)
{
cout
<<
msg
<<
": error on "
<<
x
<<
" "
<<
y
<<
"
\n
"
<<
*
this
<<
endl
;
exit
(
1
);
}
// else {
// cout << "ok " << x << " " << y << "\n";
// }
++
rank
;
}
count
+=
rank
;
}
assert
(
count
==
arcCount
());
}
}
#endif
//
// template<typename vertices, typename neighborhood>
// void EdgeSet::resize(const vertices& V, const edges& E) {
// auto N{V.size()};
// edges.resize(N);
// edges.reset();
// for(auto u : V) {
// for(auto v : E[u]) {
// edges.set(u * N + v);
// }
// }
// }
// void EdgeSet::clear(const size_t n) {
// edges.resize(n, 0);
// }
bool
EdgeSet
::
newArc
(
const
int
x
,
const
int
y
)
{
if
(
x
!=
y
)
{
auto
e
{
x
*
size_
+
y
};
if
(
not
edgeset
[
e
])
{
edgeset
.
set
(
e
);
return
true
;
}
}
return
false
;
}
bool
EdgeSet
::
has
(
const
int
x
,
const
int
y
)
const
{
return
edgeset
[
x
*
size_
+
y
];
}
void
EdgeSet
::
remove
(
const
Arc
a
)
{
assert
(
edgeset
[
a
[
0
]
*
size_
+
a
[
1
]]);
edgeset
.
reset
(
a
[
0
]
*
size_
+
a
[
1
]);
}
// void EdgeSet::remove(const int x, const int y) {
// if (x != y) {
// auto e{x * size() + y};
// if (not edges[e]) {
// edges.reset(e);
// }
// }
// }
std
::
ostream
&
schedcl
::
operator
<<
(
std
::
ostream
&
os
,
const
schedcl
::
Graph
&
x
)
{
return
x
.
display
(
os
);
}
\ No newline at end of file
src/cpp/Schedule.cpp
View file @
7e025138
#include
"Schedule.hpp"
// 0 is for the origin event, 1 is for the completion event
task
schedcl
::
TASK
(
event
x
)
{
return
x
/
2
-
1
;
}
event
schedcl
::
START
(
task
x
)
{
return
2
*
x
+
2
;
}
event
schedcl
::
END
(
task
x
)
{
return
2
*
x
+
3
;
}
//
//
//
// 0 is for the origin event, 1 is for the completion event
//
task schedcl::TASK( event x ) {
//
return x/2-1;
//
}
//
//
event schedcl::START( task x ) {
//
return 2*x+2;
//
}
//
//
event schedcl::END( task x ) {
//
return 2*x+3;
//
}
bool
schedcl
::
is_cycle
(
const
long
hint
)
{
return
static_cast
<
bool
>
(
hint
&
1
);
}
...
...
src/header/BellmanFord.hpp
View file @
7e025138
...
...
@@ -7,7 +7,7 @@
#include
"Global.hpp"
#include
"SparseSet.hpp"
//
#define DEBUG_BELLMANFORD
#define DEBUG_BELLMANFORD
using
namespace
std
;
...
...
@@ -23,14 +23,26 @@ public:
// updates all shortest paths from s and put them in 'shortest_path'. Sets the
// flag 'negative_cycle' if it finds a negative cycle including s
template
<
class
G
>
template
<
typename
G
>
void
allShortestPaths
(
const
int
s
,
const
G
&
neighbors
,
vector
<
T
>
&
shortest_path
);
template
<
typename
G
,
typename
D
>
void
allShortestPaths
(
const
int
s
,
const
G
&
neighbors
,
const
D
&
distance
,
vector
<
T
>
&
shortest_path
);
// updates all shortest paths from x (and through y) and put them in
// 'shortest_path'. Sets the flag 'negative_cycle' if it finds a negative
// cycle including x-y
template
<
typename
G
,
typename
D
>
void
allShorterPaths
(
const
int
x
,
const
int
y
,
const
T
wxy
,
const
G
&
neighbors
,
const
D
&
distance
,
vector
<
T
>
&
shortest_path
,
SparseSet
<>
&
reached
);
// updates all shortest paths from x (and through y) and put them in
// 'shortest_path'. Sets the flag 'negative_cycle' if it finds a negative
// cycle including x-y
template
<
class
G
template
<
typename
G
#ifdef DEBUG_BELLMANFORD
,
class
P
...
...
@@ -70,10 +82,11 @@ void BellmanFord<T>::initialise(const int n) {
}
template
<
typename
T
>
template
<
class
G
>
void
BellmanFord
<
T
>::
allShortestPaths
(
const
int
s
,
const
G
&
neighbors
,
vector
<
T
>&
shortest_path
// , vector<int>& predecessor
)
{
template
<
typename
G
>
void
BellmanFord
<
T
>::
allShortestPaths
(
const
int
s
,
const
G
&
neighbors
,
vector
<
T
>
&
shortest_path
// , vector<int>& predecessor
)
{
shortest_path
[
s
]
=
0
;
...
...
@@ -106,6 +119,41 @@ void BellmanFord<T>::allShortestPaths(const int s, const G& neighbors, vector<T>
}
}
template
<
typename
T
>
template
<
typename
G
,
typename
D
>
void
BellmanFord
<
T
>::
allShortestPaths
(
const
int
s
,
const
G
&
neighbors
,
const
D
&
distance
,
vector
<
T
>
&
shortest_path
)
{
shortest_path
[
s
]
=
0
;
changed
.
add
(
s
);
while
(
not
changed
.
empty
())
{
auto
u
{
changed
.
front
()};
changed
.
pop_front
();
for
(
auto
v
:
neighbors
[
u
])
{
auto
w
{
distance
.
get
(
u
,
v
)};
if
(
w
!=
INFTY
and
shortest_path
[
u
]
+
w
<
shortest_path
[
v
])
{
if
(
v
==
s
)
{
negative_cycle
=
true
;
changed
.
clear
();
return
;
}
shortest_path
[
v
]
=
shortest_path
[
u
]
+
w
;
if
(
not
changed
.
has
(
v
))
changed
.
add
(
v
);
}
}
}
}
template
<
typename
T
>
template
<
class
G
#ifdef DEBUG_BELLMANFORD
...
...
@@ -183,6 +231,88 @@ void BellmanFord<T>::allShorterPaths(const int x, const int y, const T wxy,
negative_cycle
=
true
;
changed
.
clear
();
return
;
}
// predecessor[v] = u;
shortest_path
[
v
]
=
shortest_path
[
u
]
+
w
;
if
(
not
changed
.
has
(
v
))
changed
.
add
(
v
);
if
(
not
reached
.
has
(
v
))
reached
.
add
(
v
);
}
#ifdef DEBUG_BELLMANFORD
else
if
(
debug_flag
)
cout
<<
" reject
\n
"
;