复现一篇分布式装配置换流水车间调度问题的代码——基于回溯搜索的超启发式算法
摘要
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.
期刊