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