michael_hartman_cz

MI-PAA HW02 BB, DP, FPTAS

Oct 30th, 2016
336
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 11.30 KB | None | 0 0
  1. #include <iostream>
  2. #include <sstream>
  3. #include <vector>
  4. #include <algorithm>    // std::sort
  5. #include <climits> //UINT_MAX
  6.  
  7.  
  8. using namespace std;
  9.  
  10. class CInstance
  11.  {
  12.     public:
  13.         vector<unsigned int>    weight;
  14.         vector<unsigned int>    cost;
  15.         vector<bool>            solution;
  16.         unsigned int            id;
  17.         unsigned int            quantity;
  18.         unsigned int            capacity;
  19.         unsigned int            total_cost;
  20.  };
  21.  
  22.  
  23. int readInstance ( CInstance & i, string line )
  24.  {
  25.     int tmp;
  26.     stringstream ss;
  27.     ss << line;
  28.    
  29.     ss >> i . id;
  30.     ss >> i . quantity;
  31.     ss >> i . capacity;
  32.     for ( int a = 0; a < i . quantity; ++a )
  33.      {
  34.         ss >> tmp;
  35.         i . weight . push_back ( tmp );
  36.         ss >> tmp;
  37.         i . cost . push_back ( tmp );
  38.      }
  39.     i . solution . resize ( i . weight . size(), false );
  40.     return 0;
  41.  }
  42.  
  43. int printInstance ( CInstance & i )
  44.  {
  45.     cout << i . id << " " << i . quantity << " " << i . capacity << " ";
  46.    
  47.     for ( int a = 0; a < i . quantity; ++a )
  48.      {
  49.         cout << i . cost [ a ] << " " << i . weight [ a ] << " ";
  50.      }
  51.     cout << endl;
  52.     return 0;
  53.  }
  54.  
  55. int printSolution ( CInstance & i )
  56.  {
  57.     cout << i . id << " " << i . quantity << " " << i . total_cost << "  ";
  58.    
  59.     for ( int a = 0; a < i . quantity; ++a )
  60.      {
  61.          cout << (int) i . solution [ a ] << " ";
  62.      }
  63.     cout << endl;
  64.  }
  65.  
  66. int countInstanceCost ( CInstance & i )
  67.  {
  68.     int tmp_cost = 0;
  69.     for ( size_t idx = 0; idx < i . cost . size(); ++idx )
  70.         if ( i . solution [ idx ] )
  71.             tmp_cost += i . cost [ idx ];
  72.     return tmp_cost;
  73.  
  74.  }
  75.  
  76.  
  77.  
  78. int recursiveBruteForce ( int n, int currentWeight, int currentValue, vector<bool> s, CInstance & i )
  79.  {
  80.     if ( n == -1 && currentWeight <= i . capacity && currentValue > i . total_cost )
  81.      {
  82.         i . total_cost = currentValue;
  83.         for ( size_t idx = 0; idx < i . solution . size(); ++idx )
  84.             i . solution [ idx ] = s [ idx ];
  85.      }
  86.    
  87.     if ( n == -1 )
  88.         return 0;
  89.    
  90.     //dont pack this
  91.     s [ n ] = false;
  92.     recursiveBruteForce ( n-1, currentWeight, currentValue, s, i );
  93.    
  94.     //pack this
  95.     s [ n ] = true;
  96.     recursiveBruteForce ( n-1, currentWeight + i . weight [ n ], currentValue + i . cost [ n ], s, i );
  97.  }
  98.  
  99. int branchAndBound ( int n, int currentWeight, int currentValue, vector<bool> s, CInstance & i )
  100.  {
  101.     if ( n == -1 && currentWeight <= i . capacity && currentValue > i . total_cost )
  102.      {
  103.         i . total_cost = currentValue;
  104.         for ( size_t idx = 0; idx < i . solution . size(); ++idx )
  105.             i . solution [ idx ] = s [ idx ];
  106.      }
  107.    
  108.     if ( n == -1 )
  109.         return 0;
  110.    
  111.     // bb enchancement start
  112.     int remainingItemsSumCost = 0;
  113.     for ( size_t tmp = 0; tmp <= n; ++tmp )
  114.         remainingItemsSumCost += i . cost [ tmp ];
  115.    
  116.     if ( i . total_cost > currentValue + remainingItemsSumCost )
  117.         return 0;
  118.  
  119.     if ( currentWeight > i . capacity )
  120.         return 0;  
  121.     // bb enhancement end
  122.    
  123.    
  124.     //dont pack this
  125.     s [ n ] = false;
  126.     branchAndBound ( n-1, currentWeight, currentValue, s, i );
  127.    
  128.     //pack this
  129.     s [ n ] = true;
  130.     branchAndBound ( n-1, currentWeight + i . weight [ n ], currentValue + i . cost [ n ], s, i );
  131.  }
  132.  
  133. bool compareIdValuePairbyValue ( pair<int,double> a, pair<int,double> b )
  134.  {
  135.     return ( a . second > b . second );
  136.  }
  137.  
  138.  
  139. int greedyHeuristic ( CInstance & i )
  140.  {
  141.     vector< pair<int,double> > ratio;
  142.     ratio . resize ( i . quantity );
  143.     for ( size_t idx = 0; idx < i . quantity; ++ idx )
  144.      {
  145.         ratio [ idx ] . first = idx;
  146.         ratio [ idx ] . second = (double) i . cost [ idx ] / (double) i . weight [ idx ]; //suppose positive weights...
  147.      }
  148.    
  149.     //high to low, ie best to worst
  150.     sort ( ratio.begin(), ratio.end(), compareIdValuePairbyValue );
  151.    
  152.     int currentWeight = 0;
  153.     i . total_cost = 0;
  154.     for ( size_t idx = 0; idx < i . quantity; ++ idx )
  155.      {
  156.         if ( currentWeight +  i . weight [ ratio [ idx ] . first ] <= i . capacity ) // another item still fits
  157.          {
  158.             currentWeight +=  i . weight [ ratio [ idx ] . first ];
  159.             i . total_cost += i . cost [ ratio [ idx ] . first ];
  160.             i . solution [ ratio [ idx ] . first ] = true;
  161.          }      
  162.      }
  163.    
  164.  }
  165.  
  166. int dynamicAlg ( CInstance & instance )
  167.  {    
  168.     int ** table = new int * [ instance . weight . size() + 1 ];
  169.     for(int i = 0; i < instance . weight . size() + 1; ++i)
  170.         table[i] = new int[ instance . capacity + 1 ];
  171.    
  172.     vector< vector< vector<bool> > > solutions;
  173.    
  174.     solutions . resize ( instance . weight . size() + 1 );
  175.     for ( size_t i = 0; i < instance . weight . size() + 1; ++i )
  176.      {
  177.         solutions[i] . resize ( instance . capacity + 1 );
  178.         for ( size_t j = 0; j < instance . capacity + 1; ++j )
  179.            solutions[i][j] . resize ( instance . weight . size() + 1, false);
  180.      }
  181.    
  182.     for ( unsigned int i = 0; i <= instance . weight . size(); ++i )
  183.      {
  184.         for ( unsigned int j = 0; j <= instance . capacity; ++j )
  185.          {
  186.             if ( i == 0 || j == 0 )
  187.              {
  188.                 table[i][j] = 0;
  189.              }
  190.             else if ( instance . weight [ i - 1 ] <= j )
  191.              {
  192.                 if ( instance.cost[i-1] + table[i-1][j-instance.weight[i-1]] > table[i-1][j] )
  193.                  {
  194.                     table[i][j] = instance.cost[i-1] + table[i-1][j-instance.weight[i-1]];
  195.                     solutions[i][j] = solutions[i-1][j - instance.weight[i-1]];
  196.                     solutions[i][j][i-1] = true;
  197.                  }
  198.                 else
  199.                  {
  200.                     table[i][j] = table[i-1][j];
  201.                     solutions[i][j] = solutions[i-1][j];
  202.  
  203.                  }
  204.              }
  205.             else
  206.              {
  207.                 table[i][j] = table[i-1][j];
  208.                 solutions[i][j] = solutions[i-1][j];
  209.  
  210.              }
  211.          }
  212.      }
  213.    
  214.     instance . total_cost = table [ instance . weight . size() ] [ instance . capacity ];
  215.     instance . solution = solutions [ instance . weight . size() ] [ instance . capacity ];
  216.    
  217.     for(int i = 0; i < instance . weight . size() + 1; ++i)
  218.         delete[] table[i];
  219.     delete[] table;
  220.    
  221.     return 0;    
  222.  }
  223.  
  224. unsigned int maxCost ( CInstance & instance )
  225.  {
  226.     unsigned int cmax = 0;
  227.     for ( size_t i = 0; i < instance . cost . size(); ++i )
  228.         if ( instance . cost [ i ] > cmax )
  229.             cmax = instance . cost [ i ];
  230.     return cmax;
  231.  }
  232.  
  233. unsigned int maxWeight ( CInstance & instance )
  234.  {
  235.     unsigned int wmax = 0;
  236.     for ( size_t i = 0; i < instance . weight . size(); ++i )
  237.         if ( instance . weight [ i ] > wmax )
  238.             wmax = instance . weight [ i ];
  239.     return wmax;
  240.  }
  241.  
  242. unsigned int sumOfInstanceCosts ( CInstance & instance )
  243.  {
  244.     unsigned int sum = 0;
  245.     for ( size_t i = 0; i < instance . cost . size(); ++i )
  246.      {
  247.         sum += instance . cost [ i ];
  248.      }
  249.     return sum;
  250.  }
  251.  
  252. int fptas ( CInstance & instance, double eps )
  253.  {
  254.  
  255.      /* ------------------ FPTAS MODIFICATIONS START ------------------*/
  256.  
  257.     unsigned int cmax = maxCost ( instance );
  258.     double k = (eps * cmax) / instance . cost . size();
  259.    
  260.     vector<unsigned int> cost_backup;
  261.     cost_backup . resize ( instance . cost . size() );
  262.     for ( size_t i = 0; i < instance . weight . size(); ++i )
  263.      {
  264.         cost_backup [ i ] = instance . cost [ i ];
  265.         instance . cost [ i ] = instance . cost [ i ] / k;
  266.         //instance . cost [ i ] = instance . cost [ i ] / 4;
  267.      }
  268.  
  269.     unsigned int wmax = maxWeight ( instance );
  270.     /* ------------------ DECLARATIONS START ------------------*/
  271.    
  272.     unsigned int sumOfCosts = sumOfInstanceCosts ( instance );
  273.      
  274.     unsigned int ** table = new unsigned int * [ instance . cost . size() + 1 ];
  275.     for(size_t i = 0; i < instance . cost . size() + 1; ++i)
  276.         table[i] = new unsigned int[ sumOfCosts + 1 ];
  277.    
  278.     vector< vector< vector<bool> > > solutions;
  279.    
  280.     solutions . resize ( instance . cost . size() + 1 );
  281.     for ( size_t i = 0; i < instance . cost . size() + 1; ++i )
  282.      {
  283.         solutions[i] . resize ( sumOfCosts + 1 );
  284.         for ( size_t j = 0; j < sumOfCosts + 1; ++j )
  285.            solutions[i][j] . resize ( sumOfCosts + 1, false);
  286.      }
  287.    
  288.    
  289.     /* ------------------ COMPUTATION START ------------------*/
  290.    
  291.     for ( size_t i = 0; i <= instance . cost . size(); ++i )
  292.      {
  293.         for ( unsigned int j = 0; j <= sumOfCosts; ++j )
  294.          {
  295.             if ( i == 0 )
  296.              {
  297.                 if ( j == 0 )
  298.                     table[i][j] = 0;
  299.                 else      
  300.                     table[i][j] = UINT_MAX - wmax - 10;
  301.              }
  302.             else if ( instance . cost [ i - 1 ] <= j )
  303.              {
  304.                 if ( instance.weight[i-1] + table[i-1][j-instance.cost[i-1]] < table[i-1][j] )
  305.                  {
  306.                     table[i][j] = instance.weight[i-1] + table[i-1][j-instance.cost[i-1]];
  307.                     solutions[i][j] = solutions[i-1][j - instance.cost[i-1]];
  308.                     solutions[i][j][i-1] = true;
  309.                  }
  310.                 else
  311.                  {
  312.                     table[i][j] = table[i-1][j];
  313.                     solutions[i][j] = solutions[i-1][j];
  314.  
  315.                  }
  316.              }
  317.             else
  318.              {
  319.                 table[i][j] = table[i-1][j];
  320.                 solutions[i][j] = solutions[i-1][j];
  321.  
  322.              }
  323.          }
  324.      }
  325.    
  326.     /* ------------------ BEST SOLUTION SELECTION ------------------*/
  327.    
  328.     unsigned int maxIndex = 0;
  329.     for ( size_t i = 0; i < sumOfCosts; ++i )
  330.      {
  331.         if ( table[ instance.cost.size() ] [ i ] < instance . capacity )
  332.             maxIndex = i;
  333.      }
  334.     instance . solution = solutions [ instance . cost . size() ] [ maxIndex ];
  335.  
  336.     /* ------------------ SOLUTION COST COMPUTATION ------------------*/
  337.  
  338.     instance . total_cost = 0;
  339.     for ( size_t i = 0; i < instance . cost . size(); ++i )
  340.      {
  341.         if ( instance . solution[ i ] )
  342.             instance . total_cost += cost_backup [ i ];
  343.      }    
  344.  
  345.     /* ------------------ CLEANUP ------------------*/
  346.      
  347.     for(size_t i = 0; i < instance . weight . size() + 1; ++i)
  348.         delete[] table[i];
  349.     delete[] table;
  350.    
  351.     return 0;    
  352.  }
  353.  
  354. int processInstance ( CInstance & i )
  355.  {  
  356.     //vector<bool> initSol ( i . solution );
  357.     //recursiveBruteForce ( i . quantity - 1, 0, 0, initSol, i );
  358.     //greedyHeuristic ( i );
  359.     //branchAndBound ( i . quantity - 1, 0, 0, initSol, i );
  360.     //dynamicAlg ( i );
  361.     fptas ( i, 0.3 );
  362.     return 0;
  363.  }
  364.  
  365. int main ( int argc, char ** argv )
  366. {    
  367.     string line;
  368.     vector<CInstance> instances;
  369.     while ( getline ( cin, line ) )
  370.      {
  371.         instances . resize ( instances . size () + 1 );
  372.         readInstance ( instances [ instances . size () - 1 ], line );
  373.      }
  374.    
  375.     for ( size_t i = 0; i < instances . size(); ++i )
  376.      {
  377.         processInstance ( instances [ i ] );
  378.      }
  379.  
  380.     for ( size_t i = 0; i < instances . size(); ++i )
  381.      {
  382.         printSolution ( instances [ i ] );
  383.      }
  384.  
  385.  
  386.     return 0;
  387. }
Advertisement
Add Comment
Please, Sign In to add comment