package com.aps.service.Algorithm;

import com.aps.common.util.FileHelper;
import com.aps.common.util.ProductionDeepCopyUtil;
import com.aps.entity.Algorithm.*;
import com.aps.entity.basic.Entry;
import com.aps.entity.basic.GlobalParam;
import com.aps.entity.basic.MachineOption;
import com.aps.entity.basic.Order;

import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * 作者：佟礼
 * 时间：2025-11-24
 */
public class GeneticOperations {
    private final Random rnd = new Random();


    private static GlobalParam _GlobalParam;
    private static List<Entry> allOperations;

    private static ScheduleParams param;

    public GeneticOperations() {

    }

    public GeneticOperations(GlobalParam globalParam,List<Entry> _allOperations,ScheduleParams _param) {
        _GlobalParam=globalParam;
        allOperations = _allOperations;
        param=_param;
    }

    /**
     * 锦标赛选择
     */
    public List<Chromosome> tournamentSelection(List<Chromosome> population, int tournamentSize) {
        // 前置边界校验（避免NPE和无效计算）
        if (population == null || population.isEmpty()) {
            return new ArrayList<>();
        }
        int populationSize = population.size()>100?((int)(population.size()*0.8)):population.size();
        // 预计算需要选中的个体数量，避免动态判断
        int needSelectCount = populationSize - Math.max(1, Math.min(tournamentSize, populationSize));
        List<Chromosome> selected = new ArrayList<>(needSelectCount); // 预初始化容量
        // 边界值处理：锦标赛规模不能超过种群规模，且至少为1
        int effectiveTournamentSize = Math.max(1, Math.min(tournamentSize, populationSize));
        List<Chromosome> selectedtemp = new ArrayList<>(needSelectCount); // 预初始化容量
        // 预生成随机索引，减少Random对象创建开销
        Random random = this.rnd;

        // 固定次数循环，替代动态终止条件
        for (int selectIdx = 0; selectIdx < needSelectCount; selectIdx++) {

           // 优化1：Fisher-Yates抽样（无重复、无冲突，比HashSet高效）
            List<Integer> indices = new ArrayList<>(populationSize);
            for (int i = 0; i < populationSize; i++) {
                indices.add(i);
            }
            // 仅打乱前effectiveTournamentSize个索引，减少计算量
            for (int i = 0; i < effectiveTournamentSize; i++) {
                int swapIdx = i + random.nextInt(populationSize - i);
                Collections.swap(indices, i, swapIdx);
            }
            Chromosome bestCandidate=null;

            for (int i = 0; i < effectiveTournamentSize; i++) {
                int idx = indices.get(i);
                Chromosome curr= population.get(idx);
                    if(bestCandidate!=null)
                    {
                        int rankCompare = Integer.compare(curr.getRank(), bestCandidate.getRank());

                        if(rankCompare==0)
                        {
                            int crowdingCompare = Double.compare(curr.getCrowdingDistance(), bestCandidate.getCrowdingDistance());

                            if(crowdingCompare<0)
                            {
                                bestCandidate=curr;
                            }
                        }else {
                            if(rankCompare<0)
                            {
                                bestCandidate=curr;
                            }
                        }
                    }else {
                        bestCandidate=curr;
                    }
            }
            if (bestCandidate != null) {
                selected.add(bestCandidate);
            }
        }


        return selected;// ProductionDeepCopyUtil.deepCopyList(selected, Chromosome.class);
    }

    /**
     * 锦标赛选择
     */
    public List<Chromosome> tournamentSelection2(List<Chromosome> population, int tournamentSize) {
        // 前置边界校验（避免NPE和无效计算）
        if (population == null || population.isEmpty()) {
            return new ArrayList<>();
        }
        int populationSize = population.size()>100?((int)(population.size()*0.8)):population.size();
        // 预计算需要选中的个体数量，避免动态判断
        int needSelectCount = populationSize - Math.max(1, Math.min(tournamentSize, populationSize));
        List<Chromosome> selected = new ArrayList<>(needSelectCount); // 预初始化容量
        // 边界值处理：锦标赛规模不能超过种群规模，且至少为1
        int effectiveTournamentSize = Math.max(1, Math.min(tournamentSize, populationSize));
        List<Chromosome> selectedtemp = new ArrayList<>(needSelectCount); // 预初始化容量
        // 预生成随机索引，减少Random对象创建开销
        Random random = this.rnd;

        // 固定次数循环，替代动态终止条件
        for (int selectIdx = 0; selectIdx < needSelectCount; selectIdx++) {

            // 优化1：Fisher-Yates抽样（无重复、无冲突，比HashSet高效）
            List<Integer> indices = new ArrayList<>(populationSize);
            for (int i = 0; i < populationSize; i++) {
                indices.add(i);
            }
            // 仅打乱前effectiveTournamentSize个索引，减少计算量
            for (int i = 0; i < effectiveTournamentSize; i++) {
                int swapIdx = i + random.nextInt(populationSize - i);
                Collections.swap(indices, i, swapIdx);
            }
            Chromosome bestCandidate=null;

            for (int i = 0; i < effectiveTournamentSize; i++) {
                int idx = indices.get(i);
                Chromosome curr= population.get(idx);
                if(bestCandidate!=null)
                {
                    if(isBetter(curr,bestCandidate))
                    {
                        bestCandidate=curr;
                    }
                }else {
                    bestCandidate=curr;
                }
            }
            if (bestCandidate != null) {
                selected.add(bestCandidate);
            }
        }


        return selected;// ProductionDeepCopyUtil.deepCopyList(selected, Chromosome.class);
    }

    private boolean isBetter(Chromosome c1, Chromosome c2) {

        for (int i = 0; i < c1.getFitnessLevel().length; i++) {
            double[] Fitness1 = c1.getFitnessLevel();
            double[] Fitness2 = c2.getFitnessLevel();
            if (Fitness1[i] > Fitness2[i]) {
                return true;
            }
        }
        return false;

    }


    // 重载，使用默认锦标赛大小3
    public List<Chromosome> tournamentSelection(List<Chromosome> population) {

      //  List<Chromosome> populationn=  ProductionDeepCopyUtil.deepCopyList(tournamentSelection(population, param.getTournamentSize()),Chromosome.class);
        List<Chromosome> populationn= tournamentSelection(population, param.getTournamentSize());
        populationn.parallelStream().forEach(t->DelOrder(t));

        return  populationn;
    }
    // 重载，使用默认锦标赛大小3
    public List<Chromosome> tournamentSelection2(List<Chromosome> population) {

        //  List<Chromosome> populationn=  ProductionDeepCopyUtil.deepCopyList(tournamentSelection(population, param.getTournamentSize()),Chromosome.class);
        List<Chromosome> populationn= tournamentSelection2(population, param.getTournamentSize());
        populationn.forEach(t->DelOrder(t));

        return  populationn;
    }

    /**
     * 改进POX交叉（工序排序部分）
     */
    public Pair<Chromosome, Chromosome> poxCrossover(Chromosome parent1, Chromosome parent2, int orderCount) {
        // 前置校验：确保父代序列长度一致（避免数组越界）
        int seqLength = parent1.getOperationSequencing().size();
        if (seqLength != parent2.getOperationSequencing().size()) {
            throw new IllegalArgumentException("父代操作序列长度不一致，无法交叉！");
        }

        // 步骤1：统计两个父代中每个工件的出现次数，确定最大允许次数
        Map<Integer, Integer> parent1JobCount = countJobOccurrences(parent1.getOperationSequencing());
        Map<Integer, Integer> parent2JobCount = countJobOccurrences(parent2.getOperationSequencing());
        Map<Integer, Integer> maxAllowedCount = new HashMap<>();
        for (int job = 1; job <= orderCount; job++) {
            int count1 = parent1JobCount.getOrDefault(job, 0);
            int count2 = parent2JobCount.getOrDefault(job, 0);
            maxAllowedCount.put(job, Math.max(count1, count2)); // 取父代中该工件的最大出现次数
        }

        // 步骤2：随机划分工件集
        List<Integer> jobset1 = new ArrayList<>();
        for (int i = 1; i <= orderCount; i++) {
            jobset1.add(i);
        }
        Collections.shuffle(jobset1, rnd);
        // 当orderCount为奇数时，避免jobset1过短（取ceil(orderCount/2)，确保划分均衡）
        int jobset1Size = (orderCount + 1) / 2;
        jobset1 = jobset1.subList(0, jobset1Size);

        Set<Integer> jobset1Set = new HashSet<>(jobset1);
        List<Integer> jobset2 = new ArrayList<>();
        for (int i = 1; i <= orderCount; i++) {
            if (!jobset1Set.contains(i)) {
                jobset2.add(i);
            }
        }

        CopyOnWriteArrayList<Integer> child1Os, child2Os;

        // 根据是否允许打破优先级选择不同的生成策略
        if (_GlobalParam.isIsBreakPriority()) {
            // 允许打破优先级，使用原来的方法
            child1Os = generateChildOsWithCountLimit(parent1, parent2, jobset1Set, maxAllowedCount, seqLength);
            child2Os = generateChildOsWithCountLimit(parent2, parent1, jobset1Set, maxAllowedCount, seqLength);
        } else {
            // 不允许打破优先级，使用优先级保护的方法
            child1Os = generateChildOsWithPriorityProtection(parent1, parent2, jobset1Set, maxAllowedCount, seqLength);
            child2Os = generateChildOsWithPriorityProtection(parent2, parent1, jobset1Set, maxAllowedCount, seqLength);
        }

        // 机器选择部分交叉
        // 构建工序ID到机器选择的映射，避免因GlobalOpList顺序不同导致的问题
        Map<Integer, Integer> parent1OpToMachine = buildOpToMachineMap(parent1);
        Map<Integer, Integer> parent2OpToMachine = buildOpToMachineMap(parent2);

        CopyOnWriteArrayList<Integer> child1Ms = new CopyOnWriteArrayList<>();
        CopyOnWriteArrayList<Integer> child2Ms = new CopyOnWriteArrayList<>();
        // 使用parent1的globalOpList作为基准（因为child1和child2都继承自parent1的orders/machines等）
        for (GlobalOperationInfo opInfo : parent1.getGlobalOpList()) {
            int opId = opInfo.getOp().getId();
            int m1 = parent1OpToMachine.getOrDefault(opId, 1);
            int m2 = parent2OpToMachine.getOrDefault(opId, 1);

            if (rnd.nextDouble() < 0.5) {
                child1Ms.add(m1);
                child2Ms.add(m2);
            } else {
                child1Ms.add(m2);
                child2Ms.add(m1);
            }
        }

        Chromosome child1 = new Chromosome();
        child1.setGlobalOpList(parent1.getGlobalOpList());

        child1.setMachineSelection(child1Ms);
        child1.setOperationSequencing(child1Os);

        Chromosome child2 = new Chromosome();
        child2.setGlobalOpList(parent1.getGlobalOpList());
        child2.setMachineSelection(child2Ms);
        child2.setOperationSequencing(child2Os);

        return new Pair<>(child1, child2);
    }
    /**
     * 核心方法：生成子代操作序列（遵循POX规则 + 工件出现次数限制 + 优先级保护）
     * 当不允许打破优先级时，确保高优先级的工序始终在低优先级工序之前
     * @param mainParent 主父代（优先取其基因）
     * @param secondaryParent 次父代（备选基因）
     * @param jobset1Set POX交叉的工件集判断依据
     * @param maxAllowedCount 每个工件的最大允许出现次数
     * @param seqLength 序列长度
     * @return 符合规则的子代序列
     */
    private CopyOnWriteArrayList<Integer> generateChildOsWithPriorityProtection(
            Chromosome mainParent, Chromosome secondaryParent,
            Set<Integer> jobset1Set, Map<Integer, Integer> maxAllowedCount,
            int seqLength
    ) {
        CopyOnWriteArrayList<Integer> mainSeq = mainParent.getOperationSequencing();
        CopyOnWriteArrayList<Integer> secondarySeq = secondaryParent.getOperationSequencing();

        // 1. 首先按POX规则和次数限制收集候选序列
        CopyOnWriteArrayList<Integer> candidateSeq = new CopyOnWriteArrayList<>();
        Map<Integer, Integer> childJobCount = new HashMap<>();

        for (int i = 0; i < seqLength; i++) {
            int mainOp = mainSeq.get(i);
            int secondaryOp = secondarySeq.get(i);
            int selectedOp = mainOp;

            // 遵循原POX交叉规则筛选候选工件
            if (!(jobset1Set.contains(mainOp) || jobset1Set.contains(secondaryOp))) {
                selectedOp = secondaryOp;
            }

            // 检查候选工件是否超过最大允许次数
            int currentCount = childJobCount.getOrDefault(selectedOp, 0);
            if (currentCount >= maxAllowedCount.get(selectedOp)) {
                // 切换到另一个父代的工件
                selectedOp = (selectedOp == mainOp) ? secondaryOp : mainOp;

                // 极端情况：切换后仍超过次数，从所有工件中选一个未超次数的
                if (childJobCount.getOrDefault(selectedOp, 0) >= maxAllowedCount.get(selectedOp)) {
                    selectedOp = findValidJob(maxAllowedCount, childJobCount);
                }
            }

            childJobCount.put(selectedOp, childJobCount.getOrDefault(selectedOp, 0) + 1);
            candidateSeq.add(selectedOp);
        }

        // 2. 按优先级重新排序，确保不打破优先级
        List<IndexedOperation> indexedOps = new ArrayList<>();
        for (int i = 0; i < candidateSeq.size(); i++) {
            int groupId = candidateSeq.get(i);
            Entry entry = allOperations.stream()
                    .filter(o -> o.getGroupId() == groupId)
                    .findFirst()
                    .orElse(null);
            double priority = (entry != null) ? entry.getPriority() : 0;
            indexedOps.add(new IndexedOperation(i, groupId, priority));
        }

        // 按优先级降序排序（高优先级在前），同时保持同一优先级内的相对顺序
        indexedOps.sort((a, b) -> {
            int priorityCompare = Double.compare(a.priority, b.priority);
            if (priorityCompare != 0) {
                return priorityCompare;
            }
            return Integer.compare(a.originalIndex, b.originalIndex);
        });

        // 构建最终的子序列
        CopyOnWriteArrayList<Integer> childOs = new CopyOnWriteArrayList<>();
        for (IndexedOperation io : indexedOps) {
            childOs.add(io.groupId);
        }

        return childOs;
    }
    /**
     * 辅助方法：构建工序ID到机器选择的映射
     * @param chromosome 染色体
     * @return 工序ID -> 机器选择索引的映射
     */
    private Map<Integer, Integer> buildOpToMachineMap(Chromosome chromosome) {
        Map<Integer, Integer> opToMachine = new HashMap<>();
        List<GlobalOperationInfo> globalOpList = chromosome.getGlobalOpList();
        List<Integer> machineSelection = chromosome.getMachineSelection();

        if (globalOpList != null && machineSelection != null) {
            for (int i = 0; i < Math.min(globalOpList.size(), machineSelection.size()); i++) {
                GlobalOperationInfo opInfo = globalOpList.get(i);
                if (opInfo != null && opInfo.getOp() != null) {
                    int opId = opInfo.getOp().getId();
                    opToMachine.put(opId, machineSelection.get(i));
                }
            }
        }

        return opToMachine;
    }
    /**
     * 辅助类：用于保持原始索引和优先级的工序信息
     */
    private static class IndexedOperation {
        int originalIndex;
        int groupId;
        double priority;

        IndexedOperation(int originalIndex, int groupId, double priority) {
            this.originalIndex = originalIndex;
            this.groupId = groupId;
            this.priority = priority;
        }
    }
    /**
     * 核心方法：生成子代操作序列（遵循POX规则 + 工件出现次数限制）
     * @param mainParent 主父代（优先取其基因）
     * @param secondaryParent 次父代（备选基因）
     * @param jobset1Set POX交叉的工件集判断依据
     * @param maxAllowedCount 每个工件的最大允许出现次数
     * @param seqLength 序列长度
     * @return 符合规则的子代序列
     */
    private CopyOnWriteArrayList<Integer> generateChildOsWithCountLimit(
            Chromosome mainParent, Chromosome secondaryParent,
            Set<Integer> jobset1Set, Map<Integer, Integer> maxAllowedCount,
            int seqLength
    ) {
        CopyOnWriteArrayList<Integer> childOs = new CopyOnWriteArrayList<>();
        CopyOnWriteArrayList<Integer> mainSeq = mainParent.getOperationSequencing();
        CopyOnWriteArrayList<Integer> secondarySeq = secondaryParent.getOperationSequencing();
        // 实时统计子代中每个工件的当前出现次数
        Map<Integer, Integer> childJobCount = new HashMap<>();

        for (int i = 0; i < seqLength; i++) {
            int mainOp = mainSeq.get(i); // 主父代当前位置工件
            int secondaryOp = secondarySeq.get(i); // 次父代当前位置工件
            int selectedOp = mainOp; // 先按POX规则初始化候选工件

            // 步骤1：遵循原POX交叉规则筛选候选工件
            if (!(jobset1Set.contains(mainOp) || jobset1Set.contains(secondaryOp))) {
                selectedOp = secondaryOp;
            }

            // 步骤2：检查候选工件是否超过最大允许次数，若超过则切换到另一个父代的工件
            int currentCount = childJobCount.getOrDefault(selectedOp, 0);
            if (currentCount >= maxAllowedCount.get(selectedOp)) {
                // 切换到另一个父代的工件
                selectedOp = (selectedOp == mainOp) ? secondaryOp : mainOp;

                // 步骤3：极端情况：切换后仍超过次数，从所有工件中选一个未超次数的（确保序列有效）
                if (childJobCount.getOrDefault(selectedOp, 0) >= maxAllowedCount.get(selectedOp)) {
                    selectedOp = findValidJob(maxAllowedCount, childJobCount);
                }
            }

            // 步骤4：更新子代工件计数并添加到序列
            childJobCount.put(selectedOp, childJobCount.getOrDefault(selectedOp, 0) + 1);
            childOs.add(selectedOp);
        }

        return childOs;
    }
    /**
     * 辅助方法：找到一个未超过最大允许次数的工件（极端情况兜底）
     */
    private int findValidJob(Map<Integer, Integer> maxAllowedCount, Map<Integer, Integer> childJobCount) {
        for (Map.Entry<Integer, Integer> entry : maxAllowedCount.entrySet()) {
            int job = entry.getKey();
            int maxCount = entry.getValue();
            int currentCount = childJobCount.getOrDefault(job, 0);
            if (currentCount < maxCount) {
                return job;
            }
        }
        // 理论上不会走到这里（因序列长度=父代长度，总次数不会超父代总和）
        throw new IllegalStateException("无可用工件，序列生成失败！");
    }
    /**
     * 辅助方法：统计操作序列中每个工件的出现次数
     */
    private Map<Integer, Integer> countJobOccurrences(List<Integer> operationSequencing) {
        Map<Integer, Integer> countMap = new HashMap<>();
        for (int job : operationSequencing) {
            countMap.put(job, countMap.getOrDefault(job, 0) + 1);
        }
        return countMap;
    }
    /**
     * 变异操作
     */
    public void mutate(Chromosome chromosome, List<GlobalOperationInfo> globalOpList, double baseMutationProb) {
       int i= rnd.nextInt(2);
        if(i==0) {
            // 1. 机器选择部分变异
          boolean state=  mutateMachineSelection(chromosome, globalOpList, baseMutationProb);
            if(!state)
            {
                i=1;
            }
        }
        if(i==1) {
            // 2. 工序排序部分变异
            mutateOperationSequencing(chromosome);
        }
    }

    // 重载，使用默认变异概率
    public void mutate(Chromosome chromosome, List<GlobalOperationInfo> globalOpList) {
        mutate(chromosome, globalOpList, 0.1);
    }

    private boolean mutateMachineSelection(Chromosome chromosome, List<GlobalOperationInfo> globalOpList, double baseMutationProb) {
        // 计算变异位置数量

        List<Entry> entrys=  allOperations.stream().filter(t->t.getMachineOptions().size()>1).collect(Collectors.toList());
        if(entrys==null||entrys.size()==0)
        {
            return false;
        }
        Integer count=entrys.size();
        int r = Math.max(1, (int) (count * baseMutationProb));
        int i = 0;
        while (i < r) {
            int pos1 = rnd.nextInt(count);
            // 获取对应工序
            Entry operation= entrys.get(pos1);

            int pos = IntStream.range(0, globalOpList.size())
                    .filter(h -> operation.getId()==globalOpList.get(h).getOp().getId())
                    .findFirst().orElse(0);


            CopyOnWriteArrayList<Integer>  MachineSelections=  chromosome.getMachineSelection();
            int machineSeq = MachineSelections.get(pos);


                // 选择当前所选设备外最短加工时间的机器
                List<MachineOption> optionalMachines = operation.getMachineOptions();
                // 找到当前选中的机器
                MachineOption currentMachine = optionalMachines.get(machineSeq - 1);
                // 筛选其他机器并找到加工时间最短的
                MachineOption minLoadMachine = optionalMachines.stream()
                        .filter(m -> m.getMachineId() != currentMachine.getMachineId())
                        .min(Comparator.comparingDouble(m -> m.getProcessingTime()))
                        .orElse(currentMachine); // 如果没有其他机器，保持当前

                machineSeq = optionalMachines.indexOf(minLoadMachine) + 1;
            MachineSelections.set(pos, machineSeq);
            chromosome.setMachineSelection(MachineSelections);
                i++;

        }
        return true;
    }

    /**
     * 低优先级优先的工序排序变异
     */
    private void mutateOperationSequencing(Chromosome chromosome) {
        Random rnd = new Random();

        // 选择变异方式（交换或反转）
        if (rnd.nextDouble() < 0.5) {
            // 交换：优先选择高优先级工序的索引
            OperationSequencingWeight os1 = selectHighPriorityIndex(chromosome.getOperationSequencing(), 0);
            int idx1 = os1.getIndex();
            OperationSequencingWeight os2 = selectHighPriorityIndex(chromosome.getOperationSequencing(), os1.getWeight());
            int idx2 = os2.getIndex();

            // 交换位置
            CopyOnWriteArrayList<Integer> os = chromosome.getOperationSequencing();
            Collections.swap(os, idx1, idx2);
            chromosome.setOperationSequencing(os);
        } else {
            // 反转：仅对高优先级工序集中的子序列反转
            OperationSequencingWeight osStart = selectHighPriorityIndex(chromosome.getOperationSequencing(), 0);
            int start = osStart.getIndex();
            OperationSequencingWeight osEnd = selectHighPriorityIndex(chromosome.getOperationSequencing(), osStart.getWeight());
            int end = osEnd.getIndex();

            if (start > end) {
                int temp = start;
                start = end;
                end = temp;
            }

            // 执行反转
            CopyOnWriteArrayList<Integer> os = chromosome.getOperationSequencing();
            for (int i = 0; i < (end - start + 1) / 2; i++) {
                int pos1 = start + i;
                int pos2 = end - i;
                Collections.swap(os, pos1, pos2);
            }
            chromosome.setOperationSequencing(os);
        }
    }

    /**
     * 优先选择高优先级工序的索引（用于变异）
     */
    private OperationSequencingWeight selectHighPriorityIndex(List<Integer> os, double weight) {
        Random rnd = new Random();
        List<OperationSequencingWeight> indexWeights = CommonCalculator.getOsw(os, allOperations);

        if (!_GlobalParam.isIsBreakPriority()) {
            if (weight == 0) {
                return indexWeights.get(rnd.nextInt(indexWeights.size()));
            } else {
                List<OperationSequencingWeight> filtered = indexWeights.stream()
                        .filter(t -> t.getWeight() == weight)
                        .collect(Collectors.toList());
                return filtered.get(rnd.nextInt(filtered.size()));
            }
        }

        return indexWeights.get(CommonCalculator.getOsIndex(indexWeights));
    }
    public void DelOrder(Chromosome chromosome) {
        List<Entry> allOperations = chromosome.getAllOperations();
        List<GlobalOperationInfo> globalOpList=  chromosome.getGlobalOpList();
        if(chromosome.getOrders()==null||chromosome.getOrders().size()==0)
            return;
        List<Order> orders = chromosome.getOrders();
        List<Integer> OperationSequencing=  chromosome.getOperationSequencing();
        List<Integer> newoorderids= orders.stream()
                .filter(t->t.isNewSfCreate())
                .map(Order::getId)
                .sorted(Comparator.reverseOrder())
                .collect(Collectors.toList());
        if(newoorderids!=null&&newoorderids.size()>0) {
            for (Integer id : newoorderids) {


                List<Entry> sourceOps = allOperations.stream()
                        .filter(o -> o.getGroupId()==id)
                        .sorted(Comparator.comparing(Entry::getSequence))
                        .collect(Collectors.toList());

                for (Entry entry : sourceOps) {
                    OptionalInt index1 = IntStream.range(0, globalOpList.size())
                            .filter(h -> entry.getId()==globalOpList.get(h).getOp().getId())
                            .findFirst();
                    globalOpList.remove((int)index1.orElse(0));

                    chromosome.getMachineSelection().remove((int)index1.orElse(0));
                }

                chromosome.getOperatRel().remove(id-1);

            }
            allOperations.removeIf(t ->newoorderids.contains(t.getGroupId()));
            OperationSequencing.removeIf(t ->newoorderids.contains(t));
            AtomicInteger globalOpId = new AtomicInteger(0);
            globalOpList.forEach(t-> {

                t.setGlobalOpId(globalOpId.getAndIncrement());

            });
            orders.removeIf(t ->newoorderids.contains(t.getId()));
        }
    }
    private void log(String message,  boolean enableLogging) {
        if (false ) {
            FileHelper.writeLogFile(message);
        }
    }


}
