フレキシブルジョブショップスケジューリング問題の課題
100の工程を10台の機械で処理する場合、各工程に複数の装置選択肢がある上、総所要時間の短縮と機械負荷の均衡という複数目的を同時に最適化する必要がある。このような複雑性により、従来の最適化手法では効率的な解探索が困難になる。
NSOOAアルゴリズムの生物模倣メカニズム
カモメの狩りの行動を模倣したアルゴリズム設計では、初期化段階で二重構造の染色体表現を採用:
- 工程順序:順列形式
- 機械割り当て:整数ベクトル
function population = InitializePopulation(taskCounts, deviceLimits, populationSize)
population = struct('operationOrder',[],'deviceAllocation',[],'fitness',[]);
for i=1:populationSize
orderChain = [];
for j=1:length(taskCounts)
orderChain = [orderChain, j*ones(1,taskCounts(j))];
end
population(i).operationOrder = orderChain(randperm(length(orderChain)));
population(i).deviceAllocation = randi(deviceLimits, 1, sum(taskCounts));
end
end
非支配ソートの実装
パレート前沿の維持には、次のような支配関係判定ロジックを採用:
function dominanceFlag = evaluateDominance(individualA, individualB)
superiorityExist = false;
for i=1:length(individualA.fitness)
if individualA.fitness(i) > individualB.fitness(i)
return;
elseif individualA.fitness(i) < individualB.fitness(i)
superiorityExist = true;
end
end
dominanceFlag = superiorityExist;
end
進化操作の実装
選択・交叉・変異操作には、工程順序と機械割り当てのそれぞれに最適化された手法を適用:
function offspring = hybridCrossover(parent1, parent2)
crossoverPoint = randi(length(parent1.operationOrder)-1);
childOrder = [parent1.operationOrder(1:crossoverPoint), ...
parent2.operationOrder(~ismember(parent2.operationOrder,...
parent1.operationOrder(1:crossoverPoint)))];
binaryMask = randi([0,1], size(parent1.deviceAllocation));
childDevice = parent1.deviceAllocation.*binaryMask + ...
parent2.deviceAllocation.*(1-binaryMask);
offspring = struct('operationOrder',childOrder, 'deviceAllocation',childDevice);
end
スケジューリング結果の可視化
ガントチャート生成には、機械別に色分けした矩形描画を採用:
function visualizeSchedule(timeline)
colormap = hsv(length(unique(timeline.device)));
hold on;
for i=1:size(timeline,1)
startTime = timeline.startTime(i);
duration = timeline.processTime(i);
rectangle('Position',[startTime, timeline.device(i)-0.4, duration, 0.8],...
'FaceColor',colormap(timeline.device(i),:));
end
xlabel('時間経過'); ylabel('装置ID');
end