From 52d3b978504eb979e9abc3b626f9ec7a49199a59 Mon Sep 17 00:00:00 2001
From: Johannes Mey <johannes.mey@tu-dresden.de>
Date: Wed, 15 Aug 2018 09:27:20 +0200
Subject: [PATCH] make finding random solutions faster and better

---
 .../src/main/jastadd/solvers/Helpers.jadd     | 166 +++++++++++++++++-
 1 file changed, 159 insertions(+), 7 deletions(-)

diff --git a/jastadd-mquat-base/src/main/jastadd/solvers/Helpers.jadd b/jastadd-mquat-base/src/main/jastadd/solvers/Helpers.jadd
index 5ffb352..0901536 100644
--- a/jastadd-mquat-base/src/main/jastadd/solvers/Helpers.jadd
+++ b/jastadd-mquat-base/src/main/jastadd/solvers/Helpers.jadd
@@ -15,7 +15,57 @@ aspect Helpers {
     return assignment;
   }
 
+  public void Assignment.populateAssignment(java.util.Random random, java.util.List<Resource> resourceList) {
+    // assign resources
+    ResourceRequirement resourceRequirement = this.getImplementation().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));
+
+      Resource.populateResourceMapping(mapping, resourceRequirement, chosenResource);
 
+      this.setResourceMapping(mapping);
+    }
+
+    for (ComponentMapping mapping : this.getComponentMappingList()) {
+      mapping.getAssignment().populateAssignment(random, resourceList);
+    }
+  }
+
+  public void Solution.populateSoftwareSolution(java.util.Random random) {
+
+    java.util.List<Resource> resourceList = getModel().populateResourceList(getModel().getHardwareModel().getResourceList(), new ArrayList<>());
+
+    java.util.Iterator<Assignment> iterator = assignmentIterator();
+    while (iterator.hasNext()) {
+      Assignment assignment = iterator.next();
+      ResourceRequirement resourceRequirement = assignment.getImplementation().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));
+
+        Resource.populateResourceMapping(mapping, resourceRequirement, chosenResource);
+
+        assignment.setResourceMapping(mapping);
+      }
+    }
+  }
 
   public Solution Root.createRandomSolution(java.util.Random random) {
     Solution solution = new Solution();
@@ -26,14 +76,92 @@ aspect Helpers {
     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));
+      Assignment assignment = null;
+      for (int i = 0; i < 50; i++) {
+        assignment = createRandomSoftwareAssignment(true, request, request.getTarget().getRef(), null, null, random);
+        if (assignment.isSoftwareValid()) {
+          break;
+        }
+      }
+      assignment.populateAssignment(random, resourceList);
+      solution.addAssignment(assignment);
+    }
+
+    for (int i = 0; i < 100; i++) {
+      solution.populateSoftwareSolution(random);
+      if (solution.isValid()) {
+        break;
+      }
     }
 
+    this.setSolution(solution, 0);
+
     return solution;
+   }
+
+  public Solution Root.createRandomSoftwareSolution(java.util.Random random) {
+    Solution solution = new Solution();
+
+    solution.setModel(this);
+
+    for (Request request : getRequestList()) {
+      solution.addAssignment(createRandomSoftwareAssignment(true, request, request.getTarget().getRef(), null, null, random));
+    }
+
+    this.setSolution(solution, 0);
+
+    return solution;
+  }
+
+public Assignment Root.createRandomSoftwareAssignment(boolean isTopLevel, Request request, Component component, Implementation parentImplementation, Instance parentInstance, java.util.Random random) {
+
+    Assignment assignment = new Assignment();
+    Implementation implementation;
+    assignment.setRequest(request);
+    assignment.setTopLevel(isTopLevel);
+
+
+    if (isTopLevel) {
+
+      java.util.List<Implementation> implementations = component.locallyValidImplementations(request);
+
+      if (!implementations.isEmpty()){
+        implementation = implementations.get(random.nextInt(implementations.size()));
+      } else {
+        implementation = component.getImplementation(random.nextInt(component.getNumImplementation()));
+      }
+
+      assignment.setImplementation(implementation);
+
+    } else {
+      java.util.List<Implementation> implementations = component.locallyValidImplementations(request, parentImplementation, parentInstance);
+
+      if (!implementations.isEmpty()){
+        implementation = implementations.get(random.nextInt(implementations.size()));
+      } else {
+        implementation = component.getImplementation(random.nextInt(component.getNumImplementation()));
+      }
+
+      assignment.setImplementation(implementation);
+    }
+
+
+    // 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(createRandomSoftwareAssignment(false, request, requiredComponent, implementation, componentRequirementInstance, random));
+        assignment.addComponentMapping(mapping);
+      }
+    }
+
+    return assignment;
   }
 
 
-  private java.util.List<Resource> Root.populateResourceList(List<Resource> resourceList, java.util.List<Resource> list) {
+  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);
@@ -43,22 +171,46 @@ aspect Helpers {
     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()));
+  public Assignment Root.createRandomAssignment(boolean isTopLevel, Request request, Component component, java.util.List<Resource> resourceList,  Implementation parentImplementation, Instance parentInstance, java.util.Random random) {
 
     Assignment assignment = new Assignment();
-    assignment.setImplementation(implementation);
+    Implementation implementation;
     assignment.setRequest(request);
     assignment.setTopLevel(isTopLevel);
 
+
+    if (isTopLevel) {
+
+      java.util.List<Implementation> implementations = component.locallyValidImplementations(request);
+
+      if (!implementations.isEmpty()){
+        implementation = implementations.get(random.nextInt(implementations.size()));
+      } else {
+        implementation = component.getImplementation(random.nextInt(component.getNumImplementation()));
+      }
+
+      assignment.setImplementation(implementation);
+
+    } else {
+      java.util.List<Implementation> implementations = component.locallyValidImplementations(request, parentImplementation, parentInstance);
+
+      if (!implementations.isEmpty()){
+        implementation = implementations.get(random.nextInt(implementations.size()));
+      } else {
+        implementation = component.getImplementation(random.nextInt(component.getNumImplementation()));
+      }
+
+      assignment.setImplementation(implementation);
+    }
+
+
     // 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));
+        mapping.setAssignment(createRandomAssignment(false, request, requiredComponent, resourceList, implementation, componentRequirementInstance, random));
         assignment.addComponentMapping(mapping);
       }
     }
-- 
GitLab