diff options
Diffstat (limited to 'Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization')
4 files changed, 233 insertions, 0 deletions
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/AbstractThreeValuedObjective.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/AbstractThreeValuedObjective.xtend new file mode 100644 index 00000000..241bef2a --- /dev/null +++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/AbstractThreeValuedObjective.xtend | |||
@@ -0,0 +1,102 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization | ||
2 | |||
3 | import java.util.Comparator | ||
4 | import org.eclipse.viatra.dse.base.ThreadContext | ||
5 | import org.eclipse.xtend.lib.annotations.Accessors | ||
6 | import org.eclipse.xtend.lib.annotations.Data | ||
7 | |||
8 | abstract class ObjectiveThreshold { | ||
9 | public static val NO_THRESHOLD = new hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.ObjectiveThreshold { | ||
10 | override isHard() { | ||
11 | false | ||
12 | } | ||
13 | |||
14 | override satisfiesThreshold(double cost, Comparator<Double> comparator) { | ||
15 | true | ||
16 | } | ||
17 | } | ||
18 | |||
19 | private new() { | ||
20 | } | ||
21 | |||
22 | def boolean isHard() { | ||
23 | true | ||
24 | } | ||
25 | |||
26 | def boolean satisfiesThreshold(double cost, Comparator<Double> comparator) | ||
27 | |||
28 | @Data | ||
29 | static class Exclusive extends ObjectiveThreshold { | ||
30 | val double threshold | ||
31 | |||
32 | override satisfiesThreshold(double cost, Comparator<Double> comparator) { | ||
33 | comparator.compare(threshold, cost) > 0 | ||
34 | } | ||
35 | } | ||
36 | |||
37 | @Data | ||
38 | static class Inclusive extends ObjectiveThreshold { | ||
39 | val double threshold | ||
40 | |||
41 | override satisfiesThreshold(double cost, Comparator<Double> comparator) { | ||
42 | comparator.compare(threshold, cost) >= 0 | ||
43 | } | ||
44 | } | ||
45 | } | ||
46 | |||
47 | abstract class AbstractThreeValuedObjective implements IThreeValuedObjective { | ||
48 | @Accessors val String name | ||
49 | @Accessors ObjectiveKind kind | ||
50 | @Accessors ObjectiveThreshold threshold | ||
51 | @Accessors int level | ||
52 | |||
53 | protected new(String name, ObjectiveKind kind, ObjectiveThreshold threshold, int level) { | ||
54 | this.name = name | ||
55 | this.kind = kind | ||
56 | this.threshold = threshold | ||
57 | this.level = level | ||
58 | } | ||
59 | |||
60 | abstract def double getLowestPossibleFitness(ThreadContext threadContext) | ||
61 | |||
62 | abstract def double getHighestPossibleFitness(ThreadContext threadContext) | ||
63 | |||
64 | override getWorstPossibleFitness(ThreadContext threadContext) { | ||
65 | switch (kind) { | ||
66 | case LOWER_IS_BETTER: | ||
67 | getHighestPossibleFitness(threadContext) | ||
68 | case HIGHER_IS_BETTER: | ||
69 | getLowestPossibleFitness(threadContext) | ||
70 | default: | ||
71 | throw new IllegalStateException("Unknown three valued objective kind: " + kind) | ||
72 | } | ||
73 | } | ||
74 | |||
75 | override getBestPossibleFitness(ThreadContext threadContext) { | ||
76 | switch (kind) { | ||
77 | case LOWER_IS_BETTER: | ||
78 | getLowestPossibleFitness(threadContext) | ||
79 | case HIGHER_IS_BETTER: | ||
80 | getHighestPossibleFitness(threadContext) | ||
81 | default: | ||
82 | throw new IllegalStateException("Unknown three valued objective kind: " + kind) | ||
83 | } | ||
84 | } | ||
85 | |||
86 | override isHardObjective() { | ||
87 | threshold.hard | ||
88 | } | ||
89 | |||
90 | override satisifiesHardObjective(Double fitness) { | ||
91 | threshold.satisfiesThreshold(fitness, comparator) | ||
92 | } | ||
93 | |||
94 | override getComparator() { | ||
95 | kind.comparator | ||
96 | } | ||
97 | |||
98 | override setComparator(Comparator<Double> comparator) { | ||
99 | kind = ObjectiveKind.fromComparator(comparator) | ||
100 | } | ||
101 | |||
102 | } | ||
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/IThreeValuedObjective.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/IThreeValuedObjective.xtend new file mode 100644 index 00000000..4a870a3e --- /dev/null +++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/IThreeValuedObjective.xtend | |||
@@ -0,0 +1,10 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization | ||
2 | |||
3 | import org.eclipse.viatra.dse.base.ThreadContext | ||
4 | import org.eclipse.viatra.dse.objectives.IObjective | ||
5 | |||
6 | interface IThreeValuedObjective extends IObjective { | ||
7 | def Double getWorstPossibleFitness(ThreadContext threadContext) | ||
8 | |||
9 | def Double getBestPossibleFitness(ThreadContext threadContext) | ||
10 | } | ||
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ObjectiveKind.java b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ObjectiveKind.java new file mode 100644 index 00000000..f65428fe --- /dev/null +++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ObjectiveKind.java | |||
@@ -0,0 +1,36 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization; | ||
2 | |||
3 | import java.util.Comparator; | ||
4 | |||
5 | import org.eclipse.viatra.dse.objectives.Comparators; | ||
6 | |||
7 | public enum ObjectiveKind { | ||
8 | LOWER_IS_BETTER { | ||
9 | |||
10 | @Override | ||
11 | public Comparator<Double> getComparator() { | ||
12 | return Comparators.LOWER_IS_BETTER; | ||
13 | } | ||
14 | |||
15 | }, | ||
16 | HIGHER_IS_BETTER { | ||
17 | |||
18 | @Override | ||
19 | public Comparator<Double> getComparator() { | ||
20 | return Comparators.HIGHER_IS_BETTER; | ||
21 | } | ||
22 | |||
23 | }; | ||
24 | |||
25 | public abstract Comparator<Double> getComparator(); | ||
26 | |||
27 | public static ObjectiveKind fromComparator(Comparator<Double> comparator) { | ||
28 | if (Comparators.LOWER_IS_BETTER.equals(comparator)) { | ||
29 | return ObjectiveKind.LOWER_IS_BETTER; | ||
30 | } else if (Comparators.HIGHER_IS_BETTER.equals(comparator)) { | ||
31 | return ObjectiveKind.HIGHER_IS_BETTER; | ||
32 | } else { | ||
33 | throw new IllegalStateException("Only LOWER_IS_BETTER and HIGHER_IS_BETTER comparators are supported."); | ||
34 | } | ||
35 | } | ||
36 | } | ||
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ThreeValuedCostObjective.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ThreeValuedCostObjective.xtend new file mode 100644 index 00000000..e2585c83 --- /dev/null +++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ThreeValuedCostObjective.xtend | |||
@@ -0,0 +1,85 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization | ||
2 | |||
3 | import com.google.common.collect.ImmutableList | ||
4 | import java.util.Collection | ||
5 | import org.eclipse.viatra.dse.base.ThreadContext | ||
6 | import org.eclipse.viatra.query.runtime.api.IPatternMatch | ||
7 | import org.eclipse.viatra.query.runtime.api.IQuerySpecification | ||
8 | import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher | ||
9 | import org.eclipse.xtend.lib.annotations.Data | ||
10 | |||
11 | @Data | ||
12 | class ThreeValuedCostElement { | ||
13 | val IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> currentMatchQuery | ||
14 | val IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> mayMatchQuery | ||
15 | val IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> mustMatchQuery | ||
16 | val int weight | ||
17 | } | ||
18 | |||
19 | class ThreeValuedCostObjective extends AbstractThreeValuedObjective { | ||
20 | val Collection<ThreeValuedCostElement> costElements | ||
21 | Collection<CostElementMatchers> matchers | ||
22 | |||
23 | new(String name, Collection<ThreeValuedCostElement> costElements, ObjectiveKind kind, ObjectiveThreshold threshold, | ||
24 | int level) { | ||
25 | super(name, kind, threshold, level) | ||
26 | this.costElements = costElements | ||
27 | } | ||
28 | |||
29 | override createNew() { | ||
30 | new ThreeValuedCostObjective(name, costElements, kind, threshold, level) | ||
31 | } | ||
32 | |||
33 | override init(ThreadContext context) { | ||
34 | val queryEngine = context.queryEngine | ||
35 | matchers = ImmutableList.copyOf(costElements.map [ element | | ||
36 | new CostElementMatchers( | ||
37 | queryEngine.getMatcher(element.currentMatchQuery), | ||
38 | queryEngine.getMatcher(element.mayMatchQuery), | ||
39 | queryEngine.getMatcher(element.mustMatchQuery), | ||
40 | element.weight | ||
41 | ) | ||
42 | ]) | ||
43 | } | ||
44 | |||
45 | override getFitness(ThreadContext context) { | ||
46 | var int cost = 0 | ||
47 | for (matcher : matchers) { | ||
48 | cost += matcher.weight * matcher.currentMatcher.countMatches | ||
49 | } | ||
50 | cost as double | ||
51 | } | ||
52 | |||
53 | override getLowestPossibleFitness(ThreadContext threadContext) { | ||
54 | var int cost = 0 | ||
55 | for (matcher : matchers) { | ||
56 | if (matcher.weight >= 0) { | ||
57 | cost += matcher.weight * matcher.mustMatcher.countMatches | ||
58 | } else if (matcher.mayMatcher.countMatches > 0) { | ||
59 | // TODO Count may matches. | ||
60 | return Double.NEGATIVE_INFINITY | ||
61 | } | ||
62 | } | ||
63 | cost as double | ||
64 | } | ||
65 | |||
66 | override getHighestPossibleFitness(ThreadContext threadContext) { | ||
67 | var int cost = 0 | ||
68 | for (matcher : matchers) { | ||
69 | if (matcher.weight <= 0) { | ||
70 | cost += matcher.weight * matcher.mustMatcher.countMatches | ||
71 | } else if (matcher.mayMatcher.countMatches > 0) { | ||
72 | return Double.POSITIVE_INFINITY | ||
73 | } | ||
74 | } | ||
75 | cost as double | ||
76 | } | ||
77 | |||
78 | @Data | ||
79 | private static class CostElementMatchers { | ||
80 | val ViatraQueryMatcher<? extends IPatternMatch> currentMatcher | ||
81 | val ViatraQueryMatcher<? extends IPatternMatch> mayMatcher | ||
82 | val ViatraQueryMatcher<? extends IPatternMatch> mustMatcher | ||
83 | val int weight | ||
84 | } | ||
85 | } | ||