PartitionSolver.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. /*
  2. ** Command & Conquer Generals Zero Hour(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. ////////////////////////////////////////////////////////////////////////////////
  19. // //
  20. // (c) 2001-2003 Electronic Arts Inc. //
  21. // //
  22. ////////////////////////////////////////////////////////////////////////////////
  23. // FILE: PartitionSolver.cpp //////////////////////////////////////////////////////////////////////
  24. /*---------------------------------------------------------------------------*/
  25. /* EA Pacific */
  26. /* Confidential Information */
  27. /* Copyright (C) 2001 - All Rights Reserved */
  28. /* DO NOT DISTRIBUTE */
  29. /*---------------------------------------------------------------------------*/
  30. /* Project: RTS3 */
  31. /* File name: PartitionSolver.cpp */
  32. /* Created: John K. McDonald, Jr., 4/2/2002 */
  33. /* Desc: This contains a general-purpose Partition solver */
  34. /* Revision History: */
  35. /* 4/12/2002 : Initial creation */
  36. /*---------------------------------------------------------------------------*/
  37. /**************************************************************************************************
  38. Some info about partioning problems:
  39. This problem is contained in a very interesting class of problems known as NP complete. The
  40. basic problem is that there is no way to tell whether you have an optimal solution or not.
  41. Worst case, you try out every possible solution and still don't find the optimal solution:
  42. this takes 2^n time to find, where N is the number of elements you are attempting to place.
  43. For this reason, a value near PREFER_FAST_SOLUTION should almost always be chosen. We will use
  44. a flat multiply to determine how many solutions to attempt before giving up and returning our
  45. best attempt. If you want more info, this site contains info on the problem:
  46. http://odysseus.nat.uni-magdeburg.de/~mertens/npp/index.shtml
  47. **************************************************************************************************/
  48. #include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
  49. #include "Common/PartitionSolver.h"
  50. static Bool greater_than(PairObjectIDAndUInt a, PairObjectIDAndUInt b)
  51. {
  52. return a.second > b.second;
  53. }
  54. PartitionSolver::PartitionSolver(const EntriesVec& elements, const SpacesVec& spaces, SolutionType solveHow)
  55. {
  56. m_data = elements;
  57. m_spacesForData = spaces;
  58. m_howToSolve = solveHow;
  59. //Added By Sadullah Nader
  60. //Initializations inserted
  61. m_currentSolutionLeftovers = 0;
  62. //
  63. }
  64. void PartitionSolver::solve(void)
  65. {
  66. m_bestSolution.clear();
  67. m_currentSolution.clear();
  68. m_currentSolutionLeftovers = 0x7fffffff;
  69. Int minSizeForAllData = 0;
  70. Int slotsAllotted = 0;
  71. Int i, j;
  72. // first, determine whether there is an actual solution, or we're going to have to fudge it.
  73. for (i = 0; i < m_data.size(); ++i) {
  74. minSizeForAllData += m_data[i].second;
  75. }
  76. for (i = 0; i < m_spacesForData.size(); ++i) {
  77. slotsAllotted += m_spacesForData[i].second;
  78. }
  79. // we want to attempt to place the largest things first. This allows us to throw
  80. // out whole classes of solutions
  81. std::sort(m_data.begin(), m_data.end(), greater_than);
  82. // Also make the largest partition first.
  83. std::sort(m_spacesForData.begin(), m_spacesForData.end(), greater_than);
  84. // work in our temporary vector.
  85. SpacesVec spacesStillAvailable = m_spacesForData;
  86. if (m_howToSolve == PREFER_FAST_SOLUTION)
  87. {
  88. // we prefer the fast, but not necessarily correct solution
  89. // simply start placing the stuff. Skip things you can't place.
  90. for (i = 0; i < m_data.size(); ++i)
  91. {
  92. for (j = 0; j < spacesStillAvailable.size(); ++j)
  93. {
  94. if (m_data[i].second <= spacesStillAvailable[j].second)
  95. {
  96. spacesStillAvailable[j].second -= m_data[i].second;
  97. m_bestSolution.push_back(std::make_pair(m_data[i].first, spacesStillAvailable[j].first));
  98. break;
  99. }
  100. }
  101. }
  102. } else {
  103. DEBUG_CRASH(("PREFER_CORRECT_SOLUTION @todo impl"));
  104. }
  105. }
  106. const SolutionVec& PartitionSolver::getSolution( void ) const
  107. {
  108. return m_bestSolution;
  109. }