Quintiq file version 2.0 
 | 
#parent: #root 
 | 
Method BuildBasicNeighborhood ( 
 | 
  ProductInStockingPointInPeriodPlannings anchorpispips, 
 | 
  LibOpt_Task task, 
 | 
  LibOpt_Scope out_scope, 
 | 
  LaneLegs lanelegsforopt, 
 | 
  Period_MPs periods, 
 | 
  RunContextForCapacityPlanning runcontext, 
 | 
  RunContextMeta runcontextmeta 
 | 
) 
 | 
{ 
 | 
  TextBody: 
 | 
  [* 
 | 
    // this method builds the neighborhood around the anchor (anchorpispips) given as input 
 | 
    //  
 | 
    // this consists of  
 | 
    // 1 upstream supply chain of anchor  
 | 
    // 2 downstream supply chain of anchor 
 | 
    // 3 of the neighborhood obtained thus far we search upstream along already selected langelegs ( so side products of step 2 can be properly supplied) 
 | 
    // In step 1 we look at unit periods that are bottlenecks, if applicable we add 
 | 
    // 4 neighborhood to debottlebeck a random set of those unit periods ( consists of upstream + downstream around the bottlebeck - the latter only search along existing planning)  
 | 
    // 5 We then inspect the neighborood obtained so far and for a limited set of pispips where pre production is used ( put stuff in inventory end ) we similarly build  
 | 
    //   a neigbhoorhood to debottleneck that 
 | 
    // Finally ( and if there still is room) we go through the procedure of adding friend pispips to the anchor 
 | 
     
 | 
     
 | 
    transformerup := this.GetUpstreamTransformer( runcontext, runcontextmeta ); 
 | 
    transformerdown := this.GetDownstreamTransformer( runcontext, runcontextmeta );  
 | 
     
 | 
    this.AddUpstreamNeighborhood( transformerup, out_scope, runcontext, anchorpispips, true, lanelegsforopt, periods, true /*reset visited*/ );  
 | 
     
 | 
    task.Log( 'after upstream:' + [String] transformerup.PISPIPVisitedUpstream( relsize ) + 'nr pispips =' + [String] out_scope.GetPISPIPInOptimizerRun().Size() );  
 | 
     
 | 
    pispips_inputs_to_bottleneck := this.GetPISPIPInputsToUnitPeriodBottleNeck( out_scope, runcontext, 10 ); // 10 max period tasks   
 | 
     
 | 
    // Add downstream neighborhood 
 | 
    pispipsfordownstream := out_scope.GetLeafPISPIPsInOptimizerRun();  
 | 
    beforesize := out_scope.GetEstimatedNrPISPIPs();  
 | 
    this.AddDownStreamLimitedExplore( transformerdown,  
 | 
                                      out_scope,  
 | 
                                      pispipsfordownstream,  
 | 
                                      runcontext,  
 | 
                                      false,   // debug 
 | 
                                      runcontextmeta.OptionCheckSizeLimitDownStreamForAnchor(),   // check size limit   
 | 
                                      0.25, // fraction of max neighborhood size to use in case of checking size limit 
 | 
                                      runcontextmeta.MaxFanExploreDownStreamLanes(),    
 | 
                                      false,  // limit to nonzero planning 
 | 
                                      runcontextmeta.MaxOperationExploreDownStream(),  
 | 
                                      true ); // reset visited at start - does not matter because first call 
 | 
    aftersize := out_scope.GetEstimatedNrPISPIPs();  
 | 
    task.Log( 'Selector added for downstream (up(anchor)):' + [String]( aftersize - beforesize ) + ' size before  = ' + [String] beforesize );  
 | 
     
 | 
    if ( runcontextmeta.OptionAdditionalUpstreamClosure() )  
 | 
    { 
 | 
      startpispips := out_scope.GetPISPIPInOptimizerRun();  
 | 
      beforesize := out_scope.GetEstimatedNrPISPIPs();  
 | 
      transformerup.LimitToAlreadySelectedLaneLegs( true ); // restrict to lane legs discovered in above steps 
 | 
      this.AddUpstreamNeighborhood( transformerup, out_scope, runcontext, startpispips, true, lanelegsforopt, periods, false );  
 | 
      transformerup.LimitToAlreadySelectedLaneLegs( false );  
 | 
      aftersize := out_scope.GetEstimatedNrPISPIPs();  
 | 
         
 | 
      task.Log( 'Selector added for EXTRA upstream :' + [String]( aftersize - beforesize ) + ' size before  = ' + [String] beforesize );  
 | 
    } 
 | 
     
 | 
    transformerup.PISPIPVisitedUpstream( relflush ); // forget what has been visited upstream in above searches ( because it had some restrictions we don't apply below).  
 | 
    transformerdown.PISPIPVisitedDownStream( relflush ); // same remark for downstream search 
 | 
     
 | 
    // in the following calls we do not reset transformer visited pispips anymore, so we do not repeat searches once we hit pispips already visited 
 | 
     
 | 
    if ( pispips_inputs_to_bottleneck.Size() > 0 and  ( out_scope.GetEstimatedNrPISPIPs() < runcontextmeta.OptionMaxNumberOfPISPIPSForNeighborhood() or not runcontextmeta.OptionCheckSizeLimitDebottleneckNeighborhood() ) ) 
 | 
    { 
 | 
      this.AddDebottleneckNeighborhood( task, transformerup, transformerdown, out_scope, runcontext, runcontextmeta, pispips_inputs_to_bottleneck, lanelegsforopt, periods, '[detection in upstream(anchor)]' );  
 | 
    } 
 | 
     
 | 
    task.Log( 'after debottleneck:' + [String] transformerdown.PISPIPVisitedDownStream(relsize ) + '- ' + [String] transformerup.PISPIPVisitedUpstream( relsize ) );  
 | 
     
 | 
    if ( out_scope.GetEstimatedNrPISPIPs() < runcontextmeta.OptionMaxNumberOfPISPIPSForNeighborhood() or not runcontextmeta.OptionCheckSizeLimitDebottleneckNeighborhood() )  
 | 
    { 
 | 
      this.AddPreProductionNeighborhood( task, transformerup, transformerdown, out_scope, runcontext, runcontextmeta, lanelegsforopt, periods, null( ProductInStockingPointInPeriodPlanningLeafs ), 50 ); // max 50 pispips to use   
 | 
    } 
 | 
     
 | 
    task.Log( 'after preprod:' + [String] transformerdown.PISPIPVisitedDownStream( relsize ) + '- ' + [String] transformerup.PISPIPVisitedUpstream( relsize ) );  
 | 
     
 | 
     
 | 
    if ( runcontextmeta.OptionAddFriends() and out_scope.GetEstimatedNrPISPIPs() < runcontextmeta.OptionMaxNumberOfPISPIPSForNeighborhood() )  
 | 
    { 
 | 
       
 | 
      this.AddFriendNeighborhoodForAnchorPISPIP( transformerup, transformerdown, out_scope, task, runcontext, runcontextmeta, anchorpispips, lanelegsforopt, periods, false  ); 
 | 
    } 
 | 
     
 | 
    task.Log( 'after friends:' + [String] transformerdown.PISPIPVisitedDownStream( relsize ) + '- ' + [String] transformerup.PISPIPVisitedUpstream( relsize ) ); 
 | 
  *] 
 | 
  InterfaceProperties { Accessibility: 'Module' } 
 | 
} 
 |