-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmddPrecedence.cpp
More file actions
82 lines (73 loc) · 3.12 KB
/
mddPrecedence.cpp
File metadata and controls
82 lines (73 loc) · 3.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
/*
* mini-cp is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License v3
* as published by the Free Software Foundation.
*
* mini-cp is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with mini-cp. If not, see http://www.gnu.org/licenses/lgpl-3.0.en.html
*
* Copyright (c) 2018. by Laurent Michel, Pierre Schaus, Pascal Van Hentenryck
*/
#include "mddConstraints.hpp"
#include "mddnode.hpp"
#include <limits.h>
namespace Factory {
MDDCstrDesc::Ptr precedenceMDD(MDD::Ptr m,const Factory::Veci& vars, int before, int after)
{
MDDSpec& spec = m->getSpec();
auto desc = spec.makeConstraintDescriptor(vars,"precedenceMDD");
const auto visitedBefore = spec.downIntState(desc,0,1,MaxFun);
spec.arcExist(desc,[=](const auto& parent,const auto& child,const auto& x,int v) {
if (v == after) return parent.down[visitedBefore] > 0;
return true;
});
spec.transitionDown(desc,visitedBefore,{visitedBefore},{},[=](auto& out,const auto& parent,const auto&,const auto& val) {
bool hasBefore = val.contains(before);
out[visitedBefore] = parent.down[visitedBefore] || hasBefore;
});
return desc;
}
MDDCstrDesc::Ptr requiredPrecedenceMDD(MDD::Ptr m,const Factory::Veci& vars, int before, int after, MDDOpts opts)
{
MDDSpec& spec = m->getSpec();
auto desc = spec.makeConstraintDescriptor(vars,"requiredPrecedenceMDD");
const auto visitedBefore = spec.downIntState(desc,0,1,MaxFun,opts.cstrP);
const auto visitedAfter = spec.upIntState(desc,0,1,MaxFun);
spec.arcExist(desc,[before,after,visitedBefore,visitedAfter](const auto& parent,const auto& child,const auto& x,int v) {
if (v == after && !parent.down[visitedBefore]) return false;
if (!child.up.unused() && v == before && !child.up[visitedAfter]) return false;
return true;
});
spec.transitionDown(desc,visitedBefore,{visitedBefore},{},[=](auto& out,const auto& parent,const auto&,const auto& val) {
bool hasBefore = val.contains(before);
out[visitedBefore] = parent.down[visitedBefore] || hasBefore;
});
spec.transitionUp(desc,visitedAfter,{visitedAfter},{},[=](auto& out,const auto& child,const auto&,const auto& val) {
bool hasAfter = val.contains(after);
out[visitedAfter] = child.up[visitedAfter] || hasAfter;
});
switch (opts.candP) {
case 1:
spec.candidateByLargest([visitedBefore](const auto& state, void* arcs, int numArcs) {
return state[visitedBefore]*25;
});
break;
default:
break;
}
switch (opts.appxEQMode) {
case 1:
spec.equivalenceClassValue([=](const auto& down, const auto& up){
return down[visitedBefore];
}, opts.cstrP);
break;
default:
break;
}
return desc;
}
}