org.drools.planner.examples.machinereassignment.solver.machineReassignmentScoreRules.drl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of drools-planner-examples Show documentation
Show all versions of drools-planner-examples Show documentation
Drools Planner optimizes automated planning by combining metaheuristic search algorithms with rule
engine powered score calculation. This is the drools-planner-examples module which contains examples on how to use
Drools Planner.
/*
* Copyright 2011 JBoss Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.drools.planner.examples.machinereassignment.solver;
dialect "java"
import org.drools.planner.core.score.buildin.hardandsoftlong.HardAndSoftLongScoreHolder;
import org.drools.planner.core.score.constraint.LongConstraintOccurrence;
import org.drools.planner.core.score.constraint.ConstraintType;
import org.drools.planner.examples.machinereassignment.domain.MachineReassignment;
import org.drools.planner.examples.machinereassignment.domain.MrBalancePenalty;
import org.drools.planner.examples.machinereassignment.domain.MrMachineCapacity;
import org.drools.planner.examples.machinereassignment.domain.MrGlobalPenaltyInfo;
import org.drools.planner.examples.machinereassignment.domain.MrLocation;
import org.drools.planner.examples.machinereassignment.domain.MrMachine;
import org.drools.planner.examples.machinereassignment.domain.MrMachineMoveCost;
import org.drools.planner.examples.machinereassignment.domain.MrNeighborhood;
import org.drools.planner.examples.machinereassignment.domain.MrProcess;
import org.drools.planner.examples.machinereassignment.domain.MrProcessAssignment;
import org.drools.planner.examples.machinereassignment.domain.MrResource;
import org.drools.planner.examples.machinereassignment.domain.MrService;
import org.drools.planner.examples.machinereassignment.domain.MrServiceDependency;
import org.drools.planner.examples.machinereassignment.domain.solver.MrMachineTransientUsage;
import org.drools.planner.examples.machinereassignment.domain.solver.MrMachineUsage;
import org.drools.planner.examples.machinereassignment.domain.solver.MrServiceMovedProcessesCount;
global HardAndSoftLongScoreHolder scoreHolder;
rule "machineUsage"
salience 1 // Do these rules first (optional, for performance)
when
$machineCapacity : MrMachineCapacity($machine : machine, $resource : resource)
accumulate(
$processAssignment : MrProcessAssignment(machine == $machine),
$usageTotal : sum($processAssignment.getUsage($resource))
)
then
insertLogical(new MrMachineUsage($machineCapacity, $usageTotal.intValue()));
end
rule "machineTransientUsage"
salience 1 // Do these rules first (optional, for performance)
when
$machineCapacity : MrMachineCapacity(transientlyConsumed == true, $machine : machine, $resource : resource)
accumulate(
$processAssignment : MrProcessAssignment(originalMachine == $machine, moved == true),
$usageTotal : sum($processAssignment.getUsage($resource))
)
then
insertLogical(new MrMachineTransientUsage($machineCapacity, $usageTotal.intValue()));
end
// ############################################################################
// Hard constraints
// ############################################################################
// Capacity constraints + Transient usage constraints
rule "maximumCapacityNonTransientlyConsumed"
when
$machineUsage : MrMachineUsage(transientlyConsumed == false, maximumAvailable < 0,
$maximumAvailable : maximumAvailable)
then
insertLogical(new LongConstraintOccurrence("maximumCapacity", ConstraintType.NEGATIVE_HARD,
- $maximumAvailable,
$machineUsage));
end
rule "maximumCapacityTransientlyConsumed"
when
$machineUsage : MrMachineUsage(transientlyConsumed == true,
$maximumAvailable : maximumAvailable, $resource : resource, $machine : machine)
MrMachineTransientUsage(resource == $resource, machine == $machine,
$maximumAvailable < usage, $transientUsage : usage)
then
insertLogical(new LongConstraintOccurrence("maximumCapacityTransientlyConsumed", ConstraintType.NEGATIVE_HARD,
$transientUsage - $maximumAvailable,
$machineUsage));
end
// Conflict constraints
rule "serviceConflict"
when
$leftProcessAssignment : MrProcessAssignment($service : service, $machine : machine, $leftId : id)
$rightProcessAssignment : MrProcessAssignment(service == $service, machine == $machine, id > $leftId)
then
insertLogical(new LongConstraintOccurrence("serviceConflict", ConstraintType.NEGATIVE_HARD,
1,
$leftProcessAssignment, $rightProcessAssignment));
end
// Spread constraints
rule "serviceLocationSpread"
when
$service : MrService($locationSpread : locationSpread)
$spreadCount : Number(intValue < $locationSpread) from accumulate(
$location : MrLocation()
and exists MrProcessAssignment(service == $service, location == $location),
count($location)
)
then
insertLogical(new LongConstraintOccurrence("serviceLocationSpread", ConstraintType.NEGATIVE_HARD,
$locationSpread - $spreadCount.intValue(),
$service));
end
// Dependency constraints
rule "serviceDependency"
when
$serviceDependency : MrServiceDependency($fromService : fromService, $toService : toService)
$processAssignment : MrProcessAssignment(service == $fromService, $neighborhood : neighborhood)
not MrProcessAssignment(service == $toService, neighborhood == $neighborhood)
then
insertLogical(new LongConstraintOccurrence("serviceDependency", ConstraintType.NEGATIVE_HARD,
1,
$serviceDependency, $processAssignment));
end
//// ############################################################################
//// Soft constraints
//// ############################################################################
// Load cost
rule "loadCost"
when
$machineUsage : MrMachineUsage(safetyAvailable < 0,
$safetyAvailable : safetyAvailable, $loadCostWeight : loadCostWeight)
then
insertLogical(new LongConstraintOccurrence("loadCost", ConstraintType.NEGATIVE_SOFT,
- $safetyAvailable * $loadCostWeight,
$machineUsage));
end
// Balance cost
rule "balanceCost"
when
$balancePenalty : MrBalancePenalty($originResource : originResource, $targetResource : targetResource,
$multiplicand : multiplicand, $weight : weight)
MrMachineUsage(resource == $originResource, maximumAvailable > 0,
$machine : machine, $originAvailable : maximumAvailable)
MrMachineUsage(resource == $targetResource, machine == $machine,
maximumAvailable < $originAvailable * $multiplicand,
$targetAvailable : maximumAvailable)
then
insertLogical(new LongConstraintOccurrence("balanceCost", ConstraintType.NEGATIVE_SOFT,
(($originAvailable * $multiplicand) - $targetAvailable) * $weight,
$balancePenalty, $machine));
end
// Process move cost
rule "processMoveCost"
when
MrGlobalPenaltyInfo(processMoveCostWeight > 0, $processMoveCostWeight : processMoveCostWeight)
$processAssignment : MrProcessAssignment(moved == true, processMoveCost > 0, $processMoveCost : processMoveCost)
then
insertLogical(new LongConstraintOccurrence("processMoveCost", ConstraintType.NEGATIVE_SOFT,
$processMoveCost * $processMoveCostWeight,
$processAssignment));
end
// Service move cost
rule "serviceMovedProcessesCount"
salience 1 // Do these rules first (optional, for performance)
when
$service : MrService()
accumulate(
$processAssignment : MrProcessAssignment(service == $service, moved == true),
$movedProcessesCount : count($processAssignment)
)
then
insertLogical(new MrServiceMovedProcessesCount($service, $movedProcessesCount.intValue()));
end
rule "serviceMoveCost"
when
MrGlobalPenaltyInfo(serviceMoveCostWeight > 0, $serviceMoveCostWeight : serviceMoveCostWeight)
$serviceMovedProcessesCount : MrServiceMovedProcessesCount($service : service, $serviceId : serviceId,
$movedProcessesCount : movedProcessesCount)
not MrServiceMovedProcessesCount(movedProcessesCount > $movedProcessesCount)
not MrServiceMovedProcessesCount(movedProcessesCount == $movedProcessesCount, serviceId < $serviceId)
then
insertLogical(new LongConstraintOccurrence("serviceMoveCost", ConstraintType.NEGATIVE_SOFT,
$movedProcessesCount * $serviceMoveCostWeight,
$service));
end
// Machine move cost
rule "machineMoveCost"
when
MrGlobalPenaltyInfo(machineMoveCostWeight > 0, $machineMoveCostWeight : machineMoveCostWeight)
$processAssignment : MrProcessAssignment(moved == true, machineMoveCost > 0, $machineMoveCost : machineMoveCost)
then
insertLogical(new LongConstraintOccurrence("machineMoveCost", ConstraintType.NEGATIVE_SOFT,
$machineMoveCost * $machineMoveCostWeight,
$processAssignment));
end
// ############################################################################
// Calculate score
// ############################################################################
// Accumulate hard constraints
rule "hardConstraintsBroken"
salience -1 // Do the other rules first (optional, for performance)
when
accumulate(
LongConstraintOccurrence(constraintType == ConstraintType.NEGATIVE_HARD, $weight : weight),
$hardTotal : sum($weight) // Vote for http://jira.jboss.com/jira/browse/JBRULES-1075
)
then
scoreHolder.setHardConstraintsBroken($hardTotal.longValue());
end
// Accumulate soft constraints
rule "softConstraintsBroken"
salience -1 // Do the other rules first (optional, for performance)
when
accumulate(
LongConstraintOccurrence(constraintType == ConstraintType.NEGATIVE_SOFT, $weight : weight),
$softTotal : sum($weight) // Vote for http://jira.jboss.com/jira/browse/JBRULES-1075
)
then
scoreHolder.setSoftConstraintsBroken($softTotal.longValue());
end