复现一篇分布式装配置换流水车间调度问题的代码——基于回溯搜索的超启发式算法

复现一篇分布式装配置换流水车间调度问题的代码——基于回溯搜索的超启发式算法

摘要

Distributed assembly permutation flow-shop scheduling problem (DAPFSP) is recognized as an important class of problems in modern supply chains and manufacturing systems. In this paper, a backtracking search hyper-heuristic (BS-HH) algorithm is proposed to solve the DAPFSP. In the BS-HH scheme, ten simple and effective heuristic rules are designed to construct a set of low-level heuristics (LLHs), and the backtracking search algorithm is employed as the high-level strategy to manipulate the LLHs to operate on the solution space. Additionally, an efficient solution encoding and decoding scheme is proposed to generate a feasible schedule. The effectiveness of the BS-HH is evaluated on two typical benchmark sets and the computational results indicate the superiority of the proposed BS-HH scheme over the state-of-the-art algorithms.

算法框架

在这里插入图片描述
在这里插入图片描述

说明

本篇博客在同窗@CXY_XZSong的大力帮助下得以实现,在此献上诚挚的感谢!本篇文章使用回溯搜索算法作为超启发式的高层算子,原文作者设计了10种低级启发式(对工件、产品的插入、交换、逆序等操作)解决分布式装配置换流水车间调度问题,优化目标为最大完成时间(Cmax)。本人并不精通Java,只是工作需要(还在努力学习当中),编程过程存在很多不规范的地方,代码并不能保证完全正确,请自行批判使用,有问题的请私信,诚望各位大佬指出不足,共同交流学习,这将有助于我改进自己的工作!

代码

测试集请在该网站自行下载:调度测试集

测试类

package practice.comparison.BS_HH;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @Date: 2022/4/26 8:29
 * @Author: 
 * @File: TestBSHH.class
 * @Software: IDEA
 * @Email: 1532116227@qq.com
 */
public class TestBSHH
{
    public static void main(String[] args) throws IOException
    {
//        final int[][] p = {{4, 6}, {3, 4}, {5, 2}, {5, 4}, {4, 2}, {3, 3},
//                {4, 3}, {3, 5}, {6, 2}, {3, 5}, {4, 4}, {4, 3}};//加工时间矩阵
//        final int[] assignSet = {1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4};
//        final int[] assignSet = {2, 2, 4, 3, 3, 1, 2, 1, 1, 3, 4, 4};
//        final int[] apt = {4, 8, 6, 6};
//        final int F = 2;//工厂数
//        final int t = 4;//产品数

//        int Cmax;
//
//        BSHH bshh = new BSHH(p, assignSet, apt, F, t, 5, 1, 0.8, c);
//        Cmax = bshh.algorithm();
//        System.out.println("Cmax = " + Cmax);

//======================================================================================================================

        int jobs[] = {100, 200, 500};
        int machines[] = {5, 10, 20};
        int factories[] = {4, 6, 8};
        int products[] = {30, 40, 50};
        int instnces[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

//        int jobs[] = {100};
//        int machines[] = {5};
//        int factories[] = {4};
//        int products[] = {30};
//        int instnces[] = {1};

        final int cc = 20;
        int F;//工厂数
        int t;//产品数

        int[][] p = new int[0][];
        ReadTxt readTxt = new ReadTxt();
        List<Integer> pi = new ArrayList<>();//工件序列
        int[] apt;
        int[] assignSet;
        int Cmax;
        int count = 1;

        int[][] result = new int[machines.length * factories.length * products.length * instnces.length][1];
        int index;
        int index2 = 0;
        String filePath;
        String sheetName;
//        PoiOutputXlsx poiOutputXlsx = new PoiOutputXlsx();
//        filePath = "C:\\Users\\Zhu Bo\\Desktop\\001.xlsx";
        int[] flag_NI_machine;
//        RIG2 rig2 = new RIG2(flag_NI_machine);
//        RIG2 rig2 = new RIG2();

//        int[] D = new int[jobs.length * machines.length * factories.length * products.length * instnces.length];
        int[] c;


        int Run = 5;
        for (int run = 0; run < Run; run++)
        {
            BufferedWriter bw = new BufferedWriter(new FileWriter("C:\\Users\\Zhu Bo\\Desktop\\Results\\DAMNIPFSP_BSHH_LARGE" + "_" + cc + "_" + (run + 1) + ".txt"));//使用缓冲流加快速度
            for (int n = 0; n < jobs.length; n++)//job.length - 1
            {
                index = 0;
                for (int m = 0; m < machines.length; m++)//mechine.length - 1
                {
                    for (int k = 0; k < factories.length; k++)//num.length - 1
                    {
                        for (int i = 0; i < products.length; i++)
                        {
                            index2 = 0;
                            c = new int[instnces.length];
                            for (int j = 0; j < instnces.length; j++)
                            {
                                //小规模
//                            p = readTxt.getProcessingTimes("D:\\Instances\\DAPFSPSmall\\ProcessingTime\\I" + "_"
//                                    + jobs[n] + "_" + machines[m] + " _" + factories[k] + "_" + products[i] + "_" + instnces[j] + ".txt", jobs[n], machines[m]);
//                            apt = readTxt.getAssemblyTimes("D:\\Instances\\DAPFSPSmall\\AssemblyTime\\I" + "_"
//                                    + jobs[n] + "_" + machines[m] + " _" + factories[k] + "_" + products[i] + "_" + instnces[j] + ".txt", products[i]);
//                            assignSet = new int[jobs[n]];
//                            assignSet = readTxt.getAssignSet("D:\\Instances\\DAPFSPSmall\\AssignSet\\I" + "_"
//                                    + jobs[n] + "_" + machines[m] + " _" + factories[k] + "_" + products[i] + "_" + instnces[j] + ".txt", jobs[n], products[i]);
//                            flag_NI_machine = readTxt.getNoIdleConstraint("D:\\Instances\\DAPFSPSmall\\NoIdleConstraint\\I" + "_"
//                                    + jobs[n] + "_" + machines[m] + " _" + factories[k] + "_" + products[i] + "_" + instnces[j] + ".txt", machines[m]);
                                //大规模
                                p = readTxt.getProcessingTimes("D:\\Instances\\DAPFSPLarge\\ProcessingTime\\I" + "_"
                                        + jobs[n] + "_" + machines[m] + " _" + factories[k] + "_" + products[i] + "_" + instnces[j] + ".txt", jobs[n], machines[m]);
                                apt = readTxt.getAssemblyTimes("D:\\Instances\\DAPFSPLarge\\AssemblyTime\\I" + "_"
                                        + jobs[n] + "_" + machines[m] + " _" + factories[k] + "_" + products[i] + "_" + instnces[j] + ".txt", products[i]);
                                assignSet = new int[jobs[n]];
                                assignSet = readTxt.getAssignSet("D:\\Instances\\DAPFSPLarge\\AssignSet\\I" + "_"
                                        + jobs[n] + "_" + machines[m] + " _" + factories[k] + "_" + products[i] + "_" + instnces[j] + ".txt", jobs[n], products[i]);
                                flag_NI_machine = readTxt.getNoIdleConstraint("D:\\Instances\\DAPFSPLarge\\NoIdleConstraint\\I" + "_"
                                        + jobs[n] + "_" + machines[m] + " _" + factories[k] + "_" + products[i] + "_" + instnces[j] + ".txt", machines[m]);
                                System.out.println(count++);
                                F = factories[k];
                                t = products[i];
//
                                BSHH bshh = new BSHH(p, assignSet, apt, F, t, 5, 1, 0.8, cc, flag_NI_machine);
                                Cmax = bshh.algorithm();
//
                                System.out.println("Cmax = " + Cmax);
                                System.out.println("============================================");
//                            result[index++][0] = Cmax;
                                c[index2++] = Cmax;
                            }
                            for (int ii = 0; ii < c.length; ii++)
                            {
                                bw.write(c[ii] + "\n");
                            }
                            bw.write("\n\n");
                            bw.flush();
                        }
                    }
                }
            sheetName = "Job" + jobs[n];
            poiOutputXlsx.outPutXlsx(filePath, sheetName, result);
            }
//            for (int i = 0; i < D.length; i++)
//            {
//                bw.write(D[i] + "\n");
//                if ((i + 1) % 180 == 0)
//                {
//                    bw.write("\n\n");
//                }
//            }
            bw.close();
        }
    }
}

算法主体

package practice.comparison.BS_HH;

import org.apache.commons.lang.SerializationUtils;
import practice.calculateCMAX.CalculateCmaxDAMNIPFSP2;

import java.util.*;

/**
 * @Date: 2022/4/26 8:29
 * @Author: 
 * @File: BSHH.class
 * @Software: IDEA
 * @Email: 1532116227@qq.com
 */
public class BSHH
{
    private final int[][] p;
    private final int[] assignSet;
    private final int F;
    private final int t;
    private final int lambda;
    private final double rMix;
    private final double ksi;
    private final int c;
    private final int[] apt;
    private final int[] flag_NI_machine;

    public BSHH(int[][] p, int[] assignSet, int[] apt, int f, int t, int lambda, double rMix, double ksi, int c, int[] flag_ni_machine)
    {
        this.p = p;
        this.assignSet = assignSet;
        this.apt = apt;
        F = f;
        this.t = t;
        this.lambda = lambda;
        this.rMix = rMix;
        this.ksi = ksi;
        this.c = c;
        this.flag_NI_machine = flag_ni_machine;
    }

    private final Random random = new Random();

    public int algorithm()
    {
        int n = p[0].length;
        int m = p.length;

        int ps = 50;
        int heuristicsNumber = 10;

//        Individual individual;
        List<Individual> population = new ArrayList<>();
        List<Individual> oldPopulation = new ArrayList<>();
        List<Individual> trailPopulation;
        Individual individualTemp;
        List<Integer>[] products = new List[t];
        Heuristics heuristics = new Heuristics(apt, flag_NI_machine);

        for (int i = 0; i < t; i++)
        {
            products[i] = new ArrayList<>();
        }
        for (int i = 0; i < assignSet.length; i++)
        {
            products[assignSet[i] - 1].add(i + 1);//产品与工件对应
        }

        double[][] muP = new double[ps][heuristicsNumber];
//        double[][] trailP = new double[ps][heuristicsNumber];
        double[] tempHeuristicSequence;
        double[] tempHeuristicSequence2;

        int[][] map = new int[ps][heuristicsNumber];
        List<Integer> pi = new LinkedList<>();
        for (int i = 1; i <= t; i++)
        {
            pi.add(i);
        }
        List<Integer> heuristicSequence = new ArrayList<>();
        for (int i = 0; i < heuristicsNumber; i++)
        {
            heuristicSequence.add(i + 1);
        }
        initPopulation(p, apt, pi, products, heuristicSequence, population, ps, heuristicsNumber, t, F);
        initPopulation(p, apt, pi, products, heuristicSequence, oldPopulation, ps, heuristicsNumber, t, F);


        long end = c * m * n;
        long startTime = System.currentTimeMillis();
        while (System.currentTimeMillis() - startTime < end)
        {
            if (Math.random() < Math.random())
            {
                oldPopulation = new ArrayList<>(population);
            }
            Collections.shuffle(oldPopulation);

            for (int i = 0; i < ps; i++)
            {
                Arrays.fill(map[i], 1);//填充
            }
            for (int i = 0; i < ps; i++)
            {
                if (Math.random() > Math.random())
                {
                    Collections.shuffle(heuristicSequence);
                    for (int j = 0, randIntEnd = (int) Math.ceil(rMix * heuristicsNumber * Math.random()); j < randIntEnd; j++)
                    {
                        map[i][heuristicSequence.get(j) - 1] = 0;
                    }
                }
                else
                {
                    map[i][random.nextInt(heuristicsNumber)] = 0;
                }
            }

            for (int i = 0; i < ps; i++)
            {
                tempHeuristicSequence = population.get(i).heuristicSequence;
                tempHeuristicSequence2 = oldPopulation.get(i).heuristicSequence;
                for (int j = 0; j < heuristicsNumber; j++)
                {
                    muP[i][j] = tempHeuristicSequence[j] + lambda * Math.random() * (tempHeuristicSequence2[j] - tempHeuristicSequence[j]);
                    if (muP[i][j] < 1)
                    {
                        muP[i][j] = 1;
                    }
                    else if (muP[i][j] > heuristicsNumber)
                    {
                        muP[i][j] = heuristicsNumber;
                    }
                    else
                    {
                        muP[i][j] = Math.round(muP[i][j]);
                    }
                }
            }

//            trailPopulation = new ArrayList<>(population);
            trailPopulation = new ArrayList<>();
            for (Individual individual : population)
            {
                trailPopulation.add((Individual) SerializationUtils.clone(individual));//深拷贝
            }

            for (int i = 0; i < ps; i++)
            {
                tempHeuristicSequence = population.get(i).heuristicSequence;
                tempHeuristicSequence2 = trailPopulation.get(i).heuristicSequence;
                for (int j = 0; j < heuristicsNumber; j++)
                {
                    if (map[i][j] == 1)
                    {
                        tempHeuristicSequence2[j] = tempHeuristicSequence[j];
                    }
                    else
                    {
                        tempHeuristicSequence2[j] = muP[i][j];
                    }
                }
            }

            for (int i = 0; i < ps; i++)
            {
                individualTemp = trailPopulation.get(i);
                for (double heuristicIndex : individualTemp.heuristicSequence)
                {
                    //todo 低级启发式
                    individualTemp = heuristics.improvedLLH(p, apt, individualTemp, ksi, (int) heuristicIndex, t, F);
                }
                if (individualTemp.cmax < population.get(i).cmax)
                {
                    population.set(i, individualTemp);
                }
            }
        }
//        return Collections.min(population).tf;
        return Collections.min(population).cmax;
//        return 1;
    }

    //todo 初始化种群
    private void initPopulation(int[][] p, int[] pp,
                                List<Integer> pi, List<Integer>[] products, List<Integer> heuristicSequence,
                                List<Individual> population, int ps, int heuristicsNumber, int t, int f)
    {
        Individual individual;

        CalculateCmaxDAMNIPFSP2 ccd = new CalculateCmaxDAMNIPFSP2();

        for (int i = 0; i < ps; i++)
        {
            individual = new Individual(heuristicsNumber);
            Collections.shuffle(pi);
            individual.pi = Others.copyList(pi);
            for (int j = 0; j < t; j++)
            {
                Collections.shuffle(products[j]);
            }
            individual.products = Others.copyList(products, t);
            Collections.shuffle(heuristicSequence);
            for (int j = 0; j < heuristicsNumber; j++)
            {
                individual.heuristicSequence[j] = heuristicSequence.get(j);
            }
//            individual.tf = calculateTF.nr2GetTF(p, pp, individual.products, individual.pi, f);

            List<Integer>[] schedule = new List[F];
//            CalculateCmaxDAPFSP ccd = new CalculateCmaxDAPFSP();
            Assignment assign = new Assignment();

            schedule = assign.algorithm(p, t, apt, F, individual.products, individual.pi);//NR2
//            individual.cmax = ccd.calAssembleCmax(schedule, p, F, individual.pi, products, apt);
            individual.cmax = ccd.method3(schedule, products, individual.pi, p, F, flag_NI_machine, apt);
            population.add(individual);
        }
    }
}

Assignment

package practice.comparison.BS_HH;

import practice.calculateCMAX.CalculateCmaxPFSP;

import java.util.*;

/**
 * @Date: 2022/3/30 20:58
 * @Author:
 * @File: Heuristic1.class
 * @Software: IDEA
 * @Email: 1532116227@qq.com
 */
public class Assignment
{
    public List<Integer>[] algorithm(int[][] p, int t, int[] apt, int F, List<Integer>[] sequence, List<Integer> pi_product)
    {
//        List<Integer> pi_product;
        List<Integer> piT = new ArrayList<>();
//        pi_product = ruleOfSPT(pi_product, apt);
        List<Integer>[] parSeq = new List[t];
        List<Integer>[] schedule;
//        for (int i = 0; i < t; i++)
//        {
//            parSeq[i] = new ArrayList<>();
//        }
//        for (int i = 0; i < t; i++)
//        {
            parSeq[i] = heuristicFL(p, sequence[pi_product.get(i) - 1]);
//            sequence[i] = heuristicFL(p, sequence[i]);
//        }
        for (int i = 0; i < t; i++)
        {
            piT.addAll(sequence[pi_product.get(i) - 1]);
        }
//        schedule = assignByNR1(p, piT, F);
        schedule = ecfRule(p, piT, F);

//        return parSeq;
        return schedule;
    }

    private List<Integer> heuristicFL(int[][] p, List<Integer> sequence)
    {
        int[] TPj;
        int[][] newp;
        List<Integer> R = new ArrayList<>();
        List<Integer> S = new ArrayList<>();
        List<Integer> copySeq = listCopy(sequence);
//        R = listCopy(copySeq);
        CalculateCmaxPFSP ccp = new CalculateCmaxPFSP();
        newp = getNewp(p, sequence);
        TPj = getTP(newp);
        Map<Integer, Integer> map = new HashMap<>();
        for (int i = 0; i < sequence.size(); i++)
        {
            map.put(copySeq.get(i), TPj[i]);
        }
        List<Map.Entry<Integer, Integer>> lst = new ArrayList<>(map.entrySet());
        Collections.sort(lst, (o1, o2) -> o1.getValue() - o2.getValue());
        for (Map.Entry<Integer, Integer> entry : lst)
        {
            R.add(entry.getKey());
        }
        int[][] p1 = {p[R.get(0) - 1], p[R.get(1) - 1]};
        int[][] p2 = {p[R.get(1) - 1], p[R.get(0) - 1]};
        if (ccp.forwardMethod(p1) < ccp.forwardMethod(p2))
        {
            S.add(R.get(0));
            S.add(R.get(1));
        }
        else
        {
            S.add(R.get(1));
            S.add(R.get(0));
        }
        for (int i = 2; i < R.size(); i++)
        {
            S = insertAndEvaluation(p, S, R.get(i));
        }
        //两两交换位置
        List<Integer> copyS = new ArrayList<>();
        copyS = listCopy(S);
        int[][] newp1;
        int[][] newp2;
        newp2 = getNewp(p, S);
        Map<List<Integer>, Integer> map1 = new HashMap<>();
        for (int i = 0; i < copyS.size() - 1; i++)
        {
            for (int j = i + 1; j < copyS.size(); j++)
            {
                Collections.swap(copyS, i, j);
                newp1 = getNewp(p, copyS);
                map1.put(listCopy(copyS), ccp.forwardMethod(newp1));
                Collections.swap(copyS, i, j);
            }
        }
        List<Map.Entry<List<Integer>, Integer>> lst1 = new ArrayList<>(map1.entrySet());
        Collections.sort(lst1, (o1, o2) -> o1.getValue().compareTo(o2.getValue()));//升序
        for (Map.Entry<List<Integer>, Integer> entry : lst1)
        {
            if (entry.getValue() < ccp.forwardMethod(newp2))
            {
                copyS.clear();
                copyS.addAll(entry.getKey());
            }
            break;
        }

        return copyS;
    }

    private static List<Integer> insertAndEvaluation(int[][] p, List<Integer> pi, int index)
    {
        int[] cmax = new int[pi.size() + 1];
        int[][] pp = new int[pi.size() + 1][];
//        List<Integer> list = new ArrayList<>();
        //插入得到所有的组合
        for (int i = 0; i <= pi.size(); i++)
        {
            pi.add(i, index);
            for (int j = 0; j < pi.size(); j++)
            {
                pp[j] = p[pi.get(j) - 1];
            }
//            ForwardCalculation fc = new ForwardCalculation();//前向计算
//            List<int[][]> listIE = fc.forwardMethod(pp);//前向计算
//            cmax[i] = getCmax(listIE);
            CalculateCmaxPFSP ccp = new CalculateCmaxPFSP();
            cmax[i] = ccp.forwardMethod(pp);
            pi.remove(i);

        }
        int elementIndex = minElementIndex(cmax);
        if (p.length == pi.size() + 1)
        {
            System.out.println("Cmax = " + cmax[elementIndex]);

        }
        pi.add(elementIndex, index);

        return pi;
    }

    private static int minElementIndex(int[] array)
    {
        int min = array[0];
        int index = 0;
        for (int i = 1; i < array.length; i++)
        {
            if (array[i] < min)
            {
                min = array[i];
                index = i;
            }
        }
        return index;
    }

    private List<Integer> listCopy(List<Integer> list)
    {
        List<Integer> copy = new ArrayList<>();
        copy.addAll(list);
        return copy;
    }

    private static int[][] getNewp(int[][] p, List<Integer> pi)
    {
        int[][] newp = new int[pi.size()][];
        for (int i = 0; i < pi.size(); i++)
        {
            newp[i] = p[pi.get(i) - 1];
        }
        return newp;
    }

    private static int[] getTP(int[][] p)
    {
        int[] TP = new int[p.length];
        for (int i = 0; i < p.length; i++)
        {
            for (int j = 0; j < p[0].length; j++)
            {
                TP[i] = TP[i] + p[i][j];
            }
        }
        return TP;
    }

//    public static List<Integer> ruleOfSPT(int[] apt)
//    {
//        Map<Integer, Integer> map = new HashMap<>();
//        List<Integer> pi = new ArrayList<>();
        for (int i = 0; i < apt.size(); i++)
//        for (int i = 0; i < apt.length; i++)
//        {
            map.put(i + 1, apt.get(i));
//            map.put(i + 1, apt[i]);
//        }
//        List<Map.Entry<Integer, Integer>> lst = new ArrayList<>(map.entrySet());
//        Collections.sort(lst, (o1, o2) -> o1.getValue().compareTo(o2.getValue()));//升序
        Collections.sort(list, (o1, o2) -> o2.getValue().compareTo(o1.getValue()));//降序
//        for (Map.Entry<Integer, Integer> entry : lst)
//        {
//            pi.add(entry.getKey());
//        }
//        return pi;
//    }

    public static List<Integer> ruleOfSPT(List<Integer> pi, int[] apt)
    {
        Map<Integer, Integer> map = new HashMap<>();
//        List<Integer> pi = new ArrayList<>();
//        for (int i = 0; i < apt.size(); i++)
        for (int i = 0; i < apt.length; i++)
        {
//            map.put(i + 1, apt.get(i));
            map.put(i + 1, apt[i]);
        }
        List<Map.Entry<Integer, Integer>> lst = new ArrayList<>(map.entrySet());
        Collections.sort(lst, (o1, o2) -> o1.getValue().compareTo(o2.getValue()));//升序
//        Collections.sort(list, (o1, o2) -> o2.getValue().compareTo(o1.getValue()));//降序
        for (Map.Entry<Integer, Integer> entry : lst)
        {
            pi.add(entry.getKey());
        }
        return pi;
    }

    public static List<Integer>[] assignByNR1(int[][] p, List<Integer> pi, int F)//NR1
    {
        CalculateCmaxPFSP ccp = new CalculateCmaxPFSP();
        int[][] newp;
        int Cmax;
        int Cmax_temp;
        int Factory_Index = 0;
        List<Integer>[] Lambda = new List[F];//List类型的数组

        for (int i = 0; i < F; i++)
        {
            Lambda[i] = new ArrayList<>();
        }
        for (int k = 0; k < F; k++)
        {
            if (k > pi.size() - 1)
            {
                break;
            }
            else
            {
                Lambda[k].add(pi.get(k));
            }
        }

        for (int k = F; k < pi.size(); k++)
        {
            Cmax = Integer.MAX_VALUE;
            for (int i = 0; i < F; i++)
            {
                newp = getNewp(p, Lambda[i]);
                Cmax_temp = ccp.forwardMethod(newp);
                if (Cmax_temp < Cmax)
                {
                    Cmax = Cmax_temp;
                    Factory_Index = i;
                }
            }
            Lambda[Factory_Index].add(pi.get(k));
        }
        return Lambda;
    }

    public static List<Integer>[] ecfRule(int[][] p, List<Integer> pi, int F)//NR2
    {
//        int[][] p = {{1, 4}, {86, 21}, {28, 67}, {32, 17}};
        CalculateCmaxPFSP ccp = new CalculateCmaxPFSP();
//        List<Integer> pi = List.of(1, 2, 3, 4);
//        int F = 2;
        int[][] newp;
        int Cmax;
        int Cmax_temp;
        int Factory_Index = 0;
        List<Integer>[] Lambda = new List[F];//List类型的数组

        for (int i = 0; i < F; i++)
        {
            Lambda[i] = new ArrayList<>();
        }
        for (int k = 0; k < F; k++)
        {
            if (k > pi.size() - 1)
            {
                break;
            }
            else
            {
                Lambda[k].add(pi.get(k));
            }
        }

        for (int k = F; k < p.length; k++)
        {
            if (k > pi.size() - 1)
            {
                break;
            }
            else
            {
                Cmax = Integer.MAX_VALUE;
                for (int i = 0; i < F; i++)
                {
                    Lambda[i].add(pi.get(k));
                    newp = getNewp(p, Lambda[i]);
                    Cmax_temp = ccp.forwardMethod(newp);
                    if (Cmax_temp < Cmax)
                    {
                        Cmax = Cmax_temp;
                        Factory_Index = i;
                    }
                    Lambda[i].remove(pi.get(k));
                }
                Lambda[Factory_Index].add(pi.get(k));
            }

        }
//        for (int i = 0; i < F; i++)
//        {
//            System.out.println(Lambda[i]);
//        }
        return Lambda;
    }
}

Heuristics

package practice.comparison.BS_HH;

import practice.calculateCMAX.CalculateCmaxDAMNIPFSP2;
import org.apache.commons.lang.SerializationUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;

public class Heuristics
{
    //    private final CalculateTF calculateTF;
    private final Random random = new Random();
    private final int[] apt;
    private final int[] flag_NI_machine;

    public Heuristics(int[] apt, int[] flag_ni_machine)
    {
        this.apt = apt;
        flag_NI_machine = flag_ni_machine;
    }
//    public Heuristics(CalculateTF calculateTF)
//    {
//        this.calculateTF = calculateTF;
//    }

    public Individual improvedLLH(int[][] p, int[] pp, Individual individual, double xi, int heuristicIndex, int t, int f)
    {
        double temperature = 2;
        double tMin = 1;
        Individual tempIndividual = (Individual) SerializationUtils.clone(individual);
        Individual tempIndividual2;
        llh(p, pp, tempIndividual, heuristicIndex, t, f);
        while (temperature > tMin)
        {
            tempIndividual2 = (Individual) SerializationUtils.clone(tempIndividual);
            llh(p, pp, tempIndividual2, heuristicIndex, t, f);
            if (tempIndividual2.cmax - tempIndividual.cmax < 0)
            {
                tempIndividual = tempIndividual2;
            }
            else
            {
                if (Math.random() < Math.exp((tempIndividual.cmax - tempIndividual2.cmax) / temperature))
                {
                    tempIndividual = tempIndividual2;
                }
            }
            temperature *= xi;
        }
        if (tempIndividual.cmax < individual.cmax)
        {
            individual = tempIndividual;
        }
        return individual;
    }

    public void llh(int[][] p, int[] pp, Individual individual, int heuristicIndex, int t, int f)
    {
        switch (heuristicIndex)
        {
            case 1:
                jobSwap(individual.products, t);
                break;
            case 2:
                jobForwardInsert(individual.products, t);
                break;
            case 3:
                jobBackwardInsert(individual.products, t);
                break;
            case 4:
                jobInverse(individual.products, t);
                break;
            case 5:
                jobAdjacentSwap(individual.products, t);
                break;
            case 6:
                productSwap(individual.pi, t);
                break;
            case 7:
                productForwardInsert(individual.pi, t);
                break;
            case 8:
                productBackwardInsert(individual.pi, t);
                break;
            case 9:
                productInverse(individual.pi, t);
                break;
            case 10:
                productAdjacentSwap(individual.pi, t);
                break;
        }
//        individual.tf = calculateTF.nr2GetTF(p, pp, individual.products, individual.pi, f);
        List<Integer>[] schedule = new List[f];
//        CalculateCmaxDAPFSP ccd = new CalculateCmaxDAPFSP();
        CalculateCmaxDAMNIPFSP2 ccd = new CalculateCmaxDAMNIPFSP2();
        Assignment assign = new Assignment();
        schedule = assign.algorithm(p, t, pp, f, individual.products, individual.pi);//NR2
//        individual.cmax = ccd.calAssembleCmax(schedule, p, f, individual.pi, individual.products, pp);
        individual.cmax = ccd.method3(schedule, individual.products, individual.pi, p, f, flag_NI_machine, apt);
    }

    public int[] getRandomProductAndPositions(List<Integer>[] products, int t)
    {
        int product = random.nextInt(t);
        while (products[product].size() < 2)
        {
            product = random.nextInt(t);
        }
        int size = products[product].size();

        int position1 = random.nextInt(size);
        int position2 = random.nextInt(size);
        while (position1 == position2)
        {
            position2 = random.nextInt(size);
        }
        if (position1 > position2)
        {
            int temp = position1;
            position1 = position2;
            position2 = temp;
        }
        return new int[]{product, position1, position2};
    }

    public void jobSwap(List<Integer>[] products, int t)
    {
        int[] ranArr = getRandomProductAndPositions(products, t);
        Collections.swap(products[ranArr[0]], ranArr[1], ranArr[2]);
    }

    public void jobForwardInsert(List<Integer>[] products, int t)
    {
        int[] ranArr = getRandomProductAndPositions(products, t);
        int job = products[ranArr[0]].remove(ranArr[1]);
        products[ranArr[0]].add(ranArr[2] - 1, job);
    }

    public void jobBackwardInsert(List<Integer>[] products, int t)
    {
        int[] ranArr = getRandomProductAndPositions(products, t);
        int job = products[ranArr[0]].remove(ranArr[1]);
        products[ranArr[0]].add(ranArr[2], job);
    }

    public void jobInverse(List<Integer>[] products, int t)
    {
        int[] ranArr = getRandomProductAndPositions(products, t);
        List<Integer> removedJobs = new ArrayList<>();
        int position = ranArr[1] + 1;
        for (int i = position; i < ranArr[2]; i++)
        {
            removedJobs.add(products[ranArr[0]].remove(position));
        }
        for (Integer removedJob : removedJobs)
        {
            products[ranArr[0]].add(position, removedJob);
        }
    }

    public void jobAdjacentSwap(List<Integer>[] products, int t)
    {
        int product = random.nextInt(t);
        while (products[product].size() < 2)
        {
            product = random.nextInt(t);
        }
        int size = products[product].size();
        int position = random.nextInt(size);
        if (position == size - 1)
        {
            Collections.swap(products[product], 0, position);
        }
        else
        {
            Collections.swap(products[product], position, position + 1);
        }
    }

    public int[] getRandomProducts(int t)
    {
        int position1 = random.nextInt(t);
        int position2 = random.nextInt(t);
        while (position1 == position2)
        {
            position2 = random.nextInt(t);
        }
        while (position1 > position2)
        {
            int temp = position1;
            position1 = position2;
            position2 = temp;
        }
        return new int[]{position1, position2};
    }

    public void productSwap(List<Integer> pi, int t)
    {
        int[] ranArr = getRandomProducts(t);
        Collections.swap(pi, ranArr[0], ranArr[1]);
    }

    public void productForwardInsert(List<Integer> pi, int t)
    {
        int[] ranArr = getRandomProducts(t);
        int product = pi.remove(ranArr[0]);
        pi.add(ranArr[1] - 1, product);
    }

    public void productBackwardInsert(List<Integer> pi, int t)
    {
        int[] ranArr = getRandomProducts(t);
        int product = pi.remove(ranArr[0]);
        pi.add(ranArr[1], product);
    }

    public void productInverse(List<Integer> pi, int t)
    {
        int[] ranArr = getRandomProducts(t);
        List<Integer> removedProducts = new ArrayList<>();
        int position = ranArr[0] + 1;
        for (int i = position; i < ranArr[1]; i++)
        {
            removedProducts.add(pi.remove(position));
        }
        for (Integer removedProduct : removedProducts)
        {
            pi.add(position, removedProduct);
        }
    }

    public void productAdjacentSwap(List<Integer> pi, int t)
    {
        int position = random.nextInt(t);
        if (position == t - 1)
        {
            Collections.swap(pi, 0, position);
        }
        else
        {
            Collections.swap(pi, position, position + 1);

        }
    }
}

Individual

package practice.comparison.BS_HH;

import java.io.Serializable;
import java.util.LinkedList;
import java.util.List;

public class Individual implements Serializable, Comparable<Individual>
{
    public int cmax;
    public List<Integer> pi = new LinkedList<>();
    public double[] heuristicSequence;
    public List<Integer>[] products;

    public Individual(int heuristicSize)//构造器
    {
        heuristicSequence = new double[heuristicSize];
    }

    @Override
    public int compareTo(Individual o)
    {
        return (int) (this.cmax - o.cmax);
    }
}

Methods

package practice.comparison.BS_HH;

import Common.Common;
import practice.calculateCMAX.CalculateCmaxDAPFSP;
import practice.comparison.IWO.Heuristic11;
import practice.comparison.IWO.Individual;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;

/**
 * @Date: 2022/4/18 20:29
 * @Author: ZhuBo
 * @File: Methods.class
 * @Software: IDEA
 * @Email: 1532116227@qq.com
 */
public class Methods
{
    private static Random random = new Random();

    public static int randomInit(int[][] p, int[] pp, List<Integer> pi, List<Integer>[] products, int F)
    {
        CalculateCmaxDAPFSP ccd = new CalculateCmaxDAPFSP();
        List<Integer>[] schedule;
        List<Integer> piT = new ArrayList<>();
        shiftProduct(pi);
        shiftProduct(pi);
        shiftJob(products);
        shiftJob(products);
//        return calculateTF.nr2GetTF(p, pp, products, pi, f);
        for (int i = 0; i < pp.length; i++)
        {
            piT.addAll(products[pi.get(i) - 1]);
        }
        schedule = Heuristic11.assignByNR1(p, piT, F);
        return ccd.calAssembleCmax(schedule, p, F, pi, products, pp);
//        return 1;
    }

    private static void shiftProduct(List<Integer> pi)
    {
        int position1 = random.nextInt(pi.size());
        int position2 = random.nextInt(pi.size());
        while (position1 == position2)
            position2 = random.nextInt(pi.size());
        int product = pi.remove(position1);
        pi.add(position2, product);
    }

    private static void shiftJob(List<Integer>[] products)
    {
        int productIndex = random.nextInt(products.length);
        while (products[productIndex].size() < 2)
        {
            productIndex = random.nextInt(products.length);
        }
        int position1 = random.nextInt(products[productIndex].size());
        int position2 = random.nextInt(products[productIndex].size());
        while (position1 == position2)
        {
            position2 = random.nextInt(products[productIndex].size());
        }
        int job = products[productIndex].remove(position1);
        products[productIndex].add(position2, job);
    }

    public static int getSeedsNumber(int bestCmax, int worstCmax, int currentCmax, int taoMax, int taoMin)
    {
        if (bestCmax != worstCmax)
            return (int) Math.floor((taoMin + (worstCmax - currentCmax) / (worstCmax - bestCmax) * (taoMax - taoMin)));
        else
            return (taoMax + taoMin) / 2;
    }

    public static void shiftProductDeltaTimes(List<Integer> pi, int delta)
    {
        for (int i = 0; i < delta; i++)
        {
            shiftProduct(pi);
        }
    }

    public static void shiftJobDeltaTimes(List<Integer>[] products, int delta)
    {
        for (int i = 0; i < delta; i++)
        {
            shiftJob(products);
        }
    }

    public static int getSeedMinIndex(List<Individual> population, int populationSize, int size)
    {
        int index = populationSize;
        for (int i = populationSize + 1; i < size; i++)
        {
            if (population.get(index).cmax > population.get(i).cmax)
            {
                index = i;
            }
        }
        return index;
    }

    public static int localSearchProduct(int[][] p, int[] pp, List<Integer> pi, List<Integer>[] products, int cmax, int f, int t)
    {
        CalculateCmaxDAPFSP ccd = new CalculateCmaxDAPFSP();
        int cnt = 0;
        int product;
        int cmaxTemp;
        int position;
        boolean b = false;
        Heuristic11 h11 = new Heuristic11();
        List<Integer>[] schedule;
        while (cnt < t)
        {
            product = pi.remove(cnt);
            position = cnt;
            for (int i = 0; i < t; i++)
            {
                if (i != cnt)
                {
                    pi.add(i, product);
                    schedule = h11.algorithm(p, t, pp, f, products, Others.copyList(pi));//深拷贝
//                    cmaxTemp = calculateTF.nr2GetTF(p, pp, products, pi, f);
                    cmaxTemp = ccd.calAssembleCmax(schedule, p, f, Others.copyList(pi), products, pp);//深拷贝
                    pi.remove(i);
                    if (cmaxTemp < cmax)
                    {
                        position = i;
                        cmax = cmaxTemp;
                        if (!b)
                        {
                            b = true;
                        }
                    }
                }
            }
            pi.add(position, product);
            if (b)
            {
                cnt = 0;
                b = false;
            }
            else
            {
                cnt++;
            }
        }
        return cmax;
    }

    public static int localSearchJobs(int[][] p, int[] pp, List<Integer> pi, List<Integer>[] products, int cmax, int f, int t)
    {
        CalculateCmaxDAPFSP ccd = new CalculateCmaxDAPFSP();
        int cnt = 0;
        int cntJob;
        int job;
        int productSize;
        List<Integer> partsTemp;
        List<Integer> parts;
        int cmaxTemp;
        int index, position;
        boolean b;
        Heuristic11 h11 = new Heuristic11();
        List<Integer>[] schedule;
        while (cnt < t)
        {
            cntJob = 0;
            parts = products[cnt];
//            partsTemp = Common.copyList(parts);
            partsTemp = Others.copyList(parts);
            Collections.shuffle(partsTemp);
            productSize = parts.size();
            b = false;
            while (cntJob < productSize)
            {
                job = partsTemp.remove(0);
                index = parts.indexOf(job);
                parts.remove(index);
                position = index;
                for (int i = 0; i < productSize; i++)
                {
                    if (i != index)
                    {
                        parts.add(i, job);
//                        cmaxTemp = calculateTF.nr2GetTF(p, pp, products, pi, f);
                        schedule = h11.algorithm(p, t, pp, f, products, Others.copyList(pi));//深拷贝
                        cmaxTemp = ccd.calAssembleCmax(schedule, p, f, Others.copyList(pi), products, pp);//深拷贝
                        parts.remove(i);
                        if (cmaxTemp < cmax)
                        {
                            cmax = cmaxTemp;
                            position = i;
                            if (!b)
                            {
                                b = true;
                            }
                        }
                    }
                }
                parts.add(position, job);
                if (b)
                {
                    cnt = 0;
                    cntJob = 0;
                    parts = products[cnt];
                    partsTemp = Common.copyList(parts);
                    Collections.shuffle(partsTemp);
                    productSize = parts.size();
                    b = false;
                }
                else
                {
                    cntJob++;
                }
            }
            cnt++;
        }
        return cmax;
    }
}

Others

package practice.comparison.MyEDA;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

/**
 * @Date: 2022/4/18 16:58
 * @Author: 
 * @File: Others.class
 * @Software: IDEA
 * @Email: 1532116227@qq.com
 */
public class Others
{
    public static List<Integer>[] copyList(List<Integer>[] temp, int t)
    {
        List<Integer>[] lists = new List[t];
        for (int i = 0; i < t; i++)
        {
            lists[i] = new LinkedList<>();
            for (Integer integer : temp[i])
            {
                lists[i].add(integer);
            }
        }
        return lists;
    }

    public static List<Integer> copyList(List<Integer> temp)
    {
        List<Integer> temp2 = new LinkedList<>();
        for (Integer integer : temp)
        {
            temp2.add(integer);
        }
        return temp2;
    }

    public static List<Integer>[] list1DimArrayCopy(List<Integer>[] solution)//一维List类型数组的拷贝
    {
        List<Integer>[] lists = new List[solution.length];
        for (int i = 0; i < solution.length; i++)
        {
            lists[i] = new ArrayList<>();
            lists[i].addAll(solution[i]);
        }
        return lists;
    }

    public static List<Integer> listCopy(List<Integer> list)
    {
        List<Integer> copy = new ArrayList<>();
        copy.addAll(list);
        return copy;
    }

    public static int[][] getNewp(int[][] p, List<Integer> pi)
    {
        int[][] newp = new int[pi.size()][];
        for (int i = 0; i < pi.size(); i++)
        {
            newp[i] = p[pi.get(i) - 1];
        }
        return newp;
    }

    public static List<Integer>[][] list2DimArrayCopy(List<Integer>[][] solution)//二维List类型数组的拷贝
    {
        List<Integer>[][] lists = new List[solution.length][solution[0].length];
        for (int i = 0; i < solution.length; i++)
        {
            for (int j = 0; j < solution[0].length; j++)
            {
                lists[i][j] = new ArrayList<>();
                lists[i][j].addAll(solution[i][j]);
            }
        }
        return lists;
    }

    public static int[] getTP(int[][] p)
    {
        int[] TP = new int[p.length];
        for (int i = 0; i < p.length; i++)
        {
            for (int j = 0; j < p[0].length; j++)
            {
                TP[i] = TP[i] + p[i][j];
            }
        }
        return TP;
    }
}

ReadTxt

package practice.comparison.BS_HH;

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

/**
 * @Date: 2022/4/8 16:24
 * @Author:
 * @File: ReadTxt.class
 * @Software: IDEA
 * @Email: 1532116227@qq.com
 */
public class ReadTxt
{
    public int[][] getProcessingTimes(String filePath, int n, int m)
    {
        File f = new File(filePath);
        if (!f.exists())
        {
            System.out.println("找不到文件");
            return null;
        }
        else
        {
            System.out.println(filePath);
        }
        int[][] p = new int[n][m];
        int[] a = null;
        String[] values;
        try
        {
            BufferedReader br = new BufferedReader(new FileReader(f));
            Scanner sc = new Scanner(br);
            for (int i = 0; i < n; i++)
            {
                values = sc.nextLine().split(",");
                for (int j = 0; j < m; j++)
                {
                    p[i][j] = Integer.parseInt(values[j]);
                }
            }
            br.close();
        }
        catch (FileNotFoundException e)
        {
            e.printStackTrace();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        return p;
    }

//    public List<Integer> getAssemblyTimes(String filePath, int l)
//    {
//        List<Integer> apt = new ArrayList<>();
//        File f = new File(filePath);
//        if (!f.exists())
//        {
//            System.out.println("找不到文件");
//            return null;
//        }
//        int[] pp = new int[l];
//        try
//        {
//            BufferedReader br = new BufferedReader(new FileReader(f));
//            Scanner sc = new Scanner(br);
//            for (int i = 0; i < l; i++)
//            {
//                String[] values = sc.nextLine().split(",");
//                pp[i] = Integer.parseInt(values[1]);
//            }
//            br.close();
//        }
//        catch (IOException e)
//        {
//            e.printStackTrace();
//        }
//        for (int i = 0; i < l; i++)
//        {
//            apt.add(pp[i]);
//        }
//        return apt;
//    }

    public int[] getAssemblyTimes(String filePath, int l)
    {
        List<Integer> apt = new ArrayList<>();
        File f = new File(filePath);
        if (!f.exists())
        {
            System.out.println("找不到文件");
            return null;
        }
        int[] pp = new int[l];
        try
        {
            BufferedReader br = new BufferedReader(new FileReader(f));
            Scanner sc = new Scanner(br);
            for (int i = 0; i < l; i++)
            {
                String[] values = sc.nextLine().split(",");
                pp[i] = Integer.parseInt(values[1]);
            }
            br.close();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
//        for (int i = 0; i < l; i++)
//        {
//            apt.add(pp[i]);
//        }
        return pp;
    }

    public int[] getAssignSet(String filePath, int n, int l)
    {
        File f = new File(filePath);
        if (!f.exists())
        {
            System.out.println("找不到文件");
            return null;
        }
        int[] as = new int[n];
        try
        {
            BufferedReader br = new BufferedReader(new FileReader(f));
            Scanner sc = new Scanner(br);
            for (int i = 0; i < n; i++)
            {
                String[] values = sc.nextLine().split(",");
                as[i] = Integer.parseInt(values[1]);
            }
            br.close();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        return as;
    }

    public int[] getNoIdleConstraint(String filePath, int m)
    {
        File f = new File(filePath);
        if (!f.exists())
        {
            System.out.println("找不到文件");
            return null;
        }
        int[] flag = new int[m];
        try
        {
            BufferedReader br = new BufferedReader(new FileReader(f));
            Scanner sc = new Scanner(br);
            for (int i = 0; i < m; i++)
            {
//                String[] values = sc.nextLine().split(",");
                flag[i] = sc.nextInt();
            }
            br.close();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        return flag;
    }
}

结果

在这里插入图片描述

参考文献

J. Lin, Z. J. Wang, and X. Li, “A backtracking search hyper-heuristic for the distributed assembly flow-shop scheduling problem,” Swarm and Evolutionary Computation, vol. 36, pp. 124–135, Oct. 2017, doi: 10.1016/j.swevo.2017.04.007.

期刊

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 6
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值