constraint.h 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. /*-----------------------------------------------------------------------------
  2. | Copyright (c) 2013-2017, Nucleic Development Team.
  3. |
  4. | Distributed under the terms of the Modified BSD License.
  5. |
  6. | The full license is in the file COPYING.txt, distributed with this software.
  7. |----------------------------------------------------------------------------*/
  8. #pragma once
  9. #include <map>
  10. #include <vector>
  11. #include "expression.h"
  12. #include "shareddata.h"
  13. #include "strength.h"
  14. #include "term.h"
  15. #include "variable.h"
  16. namespace kiwi
  17. {
  18. enum RelationalOperator { OP_LE, OP_GE, OP_EQ };
  19. class Constraint
  20. {
  21. public:
  22. Constraint() : m_data( 0 ) {}
  23. Constraint( const Expression& expr,
  24. RelationalOperator op,
  25. double strength = strength::required ) :
  26. m_data( new ConstraintData( expr, op, strength ) ) {}
  27. Constraint( const Constraint& other, double strength ) :
  28. m_data( new ConstraintData( other, strength ) ) {}
  29. ~Constraint() {}
  30. const Expression& expression() const
  31. {
  32. return m_data->m_expression;
  33. }
  34. RelationalOperator op() const
  35. {
  36. return m_data->m_op;
  37. }
  38. double strength() const
  39. {
  40. return m_data->m_strength;
  41. }
  42. bool operator!() const
  43. {
  44. return !m_data;
  45. }
  46. private:
  47. static Expression reduce( const Expression& expr )
  48. {
  49. std::map<Variable, double> vars;
  50. typedef std::vector<Term>::const_iterator iter_t;
  51. iter_t end = expr.terms().end();
  52. for( iter_t it = expr.terms().begin(); it != end; ++it )
  53. vars[ it->variable() ] += it->coefficient();
  54. std::vector<Term> terms( vars.begin(), vars.end() );
  55. return Expression( terms, expr.constant() );
  56. }
  57. class ConstraintData : public SharedData
  58. {
  59. public:
  60. ConstraintData( const Expression& expr,
  61. RelationalOperator op,
  62. double strength ) :
  63. SharedData(),
  64. m_expression( reduce( expr ) ),
  65. m_strength( strength::clip( strength ) ),
  66. m_op( op ) {}
  67. ConstraintData( const Constraint& other, double strength ) :
  68. SharedData(),
  69. m_expression( other.expression() ),
  70. m_strength( strength::clip( strength ) ),
  71. m_op( other.op() ) {}
  72. ~ConstraintData() {}
  73. Expression m_expression;
  74. double m_strength;
  75. RelationalOperator m_op;
  76. private:
  77. ConstraintData( const ConstraintData& other );
  78. ConstraintData& operator=( const ConstraintData& other );
  79. };
  80. SharedDataPtr<ConstraintData> m_data;
  81. friend bool operator<( const Constraint& lhs, const Constraint& rhs )
  82. {
  83. return lhs.m_data < rhs.m_data;
  84. }
  85. friend bool operator==( const Constraint& lhs, const Constraint& rhs )
  86. {
  87. return lhs.m_data == rhs.m_data;
  88. }
  89. friend bool operator!=( const Constraint& lhs, const Constraint& rhs )
  90. {
  91. return lhs.m_data != rhs.m_data;
  92. }
  93. };
  94. } // namespace kiwi