From c1f185fd8fc2c3dfc123d9271726c588963c7c01 Mon Sep 17 00:00:00 2001 From: Kristóf Marussy Date: Mon, 8 Apr 2019 00:58:00 +0200 Subject: Objective POC implementation --- .../AbstractThreeValuedObjective.xtend | 102 +++++++++++++++++++++ .../optimization/IThreeValuedObjective.xtend | 10 ++ .../reasoner/optimization/ObjectiveKind.java | 36 ++++++++ .../optimization/ThreeValuedCostObjective.xtend | 86 +++++++++++++++++ 4 files changed, 234 insertions(+) create mode 100644 Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/AbstractThreeValuedObjective.xtend create mode 100644 Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/IThreeValuedObjective.xtend create mode 100644 Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ObjectiveKind.java create mode 100644 Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization/ThreeValuedCostObjective.xtend (limited to 'Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/optimization') 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 @@ +package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization + +import java.util.Comparator +import org.eclipse.viatra.dse.base.ThreadContext +import org.eclipse.xtend.lib.annotations.Accessors +import org.eclipse.xtend.lib.annotations.Data + +abstract class ObjectiveThreshold { + public static val NO_THRESHOLD = new hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.ObjectiveThreshold { + override isHard() { + false + } + + override satisfiesThreshold(double cost, Comparator comparator) { + true + } + } + + private new() { + } + + def boolean isHard() { + true + } + + def boolean satisfiesThreshold(double cost, Comparator comparator) + + @Data + static class Exclusive extends ObjectiveThreshold { + val double threshold + + override satisfiesThreshold(double cost, Comparator comparator) { + comparator.compare(threshold, cost) > 0 + } + } + + @Data + static class Inclusive extends ObjectiveThreshold { + val double threshold + + override satisfiesThreshold(double cost, Comparator comparator) { + comparator.compare(threshold, cost) >= 0 + } + } +} + +abstract class AbstractThreeValuedObjective implements IThreeValuedObjective { + @Accessors val String name + @Accessors ObjectiveKind kind + @Accessors ObjectiveThreshold threshold + @Accessors int level + + protected new(String name, ObjectiveKind kind, ObjectiveThreshold threshold, int level) { + this.name = name + this.kind = kind + this.threshold = threshold + this.level = level + } + + abstract def double getLowestPossibleFitness(ThreadContext threadContext) + + abstract def double getHighestPossibleFitness(ThreadContext threadContext) + + override getWorstPossibleFitness(ThreadContext threadContext) { + switch (kind) { + case LOWER_IS_BETTER: + getHighestPossibleFitness(threadContext) + case HIGHER_IS_BETTER: + getLowestPossibleFitness(threadContext) + default: + throw new IllegalStateException("Unknown three valued objective kind: " + kind) + } + } + + override getBestPossibleFitness(ThreadContext threadContext) { + switch (kind) { + case LOWER_IS_BETTER: + getLowestPossibleFitness(threadContext) + case HIGHER_IS_BETTER: + getHighestPossibleFitness(threadContext) + default: + throw new IllegalStateException("Unknown three valued objective kind: " + kind) + } + } + + override isHardObjective() { + threshold.hard + } + + override satisifiesHardObjective(Double fitness) { + threshold.satisfiesThreshold(fitness, comparator) + } + + override getComparator() { + kind.comparator + } + + override setComparator(Comparator comparator) { + kind = ObjectiveKind.fromComparator(comparator) + } + +} 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 @@ +package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization + +import org.eclipse.viatra.dse.base.ThreadContext +import org.eclipse.viatra.dse.objectives.IObjective + +interface IThreeValuedObjective extends IObjective { + def Double getWorstPossibleFitness(ThreadContext threadContext) + + def Double getBestPossibleFitness(ThreadContext threadContext) +} 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 @@ +package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization; + +import java.util.Comparator; + +import org.eclipse.viatra.dse.objectives.Comparators; + +public enum ObjectiveKind { + LOWER_IS_BETTER { + + @Override + public Comparator getComparator() { + return Comparators.LOWER_IS_BETTER; + } + + }, + HIGHER_IS_BETTER { + + @Override + public Comparator getComparator() { + return Comparators.HIGHER_IS_BETTER; + } + + }; + + public abstract Comparator getComparator(); + + public static ObjectiveKind fromComparator(Comparator comparator) { + if (Comparators.LOWER_IS_BETTER.equals(comparator)) { + return ObjectiveKind.LOWER_IS_BETTER; + } else if (Comparators.HIGHER_IS_BETTER.equals(comparator)) { + return ObjectiveKind.HIGHER_IS_BETTER; + } else { + throw new IllegalStateException("Only LOWER_IS_BETTER and HIGHER_IS_BETTER comparators are supported."); + } + } +} 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..362ef4a3 --- /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,86 @@ +package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization + +import com.google.common.collect.ImmutableList +import java.util.Collection +import org.eclipse.viatra.dse.base.ThreadContext +import org.eclipse.viatra.query.runtime.api.IPatternMatch +import org.eclipse.viatra.query.runtime.api.IQuerySpecification +import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher +import org.eclipse.xtend.lib.annotations.Data + +@Data +class ThreeValuedCostElement { + val IQuerySpecification> currentMatchQuery + val IQuerySpecification> mayMatchQuery + val IQuerySpecification> mustMatchQuery + val int weight +} + +class ThreeValuedCostObjective extends AbstractThreeValuedObjective { + val Collection costElements + Collection matchers + + new(String name, Collection costElements, ObjectiveKind kind, ObjectiveThreshold threshold, + int level) { + super(name, kind, threshold, level) + this.costElements = costElements + } + + override createNew() { + new ThreeValuedCostObjective(name, costElements, kind, threshold, level) + } + + override init(ThreadContext context) { + val queryEngine = context.queryEngine + matchers = ImmutableList.copyOf(costElements.map [ element | + new CostElementMatchers( + queryEngine.getMatcher(element.currentMatchQuery), + queryEngine.getMatcher(element.mayMatchQuery), + queryEngine.getMatcher(element.mustMatchQuery), + element.weight + ) + ]) + } + + override getFitness(ThreadContext context) { + var int cost = 0 + for (matcher : matchers) { + cost += matcher.weight * matcher.currentMatcher.countMatches + } + cost as double + } + + override getLowestPossibleFitness(ThreadContext threadContext) { + var int cost = 0 + for (matcher : matchers) { + if (matcher.weight >= 0) { + cost += matcher.weight * matcher.mustMatcher.countMatches + } else if (matcher.mayMatcher.countMatches > 0) { + // TODO Count may matches. + return Double.NEGATIVE_INFINITY + } + } + cost as double + } + + override getHighestPossibleFitness(ThreadContext threadContext) { + var int cost = 0 + for (matcher : matchers) { + if (matcher.weight <= 0) { + cost += matcher.weight * matcher.mustMatcher.countMatches + } else if (matcher.mayMatcher.countMatches > 0) { + // TODO Count may matches. + return Double.POSITIVE_INFINITY + } + } + cost as double + } + + @Data + private static class CostElementMatchers { + val ViatraQueryMatcher currentMatcher + val ViatraQueryMatcher mayMatcher + val ViatraQueryMatcher mustMatcher + val int weight + } +} -- cgit v1.2.3-54-g00ecf