Commit 94e9eaae authored by Johannes Mey's avatar Johannes Mey
Browse files

initial commit of genetic solver (not working yet)

parent 26fcc753
......@@ -37,4 +37,153 @@ aspect Helpers {
return assignment;
}
}
\ No newline at end of file
public Solution Root.createRandomSolution(java.util.Random random) {
Solution solution = new Solution();
// create a resource bucket
java.util.List<Resource> resourceList = populateResourceList(this.getHardwareModel().getResourceList(), new ArrayList<>());
for (Request request : getRequestList()) {
solution.addAssignment(createRandomAssignment(true, request, request.getTarget().getRef(),resourceList, random));
}
return solution;
}
private java.util.List<Resource> Root.populateResourceList(List<Resource> resourceList, java.util.List<Resource> list) {
for (Resource resource : resourceList) {
if (resource.getType().getRef().getContainer()) {
list.add(resource);
}
populateResourceList(resource.getSubResourceList(), list);
}
return list;
}
public Assignment Root.createRandomAssignment(boolean isTopLevel, Request request, Component component, java.util.List<Resource> resourceList, java.util.Random random) {
Implementation implementation = component.getImplementation(random.nextInt(component.getNumImplementation()));
Assignment assignment = new Assignment();
assignment.setImplementation(implementation);
assignment.setRequest(request);
assignment.setTopLevel(isTopLevel);
// assign dependent software components
for (ComponentRequirement componentRequirement : implementation.getComponentRequirementList()) {
Component requiredComponent = componentRequirement.getComponentRef().getRef();
for (Instance componentRequirementInstance : componentRequirement.getInstanceList()) {
ComponentMapping mapping = new ComponentMapping();
mapping.setInstance(componentRequirementInstance);
mapping.setAssignment(createRandomAssignment(false, request, requiredComponent, resourceList, random));
assignment.addComponentMapping(mapping);
}
}
// assign resources
ResourceRequirement resourceRequirement = implementation.getResourceRequirement();
ResourceType requiredResourceType = resourceRequirement.getResourceTypeRef().getRef();
for (Instance instance : resourceRequirement.getInstanceList()) {
ResourceMapping mapping = new ResourceMapping();
mapping.setInstance(instance);
Resource chosenResource;
int resourceNumber;
do {
resourceNumber = random.nextInt(resourceList.size());
chosenResource = resourceList.get(resourceNumber);
} while (chosenResource.getType().getRef() != requiredResourceType);
mapping.setResource(resourceList.remove(resourceNumber));
assignment.setResourceMapping(mapping);
}
return assignment;
}
public java.util.List<Resource> Root.unassignedResources(Solution solution) {
java.util.List<Resource> assignedResources = solution.assignedResources();
java.util.List<Resource> allResources = getHardwareModel().allContainers();
allResources.removeAll(assignedResources);
return allResources;
}
public java.util.List<Resource> HardwareModel.allContainers() {
java.util.List<Resource> allContainers = new java.util.ArrayList<>();
for (Resource resource : getResourceList()) {
allContainers.addAll(resource.allContainers());
}
return allContainers;
}
public java.util.List<Resource> Resource.allContainers() {
java.util.List<Resource> allContainers = null;
for (Resource subResource : getSubResourceList()) {
java.util.List<Resource> subResourceContainers = subResource.allContainers();
if (!subResourceContainers.isEmpty()) {
if (allContainers == null) {
allContainers = new ArrayList<>(subResourceContainers);
} else {
allContainers.addAll(subResourceContainers);
}
}
}
if (this.getType().getRef().getContainer()) {
if (allContainers == null || allContainers.isEmpty()) {
return java.util.Collections.singletonList(this);
} else {
allContainers.add(this);
}
}
return allContainers == null ? java.util.Collections.emptyList() : allContainers;
}
public java.util.List<Resource> Assignment.assignedResources() {
java.util.List<Resource> assignedResources = new java.util.ArrayList<>();
if (this.getResource() != null) {
assignedResources.add(this.getResource());
}
for (ComponentMapping mapping : this.getComponentMappingList()) {
assignedResources.addAll(mapping.getAssignment().assignedResources());
}
return assignedResources;
}
public java.util.List<Resource> Solution.assignedResources() {
java.util.List<Resource> assignedResources = new java.util.ArrayList<>();
for (Assignment assignment : this.getAssignmentList()) {
assignedResources.addAll(assignment.assignedResources());
}
return assignedResources;
}
inh Solution Assignment.containingSolution();
eq Solution.getAssignment().containingSolution() = this;
public boolean List.contains(ASTNode node) {
for (Object o : astChildren()) {
if (node == o) {
return true;
}
}
return false;
}
}
aspect Checking {
syn int Solution.evaluateValidity() {
int faults = evaluateSoftwareCompletenessa();
Set<Request> requestSet = new HashSet<>();
Set<Resource> resourceSet = new HashSet<>();
// check assignments
Iterator<Assignment> assignmentIterator = this.assignmentIterator();
while (assignmentIterator.hasNext()) {
Assignment assignment = assignmentIterator.next();
faults += assignment.evaluateValidity();
if (assignment.getImplementation().containingComponent() ==
assignment.getRequest().getTarget().getRef()) {
requestSet.add(assignment.getRequest());
}
if (resourceSet.contains(assignment.getResource())) {
// double usage of resources
faults++;
}
resourceSet.add(assignment.getResource());
}
return faults;
}
syn int Assignment.evaluateValidity() {
int faults = 0;
if (getResource() == null) {
faults++;
}
for (Clause clause : getImplementation().requirementClauses()) {
if (!clause.checkUsing(this)) {
faults++;
}
}
// if this is a "top-level" assignment, check the properties from the request
if (this.getRequest().getTarget().getRef().equals(getImplementation().containingComponent())) {
for (Clause clause : getRequest().getConstraintList()) {
if (clause.isRequiringClause() && !clause.checkUsing(this)) {
faults++;
}
}
}
return faults;
}
syn int Solution.evaluateSoftwareValidity() {
int faults = evaluateSoftwareCompletenessa();
// check assignments
Iterator<Assignment> assignmentIterator = this.assignmentIterator();
while (assignmentIterator.hasNext()) {
faults += assignmentIterator.next().evaluateSoftwareValidity();
}
return faults;
}
syn int Assignment.evaluateSoftwareValidity() {
int faults = 0;
for (Clause clause : getImplementation().requirementClauses()) {
if (clause.getDesignator().isSoftwareDesignator()) {
if (!clause.checkUsing(this)) {
faults++;
}
}
}
// if this is a "top-level" assignment, check the properties from the request
if (this.getRequest().getTarget().getRef().equals(getImplementation().containingComponent())) {
for (Clause clause : getRequest().getConstraintList()) {
if (clause.isRequiringClause() && clause.getDesignator().isSoftwareDesignator()) {
if (!clause.checkUsing(this)) {
faults++;
}
}
}
}
return faults;
}
syn int Solution.evaluateSoftwareCompletenessa() {
int faults = 0;
java.util.List<Component> targets = new java.util.ArrayList<>();
for (Request request : this.getModel().getRequestList()) {
targets.add(request.getTarget().getRef());
}
for (Assignment assignment : getAssignmentList()) {
faults += assignment.evaluateSoftwareCompletenessa();
targets.remove(assignment.getImplementation().containingComponent());
}
for (Component target : targets) {
// System.out.println("[SOFTWARE SOLUTION STRUCTURAL CHECK] request for component " + target.getName().getName() + " has no assignment.");
}
return faults + targets.size();
}
syn int Assignment.evaluateSoftwareCompletenessa() {
int faults = 0;
if (getRequest() == null) {
faults++;
// System.out.println("[SOFTWARE SOLUTION STRUCTURAL CHECK] assignment " + this.name() + " has no request.");
}
if (getImplementation() == null) {
faults++;
// System.out.println("[SOFTWARE SOLUTION STRUCTURAL CHECK] assignment " + this.name() + " has no implementation.");
}
for (ComponentRequirement requirement : getImplementation().getComponentRequirementList()) {
for (Instance instance : requirement.getInstanceList()) {
boolean foundInstance = false;
for (ComponentMapping mapping : this.getComponentMappingList()) {
if (mapping.getInstance() == instance) {
if (foundInstance == true) {
faults++;
// System.out.println("[SOFTWARE SOLUTION STRUCTURAL CHECK] instance " + instance.getName().getName() + " is contained twice in the component mapping.");
}
foundInstance = true;
}
}
if (!foundInstance) {
faults++;
// System.out.println("[SOFTWARE SOLUTION STRUCTURAL CHECK] instance " + instance.getName().getName() + " is not contained in the assignment.");
}
}
}
return faults;
}
}
......@@ -15,6 +15,7 @@ dependencies {
compile project(':jastadd-mquat-solver-aco')
compile project(':jastadd-mquat-solver-ilp')
compile project(':jastadd-mquat-solver-emfer')
compile project(':jastadd-mquat-solver-genetic')
compile project(':jastadd-mquat-solver-simple')
compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.8.8.1'
compile group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.10.0'
......
......@@ -3,6 +3,7 @@ package de.tudresden.inf.st.mquat.benchmark;
import de.tudresden.inf.st.mquat.solving.BenchmarkableSolver;
import de.tudresden.inf.st.mquat.solving.ilp.ILPDirectSolver;
import de.tudresden.inf.st.mquat.solving.ilp.ILPExternalSolver;
import de.tudresden.inf.st.mquat.solving.genetic.GeneticSolver;
import de.tudresden.inf.st.mquat.solving.simple.SimpleSolver;
import ir.ac.ui.eng.ACOSolver;
import uniks.EMFeRSolver;
......@@ -28,7 +29,8 @@ public class SolverFactory {
new EMFeRSolver(),
new ILPExternalSolver(),
new ILPDirectSolver(),
new SimpleSolver()
new SimpleSolver(),
new GeneticSolver()
).collect(Collectors.toMap(BenchmarkableSolver::getName, Function.identity()));
}
return availableSolvers;
......
build/
log/
\ No newline at end of file
apply plugin: 'java'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
compile group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.10.0'
compile group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.10.0'
compile project(':jastadd-mquat-base')
compile project(':jastadd-mquat-solver')
testCompile group: 'junit', name: 'junit', version: '4.12'
testCompile project(path: ':jastadd-mquat-solver', configuration: 'testArtifacts')
compile group: 'org.opt4j', name: 'opt4j-core', version: '3.1.4'
compile group: 'org.opt4j', name: 'opt4j-optimizers', version: '3.1.4'
compile group: 'org.opt4j', name: 'opt4j-operators', version: '3.1.4'
compile group: 'org.opt4j', name: 'opt4j-satdecoding', version: '3.1.4'
compile group: 'org.opt4j', name: 'opt4j-viewer', version: '3.1.4'
compile group: 'org.opt4j', name: 'opt4j-benchmarks', version: '3.1.4'
}
package de.tudresden.inf.st.mquat.solving.genetic;
import de.tudresden.inf.st.mquat.jastadd.model.Root;
import de.tudresden.inf.st.mquat.jastadd.model.Solution;
import de.tudresden.inf.st.mquat.solving.BenchmarkableSolver;
import de.tudresden.inf.st.mquat.solving.Solver;
import de.tudresden.inf.st.mquat.solving.SolvingException;
import de.tudresden.inf.st.mquat.utils.StopWatch;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
public class GeneticSolver implements BenchmarkableSolver {
private static final Logger logger = LogManager.getLogger(GeneticSolver.class);
private Solution lastSolution;
private long lastSolvingTime;
private int solutionCounter;
private StopWatch stopWatch;
private long maxSolvingTime;
private boolean timedOut;
public GeneticSolver() {
this(Long.MAX_VALUE);
}
public GeneticSolver(long maxSolvingTime) {
this.maxSolvingTime = maxSolvingTime;
reset();
}
@Override
public Solution solve(Root model) throws SolvingException {
reset();
if (model.getNumRequest() == 0) {
return Solution.emptySolutionOf(model);
}
stopWatch = StopWatch.start();
List<Solution> solutions = new ArrayList<>();
// do some solvin'
if (solutions.size() > 0) {
lastSolution = solutions.get(solutions.size() - 1);
} else {
lastSolution = Solution.emptySolutionOf(model);
logger.warn("Found no solution!");
}
lastSolvingTime = stopWatch.time(TimeUnit.MILLISECONDS);
return lastSolution;
}
private void reset() {
this.lastSolution = null;
this.solutionCounter = 0;
this.lastSolvingTime = 0;
this.timedOut = false;
}
@Override
public String getName() {
return "genetic";
}
@Override
public long getLastSolvingTime() {
return lastSolvingTime;
}
@Override
public double getLastObjective() {
if (lastSolution != null) {
return lastSolution.computeObjective();
} else {
// TODO throw exception or do something reasonable
return 0d;
}
}
@Override
public Solver setTimeout(long timeoutValue, TimeUnit timeoutUnit) {
this.maxSolvingTime = timeoutUnit.toMillis(timeoutValue);
return this;
}
@Override
public boolean hadTimeout() {
return this.timedOut;
}
}
package de.tudresden.inf.st.mquat.solving.genetic.opt4j;
import de.tudresden.inf.st.mquat.jastadd.model.*;
import de.tudresden.inf.st.mquat.solving.genetic.opt4j.custom.genotypes.TreeGenotype;
import de.tudresden.inf.st.mquat.solving.genetic.opt4j.custom.genotypes.TreeGenotypeNode;
import org.opt4j.core.problem.Creator;
import java.util.Random;
public class Opt4jCreator implements Creator<TreeGenotype> {
public static TreeGenotypeNode<Request, Instance, Resource, Implementation> createNode(Assignment assignment, TreeGenotype<Request, Instance, Resource, Implementation> container) {
TreeGenotypeNode<Request, Instance, Resource, Implementation> node = new TreeGenotypeNode<>(container);
node.setImpl(assignment.getImplementation());
node.setResource(assignment.getResource());
for (ComponentMapping subAssignment : assignment.getComponentMappingList()) {
node.getSubStructure().put(subAssignment.getInstance(), createNode(subAssignment.getAssignment(), container));
}
return node;
}
public TreeGenotype<Request, Instance, Resource, Implementation> create() {
// TODO this method create a phenotype and translates it to a genotype. this is not nice!
Root model = Opt4jModule.getModel();
Solution phenotype = model.createRandomSolution(new Random());
TreeGenotype<Request, Instance, Resource, Implementation> genotype = new TreeGenotype<>(model.getHardwareModel().allContainers());
for (Assignment a : phenotype.getAssignmentList()) {
if (a.getTopLevel() && a.getImplementation().getName().getName().length() > 19) {
throw new RuntimeException();
}
genotype.getRequestMap().put(a.getRequest(), createNode(a, genotype));
}
return genotype;
}
}
package de.tudresden.inf.st.mquat.solving.genetic.opt4j;
import de.tudresden.inf.st.mquat.jastadd.model.*;
import de.tudresden.inf.st.mquat.solving.genetic.opt4j.custom.genotypes.TreeGenotype;
import de.tudresden.inf.st.mquat.solving.genetic.opt4j.custom.genotypes.TreeGenotypeNode;
import org.opt4j.core.problem.Decoder;
import java.util.Map;
public class Opt4jDecoder implements Decoder<TreeGenotype<Request, Instance, Resource, Implementation>, Solution> {
private static void populateResourceMapping(ResourceMapping mapping, ResourceRequirement requirement,
Resource resource) {
for (ResourceRequirement subRequirement : requirement.getResourceRequirementList()) {
int fittingResourceCount = 0;
for (int currentInstance = 0; currentInstance < subRequirement.getNumInstance(); currentInstance++) {
for (int currentResource = 0; currentResource < resource.getNumSubResource(); currentResource++) {
Resource subResource = resource.getSubResource(currentResource);
if (subResource.getType().getRef() == subRequirement.getResourceTypeRef().getRef()) {
if (currentInstance == fittingResourceCount) {
ResourceMapping newMapping = new ResourceMapping();
Instance instance = subRequirement.getInstance(currentInstance);
newMapping.setInstance(instance);
newMapping.setResource(subResource);
mapping.addResourceMapping(newMapping);
populateResourceMapping(newMapping, subRequirement, subResource);
fittingResourceCount++;
}
currentInstance++;
}
}
}
}
}
@Override
public Solution decode(TreeGenotype<Request, Instance, Resource, Implementation> genotype) {
Solution phenotype = new Solution();
phenotype.setModel(Opt4jModule.getModel());
for (Map.Entry<Request, TreeGenotypeNode<Request, Instance, Resource, Implementation>> e : genotype.getRequestMap()
.entrySet()) {
phenotype.addAssignment(decodeNode(true, e.getKey(), e.getValue()));
}
return phenotype;
}
private Assignment decodeNode(boolean isTopLevel, Request request, TreeGenotypeNode<Request, Instance, Resource, Implementation> node) {
Assignment assignment = new Assignment();
assignment.setTopLevel(isTopLevel);
assignment.setRequest(request);
assignment.setImplementation(node.getImpl());
// fix the resource mapping
// we assume that exactly one resource is required
Instance resourceInstance = node.getImpl().getResourceRequirement().getInstance(0);
ResourceMapping rm = new ResourceMapping();
rm.setInstance(resourceInstance);
rm.setResource(node.getResource());
populateResourceMapping(rm, node.getImpl().getResourceRequirement(), node.getResource());
assignment.setResourceMapping(rm);
for (Map.Entry<Instance, TreeGenotypeNode<Request, Instance, Resource, Implementation>> e : node.getSubStructure()
.entrySet()) {
assignment.addComponentMapping(new ComponentMapping(e.getKey(), decodeNode(false, request, e.getValue())));
}
return assignment;
}
}