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
29b02a65
Commit
29b02a65
authored
Sep 09, 2021
by
ehebrard
Browse files
gr
parent
be39536e
Changes
9
Hide whitespace changes
Inline
Side-by-side
examples/src/testcons.cpp
0 → 100644
View file @
29b02a65
/*************************************************************************
minicsp
Copyright 2010--2011 George Katsirelos
Minicsp is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
Minicsp is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with minicsp. If not, see <http://www.gnu.org/licenses/>.
*************************************************************************/
// #include "DistanceVariable.hpp"
#include
"BellmanFord.hpp"
#include
"DistanceGraph.hpp"
#include
"SparseDistanceGraph.hpp"
#include
"TimeTabling.hpp"
#include
"osp.hpp"
using
namespace
std
;
using
namespace
schedcl
;
int
main
(
int
argc
,
char
*
argv
[])
{
vector
<
int
>
duration
;
vector
<
vector
<
int
>>
resource
;
osp
::
read_instance
(
"j3-per0-1.txt"
,
duration
,
resource
);
cout
<<
duration
.
size
()
<<
" tasks:"
;
for
(
auto
d
:
duration
)
{
cout
<<
" "
<<
d
;
}
cout
<<
endl
;
cout
<<
resource
.
size
()
<<
" resources:"
;
for
(
auto
R
:
resource
)
{
cout
<<
" ("
;
for
(
auto
x
:
R
)
{
cout
<<
" "
<<
x
;
}
cout
<<
")"
;
}
cout
<<
endl
;
Schedule
<
int
>
S
;
for
(
auto
d
:
duration
)
{
S
.
addTask
(
"t"
+
to_string
(
S
.
numTask
()),
d
,
d
);
}
vector
<
CumulativeTimeTabling
<
int
,
int
>
*>
cons
;
for
(
auto
&
R
:
resource
)
{
vector
<
int
>
demand
(
R
.
size
(),
1
);
cons
.
push_back
(
new
CumulativeTimeTabling
<
int
,
int
>
(
S
,
R
.
begin
(),
R
.
end
(),
demand
.
begin
(),
demand
.
end
(),
1
));
// for (auto x : R) {
// for (auto y : R)
// if (x != y) {
// S.addEdge(START(x), START(y));
// S.addEdge(START(x), END(y));
// S.addEdge(END(x), START(y));
// S.addEdge(END(x), END(y));
// S2.addEdge(START(x), START(y));
// S2.addEdge(START(x), END(y));
// S2.addEdge(END(x), START(y));
// S2.addEdge(END(x), END(y));
// }
// }
cons
.
back
()
->
debug_flag
=
true
;
}
auto
ub
{
osp
::
getUb
(
duration
,
resource
)};
S
.
setUpperBound
(
ub
);
// vector<task> scope;
// vector<int> demand;
// for (auto &job : resource) {
// demand.resize(job.size(), 1);
// for (auto j : job)
// scope.push_back(j);
// SparseDistanceGraph<int> SG(S);
// cout << SG << endl;
// DistanceGraph<int> G(S2);
// cout << G << endl;
// G.FloydWarshall();
// cout << G << endl;
// BellmanFord<int> BF(SG.size());
// vector<int> shortest_path(S.numEvent(), numeric_limits<int>::max());
//
// BF.allShortestPaths(ORIGIN, SG.successor, shortest_path);
// for(auto v{0}; v<S.numEvent(); ++v)
// cout << S.label(v) << ": " << shortest_path[v] << endl;
S
.
initialise
();
cout
<<
S
<<
endl
;
S
.
updateDistances
();
cout
<<
S
<<
endl
;
auto
u
{
S
.
getVariable
(
START
(
1
),
END
(
0
))};
S
.
addConstraint
(
u
,
0
);
S
.
updateDistances
();
cout
<<
S
<<
endl
;
cout
<<
"save
\n
"
;
ReversibleObject
::
env
->
save
();
cout
<<
S
.
graph
<<
endl
;
// cout << "merge\n";
for
(
auto
i
{
0
};
i
<
S
.
numTask
();
++
i
)
S
.
graph
.
merge
(
START
(
i
),
END
(
i
),
duration
[
i
]);
cout
<<
S
.
graph
<<
endl
;
cout
<<
"restore to level "
<<
ReversibleObject
::
env
->
level
()
<<
"
\n
"
;
ReversibleObject
::
env
->
restore
(
ReversibleObject
::
env
->
level
());
cout
<<
S
<<
endl
;
cout
<<
"OK!
\n
"
;
for
(
auto
c
:
cons
)
{
c
->
propagate
();
}
}
examples/src/testsg.cpp
View file @
29b02a65
...
...
@@ -73,6 +73,7 @@ int main(int argc, char *argv[]) {
S1
.
addEdge
(
START
(
x
),
END
(
y
));
S1
.
addEdge
(
END
(
x
),
START
(
y
));
S1
.
addEdge
(
END
(
x
),
END
(
y
));
S2
.
addEdge
(
START
(
x
),
START
(
y
));
S2
.
addEdge
(
START
(
x
),
END
(
y
));
S2
.
addEdge
(
END
(
x
),
START
(
y
));
...
...
@@ -159,7 +160,7 @@ int main(int argc, char *argv[]) {
// cout << "merge\n";
for
(
auto
i
{
0
};
i
<
S1
.
numTask
();
++
i
)
S1
.
graph
.
merge
(
START
(
i
),
END
(
i
));
S1
.
graph
.
merge
(
START
(
i
),
END
(
i
)
,
duration
[
i
]
);
cout
<<
S1
.
graph
<<
endl
;
...
...
@@ -174,14 +175,18 @@ int main(int argc, char *argv[]) {
// auto v2{S2.getVariable(START(1), END(0))};
// v2->set(0);
// G.FloydWarshall();
// auto v1{S1.getVariable(START(1), END(0))};
// S1.set(v1, 0);
//
// cout << S1 << endl;
// auto v{S.getVariable(START(1), END(0))};
// S.set(v, 0);
//
// cout << S << endl;
//
//
//
//
//
// //
//
// DistanceGraph<int> G(S,
// events.begin(), events.end());
// G.initialise();
...
...
src/cpp/TimeTabling.cpp
0 → 100644
View file @
29b02a65
#include
"TimeTabling.hpp"
src/header/BellmanFord.hpp
View file @
29b02a65
...
...
@@ -71,13 +71,13 @@ void BellmanFord<T>::allShortestPaths(const int s, const G& neighbors, vector<T>
auto
u
{
changed
.
front
()};
changed
.
pop_front
();
cout
<<
u
<<
":"
;
//
cout << u << ":";
for
(
auto
e
:
neighbors
[
u
])
{
auto
v
{
e
.
ne
xt
(
u
)};
auto
v
{
e
.
ne
ighbor
(
)};
auto
w
{
e
.
length
()};
cout
<<
" ("
<<
v
<<
"|"
<<
w
<<
")"
;
//
cout << " (" << v << "|" << w << ")";
if
(
w
!=
INFTY
and
shortest_path
[
u
]
+
w
<
shortest_path
[
v
])
{
...
...
@@ -88,7 +88,7 @@ void BellmanFord<T>::allShortestPaths(const int s, const G& neighbors, vector<T>
shortest_path
[
v
]
=
shortest_path
[
u
]
+
w
;
cout
<<
" ("
<<
shortest_path
[
v
]
<<
")"
;
//
cout << " (" << shortest_path[v] << ")";
if
(
not
changed
.
has
(
v
))
changed
.
add
(
v
);
...
...
@@ -97,7 +97,7 @@ void BellmanFord<T>::allShortestPaths(const int s, const G& neighbors, vector<T>
}
}
cout
<<
endl
;
//
cout << endl;
}
}
...
...
@@ -115,7 +115,7 @@ void BellmanFord<T>::allShorterPaths(const int x, const int y, const T wxy, cons
changed
.
pop_front
();
for
(
auto
e
:
neighbors
[
u
])
{
auto
v
{
e
.
ne
xt
(
u
)};
auto
v
{
e
.
ne
ighbor
(
)};
auto
w
{
e
.
length
()};
if
(
w
!=
INFTY
and
shortest_path
[
u
]
+
w
<
shortest_path
[
v
])
{
...
...
src/header/DistanceVariable.hpp
View file @
29b02a65
...
...
@@ -13,15 +13,14 @@ using event = int;
using
namespace
std
;
//
// template <
class
T>
// template <
typename
T>
// class DistanceVariable ;
template
<
typename
T
>
class
Schedule
;
template
<
class
T
>
class
Schedu
le
;
template
<
typename
T
>
class
DistanceVariab
le
;
template
<
class
T
>
class
DistanceVariable
;
template
<
class
T
>
class
DistanceLiteral
{
template
<
typename
T
>
class
DistanceLiteral
{
public:
// DistanceLiteral() {
...
...
@@ -31,6 +30,13 @@ public:
DistanceVariable
<
T
>
*
var
{
NULL
};
int
lit
{
-
1
};
ostream
&
display
(
ostream
&
os
)
const
{
os
<<
var
->
sched
.
label
(
var
->
to
)
<<
" - "
<<
var
->
sched
.
label
(
var
->
from
)
<<
" <= "
<<
var
->
get
(
lit
).
value
;
// os << "e" << to << " - e" << from << " <= " << get();
return
os
;
}
};
// class DistanceLiteral {
...
...
@@ -53,26 +59,26 @@ DistanceGraph are also explainers, for the transitivity
The static object "NoReason" is the empty reason
*/
template
<
class
T
>
class
Explainer
{
template
<
typename
T
>
class
Explainer
{
public:
virtual
void
xplain
(
const
int
hint
,
vector
<
DistanceLiteral
<
T
>>
&
Cl
)
const
{};
// virtual void xplain(const int hint, vector<DistanceLiteral>& Cl)
// const {};
};
template
<
class
T
>
class
Constant
{
template
<
typename
T
>
class
Constant
{
public:
static
Explainer
<
T
>
*
NoReason
;
static
DistanceLiteral
<
T
>
NoLiteral
;
};
template
<
class
T
>
Explainer
<
T
>
*
Constant
<
T
>::
NoReason
=
new
Explainer
<
T
>
();
template
<
typename
T
>
Explainer
<
T
>
*
Constant
<
T
>::
NoReason
=
new
Explainer
<
T
>
();
template
<
class
T
>
template
<
typename
T
>
DistanceLiteral
<
T
>
Constant
<
T
>::
NoLiteral
=
{
static_cast
<
DistanceVariable
<
T
>
*>
(
NULL
),
-
1
};
template
<
class
T
>
struct
Bound
{
template
<
typename
T
>
struct
Bound
{
T
value
;
const
Explainer
<
T
>
*
reason
;
...
...
@@ -82,7 +88,7 @@ template <class T> struct Bound {
// literals x - y <= k (with x,y pointing to vars and k a constant)
template
<
class
T
>
class
DistanceVariable
:
public
ReversibleObject
{
template
<
typename
T
>
class
DistanceVariable
:
public
ReversibleObject
{
public:
Schedule
<
T
>
&
sched
;
...
...
@@ -111,6 +117,10 @@ public:
// reason.push_back(Constant<T>::NoReason);
}
DistanceLiteral
<
T
>
current
()
{
return
{
this
,
static_cast
<
int
>
(
literals
.
size
())
-
1
};
}
// get the current distance
T
get
()
const
{
return
literals
.
back
().
value
;
}
...
...
@@ -223,11 +233,16 @@ protected:
// vector<const int> hint;
};
template
<
class
T
>
template
<
typename
T
>
ostream
&
operator
<<
(
ostream
&
os
,
const
DistanceVariable
<
T
>
&
x
)
{
return
x
.
display
(
os
);
}
template
<
typename
T
>
ostream
&
operator
<<
(
ostream
&
os
,
const
DistanceLiteral
<
T
>
&
x
)
{
return
x
.
display
(
os
);
}
}
// namespace schedcl
#endif
src/header/Global.hpp
View file @
29b02a65
...
...
@@ -16,11 +16,79 @@ namespace schedcl {
#define HORIZON 1
#define CMAX 0
#define LOWERBOUND 1
#define SUCCESSOR 0
#define PREDECESSOR 1
task
TASK
(
event
x
);
event
START
(
task
x
);
event
END
(
task
x
);
template
<
class
T
>
class
Gap
{
public:
static
constexpr
T
epsilon
()
noexcept
{
return
T
();
}
};
template
<
>
class
Gap
<
short
>
{
public:
static
constexpr
short
epsilon
()
noexcept
{
return
1
;
}
};
template
<
>
class
Gap
<
int
>
{
public:
static
constexpr
int
epsilon
()
noexcept
{
return
1
;
}
};
template
<
>
class
Gap
<
long
>
{
public:
static
constexpr
long
int
epsilon
()
noexcept
{
return
1
;
}
};
template
<
>
class
Gap
<
long
long
>
{
public:
static
constexpr
long
long
int
epsilon
()
noexcept
{
return
1
;
}
};
template
<
>
class
Gap
<
unsigned
short
>
{
public:
static
constexpr
short
epsilon
()
noexcept
{
return
1
;
}
};
template
<
>
class
Gap
<
unsigned
int
>
{
public:
static
constexpr
int
epsilon
()
noexcept
{
return
1
;
}
};
template
<
>
class
Gap
<
unsigned
long
>
{
public:
static
constexpr
long
int
epsilon
()
noexcept
{
return
1
;
}
};
template
<
>
class
Gap
<
unsigned
long
long
>
{
public:
static
constexpr
long
long
int
epsilon
()
noexcept
{
return
1
;
}
};
template
<
>
class
Gap
<
float
>
{
public:
static
constexpr
float
epsilon
()
noexcept
{
return
10e-6
;
// std::numeric_limits<float>::epsilon();
}
};
template
<
>
class
Gap
<
double
>
{
public:
static
constexpr
double
epsilon
()
noexcept
{
return
10e-9
;
// std::numeric_limits<double>::epsilon();
}
};
template
<
>
class
Gap
<
long
double
>
{
public:
static
constexpr
double
epsilon
()
noexcept
{
return
10e-12
;
// std::numeric_limits<long double>::epsilon();
}
};
}
// namespace SCHEDCL
#endif // _SCHEDCL_SCHEDULING_HPP
src/header/Schedule.hpp
View file @
29b02a65
...
...
@@ -7,15 +7,16 @@
// #include <boost/dynamic_bitset.hpp>
#include
"Global.hpp"
#include
"BellmanFord.hpp"
#include
"SparseDistanceGraph.hpp"
#include
"Global.hpp"
#include
"SparseGraph.hpp"
// #include "SparseDistanceGraph.hpp"
namespace
schedcl
{
template
<
class
T
>
class
DistanceVariable
;
template
<
class
T
>
class
DistanceGraph
;
//
template <class T> class DistanceGraph;
// class ConstraintQueue {
//
...
...
@@ -61,8 +62,10 @@ public:
//@{
void
addTask
(
const
std
::
string
&
label
,
const
T
min_processing
,
const
T
max_processing
);
void
addMaximumLag
(
const
event
x
,
const
event
y
,
const
T
lag
=
0
);
void
addPrecedence
(
const
event
x
,
const
event
y
,
const
T
delay
=
0
);
DistanceVariable
<
T
>
*
addMaximumLag
(
const
event
x
,
const
event
y
,
const
T
lag
=
0
);
DistanceVariable
<
T
>
*
addPrecedence
(
const
event
x
,
const
event
y
,
const
T
delay
=
0
);
void
addEdge
(
const
event
x
,
const
event
y
);
void
setUpperBound
(
const
T
b
);
//@}
...
...
@@ -73,6 +76,8 @@ public:
void
updateDistances
();
void
fail
(
Explainer
<
T
>
*
expl
,
const
int
hint
);
// set the distance var v to 'bound' and update all shortest paths
void
set
(
DistanceVariable
<
T
>
*
v
,
const
T
bound
);
//@}
...
...
@@ -83,7 +88,9 @@ public:
//@}
// the graph of distances
SparseDistanceGraph
<
T
>
graph
;
// SparseDistanceGraph<T> graph;
SparseGraph
<
T
>
graph
;
private:
/*!@name Private Parameters*/
...
...
@@ -101,6 +108,15 @@ private:
// the value corresponding to the requests above
vector
<
T
>
new_bound
;
// tail[i] == last variable mapped to i
vector
<
int
>
tail
;
// next[i] == next variable mapped to the same variable as i (i, if there is
// none)
vector
<
int
>
next
;
// prev[i] == prev variable mapped to the same variable as i (i, if there is
// none)
vector
<
int
>
prev
;
// the Bellman-Ford algorithm and structures required to handle the changes
BellmanFord
<
T
>
algo
;
...
...
@@ -122,6 +138,8 @@ template <class T> Schedule<T>::Schedule() {
}
template
<
class
T
>
void
Schedule
<
T
>::
initialise
()
{
// graph.initialise(*this);
graph
.
initialise
(
*
this
);
shortest_path_from_x
.
resize
(
numEvent
(),
INFTY
);
...
...
@@ -251,16 +269,18 @@ DistanceVariable<T> *Schedule<T>::getVariable(event x, event y) {
//
template
<
class
T
>
void
Schedule
<
T
>::
addPrecedence
(
const
event
x
,
const
event
y
,
const
T
delay
)
{
DistanceVariable
<
T
>
*
Schedule
<
T
>::
addPrecedence
(
const
event
x
,
const
event
y
,
const
T
delay
)
{
// variables.push_back(new DistanceVariable<T>(*this, y, x,
// numVar(), -delay));
addMaximumLag
(
y
,
x
,
-
delay
);
return
addMaximumLag
(
y
,
x
,
-
delay
);
}
template
<
class
T
>
void
Schedule
<
T
>::
addMaximumLag
(
const
event
x
,
const
event
y
,
const
T
lag
)
{
DistanceVariable
<
T
>
*
Schedule
<
T
>::
addMaximumLag
(
const
event
x
,
const
event
y
,
const
T
lag
)
{
pair
<
event
,
event
>
key
{
x
,
y
};
auto
v
{
varmap
.
find
(
key
)};
...
...
@@ -298,6 +318,8 @@ void Schedule<T>::addMaximumLag(const event x, const event y, const T lag) {
if
(
lag
!=
INFTY
)
{
addConstraint
(
variables
[
idvar
],
lag
);
}
return
variables
[
idvar
];
}
template
<
class
T
>
...
...
@@ -343,6 +365,10 @@ void Schedule<T>::addConstraint(DistanceVariable<T> *v, const T d) {
}
}
template
<
class
T
>
void
Schedule
<
T
>::
fail
(
Explainer
<
T
>
*
expl
,
const
int
hint
)
{
cout
<<
"FAIL!!
\n
"
;
// TODO
}
template
<
class
T
>
void
Schedule
<
T
>::
updateDistances
()
{
// int k{3};
...
...
@@ -392,8 +418,11 @@ void Schedule<T>::set(DistanceVariable<T> *v, const T bound) {
algo
.
initialise
(
numEvent
());
// backwardAlgo.initialise(numEvent());
algo
.
allShortestPaths
(
x
,
graph
.
successor
,
shortest_path_from_x
);
algo
.
allShortestPaths
(
y
,
graph
.
predecessor
,
shortest_path_to_y
);
// algo.allShortestPaths(x, graph.successor, shortest_path_from_x);
// algo.allShortestPaths(y, graph.predecessor, shortest_path_to_y);
algo
.
allShortestPaths
(
x
,
graph
.
neighbor
[
SUCCESSOR
],
shortest_path_from_x
);
algo
.
allShortestPaths
(
y
,
graph
.
neighbor
[
PREDECESSOR
],
shortest_path_to_y
);
for
(
auto
i
{
0
};
i
<
numEvent
();
++
i
)
{
cout
<<
setw
(
4
)
<<
label
(
i
)
<<
": "
<<
shortest_path_from_x
[
i
]
<<
" / "
...
...
@@ -402,11 +431,17 @@ void Schedule<T>::set(DistanceVariable<T> *v, const T bound) {
v
->
set
(
bound
);
algo
.
allShorterPaths
(
x
,
y
,
bound
,
graph
.
successor
,
shortest_path_from_x
,
fCandidates
);
// algo.allShorterPaths(x, y, bound, graph.successor, shortest_path_from_x,
// fCandidates);
//
// algo.allShorterPaths(y, x, bound, graph.predecessor, shortest_path_to_y,
// bCandidates);
algo
.
allShorterPaths
(
y
,
x
,
bound
,
graph
.
predecessor
,
shortest_path_to_y
,
bCandidates
);
algo
.
allShorterPaths
(
x
,
y
,
bound
,
graph
.
neighbor
[
SUCCESSOR
],
shortest_path_from_x
,
fCandidates
);
algo
.
allShorterPaths
(
y
,
x
,
bound
,
graph
.
neighbor
[
PREDECESSOR
],
shortest_path_to_y
,
bCandidates
);
cout
<<
"f cand:
\n
"
;
for
(
auto
i
{
0
};
i
<
numEvent
();
++
i
)
...
...
@@ -424,8 +459,8 @@ void Schedule<T>::set(DistanceVariable<T> *v, const T bound) {
// vertices whose distance from x has been reduced
for
(
auto
b
:
fCandidates
)
{
for
(
auto
e
:
graph
.
predecessor
[
b
])
{
auto
a
{
e
.
from
()};
for
(
auto
e
:
graph
.
neighbor
[
PREDECESSOR
]
[
b
])
{
auto
a
{
e
.
neighbor
()};
if
(
shortest_path_to_y
[
a
]
!=
INFTY
and
shortest_path_from_x
[
b
]
!=
INFTY
)
{
auto
nd
{
shortest_path_to_y
[
a
]
-
bound
+
shortest_path_from_x
[
b
]};
if
(
nd
<
e
.
length
())
{
...
...
@@ -438,8 +473,8 @@ void Schedule<T>::set(DistanceVariable<T> *v, const T bound) {
}
for
(
auto
a
:
bCandidates
)
{
for
(
auto
e
:
graph
.
successor
[
a
])
{
auto
b
{
e
.
to
()};
for
(
auto
e
:
graph
.
neighbor
[
SUCCESSOR
]
[
a
])
{
auto
b
{
e
.
neighbor
()};
if
(
shortest_path_to_y
[
a
]
!=
INFTY
and
shortest_path_from_x
[
b
]
!=
INFTY
)
{
auto
nd
{
shortest_path_to_y
[
a
]
-
bound
+
shortest_path_from_x
[
b
]};
if
(
nd
<
e
.
length
())
{
...
...
@@ -776,7 +811,39 @@ template <class T> ostream &Schedule<T>::display(ostream &os) const
{
vector
<
T
>
dbuffer
(
numEvent
(),
-
INFTY
);
os
<<
" "
;
// os << " ";
// for (auto i{0}; i < numEvent(); ++i)
// // if (vertices.has(i))
// os << " " << setw(4) << label(i);
// os << endl;
// for (auto i{0}; i < numEvent(); ++i) {
// // if (vertices.has(i)) {
//
// os << setw(4) << label(i) << ":";
// for (auto &e : graph.successor[i])
// dbuffer[e.to()] = e.length();
// for (auto j{0}; j < numEvent(); ++j)
// if (dbuffer[j] != -INFTY) {
// if (dbuffer[j] == INFTY) {
// os << " oo";
// } else {
// os << " " << setw(4) << dbuffer[j];
// }
// } else {
// os << " ";
// }
// for (auto &e : graph.successor[i])
// dbuffer[e.to()] = -INFTY;
// os << endl;
// // }
// }
// return os;