/* * Copyright 2013 Red Hat, Inc. and/or its affiliates. * * 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.optaplanner.examples.vehiclerouting.solver.score; import java.util.HashMap; import java.util.List; import java.util.Map; import org.optaplanner.core.api.score.buildin.hardsoftlong.HardSoftLongScore; import org.optaplanner.core.impl.score.director.easy.EasyScoreCalculator; import org.optaplanner.examples.vehiclerouting.domain.Customer; import org.optaplanner.examples.vehiclerouting.domain.Standstill; import org.optaplanner.examples.vehiclerouting.domain.Vehicle; import org.optaplanner.examples.vehiclerouting.domain.VehicleRoutingSolution; import org.optaplanner.examples.vehiclerouting.domain.timewindowed.TimeWindowedCustomer; import org.optaplanner.examples.vehiclerouting.domain.timewindowed.TimeWindowedVehicleRoutingSolution; public class VehicleRoutingEasyScoreCalculator implements EasyScoreCalculator<VehicleRoutingSolution> { @Override public HardSoftLongScore calculateScore(VehicleRoutingSolution solution) { boolean timeWindowed = solution instanceof TimeWindowedVehicleRoutingSolution; List<Customer> customerList = solution.getCustomerList(); List<Vehicle> vehicleList = solution.getVehicleList(); Map<Vehicle, Integer> vehicleDemandMap = new HashMap<>(vehicleList.size()); for (Vehicle vehicle : vehicleList) { vehicleDemandMap.put(vehicle, 0); } long hardScore = 0L; long softScore = 0L; for (Customer customer : customerList) { Standstill previousStandstill = customer.getPreviousStandstill(); if (previousStandstill != null) { Vehicle vehicle = customer.getVehicle(); vehicleDemandMap.put(vehicle, vehicleDemandMap.get(vehicle) + customer.getDemand()); // Score constraint distanceToPreviousStandstill softScore -= customer.getDistanceFromPreviousStandstill(); if (customer.getNextCustomer() == null) { // Score constraint distanceFromLastCustomerToDepot softScore -= customer.getLocation().getDistanceTo(vehicle.getLocation()); } if (timeWindowed) { TimeWindowedCustomer timeWindowedCustomer = (TimeWindowedCustomer) customer; long dueTime = timeWindowedCustomer.getDueTime(); Long arrivalTime = timeWindowedCustomer.getArrivalTime(); if (dueTime < arrivalTime) { // Score constraint arrivalAfterDueTime hardScore -= (arrivalTime - dueTime); } } } } for (Map.Entry<Vehicle, Integer> entry : vehicleDemandMap.entrySet()) { int capacity = entry.getKey().getCapacity(); int demand = entry.getValue(); if (demand > capacity) { // Score constraint vehicleCapacity hardScore -= (demand - capacity); } } // Score constraint arrivalAfterDueTimeAtDepot is a built-in hard constraint in VehicleRoutingImporter return HardSoftLongScore.valueOf(hardScore, softScore); } }