Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.exigen.ie.constrainer.impl.IntExpMulExpPP Maven / Gradle / Ivy
package com.exigen.ie.constrainer.impl;
import java.util.Map;
import com.exigen.ie.constrainer.EventOfInterest;
import com.exigen.ie.constrainer.Failure;
import com.exigen.ie.constrainer.IntExp;
import com.exigen.ie.constrainer.IntVar;
import com.exigen.ie.constrainer.NonLinearExpression;
import com.exigen.ie.constrainer.Observer;
import com.exigen.ie.constrainer.Subject;
///////////////////////////////////////////////////////////////////////////////
/*
* Copyright Exigen Group 1998, 1999, 2000
* 320 Amboy Ave., Metuchen, NJ, 08840, USA, www.exigengroup.com
*
* The copyright to the computer program(s) herein
* is the property of Exigen Group, USA. All rights reserved.
* The program(s) may be used and/or copied only with
* the written permission of Exigen Group
* or in accordance with the terms and conditions
* stipulated in the agreement/contract under which
* the program(s) have been supplied.
*/
///////////////////////////////////////////////////////////////////////////////
//
//: IntExpMulExpPP.java
//
/**
* An implementation of the expression: (IntExp1 * IntExp2)
* where both IntExp1 and IntExp2 are non-negative.
*/
public final class IntExpMulExpPP extends IntExpImpl
{
private IntExp _exp1, _exp2;
private Observer _observer;
private IntVar _product;
class ExpMultiplyPositiveObserver extends Observer
{
ExpMultiplyPositiveObserver()
{
// super(event_map);
}
public void update(Subject subject, EventOfInterest event)
throws Failure
{
// System.out.println(this);
int mask = event.type();
if ((mask & MAX) != 0)
_product.setMax(calc_max());
if ((mask & MIN) != 0)
_product.setMin(calc_min());
}
public String toString()
{
return "ExpMulExpPPObserver: " + _exp1 + " x " + _exp2;
}
public int subscriberMask()
{
return MIN | MAX | VALUE;
}
public Object master()
{
return IntExpMulExpPP.this;
}
} //~ ExpMultiplyPositiveObserver
public IntExpMulExpPP(IntExp exp1, IntExp exp2)
{
super(exp1.constrainer());
//if ( value <= 0 )
// abort("negative value in IntExpMultiplyPositive");
_exp1 = exp1;
_exp2 = exp2;
if(constrainer().showInternalNames())
{
_name = "("+exp1.name()+"*"+exp2.name()+")";
}
int trace = 0;
_product = constrainer().addIntVarTraceInternal(calc_min(), calc_max(), "mul",IntVar.DOMAIN_PLAIN, trace);
_observer = new ExpMultiplyPositiveObserver();
_exp1.attachObserver(_observer);
_exp2.attachObserver(_observer);
}
int calc_max()
{
return _exp1.max() * _exp2.max();
}
int calc_min()
{
return _exp1.min() * _exp2.min();
}
public void onMaskChange()
{
// _observer.publish(publisherMask(), _exp1);
// _observer.publish(publisherMask(), _exp2);
}
public void attachObserver(Observer observer)
{
super.attachObserver(observer);
_product.attachObserver(observer);
}
public void reattachObserver(Observer observer)
{
super.reattachObserver(observer);
_product.reattachObserver(observer);
}
public void detachObserver(Observer observer)
{
super.detachObserver(observer);
_product.detachObserver(observer);
}
public boolean contains(int value)
{
/*
if (value % _value != 0)
return false;
return _exp.contains(value/_value);
*/
return super.contains(value);
}
public int max()
{
return _product.max();
}
public int min()
{
return _product.min();
}
public void setMax(int max) throws Failure
{
if (max >= max())
return;
_product.setMax(max);
// System.out.println("++++ Set max: " + max + " in " + this);
// System.out.println("setmax: " + max + " in " + this);
if (max < min())
constrainer().fail("Mul PP Set Max");
int Pmax = max;
int Min, Max, delta, q ;
//(a/b)*b + (a%b) = a - java spec
// 5/3 = 1(2)
// -5/3 = -1(-2)
// -5/-3 = 1(-2)
// 5/-3 = -1(2)
// P = (71, 90), val = 10, var=(8,9)
// P = (70, 89), val = 10, var=(7,8)
// P = (-80, -61), val = 10, var = (-8, -7)
// P = (-79, -60), val = 10, var = (-7, -6)
int v = _exp2.min();
if (v != 0)
{
q = Pmax / v;
delta = Pmax - q * v;
Max = delta >= 0 ? q : q - 1;
// System.out.println("setmax 1: " + Max + " in " + this);
_exp1.setMax(Max); // may fail
}
v = _exp1.min();
if (v != 0)
{
q = Pmax / v;
delta = Pmax - q * v;
Max = delta >= 0 ? q : q - 1;
// System.out.println("setmax 2: " + Max + " in " + this);
_exp2.setMax(Max); // may fail
}
}
public void setMin(int min) throws Failure
{
if (min <= min())
return;
_product.setMin(min);
// System.out.println("setmin: " + min + " in " + this);
if (min > max())
constrainer().fail("Mul PP Set Min");
int Pmin = min;
int Min, Max, delta, q ;
//(a/b)*b + (a%b) = a - java spec
// 5/3 = 1(2)
// -5/3 = -1(-2)
// -5/-3 = 1(-2)
// 5/-3 = -1(2)
// P = (71, 90), val = 10, var=(8,9)
// P = (70, 89), val = 10, var=(7,8)
// P = (-80, -61), val = 10, var = (-8, -7)
// P = (-79, -60), val = 10, var = (-7, -6)
// V > 0
// min: Pmin = q * V + d, V > d > -V
// Xmin * V >= q * V + d > (Xmin - 1) * V
// Xmin > q - 1
// a) d > 0
// Xmin * V > q * V
// Xmin > q >> Xmin = q + 1
//
// b) d <= 0
// q > Xmin - 1
// q+1 > Xmin >> Xmin = q
int v = _exp2.max();
if (v != 0)
{
q = Pmin / v;
delta = Pmin - q * v;
Min = delta > 0 ? q + 1 : q;
_exp1.setMin(Min); // may fail
}
// System.out.println("setmin 1: " + Min + " in " + this);
v = _exp1.max();
if (v != 0)
{
q = Pmin / v;
delta = Pmin - q * v;
Min = delta > 0 ? q + 1 : q;
// System.out.println("setmin 2: " + Min + " in " + this);
_exp2.setMin(Min); // may fail
}
}
public void setValue(int value) throws Failure
{
//if (value % _value != 0)
// constrainer().fail("invalid setValue in IntExpMultiplyPositiveImpl");
//_exp.setValue(value/_value);
setMin(value);
setMax(value);
}
public void removeValue(int value) throws Failure
{
//if (value % _value != 0)
// return;
//_exp.removeValue(value/_value);
}
/*
public int size() // not necessary the true
{
return _exp1.size() * _exp2.size();
}
*/
public int value() throws Failure
{
return _product.value();
}
public boolean isLinear(){
if (! ( (_exp1.bound()) || (_exp2.bound()) ) )
return false;
return (_exp1.isLinear() && _exp2.isLinear());
}
public double calcCoeffs(Map map, double factor) throws NonLinearExpression{
if (_exp1.bound())
return _exp2.calcCoeffs(map,factor*_exp1.max());
if (_exp2.bound())
return _exp1.calcCoeffs(map, factor*_exp2.max());
throw new NonLinearExpression(this);
}
} // ~IntExpMulPP