Package com.exigen.ie.constrainer.impl

Source Code of com.exigen.ie.constrainer.impl.IntExpAddArray1$DomainVar

package com.exigen.ie.constrainer.impl;
import java.util.Map;

import com.exigen.ie.constrainer.Constrainer;
import com.exigen.ie.constrainer.EventOfInterest;
import com.exigen.ie.constrainer.Failure;
import com.exigen.ie.constrainer.IntExp;
import com.exigen.ie.constrainer.IntExpArray;
import com.exigen.ie.constrainer.IntVar;
import com.exigen.ie.constrainer.NonLinearExpression;
import com.exigen.ie.constrainer.Observer;
import com.exigen.ie.constrainer.Subject;
/**
* An implementation of the expression: <code>sum(IntExpArray)</code>.
* This implementation "remember and propagate" setMin/Max.
*/
public final class IntExpAddArray1 extends IntExpImpl
{
  private IntExpArray         _vars;
  private Observer _observer;

  private IntVar    _domainC; // constraint domain
  private DomainVar _domainE; // expression domain

  static final private int[] event_map = {
      MIN,              MIN,
      MAX,              MAX,
      MIN| MAX | VALUE, VALUE,
                                       //         REMOVE, REMOVE
                                           };


  class ExpAddVectorObserver extends Observer
  {

    ExpAddVectorObserver()
    {
//      super(event_map);
    }

    public int subscriberMask()
    {
      return MIN | MAX | VALUE;
    }

    public void update(Subject exp, EventOfInterest event)
      throws Failure
    {
      IntEvent e = (IntEvent) event;

  //    System.out.println("Event:" + e);

      _domainE.setMin(_domainE.min() + e.mindiff());
      _domainE.setMax(_domainE.max() + e.maxdiff());

      // update domainC
      _domainC.setMin(_domainE.min());
      _domainC.setMax(_domainE.max());

    }


      public String toString()
      {
        return "ExpAddVectorObserver: "+_vars;
      }

      public Object master()
      {
        return IntExpAddArray1.this;
      }


  } //~ ExpAddVectorObserver


  public IntExpAddArray1(Constrainer constrainer, IntExpArray vars)
  {
    super(constrainer);
    int size = vars.size();
    _vars = vars;
    _observer = new ExpAddVectorObserver();

    IntExp[] data = _vars.data();

    for(int i=0; i < data.length; i++)
    {
      data[i].attachObserver(_observer);
    }

    String sum_name = "";

    if (constrainer().showInternalNames())
    {
      StringBuffer s = new StringBuffer();
      s.append("(");
      for(int i=0; i<data.length; i++)
      {
        if(i!=0)
          s.append("+");
        s.append(data[i].name());
      }
      s.append(")");
      _name = s.toString();

      sum_name = "sum(" + _vars.name() + ")";
    }

    int trace = 0;
    int min = calc_min();
    int max = calc_max();
    _domainC = constrainer().addIntVarTraceInternal(min, max, sum_name, IntVar.DOMAIN_PLAIN, trace);
    _domainE = new DomainVar(constrainer(),min,max);
  }

  public void onMaskChange()
  {
//    int mask = publisherMask();
//    IntExp[] data =_vars.data();
//    for(int i=0; i < data.length; i++)
//    {
//      _observer.publish(mask,data[i]);
//    }
  }


  public void name(String name)
  {
    super.name(name);
    _domainC.name(name);
  }

  public void attachObserver(Observer observer)
  {
    super.attachObserver(observer);
    _domainC.attachObserver(observer);
  }

  public void reattachObserver(Observer observer)
  {
    super.reattachObserver(observer);
    _domainC.reattachObserver(observer);
  }

  public void detachObserver(Observer observer)
  {
    super.detachObserver(observer);
    _domainC.detachObserver(observer);
  }



  int calc_max()
  {
    int max_sum = 0;

    IntExp[] vars = _vars.data();

    for(int i=0; i < vars.length; i++)
    {
      max_sum += vars[i].max();
    }
    return max_sum;
  }

  int calc_min()
  {
    int min_sum = 0;

    IntExp[] vars = _vars.data();

    for(int i=0; i < vars.length; i++)
    {
      min_sum += vars[i].min();
    }
    return min_sum;
  }

  public int min()
  {
    return _domainC.min();
  }

  public int max()
  {
    return _domainC.max();
  }


  public void setMax(int max) throws Failure
  {

    if (max >= _domainC.max())
      return;

    _domainC.setMax(max);

//    System.out.println("++++ Set max: " + max + " in " + this);

    int min_sum = _domainE.min();


    IntExp[] vars = _vars.data();

    for(int i=0; i < vars.length; i++)
    {
      IntExp vari = vars[i];
      int maxi = max - (min_sum - vari.min());
      if (maxi < vari.max())
      {
        vari.setMax(maxi);
      }
    }
//    System.out.println("---- set max:" + max + " in " + this);
  }

  public void setMin(int min) throws Failure
  {

    if (min <= _domainC.min())
      return;

    _domainC.setMin(min);

//    System.out.println("++++ Set min: " + min + " in " + this);


    int max_sum = _domainE.max();


    IntExp[] vars = _vars.data();

    for(int i=0; i < vars.length; i++)
    {
      IntExp vari = vars[i];
      int mini = min - (max_sum - vari.max());
      if (mini > vari.min())
      {
        vari.setMin(mini);
      }
    }
//    System.out.println("---- set min:" + min + " in " + this);
  }

  public void setValue(int value) throws Failure
  {
    if(_domainC.min() == value && _domainC.max() == value)
      return;

    _domainC.setValue(value);

    //    System.out.println("++++ Set value: " + value + " in " + this);

    int sum_min = _domainE.min();
    int sum_max = _domainE.max();

    IntExp[] vars = _vars.data();

    for(int i=0; i < vars.length; i++)
    {
      IntExp vari = (IntExp)vars[i];
      int mini = vari.min();
      int maxi = vari.max();

      int new_min = value - (sum_max - maxi);
      if (new_min > mini)
      {
        vari.setMin(new_min);
      }

      int new_max = value - (sum_min - mini);
      if (new_max < maxi)
      {
        vari.setMax(new_max);
      }
    }

//    System.out.println("---- set value: " + value + " in " + this);
  }

  public void removeValue(int value) throws Failure
  {
    int Max = _domainC.max();
    if (value > Max)
      return;
    int Min = _domainC.min();
    if (value < Min)
      return;
    if (Min == Max)
      constrainer().fail("remove for IntExpAddVector");
    if (value == Max)
      setMax(value-1);
    if (value == Min)
      setMin(value+1);
  }

  public int size()
  {
    return max() - min() + 1;
  }

  void enforceDomainC() throws Failure
  {
    int minC = _domainC.min();
    int maxC = _domainC.max();
    int minE = _domainE.min();
    int maxE = _domainE.max();

    if(minC == minE && maxC == maxE)
    {
//      System.out.println("*** enforceDomainC(): ["+minE+".."+maxE+"]->["+minC+".."+maxC+"]");
      return;
    }

    IntExp[] vars = _vars.data();

    for(int i=0; i < vars.length; i++)
    {
      IntExp vari = vars[i];
      int mini = vari.min();
      int maxi = vari.max();

      int new_min = minC - (maxE - maxi);
      if (new_min > mini)
      {
        vari.setMin(new_min);
      }

      int new_max = maxC - (minE - mini);
      if (new_max < maxi)
      {
        vari.setMax(new_max);
      }
    }
  }

  final class DomainVar extends IntVarImpl
  {
    public DomainVar(Constrainer c, int min, int max)
    {
      super(c,min,max,"",DOMAIN_PLAIN);
    }

    public void propagate() throws Failure
    {
      enforceDomainC();
    }

  } // ~DomainVar

  public boolean isLinear(){
    for (int i=0;i<_vars.size();i++){
      if (!_vars.get(i).isLinear())
        return false;
    }
    return true;
  }

  public double calcCoeffs(Map map, double factor) throws NonLinearExpression{
    if (!isLinear())
      throw new NonLinearExpression(this);
    double cumSum = 0;
    for (int i=0;i<_vars.size();i++){
      cumSum += _vars.get(i).calcCoeffs(map, factor);
    }
    return cumSum;
  }

} // ~IntExpAddArray1
TOP

Related Classes of com.exigen.ie.constrainer.impl.IntExpAddArray1$DomainVar

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.