All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.drools.planner.examples.machinereassignment.solver.machineReassignmentScoreRules.drl Maven / Gradle / Ivy

Go to download

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.

There is a newer version: 6.0.0.Alpha9
Show newest version
/*
 * 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




© 2015 - 2024 Weber Informatics LLC | Privacy Policy