Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

90 lines
3.7 KiB

  1. //========= Copyright c 1996-2009, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #ifndef VPHYSICS_PHYSX_SIMPLEX_H
  8. #define VPHYSICS_PHYSX_SIMPLEX_H
  9. #include "tier0/dbg.h"
  10. //////////////////////////////////////////////////////////////////////////
  11. // Direct simplex LP solver using tableau and Gauss pivoting rule;
  12. // see http://www.teachers.ash.org.au/mikemath/mathsc/linearprogramming/simplex.PDF
  13. // After constructing an instance of this class with the appropriate number of vars and constraints,
  14. // fill in constraints using SetConstraintFactor and SetConstraintConst
  15. //
  16. // Here's the problem in its canonical form:
  17. // Maximize objective = c'x : x[i] >= 0, A.x <= b; and make that c' positive! negative will automatically mean 0 is your best answer
  18. // Vector x is the vector of unknowns (variables) and has dimentionality of numVariables
  19. // Vector c is dotted with the x, so has the same dimentionality; you set it with SetObjectiveFactor()
  20. // every component of x must be positive in feasible solution
  21. // A is constraint matrix and has dims: m_numConstraints by m_numVariables; you set it with SetConstraintFactor();
  22. // b has dims: m_numConstraints, you set it with SetConstraintConst()
  23. //
  24. // This is solved with the simplest possible simplex method (I have no good reason to implement pivot rules now)
  25. // The simplex tableau (m_pTableau) starts like this:
  26. // | A | b |
  27. // | c' | 0 |
  28. //
  29. class CSimplex
  30. {
  31. public:
  32. int m_numConstraints, m_numVariables;
  33. float *m_pTableau;
  34. float *m_pInitialTableau;
  35. float *m_pSolution;
  36. int *m_pBasis; // indices of basis variables, corresponding to each row in the tableau; >= numVars if the slack var corresponds to that row
  37. int *m_pNonBasis; // indices of non-basis primal variables (labels on the top of the classic Tucker(?) tableau)
  38. enum StateEnum{kInfeasible, kUnbound, kOptimal, kUnknown, kCannotPivot};
  39. StateEnum m_state;
  40. //CVarBitVec m_isBasis;
  41. public:
  42. CSimplex();
  43. CSimplex(int numVariables, int numConstraints);
  44. ~CSimplex();
  45. void Init(int numVariables, int numConstraints);
  46. void InitTableau(const float *pTableau);
  47. void SetObjectiveFactors(int numFactors, const float *pFactors);
  48. void SetConstraintFactor(int nConstraint, int nConstant, float fFactor);
  49. void SetConstraintConst(int nConstraint, float fConst);
  50. void SetObjectiveFactor(int nConstant, float fFactor);
  51. StateEnum Solve(float flThreshold = 1e-5f, int maxStallIterations = 128);
  52. StateEnum SolvePhase1(float flThreshold = 1e-5f, int maxStallIterations = 128);
  53. StateEnum SolvePhase2(float flThreshold = 1e-5f, int maxStallIterations = 128);
  54. float GetSolution(int nVariable)const;
  55. float GetSlack(int nConstraint)const;
  56. float GetObjective()const;
  57. void PrintTableau()const;
  58. protected:
  59. void Destruct();
  60. float *operator [] (int row) {Assert(row >= 0 && row < NumRows());return m_pTableau + row * NumColumns();}
  61. float &Tableau(int row, int col){Assert(row >= 0 && row < NumRows());return m_pTableau[row * NumColumns()+col];}
  62. float Tableau(int row, int col)const{Assert(row >= 0 && row < NumRows());return m_pTableau[row * NumColumns()+col];}
  63. float GetInitialTableau(int row, int col)const{return m_pInitialTableau[row * NumColumns()+col];}
  64. bool IteratePhase1();
  65. bool IteratePhase2();
  66. int NumRows()const {return m_numConstraints + 1;}
  67. int NumColumns()const{return m_numVariables + 1;}
  68. void Validate();
  69. void PrepareTableau();
  70. void GatherSolution();
  71. bool Pivot(int nPivotRow, int nPivotColumn);
  72. void MultiplyRow(int nRow, float fFactor);
  73. void AddRowMulFactor(int nTargetRow, int nPivotRow, float fFactor);
  74. int FindPivotColumn();
  75. int FindPivotRow(int nColumn);
  76. int FindLastNegConstrRow();
  77. int ChooseNegativeElementInRow(int nRow);
  78. };
  79. #endif