From fd3684b5440dacca0c4bf4be15930555a79e2100 Mon Sep 17 00:00:00 2001 From: Kristóf Marussy Date: Tue, 21 May 2019 17:00:01 -0400 Subject: VIATRA DSE and COIN-OR CBC implementations of CPS case study --- .../domains/cps/cplex/CpsToLpTranslator.xtend | 171 +++++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 Domains/hu.bme.mit.inf.dslreasoner.domains.cps/src/hu/bme/mit/inf/dslreasoner/domains/cps/cplex/CpsToLpTranslator.xtend (limited to 'Domains/hu.bme.mit.inf.dslreasoner.domains.cps/src/hu/bme/mit/inf/dslreasoner/domains/cps/cplex/CpsToLpTranslator.xtend') diff --git a/Domains/hu.bme.mit.inf.dslreasoner.domains.cps/src/hu/bme/mit/inf/dslreasoner/domains/cps/cplex/CpsToLpTranslator.xtend b/Domains/hu.bme.mit.inf.dslreasoner.domains.cps/src/hu/bme/mit/inf/dslreasoner/domains/cps/cplex/CpsToLpTranslator.xtend new file mode 100644 index 00000000..c38af3a0 --- /dev/null +++ b/Domains/hu.bme.mit.inf.dslreasoner.domains.cps/src/hu/bme/mit/inf/dslreasoner/domains/cps/cplex/CpsToLpTranslator.xtend @@ -0,0 +1,171 @@ +package hu.bme.mit.inf.dslreasoner.domains.cps.cplex + +import com.google.common.collect.ImmutableList +import com.google.common.collect.ImmutableMap +import hu.bme.mit.inf.dslreasoner.domains.cps.ApplicationType +import hu.bme.mit.inf.dslreasoner.domains.cps.CyberPhysicalSystem +import hu.bme.mit.inf.dslreasoner.domains.cps.HostType +import hu.bme.mit.inf.dslreasoner.domains.cps.Requirement +import java.util.List +import java.util.Map + +class CpsToLpTranslator { + static val MINIMUM_MEMORY_USAGE = 0.25 + static val MINIMUM_HDD_USAGE = 0.25 + + val CyberPhysicalSystem cps + val Map> appInstances + val Map> hostInstances + val boolean breakSymmetry + + new(CyberPhysicalSystem cps, int hostInstanceCount, boolean breakSymmetry) { + this.cps = cps + appInstances = createAppInstances + hostInstances = createHostInstances(hostInstanceCount) + this.breakSymmetry = breakSymmetry + } + + private def createAppInstances() { + val builder = ImmutableMap.builder + var int i = 0 + for (req : requirements) { + val listBuilder = ImmutableList.builder + for (var int j = 0; j < req.count; j++) { + listBuilder.add('''r«i»a«j»''') + } + builder.put(req, listBuilder.build) + i++ + } + builder.build + } + + private def createHostInstances(int hostInstanceCount) { + val builder = ImmutableMap.builder + var int i = 0 + for (hostType : cps.hostTypes) { + val listBuilder = ImmutableList.builder + for (var int j = 0; j < hostInstanceCount; j++) { + listBuilder.add('''h«i»i«j»''') + } + builder.put(hostType, listBuilder.build) + i++ + } + builder.build + } + + def getLpProblem() { + ''' + Minimize + total_cost: «objective» + Subject To + «constraints» + Bounds + «bounds» + Binary + «binaryVariables» + End + ''' + } + + private def getObjective() { + '''«FOR pair : hostInstancesWithType SEPARATOR " + "»«pair.key.cost» «pair.value.existsVariable»«ENDFOR»''' + } + + private def getConstraints() { + ''' + «FOR appPair : appInstancesWithType» + «appPair.value»_allocated: «FOR host : appPair.key.possibleHostInstances SEPARATOR " + "»«getAllocatedToVariable(appPair.value, host)»«ENDFOR» = 1 + «FOR host : appPair.key.possibleHostInstances» + «appPair.value»_to_«host»_exists: «host.existsVariable» - «getAllocatedToVariable(appPair.value, host)» >= 0 + «ENDFOR» + «ENDFOR» + «FOR hostPair : hostInstancesWithType» + «hostPair.value»_mem_use: «FOR appPair : hostPair.key.possibleAppInstancesWithRequirements SEPARATOR " + "»«appPair.key.requiredMemory» «getAllocatedToVariable(appPair.value, hostPair.value)»«ENDFOR» - «hostPair.key.defaultMemory» «hostPair.value.memoryUsageVariable» = 0 + «hostPair.value»_hdd_use: «FOR appPair : hostPair.key.possibleAppInstancesWithRequirements SEPARATOR " + "»«appPair.key.requiredHdd» «getAllocatedToVariable(appPair.value, hostPair.value)»«ENDFOR» - «hostPair.key.defaultHdd» «hostPair.value.hddUsageVariable» = 0 + «ENDFOR» + average_mem: «FOR host : allHostInstances SEPARATOR " + "»«host.memoryUsageVariable» - «MINIMUM_MEMORY_USAGE» «host.existsVariable»«ENDFOR» >= 0 + average_hdd: «FOR host : allHostInstances SEPARATOR " + "»«host.memoryUsageVariable» - «MINIMUM_HDD_USAGE» «host.existsVariable»«ENDFOR» >= 0 + «FOR reqPair : requirements.filter[count > 1].indexed» + «FOR host : reqPair.value.type.requirements.flatMap[hostInstances.get(hostType)]» + r«reqPair.key»_«host»_redundant: «FOR app : appInstances.get(reqPair.value) SEPARATOR " + "»«getAllocatedToVariable(app, host)»«ENDFOR» <= 1 + «ENDFOR» + «ENDFOR» + «IF breakSymmetry» + «FOR hosts : hostInstances.values» + «FOR i : 0 ..< (hosts.size - 1)» + «hosts.get(i + 1)»_after_«hosts.get(i)»: «hosts.get(i).existsVariable» - «hosts.get(i + 1).existsVariable» >= 0 + «ENDFOR» + «ENDFOR» + «ENDIF» + ''' + } + + private def getBounds() { + ''' + «FOR host : allHostInstances» + 0 <= «host.memoryUsageVariable» <= 1 + 0 <= «host.hddUsageVariable» <= 1 + «ENDFOR» + ''' + } + + private def getBinaryVariables() { + ''' + «FOR host : allHostInstances» + «host.existsVariable» + «ENDFOR» + «FOR appPair : appInstancesWithType» + «FOR host : appPair.key.possibleHostInstances» + «getAllocatedToVariable(appPair.value, host)» + «ENDFOR» + «ENDFOR» + ''' + } + + private def getRequirements() { + cps.requests.flatMap[requirements] + } + + private def getAllHostInstances() { + hostInstances.values.flatMap[it] + } + + private def getHostInstancesWithType() { + hostInstances.entrySet.flatMap[pair|pair.value.map[pair.key -> it]] + } + + private def getAppInstancesWithType() { + appInstances.entrySet.flatMap[pair|pair.value.map[pair.key.type -> it]] + } + + private def getPossibleHostInstances(ApplicationType appType) { + appType.requirements.flatMap[req|hostInstances.get(req.hostType)] + } + + private def getPossibleAppInstancesWithRequirements(HostType hostType) { + appInstances.entrySet.flatMap [ pair | + val resourceReq = pair.key.type.requirements.findFirst[it.hostType == hostType] + if (resourceReq === null) { + emptyList + } else { + pair.value.map[resourceReq -> it] + } + ] + } + + private def getExistsVariable(String hostInstance) { + '''«hostInstance»_exists''' + } + + private def getMemoryUsageVariable(String hostInstance) { + '''«hostInstance»_mem''' + } + + private def getHddUsageVariable(String hostInstance) { + '''«hostInstance»_hdd''' + } + + private def getAllocatedToVariable(String appInstance, String hostInstance) { + '''«appInstance»_to_«hostInstance»''' + } +} -- cgit v1.2.3-54-g00ecf