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

com.powsybl.openrao.searchtreerao.searchtree.algorithms.SearchTreeBloomer Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2021, RTE (http://www.rte-france.com)
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

package com.powsybl.openrao.searchtreerao.searchtree.algorithms;

import com.powsybl.openrao.data.crac.api.RaUsageLimits;
import com.powsybl.openrao.data.crac.api.RemedialAction;
import com.powsybl.openrao.data.crac.api.State;
import com.powsybl.openrao.data.crac.api.networkaction.NetworkAction;
import com.powsybl.openrao.data.crac.api.rangeaction.PstRangeAction;
import com.powsybl.openrao.data.crac.api.rangeaction.RangeAction;
import com.powsybl.openrao.searchtreerao.commons.NetworkActionCombination;
import com.powsybl.openrao.searchtreerao.result.api.OptimizationResult;
import com.powsybl.openrao.searchtreerao.searchtree.inputs.SearchTreeInput;
import com.powsybl.openrao.searchtreerao.searchtree.parameters.SearchTreeParameters;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author Joris Mancini {@literal }
 */
public final class SearchTreeBloomer {
    private final List preDefinedNaCombinations;
    private final List networkActionCombinationFilters;
    private final SearchTreeInput input;
    private final SearchTreeParameters parameters;

    public SearchTreeBloomer(SearchTreeInput input, SearchTreeParameters parameters) {
        RaUsageLimits raUsageLimits = parameters.getRaLimitationParameters().getOrDefault(input.getOptimizationPerimeter().getMainOptimizationState().getInstant(), new RaUsageLimits());
        this.preDefinedNaCombinations = parameters.getNetworkActionParameters().getNetworkActionCombinations();
        this.networkActionCombinationFilters = List.of(
            new AlreadyAppliedNetworkActionsFilter(),
            new AlreadyTestedCombinationsFilter(preDefinedNaCombinations),
            new MaximumNumberOfRemedialActionsFilter(raUsageLimits.getMaxRa()),
            new MaximumNumberOfRemedialActionPerTsoFilter(raUsageLimits.getMaxTopoPerTso(), raUsageLimits.getMaxRaPerTso()),
            new MaximumNumberOfTsosFilter(raUsageLimits.getMaxTso()),
            new FarFromMostLimitingElementFilter(input.getNetwork(), parameters.getNetworkActionParameters().skipNetworkActionFarFromMostLimitingElements(), parameters.getNetworkActionParameters().getMaxNumberOfBoundariesForSkippingNetworkActions()),
            new ElementaryActionsCompatibilityFilter(),
            new MaximumNumberOfElementaryActionsFilter(raUsageLimits.getMaxElementaryActionsPerTso())
        );
        this.input = input;
        this.parameters = parameters;
    }

    /**
     * This method generates a Set of NetworkActionCombinations.
     * The networkActionCombinations generated would be available after this leaf inside the tree.
     * They are either individual NetworkAction as defined in the Crac, or predefined
     * combinations of NetworkActions, defined in the SearchTreeRaoParameters and considered as being efficient when
     * activated together.
     * The bloom method ensures that the returned NetworkActionCombinations respect the following rules:
     * 
    *
  • they do not exceed the maximum number of usable remedial actions
  • *
  • they do not exceed the maximum number of usable remedial actions (PST & topo) per operator
  • *
  • they do not exceed the maximum number of operators
  • *
  • they are not too far away from the most limiting CNEC
  • *
*/ Set bloom(Leaf fromLeaf, Set networkActions) { // preDefined combinations Set networkActionCombinations = preDefinedNaCombinations.stream() .distinct() .filter(naCombination -> networkActions.containsAll(naCombination.getNetworkActionSet())) .collect(Collectors.toSet()); // + individual available Network Actions final List finalNetworkActionCombinations = new ArrayList<>(networkActionCombinations); Set effectivelyFinalNACombinations = networkActionCombinations; networkActions.stream() .filter(na -> finalNetworkActionCombinations.stream().noneMatch(naCombi -> naCombi.getNetworkActionSet().size() == 1 && naCombi.getNetworkActionSet().contains(na)) ) .forEach(ra -> effectivelyFinalNACombinations.add(new NetworkActionCombination(Set.of(ra)))); networkActionCombinations.addAll(effectivelyFinalNACombinations); // filters for (NetworkActionCombinationFilter networkActionCombinationFilter : networkActionCombinationFilters) { networkActionCombinations = networkActionCombinationFilter.filter(networkActionCombinations, fromLeaf); } return networkActionCombinations; } /** * This method checks if range action must be removed before applying a network action combination. * If so, parentLeafRangeActions must be removed before applying the combination. * Otherwise, it can be applied while keeping them. * Such a check is performed by analyzing RaUsageLimits for the given state. */ boolean shouldRangeActionsBeRemovedToApplyNa(NetworkActionCombination naCombination, OptimizationResult optimizationResult) { State optimizationState = input.getOptimizationPerimeter().getMainOptimizationState(); RaUsageLimits raUsageLimits = parameters.getRaLimitationParameters().get(optimizationState.getInstant()); if (Objects.isNull(raUsageLimits)) { return false; } // maxRa int naCombinationSize = naCombination.getNetworkActionSet().size(); Set alreadyActivatedNetworkActions = optimizationResult.getActivatedNetworkActions(); Set> alreadyActivatedRangeActions = optimizationResult.getActivatedRangeActions(optimizationState); if (alreadyActivatedNetworkActions.size() + alreadyActivatedRangeActions.size() + naCombinationSize > raUsageLimits.getMaxRa()) { return true; } // maxTso Set operators = naCombination.getOperators(); Set activatedTsos = alreadyActivatedNetworkActions.stream().map(RemedialAction::getOperator).filter(Objects::nonNull).collect(Collectors.toSet()); alreadyActivatedRangeActions.stream().map(RemedialAction::getOperator).filter(Objects::nonNull).forEach(activatedTsos::add); activatedTsos.addAll(operators); if (activatedTsos.size() > raUsageLimits.getMaxTso()) { return true; } // maxRaPerTso for (String tso : operators) { int numberOfAlreadyActivatedRangeActionsForTso = (int) alreadyActivatedRangeActions.stream().filter(ra -> tso.equals(ra.getOperator())).count(); int numberOfAlreadyAppliedNetworkActionsForTso = (int) alreadyActivatedNetworkActions.stream().filter(na -> tso.equals(na.getOperator())).count(); if (numberOfAlreadyAppliedNetworkActionsForTso + numberOfAlreadyActivatedRangeActionsForTso + naCombinationSize > raUsageLimits.getMaxRaPerTso().getOrDefault(tso, Integer.MAX_VALUE)) { return true; } } // maxElementaryActionPerTso Map movedPstTapsPerTso = getNumberOfPstTapsMovedByTso(optimizationResult); for (String tso : raUsageLimits.getMaxElementaryActionsPerTso().keySet()) { int elementaryActions = 0; Set tsosNetworkActions = naCombination.getNetworkActionSet().stream().filter(networkAction -> tso.equals(networkAction.getOperator())).collect(Collectors.toSet()); for (NetworkAction networkAction : tsosNetworkActions) { // TODO: what if some network actions share common elementary action? elementaryActions = elementaryActions + networkAction.getElementaryActions().size(); } if (elementaryActions + movedPstTapsPerTso.getOrDefault(tso, 0) > raUsageLimits.getMaxElementaryActionsPerTso().getOrDefault(tso, Integer.MAX_VALUE)) { return true; } } return false; } boolean hasPreDefinedNetworkActionCombination(NetworkActionCombination naCombination) { return this.preDefinedNaCombinations.contains(naCombination); } Map getNumberOfPstTapsMovedByTso(OptimizationResult optimizationResult) { Map pstTapsMovedByTso = new HashMap<>(); Set activatedRangeActions = optimizationResult.getActivatedRangeActions(input.getOptimizationPerimeter().getMainOptimizationState()).stream().filter(PstRangeAction.class::isInstance).map(ra -> (PstRangeAction) ra).collect(Collectors.toSet()); for (PstRangeAction pstRangeAction : activatedRangeActions) { String operator = pstRangeAction.getOperator(); int tapsMoved = Math.abs(optimizationResult.getOptimizedTap(pstRangeAction, input.getOptimizationPerimeter().getMainOptimizationState()) - input.getPrePerimeterResult().getTap(pstRangeAction)); pstTapsMovedByTso.put(operator, pstTapsMovedByTso.getOrDefault(operator, 0) + tapsMoved); } return pstTapsMovedByTso; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy