// Path: heuristicsearch/src/main/java/xyz/thepathfinder/routing/domain/CommodityAction.java
// @PlanningEntity(difficultyComparatorClass = NaiveDifficultyComparator.class)
// public abstract class CommodityAction implements RouteAction {
//     Transport transport;
//     CommodityAction nextCommodityAction;
//     RouteAction previousRouteAction;
//     Map<RouteAction, Long> distances = new HashMap<>();
//     Map<String, Integer> capacities;
//     int id;
// 
//     @Override
//     @AnchorShadowVariable(sourceVariableName = "previousRouteAction")
//     public Transport getTransport() {
//         return transport;
//     }
// 
//     public void setTransport(Transport transport) {
//         this.transport = transport;
//     }
// 
//     @Override
//     public CommodityAction getNextCommodityAction() {
//         return nextCommodityAction;
//     }
// 
//     @Override
//     public void setNextCommodityAction(CommodityAction commodityAction) {
//         nextCommodityAction = commodityAction;
//     }
// 
//     @PlanningVariable(valueRangeProviderRefs = {"transportRange", "commodityActionRange"},
//         graphType = PlanningVariableGraphType.CHAINED)
//     public RouteAction getPreviousRouteAction() {
//         return previousRouteAction;
//     }
// 
//     public void setPreviousRouteAction(RouteAction routeAction) {
//         previousRouteAction = routeAction;
//     }
// 
//     @Override
//     public long distanceTo(RouteAction routeAction) {
//         return distances.getOrDefault(routeAction, Long.MAX_VALUE);
//     }
// 
//     @Override
//     public void setDistance(RouteAction routeAction, long distance) {
//         distances.put(routeAction, distance);
//     }
// 
//     @Override
//     public int id() {
//         return id;
//     }
// 
//     @Override
//     public int getCapacity(String key) {
//         return capacities.getOrDefault(key, 0);
//     }
// }
// 
// Path: simulatedannealing/src/main/java/xyz/thepathfinder/routing/domain/CommodityDropoff.java
// public class CommodityDropoff implements CommodityAction {
//     final CommodityStart start;
//     final String name;
// 
//     public CommodityDropoff(String name, CommodityStart start) {
//         this.start = start;
//         this.name = name;
//     }
// 
//     @Override
//     public String getName() {
//         return name;
//     }
// 
//     @Override
//     public String toString() {
//         return getName();
//     }
// }
// 
// Path: heuristicsearch/src/main/java/xyz/thepathfinder/routing/domain/RoutingSolution.java
// @PlanningSolution
// public class RoutingSolution implements Solution<HardSoftLongScore> {
// 
//     HardSoftLongScore score;
//     List<Transport> transportList;
//     List<CommodityAction> commodityActionList;
// 
//     @Override
//     public HardSoftLongScore getScore() {
//         return score;
//     }
// 
//     @Override
//     public void setScore(HardSoftLongScore score) {
//         this.score = score;
//     }
// 
//     @Override
//     public Collection<? extends RouteAction> getProblemFacts() {
//         List<RouteAction> routeActions = new ArrayList<>();
//         routeActions.addAll(transportList);
//         routeActions.addAll(commodityActionList);
//         return routeActions;
//     }
// 
//     @PlanningEntityCollectionProperty
//     @ValueRangeProvider(id = "transportRange")
//     public List<Transport> getTransportList() {
//         return transportList;
//     }
// 
//     public void setTransportList(List<Transport> transports) {
//         transportList = transports;
//     }
// 
//     @PlanningEntityCollectionProperty
//     @ValueRangeProvider(id = "commodityActionRange")
//     public List<CommodityAction> getCommodityActionList() {
//         return commodityActionList;
//     }
// 
//     public void setCommodityActionList(List<CommodityAction> commodityActions) {
//         commodityActionList = commodityActions;
//     }
// }


import org.optaplanner.core.api.score.Score;
import org.optaplanner.core.api.score.buildin.hardsoftlong.HardSoftLongScore;
import org.optaplanner.core.impl.score.director.easy.EasyScoreCalculator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import xyz.thepathfinder.routing.domain.CommodityAction;
import xyz.thepathfinder.routing.domain.CommodityDropoff;
import xyz.thepathfinder.routing.domain.RoutingSolution;
import static java.util.stream.Collectors.summingLong;
                        }
                    }
                }
            }
            return violations;
        }));
    }

    static long capacitiesViolated(RoutingSolution solution) {
        return solution.getTransportList().stream().collect(summingLong(t -> {
            Map<String, Integer> capacities = new HashMap<>(t.getCapacities());
            CommodityAction commodityAction = t.getNextCommodityAction();
            while (commodityAction != null) {
                for (String key : capacities.keySet()) {
                    capacities.put(key, capacities.get(key) - commodityAction.getCapacity(key));
                }
                if (capacities.values().stream().anyMatch(x -> x < 0)) {
                    return 1;
                }
                commodityAction = commodityAction.getNextCommodityAction();
            }
            return 0;
        }));
    }

    static long getTotalDistance(RoutingSolution solution) {
        return solution.getTransportList().stream().collect(
            summingLong(t -> getPathDistance(t.getNextCommodityAction())));
    }

// Path: heuristicsearch/src/main/java/xyz/thepathfinder/routing/domain/CommodityAction.java
// @PlanningEntity(difficultyComparatorClass = NaiveDifficultyComparator.class)
// public abstract class CommodityAction implements RouteAction {
//     Transport transport;
//     CommodityAction nextCommodityAction;
//     RouteAction previousRouteAction;
//     Map<RouteAction, Long> distances = new HashMap<>();
//     Map<String, Integer> capacities;
//     int id;
// 
//     @Override
//     @AnchorShadowVariable(sourceVariableName = "previousRouteAction")
//     public Transport getTransport() {
//         return transport;
//     }
// 
//     public void setTransport(Transport transport) {
//         this.transport = transport;
//     }
// 
//     @Override
//     public CommodityAction getNextCommodityAction() {
//         return nextCommodityAction;
//     }
// 
//     @Override
//     public void setNextCommodityAction(CommodityAction commodityAction) {
//         nextCommodityAction = commodityAction;
//     }
// 
//     @PlanningVariable(valueRangeProviderRefs = {"transportRange", "commodityActionRange"},
//         graphType = PlanningVariableGraphType.CHAINED)
//     public RouteAction getPreviousRouteAction() {
//         return previousRouteAction;
//     }
// 
//     public void setPreviousRouteAction(RouteAction routeAction) {
//         previousRouteAction = routeAction;
//     }
// 
//     @Override
//     public long distanceTo(RouteAction routeAction) {
//         return distances.getOrDefault(routeAction, Long.MAX_VALUE);
//     }
// 
//     @Override
//     public void setDistance(RouteAction routeAction, long distance) {
//         distances.put(routeAction, distance);
//     }
// 
//     @Override
//     public int id() {
//         return id;
//     }
// 
//     @Override
//     public int getCapacity(String key) {
//         return capacities.getOrDefault(key, 0);
//     }
// }
// 
// Path: simulatedannealing/src/main/java/xyz/thepathfinder/routing/domain/CommodityDropoff.java
// public class CommodityDropoff implements CommodityAction {
//     final CommodityStart start;
//     final String name;
// 
//     public CommodityDropoff(String name, CommodityStart start) {
//         this.start = start;
//         this.name = name;
//     }
// 
//     @Override
//     public String getName() {
//         return name;
//     }
// 
//     @Override
//     public String toString() {
//         return getName();
//     }
// }
// 
// Path: heuristicsearch/src/main/java/xyz/thepathfinder/routing/domain/RoutingSolution.java
// @PlanningSolution
// public class RoutingSolution implements Solution<HardSoftLongScore> {
// 
//     HardSoftLongScore score;
//     List<Transport> transportList;
//     List<CommodityAction> commodityActionList;
// 
//     @Override
//     public HardSoftLongScore getScore() {
//         return score;
//     }
// 
//     @Override
//     public void setScore(HardSoftLongScore score) {
//         this.score = score;
//     }
// 
//     @Override
//     public Collection<? extends RouteAction> getProblemFacts() {
//         List<RouteAction> routeActions = new ArrayList<>();
//         routeActions.addAll(transportList);
//         routeActions.addAll(commodityActionList);
//         return routeActions;
//     }
// 
//     @PlanningEntityCollectionProperty
//     @ValueRangeProvider(id = "transportRange")
//     public List<Transport> getTransportList() {
//         return transportList;
//     }
// 
//     public void setTransportList(List<Transport> transports) {
//         transportList = transports;
//     }
// 
//     @PlanningEntityCollectionProperty
//     @ValueRangeProvider(id = "commodityActionRange")
//     public List<CommodityAction> getCommodityActionList() {
//         return commodityActionList;
//     }
// 
//     public void setCommodityActionList(List<CommodityAction> commodityActions) {
//         commodityActionList = commodityActions;
//     }
// }


// Path: heuristicsearch/src/main/java/xyz/thepathfinder/routing/score/RoutingScoreCalculator.java
import org.optaplanner.core.api.score.Score;
import org.optaplanner.core.api.score.buildin.hardsoftlong.HardSoftLongScore;
import org.optaplanner.core.impl.score.director.easy.EasyScoreCalculator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import xyz.thepathfinder.routing.domain.CommodityAction;
import xyz.thepathfinder.routing.domain.CommodityDropoff;
import xyz.thepathfinder.routing.domain.RoutingSolution;
import static java.util.stream.Collectors.summingLong;

                        }
                    }
                }
            }
            return violations;
        }));
    }

    static long capacitiesViolated(RoutingSolution solution) {
        return solution.getTransportList().stream().collect(summingLong(t -> {
            Map<String, Integer> capacities = new HashMap<>(t.getCapacities());
            CommodityAction commodityAction = t.getNextCommodityAction();
            while (commodityAction != null) {
                for (String key : capacities.keySet()) {
                    capacities.put(key, capacities.get(key) - commodityAction.getCapacity(key));
                }
                if (capacities.values().stream().anyMatch(x -> x < 0)) {
                    return 1;
                }
                commodityAction = commodityAction.getNextCommodityAction();
            }
            return 0;
        }));
    }

    static long getTotalDistance(RoutingSolution solution) {
        return solution.getTransportList().stream().collect(
            summingLong(t -> getPathDistance(t.getNextCommodityAction())));
    }

    static long getPathDistance(CommodityAction commodityAction) {