Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
las3_pub
/
jester
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
24eebe3e
authored
May 22, 2020
by
Michael Schmid
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Binary dec tree and nfj creation finished
parent
a15a466e
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
273 additions
and
130 deletions
+273
-130
src/main/java/mvd/jester/model/DagTask.java
+200
-108
src/main/java/mvd/jester/utils/BinaryDecompositionTree.java
+8
-2
src/test/java/mvd/jester/model/TestDagUtils.java
+65
-20
No files found.
src/main/java/mvd/jester/model/DagTask.java
View file @
24eebe3e
...
@@ -2,15 +2,14 @@ package mvd.jester.model;
...
@@ -2,15 +2,14 @@ package mvd.jester.model;
import
java.util.Arrays
;
import
java.util.Arrays
;
import
java.util.HashSet
;
import
java.util.HashSet
;
import
java.util.Iterator
;
import
java.util.LinkedHashSet
;
import
java.util.LinkedHashSet
;
import
java.util.LinkedList
;
import
java.util.LinkedList
;
import
java.util.List
;
import
java.util.List
;
import
java.util.Optional
;
import
java.util.Set
;
import
java.util.Set
;
import
com.google.common.collect.Iterables
;
import
com.google.common.collect.Iterables
;
import
com.google.common.collect.Sets
;
import
com.google.common.collect.Sets
;
import
org.jgrapht.Graphs
;
import
org.jgrapht.Graphs
;
import
org.jgrapht.alg.shortestpath.AllDirectedPaths
;
import
org.jgrapht.experimental.dag.DirectedAcyclicGraph
;
import
org.jgrapht.experimental.dag.DirectedAcyclicGraph
;
import
org.jgrapht.graph.DefaultEdge
;
import
org.jgrapht.graph.DefaultEdge
;
import
mvd.jester.utils.BinaryDecompositionTree
;
import
mvd.jester.utils.BinaryDecompositionTree
;
...
@@ -241,65 +240,67 @@ public class DagTask implements Task {
...
@@ -241,65 +240,67 @@ public class DagTask implements Task {
public
static
BinaryDecompositionTree
<
Job
>
createDecompositionTree
(
public
static
BinaryDecompositionTree
<
Job
>
createDecompositionTree
(
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
,
LinkedList
<
Job
>
forkNodes
,
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
,
LinkedList
<
Job
>
forkNodes
,
LinkedList
<
Job
>
joinNodes
)
{
LinkedList
<
Job
>
joinNodes
)
{
Job
source
=
forkNodes
.
getFirst
();
Job
sink
=
joinNodes
.
getLast
();
Job
current
=
source
;
BinaryDecompositionTree
<
Job
>
tree
=
new
BinaryDecompositionTree
<>();
BinaryDecompositionTree
<
Job
>
tree
=
new
BinaryDecompositionTree
<>();
DagUtils
.
constructTree
(
jobDag
,
null
,
current
,
tree
,
forkNodes
,
joinNodes
,
sink
);
Optional
<
Job
>
source
=
Optional
.
empty
();
Optional
<
Job
>
sink
=
Optional
.
empty
();
if
(
forkNodes
.
size
()
>
0
)
{
source
=
Optional
.
of
(
forkNodes
.
getFirst
());
sink
=
Optional
.
of
(
joinNodes
.
getLast
());
}
else
{
boolean
firstRun
=
true
;
for
(
Job
j
:
jobDag
)
{
if
(
firstRun
)
{
firstRun
=
false
;
source
=
Optional
.
of
(
j
);
}
sink
=
Optional
.
of
(
j
);
}
}
if
(
source
.
isPresent
()
&&
sink
.
isPresent
())
{
Job
current
=
source
.
get
();
DagUtils
.
treeDec
(
jobDag
,
null
,
current
,
tree
,
forkNodes
,
joinNodes
,
sink
.
get
());
}
return
tree
;
return
tree
;
}
}
private
static
Node
<
Job
>
constructTree
(
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
,
private
static
Node
<
Job
>
treeDec
(
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
,
Node
<
Job
>
parent
,
Job
current
,
BinaryDecompositionTree
<
Job
>
tree
,
Node
<
Job
>
parentNode
,
Job
currentJob
,
BinaryDecompositionTree
<
Job
>
tree
,
LinkedList
<
Job
>
forkVertices
,
LinkedList
<
Job
>
joinVertices
,
Job
sink
)
{
LinkedList
<
Job
>
forkVertices
,
LinkedList
<
Job
>
joinVertices
,
Job
sinkJob
)
{
if
(
forkVertices
.
contains
(
current
))
{
if
(
forkVertices
.
contains
(
currentJob
))
{
Job
join
=
findJoin
(
jobDag
,
current
,
sink
,
joinVertices
);
Job
forkJob
=
currentJob
;
if
(
jobDag
.
outDegreeOf
(
join
)
>
1
)
{
Job
joinJob
=
findJoin
(
jobDag
,
forkJob
,
sinkJob
,
joinVertices
);
throw
new
RuntimeException
(
"Join und Fork in Einem! Ohoh!"
);
}
Node
<
Job
>
forkNode
=
new
Node
<
Job
>(
parent
,
NodeType
.
SEQ
);
Node
<
Job
>
seqForkNode
=
new
Node
<
Job
>(
parentNode
,
NodeType
.
SEQ
);
seqForkNode
.
setLeftNode
(
new
Node
<
Job
>(
seqForkNode
,
forkJob
));
if
(
tree
.
isEmpty
())
{
if
(
tree
.
isEmpty
())
{
tree
.
setRoot
(
f
orkNode
);
tree
.
setRoot
(
seqF
orkNode
);
}
}
forkNode
.
setLeftNode
(
new
Node
<
Job
>(
forkNode
,
current
));
final
Node
<
Job
>
parContinuationNode
;
final
Node
<
Job
>
continuationNode
;
if
(!
tree
.
contains
(
joinJob
))
{
if
(!
tree
.
contains
(
join
))
{
Node
<
Job
>
seqJoinNode
=
forkNode
.
setRightNode
(
new
Node
<
Job
>(
forkNode
,
NodeType
.
SEQ
));
seqForkNode
.
setRightNode
(
new
Node
<
Job
>(
seqForkNode
,
NodeType
.
SEQ
));
Node
<
Job
>
joinNode
=
forkNode
.
getRightNode
();
Iterator
<
Job
>
successorIterator
=
Node
<
Job
>
subTreeOfJoin
=
treeDec
(
jobDag
,
seqJoinNode
,
joinJob
,
tree
,
Graphs
.
successorListOf
(
jobDag
,
join
).
iterator
();
forkVertices
,
joinVertices
,
sinkJob
);
if
(
successorIterator
.
hasNext
())
{
seqJoinNode
.
setRightNode
(
subTreeOfJoin
);
Job
successor
=
successorIterator
.
next
();
if
(!
tree
.
contains
(
successor
))
{
parContinuationNode
=
joinNode
.
setRightNode
(
new
Node
<>(
joinNode
,
NodeType
.
SEQ
));
seqJoinNode
.
setLeftNode
(
new
Node
<
Job
>(
seqJoinNode
,
NodeType
.
PAR
));
Node
<
Job
>
successorNode
=
joinNode
.
getRightNode
();
successorNode
.
setLeftNode
(
new
Node
<>(
successorNode
,
join
));
Node
<
Job
>
subTree
=
constructTree
(
jobDag
,
successorNode
,
successor
,
tree
,
forkVertices
,
joinVertices
,
sink
);
successorNode
.
setRightNode
(
subTree
);
}
else
{
joinNode
.
setRightNode
(
new
Node
<>(
joinNode
,
join
));
}
}
else
{
joinNode
.
setRightNode
(
new
Node
<>(
joinNode
,
join
));
}
joinNode
.
setLeftNode
(
new
Node
<>(
joinNode
,
NodeType
.
PAR
));
continuationNode
=
joinNode
.
getLeftNode
();
}
else
{
}
else
{
forkNode
.
setRightNode
(
new
Node
<>(
forkNode
,
NodeType
.
PAR
));
parContinuationNode
=
continuationNode
=
forkNode
.
getRightNode
(
);
seqForkNode
.
setRightNode
(
new
Node
<
Job
>(
seqForkNode
,
NodeType
.
PAR
)
);
}
}
Node
<
Job
>
successorParent
=
continuationNode
;
List
<
Job
>
successors
=
Graphs
.
successorListOf
(
jobDag
,
current
);
Node
<
Job
>
successorParent
=
parContinuationNode
;
List
<
Job
>
successors
=
Graphs
.
successorListOf
(
jobDag
,
currentJob
);
// create leftSide of joinNode
// create leftSide of joinNode
for
(
int
i
=
0
;
i
<
successors
.
size
();
++
i
)
{
for
(
int
i
=
0
;
i
<
successors
.
size
();
++
i
)
{
Job
succ
=
successors
.
get
(
i
);
Job
succ
=
successors
.
get
(
i
);
Node
<
Job
>
thisNode
=
constructTree
(
jobDag
,
successorParent
,
succ
,
tree
,
Node
<
Job
>
thisNode
=
treeDec
(
jobDag
,
successorParent
,
succ
,
tree
,
forkVertices
,
forkVertices
,
joinVertices
,
sink
);
joinVertices
,
sinkJob
);
if
(
i
==
successors
.
size
()
-
1
)
{
if
(
i
==
successors
.
size
()
-
1
)
{
successorParent
.
setRightNode
(
thisNode
);
successorParent
.
setRightNode
(
thisNode
);
}
else
if
(
i
==
successors
.
size
()
-
2
)
{
}
else
if
(
i
==
successors
.
size
()
-
2
)
{
...
@@ -311,12 +312,94 @@ public class DagTask implements Task {
...
@@ -311,12 +312,94 @@ public class DagTask implements Task {
}
}
}
}
return
f
orkNode
;
return
seqF
orkNode
;
}
else
{
}
else
{
return
new
Node
<>(
parent
,
current
);
List
<
Job
>
successorList
=
Graphs
.
successorListOf
(
jobDag
,
currentJob
);
if
(
successorList
.
size
()
>
0
)
{
Job
successor
=
successorList
.
get
(
0
);
if
(!
tree
.
contains
(
successor
))
{
Node
<
Job
>
seqJobNode
=
new
Node
<
Job
>(
parentNode
,
NodeType
.
SEQ
);
if
(
tree
.
isEmpty
())
{
tree
.
setRoot
(
seqJobNode
);
}
seqJobNode
.
setLeftNode
(
new
Node
<
Job
>(
seqJobNode
,
currentJob
));
Node
<
Job
>
contNode
=
treeDec
(
jobDag
,
seqJobNode
,
successor
,
tree
,
forkVertices
,
joinVertices
,
sinkJob
);
seqJobNode
.
setRightNode
(
contNode
);
return
seqJobNode
;
}
}
Node
<
Job
>
jobNode
=
new
Node
<
Job
>(
parentNode
,
currentJob
);
if
(
tree
.
isEmpty
())
{
tree
.
setRoot
(
jobNode
);
}
return
jobNode
;
}
}
}
}
// private static Node<Job> constructTree(DirectedAcyclicGraph<Job, DefaultEdge> jobDag,
// Node<Job> parent, Job currentFork, BinaryDecompositionTree<Job> tree,
// LinkedList<Job> forkVertices, LinkedList<Job> joinVertices, Job sink) {
// if (forkVertices.contains(currentFork)) {
// Job join = findJoin(jobDag, currentFork, sink, joinVertices);
// Node<Job> forkNode = new Node<Job>(parent, NodeType.SEQ);
// if (tree.isEmpty()) {
// tree.setRoot(forkNode);
// }
// forkNode.setLeftNode(new Node<Job>(forkNode, currentFork));
// final Node<Job> continuationNode;
// if (!tree.contains(join)) {
// forkNode.setRightNode(new Node<Job>(forkNode, NodeType.SEQ));
// Node<Job> joinNode = forkNode.getRightNode();
// Iterator<Job> successorIterator =
// Graphs.successorListOf(jobDag, join).iterator();
// if (successorIterator.hasNext()) {
// Job successor = successorIterator.next();
// if (!tree.contains(successor)) {
// joinNode.setRightNode(new Node<>(joinNode, NodeType.SEQ));
// Node<Job> successorNode = joinNode.getRightNode();
// successorNode.setLeftNode(new Node<>(successorNode, join));
// Node<Job> subTree = constructTree(jobDag, successorNode, successor,
// tree, forkVertices, joinVertices, sink);
// successorNode.setRightNode(subTree);
// } else {
// joinNode.setRightNode(new Node<>(joinNode, join));
// }
// } else {
// joinNode.setRightNode(new Node<>(joinNode, join));
// }
// joinNode.setLeftNode(new Node<>(joinNode, NodeType.PAR));
// continuationNode = joinNode.getLeftNode();
// } else {
// forkNode.setRightNode(new Node<>(forkNode, NodeType.PAR));
// continuationNode = forkNode.getRightNode();
// }
// Node<Job> successorParent = continuationNode;
// List<Job> successors = Graphs.successorListOf(jobDag, currentFork);
// // create leftSide of joinNode
// for (int i = 0; i < successors.size(); ++i) {
// Job succ = successors.get(i);
// Node<Job> thisNode = constructTree(jobDag, successorParent, succ, tree,
// forkVertices, joinVertices, sink);
// if (i == successors.size() - 1) {
// successorParent.setRightNode(thisNode);
// } else if (i == successors.size() - 2) {
// successorParent.setLeftNode(thisNode);
// } else {
// successorParent.setLeftNode(thisNode);
// successorParent.setRightNode(new Node<>(successorParent, NodeType.PAR));
// successorParent = successorParent.getRightNode();
// }
// }
// return forkNode;
// } else {
// return new Node<>(parent, currentFork);
// }
// }
public
static
boolean
checkNFJProperty
(
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
)
{
public
static
boolean
checkNFJProperty
(
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
)
{
LinkedList
<
Job
>
joinNodes
=
new
LinkedList
<>();
LinkedList
<
Job
>
joinNodes
=
new
LinkedList
<>();
LinkedList
<
Job
>
forkNodes
=
new
LinkedList
<>();
LinkedList
<
Job
>
forkNodes
=
new
LinkedList
<>();
...
@@ -327,43 +410,58 @@ public class DagTask implements Task {
...
@@ -327,43 +410,58 @@ public class DagTask implements Task {
return
true
;
return
true
;
}
}
for
(
Job
j
:
joinNodes
)
{
nextJoin:
for
(
Job
j
:
joinNodes
)
{
nextFork:
for
(
Job
f
:
forkNodes
)
{
for
(
Job
f
:
forkNodes
)
{
Set
<
DefaultEdge
>
edgeSet
=
jobDag
.
getAllEdges
(
f
,
j
);
Set
<
Job
>
ancestorsOfJ
=
jobDag
.
getAncestors
(
jobDag
,
j
);
Set
<
Job
>
ancesotorsOfF
=
jobDag
.
getAncestors
(
jobDag
,
f
);
for
(
DefaultEdge
e
:
edgeSet
)
{
ancesotorsOfF
.
add
(
f
);
Job
a
=
jobDag
.
getEdgeSource
(
e
);
Set
<
Job
>
inbetweenJobs
=
new
HashSet
<>(
ancestorsOfJ
);
if
(
a
!=
f
)
{
inbetweenJobs
.
removeAll
(
ancesotorsOfF
);
Set
<
Job
>
succAndPred
=
new
HashSet
<>();
if
(
inbetweenJobs
.
isEmpty
())
{
succAndPred
.
addAll
(
Graphs
.
predecessorListOf
(
jobDag
,
a
))
;
continue
;
succAndPred
.
addAll
(
Graphs
.
successorListOf
(
jobDag
,
a
));
}
for
(
Job
b
:
succAndPred
)
{
for
(
Job
a
:
inbetweenJobs
)
{
if
(!((
jobDag
.
getAncestors
(
jobDag
,
j
).
contains
(
b
)
||
b
==
j
)
List
<
Job
>
neighboursOfA
=
Graphs
.
neighborListOf
(
jobDag
,
a
);
&&
(
jobDag
.
getDescendants
(
jobDag
,
f
).
contains
(
b
)
for
(
Job
b
:
neighboursOfA
)
{
||
b
==
f
)))
{
if
((
jobDag
.
getAncestors
(
jobDag
,
j
).
contains
(
b
)
||
b
==
j
)
continue
nextFork
;
&&
(
jobDag
.
getDescendants
(
jobDag
,
f
).
contains
(
b
)
||
b
==
f
))
{
}
continue
nextJoin
;
}
}
}
}
}
}
return
true
;
}
}
return
false
;
}
}
return
fals
e
;
return
tru
e
;
}
}
private
static
Job
findJoin
(
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
,
Job
forkNode
,
private
static
Job
findJoin
(
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
,
Job
forkNode
,
Job
sink
,
List
<
Job
>
joinNodes
)
{
Job
sink
,
List
<
Job
>
joinNodes
)
{
for
(
Job
j
:
joinNodes
)
{
for
(
Job
j
:
joinNodes
)
{
final
Set
<
DefaultEdge
>
edgeSet
=
new
HashSet
<>();
Set
<
Job
>
ancestorsOfJ
=
jobDag
.
getAncestors
(
jobDag
,
j
);
AllDirectedPaths
<
Job
,
DefaultEdge
>
finder
=
new
AllDirectedPaths
<>(
jobDag
);
Set
<
Job
>
ancesotorsOfFork
=
jobDag
.
getAncestors
(
jobDag
,
forkNode
);
finder
.
getAllPaths
(
forkNode
,
j
,
true
,
null
)
ancesotorsOfFork
.
add
(
forkNode
);
.
forEach
(
g
->
edgeSet
.
addAll
(
g
.
getEdgeList
()));
Set
<
Job
>
inbetweenJobs
=
new
HashSet
<>(
ancestorsOfJ
);
Set
<
DefaultEdge
>
outgoingEdges
=
jobDag
.
outgoingEdgesOf
(
forkNode
);
inbetweenJobs
.
removeAll
(
ancesotorsOfFork
);
if
(
edgeSet
.
containsAll
(
outgoingEdges
))
{
if
(
inbetweenJobs
.
isEmpty
())
{
continue
;
}
List
<
Job
>
successorOfFork
=
Graphs
.
successorListOf
(
jobDag
,
forkNode
);
if
(
inbetweenJobs
.
containsAll
(
successorOfFork
))
{
return
j
;
return
j
;
}
}
// final Set<DefaultEdge> edgeSet = new HashSet<>();
// AllDirectedPaths<Job, DefaultEdge> finder = new AllDirectedPaths<>(jobDag);
// finder.getAllPaths(forkNode, j, true, null)
// .forEach(g -> edgeSet.addAll(g.getEdgeList()));
// Set<DefaultEdge> outgoingEdges = jobDag.outgoingEdgesOf(forkNode);
// if (edgeSet.containsAll(outgoingEdges)) {
// return j;
// }
}
}
return
sink
;
return
sink
;
...
@@ -394,63 +492,57 @@ public class DagTask implements Task {
...
@@ -394,63 +492,57 @@ public class DagTask implements Task {
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
=
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
=
new
DirectedAcyclicGraph
<>(
DefaultEdge
.
class
);
new
DirectedAcyclicGraph
<>(
DefaultEdge
.
class
);
traverseNodes
(
jobDag
,
tree
.
getRootNode
(),
TraversalOrder
.
LEFT
);
if
(
tree
.
getRootNode
()
!=
null
)
{
traverseNodes
(
jobDag
,
tree
.
getRootNode
());
}
return
jobDag
;
return
jobDag
;
}
}
private
static
Set
<
Job
>
traverseNodes
(
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
,
private
static
GraphEndPoints
traverseNodes
(
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
,
Node
<
Job
>
node
,
TraversalOrder
order
)
{
Node
<
Job
>
node
)
{
switch
(
node
.
getNodeType
())
{
switch
(
node
.
getNodeType
())
{
case
LEAF:
{
case
LEAF:
{
Job
j
=
node
.
getObject
();
Job
j
=
node
.
getObject
();
jobDag
.
addVertex
(
j
);
jobDag
.
addVertex
(
j
);
return
new
HashSet
<
Job
>(
Arrays
.
asList
(
j
));
Set
<
Job
>
endPoints
=
new
HashSet
<
Job
>(
Arrays
.
asList
(
j
));
return
new
GraphEndPoints
(
endPoints
,
endPoints
);
}
}
case
SEQ:
{
case
SEQ:
{
Set
<
Job
>
left
=
traverseNodes
(
jobDag
,
node
.
getLeftNode
(),
TraversalOrder
.
LEFT
);
GraphEndPoints
leftEndPoints
=
traverseNodes
(
jobDag
,
node
.
getLeftNode
());
Set
<
Job
>
right
=
GraphEndPoints
rightEndPoints
=
traverseNodes
(
jobDag
,
node
.
getRightNode
());
traverseNodes
(
jobDag
,
node
.
getRightNode
(),
TraversalOrder
.
RIGHT
);
for
(
Job
l
:
leftEndPoints
.
right
)
{
try
{
for
(
Job
r
:
rightEndPoints
.
left
)
{
for
(
Job
l
:
left
)
{
if
(
r
==
l
)
{
for
(
Job
r
:
right
)
{
continue
;
jobDag
.
addDagEdge
(
l
,
r
);
}
}
}
catch
(
Exception
e
)
{
}
if
(
order
==
TraversalOrder
.
LEFT
)
{
Set
<
Job
>
openEndJobs
=
new
HashSet
<>();
for
(
Job
j
:
right
)
{
if
(
jobDag
.
outDegreeOf
(
j
)
==
0
)
{
openEndJobs
.
add
(
j
);
}
}
for
(
Job
d
:
jobDag
.
getDescendants
(
jobDag
,
j
))
{
try
{
if
(
jobDag
.
outDegreeOf
(
d
)
==
0
)
{
jobDag
.
addDagEdge
(
l
,
r
);
openEndJobs
.
add
(
d
);
}
catch
(
Exception
e
)
{
}
int
test
=
3
;
}
}
}
}
return
openEndJobs
;
}
else
{
return
left
;
}
}
// return order == TraversalOrder.LEFT ? right : left; // left -> right; right
// ->
return
new
GraphEndPoints
(
leftEndPoints
.
left
,
rightEndPoints
.
right
);
}
}
case
PAR:
{
case
PAR:
{
Set
<
Job
>
left
=
traverseNodes
(
jobDag
,
node
.
getLeftNode
(),
order
);
GraphEndPoints
leftEndPoints
=
traverseNodes
(
jobDag
,
node
.
getLeftNode
());
Set
<
Job
>
right
=
traverseNodes
(
jobDag
,
node
.
getRightNode
(),
order
);
GraphEndPoints
rightEndPoints
=
traverseNodes
(
jobDag
,
node
.
getRightNode
());
return
Sets
.
newHashSet
(
Iterables
.
concat
(
left
,
right
));
Set
<
Job
>
leftEndPointJobs
=
Sets
.
newHashSet
(
Iterables
.
concat
(
leftEndPoints
.
left
,
rightEndPoints
.
left
));
Set
<
Job
>
rightEndPointJobs
=
Sets
.
newHashSet
(
Iterables
.
concat
(
leftEndPoints
.
right
,
rightEndPoints
.
right
));
return
new
GraphEndPoints
(
leftEndPointJobs
,
rightEndPointJobs
);
}
}
default
:
default
:
break
;
break
;
}
}
return
new
HashSet
<>(
);
return
new
GraphEndPoints
(
new
HashSet
<>(),
new
HashSet
<>()
);
}
}
p
rivate
class
GraphEndPoints
{
p
ublic
static
class
GraphEndPoints
{
public
Set
<
Job
>
left
;
public
Set
<
Job
>
left
;
public
Set
<
Job
>
right
;
public
Set
<
Job
>
right
;
...
...
src/main/java/mvd/jester/utils/BinaryDecompositionTree.java
View file @
24eebe3e
package
mvd
.
jester
.
utils
;
package
mvd
.
jester
.
utils
;
public
class
BinaryDecompositionTree
<
N
>
{
public
class
BinaryDecompositionTree
<
N
>
{
private
Node
<
N
>
root
;
private
Node
<
N
>
root
;
...
@@ -12,6 +13,9 @@ public class BinaryDecompositionTree<N> {
...
@@ -12,6 +13,9 @@ public class BinaryDecompositionTree<N> {
}
}
public
boolean
contains
(
N
object
)
{
public
boolean
contains
(
N
object
)
{
if
(
root
==
null
)
{
return
false
;
}
return
root
.
contains
(
object
);
return
root
.
contains
(
object
);
}
}
...
@@ -75,8 +79,9 @@ public class BinaryDecompositionTree<N> {
...
@@ -75,8 +79,9 @@ public class BinaryDecompositionTree<N> {
/**
/**
* @param leftNode the leftNode to set
* @param leftNode the leftNode to set
*/
*/
public
void
setLeftNode
(
Node
<
T
>
leftNode
)
{
public
Node
<
T
>
setLeftNode
(
Node
<
T
>
leftNode
)
{
this
.
leftNode
=
leftNode
;
this
.
leftNode
=
leftNode
;
return
this
.
leftNode
;
}
}
/**
/**
...
@@ -89,8 +94,9 @@ public class BinaryDecompositionTree<N> {
...
@@ -89,8 +94,9 @@ public class BinaryDecompositionTree<N> {
/**
/**
* @param rightNode the rightNode to set
* @param rightNode the rightNode to set
*/
*/
public
void
setRightNode
(
Node
<
T
>
rightNode
)
{
public
Node
<
T
>
setRightNode
(
Node
<
T
>
rightNode
)
{
this
.
rightNode
=
rightNode
;
this
.
rightNode
=
rightNode
;
return
this
.
rightNode
;
}
}
/**
/**
...
...
src/test/java/mvd/jester/model/TestDagUtils.java
View file @
24eebe3e
package
mvd
.
jester
.
model
;
package
mvd
.
jester
.
model
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertTrue
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertTrue
;
import
org.jgrapht.Graphs
;
import
org.jgrapht.experimental.dag.DirectedAcyclicGraph
;
import
org.jgrapht.experimental.dag.DirectedAcyclicGraph
;
import
org.jgrapht.graph.DefaultEdge
;
import
org.jgrapht.graph.DefaultEdge
;
import
org.junit.jupiter.api.DisplayName
;
import
org.junit.jupiter.api.DisplayName
;
...
@@ -12,20 +13,6 @@ import mvd.jester.utils.BinaryDecompositionTree;
...
@@ -12,20 +13,6 @@ import mvd.jester.utils.BinaryDecompositionTree;
public
class
TestDagUtils
{
public
class
TestDagUtils
{
@Test
@Test
@DisplayName
(
"Test if a NFJ Graph is created correctly."
)
public
void
checkNFJCreation
()
{
for
(
int
i
=
0
;
i
<
100
;
++
i
)
{
DagTaskBuilder
builder
=
new
DagTaskBuilder
();
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
=
builder
.
generateTask
().
getJobDag
();
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
modifiedJobDag
=
DagUtils
.
createNFJGraph
(
jobDag
);
assertTrue
(
DagUtils
.
checkNFJProperty
(
modifiedJobDag
));
}
}
@Test
@DisplayName
(
"Test if dynamic segments are constructed correctly."
)
@DisplayName
(
"Test if dynamic segments are constructed correctly."
)
public
void
checkPathLength
()
{
public
void
checkPathLength
()
{
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
=
createJobDag
();
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
=
createJobDag
();
...
@@ -45,15 +32,73 @@ public class TestDagUtils {
...
@@ -45,15 +32,73 @@ public class TestDagUtils {
@Test
@Test
@DisplayName
(
"Check if NFJ DAGs are created correctly."
)
void
checkNfjDagCreation
()
{
for
(
int
i
=
0
;
i
<
100
;
++
i
)
{
DagTaskBuilder
b
=
new
DagTaskBuilder
();
DagTask
t
=
b
.
generateTask
();
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
nfjDag
=
DagUtils
.
createNFJGraph
(
t
.
getJobDag
());
assertTrue
(
DagUtils
.
checkNFJProperty
(
nfjDag
));
}
}
@Test
@DisplayName
(
"Check if Decomposition Tree is created correctly for NFJ Dag."
)
@DisplayName
(
"Check if Decomposition Tree is created correctly for NFJ Dag."
)
void
checkDecompositionTreeCreation
()
{
void
checkDecompositionTreeCreation
()
{
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
=
createJobDag
();
for
(
int
i
=
0
;
i
<
100
;
++
i
)
{
DagTaskBuilder
b
=
new
DagTaskBuilder
();
BinaryDecompositionTree
<
Job
>
tree
=
DagUtils
.
createDecompositionTree
(
jobDag
);
DagTask
t
=
b
.
generateTask
();
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDagFromTree
=
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDag
=
t
.
getJobDag
();
DagUtils
.
createNFJfromDecompositionTree
(
tree
);
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
nfjJobDag
=
DagUtils
.
createNFJGraph
(
jobDag
);
BinaryDecompositionTree
<
Job
>
tree
=
DagUtils
.
createDecompositionTree
(
nfjJobDag
);
DirectedAcyclicGraph
<
Job
,
DefaultEdge
>
jobDagFromTree
=
DagUtils
.
createNFJfromDecompositionTree
(
tree
);
assertTrue
(
jobDag
.
vertexSet
().
equals
(
nfjJobDag
.
vertexSet
()));
assertTrue
(
jobDag
.
vertexSet
().
equals
(
jobDagFromTree
.
vertexSet
()));
assertTrue
(
jobDagFromTree
.
edgeSet
().
size
()
==
nfjJobDag
.
edgeSet
().
size
());
for
(
DefaultEdge
e
:
nfjJobDag
.
edgeSet
())
{
Job
target
=
nfjJobDag
.
getEdgeTarget
(
e
);
Job
source
=
nfjJobDag
.
getEdgeSource
(
e
);
assertTrue
(
jobDagFromTree
.
containsEdge
(
source
,
target
));
}
for
(
Job
j
:
nfjJobDag
)
{
for
(
Job
n
:
nfjJobDag
)
{
if
(
n
==
j
)
{
continue
;
}
if
(
nfjJobDag
.
containsEdge
(
n
,
j
))
{
assertTrue
(
jobDagFromTree
.
containsEdge
(
n
,
j
));
}
}
assertTrue
(
nfjJobDag
.
inDegreeOf
(
j
)
==
jobDagFromTree
.
inDegreeOf
(
j
));
assertTrue
(
nfjJobDag
.
outDegreeOf
(
j
)
==
jobDagFromTree
.
outDegreeOf
(
j
));
for
(
Job
p
:
Graphs
.
predecessorListOf
(
nfjJobDag
,
j
))
{
assertTrue
(
Graphs
.
predecessorListOf
(
jobDagFromTree
,
j
).
contains
(
p
));
}
for
(
Job
s
:
Graphs
.
successorListOf
(
jobDagFromTree
,
j
))
{
assertTrue
(
Graphs
.
successorListOf
(
jobDagFromTree
,
j
).
contains
(
s
));
}
for
(
Job
a
:
nfjJobDag
.
getAncestors
(
nfjJobDag
,
j
))
{
assertTrue
(
jobDagFromTree
.
getAncestors
(
jobDagFromTree
,
j
).
contains
(
a
));
}
for
(
Job
d
:
nfjJobDag
.
getDescendants
(
nfjJobDag
,
j
))
{
assertTrue
(
jobDagFromTree
.
getDescendants
(
jobDagFromTree
,
j
).
contains
(
d
));
}
}
assertTrue
(
jobDag
.
equals
(
jobDagFromTree
));
}
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment