001package org.opengion.penguin.math.ga; 002 003import java.util.ArrayList; 004import java.util.List; 005import java.util.Map; 006import java.util.HashMap; 007import java.util.Collections; // 6.9.8.0 (2018/05/28) 008 009import org.apache.commons.math3.genetics.InvalidRepresentationException; 010 011/** 012 * AbstractHybsGAChromosomeのサンプル実装クラスです。 013 * HybsGAObjectImplを利用しています。 014 * 属性値配列(文字列)にタスクの割当先(機械や人)候補 015 * 属性値(実数)にこのタスクにかかる時間 016 * 属性値配列(実数)[0]にこのタスクの納期(開始からの経過時間) 017 * を持たせているという想定です。 018 * このクラスでは次のようにスケジュールを決めます。 019 * 1.候補のうち、一番タスクが積まれていないものに前から積む 020 * 2.同じであればリストの先頭の方に割り当てられる 021 * 3.納期オーバーの場合は評価関数の値が小さくなるようにする 022 * 023 */ 024public class HybsScheduleChromosome extends AbstractHybsGAChromosome { 025 026 /** 027 * コンストラクタ。 028 */ 029 public HybsScheduleChromosome() { super(); } // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。 030 031 /** 032 * コンストラクタ。 033 * 034 * @param representation 染色体表現 035 */ 036 public HybsScheduleChromosome(final List<HybsGAObject> representation) { 037 super(representation); 038 } 039 040 /** 041 * 適合度計算。 042 * 043 * @return 適合度計算の結果 044 */ 045 public double fitness() { 046 final List<HybsGAObject> representation = getRepresentation(); 047 final Map<String,Double> machineList = new HashMap<>(); //名前は機械リストだが、人でも良い 048 final Map<String, List<String>> taskSchedule = new HashMap<>(); 049 050 // 実際にスケジュールの積み上げを行い、納期遅れの合計を出します 051 // 6.9.8.0 (2018/05/28) 変数手直し 052// double nokisum = 0.0; 053// nokisum = makeSchedule( representation, machineList, taskSchedule ); 054 final double nokisum = makeSchedule( representation, machineList, taskSchedule ); 055 056// // リストから最大値を取得する(出てくる順番は問わない) 057// double maxWork=0; 058// for( final String mw : machineList.keySet() ){ 059// maxWork = machineList.get(mw) > maxWork ? machineList.get(mw) :maxWork; // 6.9.7.0 (2018/05/14) PMD Useless parentheses. 060// } 061 062 // リストから最大値を取得する(出てくる順番は問わない) 063 // 6.9.8.0 (2018/05/28) 処理手直し 064 final double maxWork = Collections.max( machineList.values() ); 065 066 return 1 / ( maxWork + nokisum*nokisum); //納期遅れが多くなるとどんどん値が小さくなるように評価する 067 } 068 069 /** 070 * HybsGAObjectImplを利用して前からスケジュールを積み上げていきます。 071 * 072 * @og.rev 6.8.2.3 (2017/11/10) Doubleインスタンス作成方法の変更。 073 * 074 * @param representation 染色体表現 075 * @param machineList マシンに対する積み上げ工数のリスト。(書き込まれるのでfinalにしない) 076 * @param taskSchedule マシンに対して、前からタスクをセットするリスト。(書き込まれるのでfinalにしない) 077 * @return 納期遅れの累計 078 */ 079 public double makeSchedule( final List<HybsGAObject> representation , final Map<String,Double> machineList, final Map<String, List<String>> taskSchedule){ 080 HybsGAObjectImpl chrom; 081 double nokisum = 0.0; 082 083 for ( int i=0; i<representation.size(); i++){ 084 chrom = (HybsGAObjectImpl)representation.get(i); 085 086 final String[] machines = chrom.getAttrStrArray(); 087 // ここでスケジュールを当てはめていく 088 final double noki = chrom.getAttrArray()[0]; 089 String hitMachine = null; 090 double work=999999999; 091 for( int j=0; j<machines.length; j++ ){ 092 if(!machineList.containsKey( machines[j] )){ 093 machineList.put( machines[j], Double.valueOf(0) ); // 6.8.2.3 (2017/11/10) 094 taskSchedule.put( machines[j], new ArrayList<String>() ); 095 } 096 097 if( machineList.get(machines[j]) < work){ 098 work = machineList.get(machines[j]); 099 hitMachine = machines[j]; 100 } 101 } 102 103 machineList.put( hitMachine, Double.valueOf(work + chrom.getAttr()) ); // 総工数 6.8.2.3 (2017/11/10) 104 taskSchedule.get( hitMachine ).add( chrom.getName() ); // 割りついたタスクリスト 105 106 if( work + chrom.getAttr() > noki ){ 107 nokisum += noki - work + chrom.getAttr(); // 6.9.7.0 (2018/05/14) PMD Useless parentheses. 108 } 109 } 110 return nokisum; 111 } 112 113 /** 114 * 自身のクラスを新たに作成するメソッド。 115 * 116 * ここではオプションデータはクローンせずに参照で渡しています。 117 * (計算では利用していません) 118 * 119 * @param repr 染色体表現 120 * @return 作成された自分自身のクラス 121 */ 122 @Override 123 public AbstractHybsGAChromosome newFixedLengthChromosome(final List<HybsGAObject> repr) { 124 final HybsScheduleChromosome rtn = new HybsScheduleChromosome(repr); 125 rtn .setOptionData( optionData ); 126 return rtn; 127 } 128 129 /** 130 * 染色体表現のチェック。 131 * 132 * @param repr HybsGAObjectのリスト 133 */ 134 @Override 135 protected void checkValidity(final List<HybsGAObject> repr) throws InvalidRepresentationException { 136 // Listの中身のチェックをする箇所。必要であれば記述する 137 } 138}