michael_hartman_cz

MI-PAA HW04 GA

Dec 27th, 2016
316
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 15.52 KB | None | 0 0
  1.                                                       #include <iostream>
  2. #include <sstream>
  3. #include <vector>
  4. #include <algorithm>    // std::sort
  5. #include <climits> //UINT_MAX
  6. #include <cstdlib> //srand, rand
  7. #include <ctime>
  8.  
  9.  
  10. using namespace std;
  11.  
  12. class CInstance
  13.  {
  14.     public:
  15.         vector<unsigned int>    weight;
  16.         vector<unsigned int>    cost;
  17.         vector<bool>            solution;
  18.         unsigned int            id;
  19.         unsigned int            quantity;
  20.         unsigned int            capacity;
  21.         unsigned int            total_cost;
  22.  };
  23.  
  24. class ga_individual
  25.  {
  26.     public:
  27.         vector<bool>    solution;
  28.         int             fitness;
  29.  };
  30.  
  31.  
  32. int readInstance ( CInstance & i, string line )
  33.  {
  34.     int tmp;
  35.     stringstream ss;
  36.     ss << line;
  37.    
  38.     ss >> i . id;
  39.     ss >> i . quantity;
  40.     ss >> i . capacity;
  41.     for ( int a = 0; a < i . quantity; ++a )
  42.      {
  43.         ss >> tmp;
  44.         i . weight . push_back ( tmp );
  45.         ss >> tmp;
  46.         i . cost . push_back ( tmp );
  47.      }
  48.     i . solution . resize ( i . weight . size(), false );
  49.     return 0;
  50.  }
  51.  
  52. int printInstance ( CInstance & i )
  53.  {
  54.     cout << i . id << " " << i . quantity << " " << i . capacity << " ";
  55.    
  56.     for ( int a = 0; a < i . quantity; ++a )
  57.      {
  58.         cout << i . cost [ a ] << " " << i . weight [ a ] << " ";
  59.      }
  60.     cout << endl;
  61.     return 0;
  62.  }
  63.  
  64. int printSolution ( CInstance & i )
  65.  {
  66.     cout << i . id << " " << i . quantity << " " << i . total_cost << "  ";
  67.    
  68.     for ( int a = 0; a < i . quantity; ++a )
  69.      {
  70.          cout << (int) i . solution [ a ] << " ";
  71.      }
  72.     cout << endl;
  73.  }
  74.  
  75. int countInstanceCost ( CInstance & i )
  76.  {
  77.     int tmp_cost = 0;
  78.     for ( size_t idx = 0; idx < i . cost . size(); ++idx )
  79.         if ( i . solution [ idx ] )
  80.             tmp_cost += i . cost [ idx ];
  81.     return tmp_cost;
  82.  
  83.  }
  84.  
  85.  
  86.  
  87. int recursiveBruteForce ( int n, int currentWeight, int currentValue, vector<bool> s, CInstance & i )
  88.  {
  89.     if ( n == -1 && currentWeight <= i . capacity && currentValue > i . total_cost )
  90.      {
  91.         i . total_cost = currentValue;
  92.         for ( size_t idx = 0; idx < i . solution . size(); ++idx )
  93.             i . solution [ idx ] = s [ idx ];
  94.      }
  95.    
  96.     if ( n == -1 )
  97.         return 0;
  98.    
  99.     //dont pack this
  100.     s [ n ] = false;
  101.     recursiveBruteForce ( n-1, currentWeight, currentValue, s, i );
  102.    
  103.     //pack this
  104.     s [ n ] = true;
  105.     recursiveBruteForce ( n-1, currentWeight + i . weight [ n ], currentValue + i . cost [ n ], s, i );
  106.  }
  107.  
  108. int branchAndBound ( int n, int currentWeight, int currentValue, vector<bool> s, CInstance & i )
  109.  {
  110.     if ( n == -1 && currentWeight <= i . capacity && currentValue > i . total_cost )
  111.      {
  112.         i . total_cost = currentValue;
  113.         for ( size_t idx = 0; idx < i . solution . size(); ++idx )
  114.             i . solution [ idx ] = s [ idx ];
  115.      }
  116.    
  117.     if ( n == -1 )
  118.         return 0;
  119.    
  120.     // bb enchancement start
  121.     int remainingItemsSumCost = 0;
  122.     for ( size_t tmp = 0; tmp <= n; ++tmp )
  123.         remainingItemsSumCost += i . cost [ tmp ];
  124.    
  125.     if ( i . total_cost > currentValue + remainingItemsSumCost )
  126.         return 0;
  127.  
  128.     if ( currentWeight > i . capacity )
  129.         return 0;  
  130.     // bb enhancement end
  131.    
  132.    
  133.     //dont pack this
  134.     s [ n ] = false;
  135.     branchAndBound ( n-1, currentWeight, currentValue, s, i );
  136.    
  137.     //pack this
  138.     s [ n ] = true;
  139.     branchAndBound ( n-1, currentWeight + i . weight [ n ], currentValue + i . cost [ n ], s, i );
  140.  }
  141.  
  142. bool compareIdValuePairbyValue ( pair<int,double> a, pair<int,double> b )
  143.  {
  144.     return ( a . second > b . second );
  145.  }
  146.  
  147.  
  148. int greedyHeuristic ( CInstance & i )
  149.  {
  150.     vector< pair<int,double> > ratio;
  151.     ratio . resize ( i . quantity );
  152.     for ( size_t idx = 0; idx < i . quantity; ++ idx )
  153.      {
  154.         ratio [ idx ] . first = idx;
  155.         ratio [ idx ] . second = (double) i . cost [ idx ] / (double) i . weight [ idx ]; //suppose positive weights...
  156.      }
  157.    
  158.     //high to low, ie best to worst
  159.     sort ( ratio.begin(), ratio.end(), compareIdValuePairbyValue );
  160.    
  161.     int currentWeight = 0;
  162.     i . total_cost = 0;
  163.     for ( size_t idx = 0; idx < i . quantity; ++ idx )
  164.      {
  165.         if ( currentWeight +  i . weight [ ratio [ idx ] . first ] <= i . capacity ) // another item still fits
  166.          {
  167.             currentWeight +=  i . weight [ ratio [ idx ] . first ];
  168.             i . total_cost += i . cost [ ratio [ idx ] . first ];
  169.             i . solution [ ratio [ idx ] . first ] = true;
  170.          }      
  171.      }
  172.    
  173.  }
  174.  
  175. int dynamicAlg ( CInstance & instance )
  176.  {    
  177.     int ** table = new int * [ instance . weight . size() + 1 ];
  178.     for(int i = 0; i < instance . weight . size() + 1; ++i)
  179.         table[i] = new int[ instance . capacity + 1 ];
  180.    
  181.     vector< vector< vector<bool> > > solutions;
  182.    
  183.     solutions . resize ( instance . weight . size() + 1 );
  184.     for ( size_t i = 0; i < instance . weight . size() + 1; ++i )
  185.      {
  186.         solutions[i] . resize ( instance . capacity + 1 );
  187.         for ( size_t j = 0; j < instance . capacity + 1; ++j )
  188.            solutions[i][j] . resize ( instance . weight . size() + 1, false);
  189.      }
  190.    
  191.     for ( unsigned int i = 0; i <= instance . weight . size(); ++i )
  192.      {
  193.         for ( unsigned int j = 0; j <= instance . capacity; ++j )
  194.          {
  195.             if ( i == 0 || j == 0 )
  196.              {
  197.                 table[i][j] = 0;
  198.              }
  199.             else if ( instance . weight [ i - 1 ] <= j )
  200.              {
  201.                 if ( instance.cost[i-1] + table[i-1][j-instance.weight[i-1]] > table[i-1][j] )
  202.                  {
  203.                     table[i][j] = instance.cost[i-1] + table[i-1][j-instance.weight[i-1]];
  204.                     solutions[i][j] = solutions[i-1][j - instance.weight[i-1]];
  205.                     solutions[i][j][i-1] = true;
  206.                  }
  207.                 else
  208.                  {
  209.                     table[i][j] = table[i-1][j];
  210.                     solutions[i][j] = solutions[i-1][j];
  211.  
  212.                  }
  213.              }
  214.             else
  215.              {
  216.                 table[i][j] = table[i-1][j];
  217.                 solutions[i][j] = solutions[i-1][j];
  218.  
  219.              }
  220.          }
  221.      }
  222.    
  223.     instance . total_cost = table [ instance . weight . size() ] [ instance . capacity ];
  224.     instance . solution = solutions [ instance . weight . size() ] [ instance . capacity ];
  225.    
  226.     for(int i = 0; i < instance . weight . size() + 1; ++i)
  227.         delete[] table[i];
  228.     delete[] table;
  229.    
  230.     return 0;    
  231.  }
  232.  
  233. unsigned int maxCost ( CInstance & instance )
  234.  {
  235.     unsigned int cmax = 0;
  236.     for ( size_t i = 0; i < instance . cost . size(); ++i )
  237.         if ( instance . cost [ i ] > cmax )
  238.             cmax = instance . cost [ i ];
  239.     return cmax;
  240.  }
  241.  
  242. unsigned int maxWeight ( CInstance & instance )
  243.  {
  244.     unsigned int wmax = 0;
  245.     for ( size_t i = 0; i < instance . weight . size(); ++i )
  246.         if ( instance . weight [ i ] > wmax )
  247.             wmax = instance . weight [ i ];
  248.     return wmax;
  249.  }
  250.  
  251. unsigned int sumOfInstanceCosts ( CInstance & instance )
  252.  {
  253.     unsigned int sum = 0;
  254.     for ( size_t i = 0; i < instance . cost . size(); ++i )
  255.      {
  256.         sum += instance . cost [ i ];
  257.      }
  258.     return sum;
  259.  }
  260.  
  261. int fptas ( CInstance & instance, double eps )
  262.  {
  263.  
  264.      /* ------------------ FPTAS MODIFICATIONS START ------------------*/
  265.  
  266.     unsigned int cmax = maxCost ( instance );
  267.     double k = (eps * cmax) / instance . cost . size();
  268.    
  269.     vector<unsigned int> cost_backup;
  270.     cost_backup . resize ( instance . cost . size() );
  271.     for ( size_t i = 0; i < instance . weight . size(); ++i )
  272.      {
  273.         cost_backup [ i ] = instance . cost [ i ];
  274.         instance . cost [ i ] = instance . cost [ i ] / k;
  275.         //instance . cost [ i ] = instance . cost [ i ] / 4;
  276.      }
  277.  
  278.     unsigned int wmax = maxWeight ( instance );
  279.     /* ------------------ DECLARATIONS START ------------------*/
  280.    
  281.     unsigned int sumOfCosts = sumOfInstanceCosts ( instance );
  282.      
  283.     unsigned int ** table = new unsigned int * [ instance . cost . size() + 1 ];
  284.     for(size_t i = 0; i < instance . cost . size() + 1; ++i)
  285.         table[i] = new unsigned int[ sumOfCosts + 1 ];
  286.    
  287.     vector< vector< vector<bool> > > solutions;
  288.    
  289.     solutions . resize ( instance . cost . size() + 1 );
  290.     for ( size_t i = 0; i < instance . cost . size() + 1; ++i )
  291.      {
  292.         solutions[i] . resize ( sumOfCosts + 1 );
  293.         for ( size_t j = 0; j < sumOfCosts + 1; ++j )
  294.            solutions[i][j] . resize ( sumOfCosts + 1, false);
  295.      }
  296.    
  297.    
  298.     /* ------------------ COMPUTATION START ------------------*/
  299.    
  300.     for ( size_t i = 0; i <= instance . cost . size(); ++i )
  301.      {
  302.         for ( unsigned int j = 0; j <= sumOfCosts; ++j )
  303.          {
  304.             if ( i == 0 )
  305.              {
  306.                 if ( j == 0 )
  307.                     table[i][j] = 0;
  308.                 else      
  309.                     table[i][j] = UINT_MAX - wmax - 10;
  310.              }
  311.             else if ( instance . cost [ i - 1 ] <= j )
  312.              {
  313.                 if ( instance.weight[i-1] + table[i-1][j-instance.cost[i-1]] < table[i-1][j] )
  314.                  {
  315.                     table[i][j] = instance.weight[i-1] + table[i-1][j-instance.cost[i-1]];
  316.                     solutions[i][j] = solutions[i-1][j - instance.cost[i-1]];
  317.                     solutions[i][j][i-1] = true;
  318.                  }
  319.                 else
  320.                  {
  321.                     table[i][j] = table[i-1][j];
  322.                     solutions[i][j] = solutions[i-1][j];
  323.  
  324.                  }
  325.              }
  326.             else
  327.              {
  328.                 table[i][j] = table[i-1][j];
  329.                 solutions[i][j] = solutions[i-1][j];
  330.  
  331.              }
  332.          }
  333.      }
  334.    
  335.     /* ------------------ BEST SOLUTION SELECTION ------------------*/
  336.    
  337.     unsigned int maxIndex = 0;
  338.     for ( size_t i = 0; i < sumOfCosts; ++i )
  339.      {
  340.         if ( table[ instance.cost.size() ] [ i ] < instance . capacity )
  341.             maxIndex = i;
  342.      }
  343.     instance . solution = solutions [ instance . cost . size() ] [ maxIndex ];
  344.  
  345.     /* ------------------ SOLUTION COST COMPUTATION ------------------*/
  346.  
  347.     instance . total_cost = 0;
  348.     for ( size_t i = 0; i < instance . cost . size(); ++i )
  349.      {
  350.         if ( instance . solution[ i ] )
  351.             instance . total_cost += cost_backup [ i ];
  352.      }    
  353.  
  354.     /* ------------------ CLEANUP ------------------*/
  355.      
  356.     for(size_t i = 0; i < instance . weight . size() + 1; ++i)
  357.         delete[] table[i];
  358.     delete[] table;
  359.    
  360.     return 0;    
  361.  }
  362.  
  363. vector< ga_individual > ga_generateInitialPopulation ( int initPopSize, int solutionSize )
  364.  {
  365.     vector<ga_individual> initPop;
  366.     initPop . resize ( initPopSize );
  367.     srand (time(NULL));
  368.  
  369.     for ( int i = 0; i < initPopSize; ++i )
  370.      {
  371.         initPop[i] . solution . resize ( solutionSize );
  372.         for ( int j = 0; j < solutionSize; ++j )
  373.          {
  374.             initPop[i] . solution[j] = rand() % 2;
  375.             //cout << initPop[i] . solution[j] << endl;
  376.          }
  377.      }
  378.     return initPop;
  379.  }
  380.  
  381. void ga_evaulateFitness ( vector<ga_individual>  & population, CInstance & instance )
  382.  {
  383.     for ( size_t i = 0; i < population . size(); ++i )
  384.      {
  385.         int cost = 0;
  386.         int weight = 0;
  387.         for ( size_t j = 0; j < population [0] . solution . size(); ++j )
  388.          {
  389.             if ( population[i] . solution [j] == true )
  390.              {
  391.                 cost += instance . cost [j];
  392.                 weight += instance . weight [j];
  393.              }
  394.             if ( weight > instance . capacity )
  395.                 break;
  396.          }
  397.         if ( weight <= instance . capacity )
  398.             population[i] . fitness = cost;
  399.         else
  400.             population[i] . fitness = 0;
  401.      }
  402.  }
  403.  
  404. bool compareGA_individualByFitness ( ga_individual a, ga_individual b )
  405.  {
  406.     return a . fitness > b . fitness;
  407.  }
  408.  
  409. void ga_sortPopulationByFitness ( vector<ga_individual> & population )
  410.  {
  411.     sort ( population.begin(), population.end(), compareGA_individualByFitness );
  412.  }
  413.  
  414. vector<ga_individual> ga_generateNewPopulation ( vector<ga_individual> & oldPopulation )
  415.  {
  416.     vector<ga_individual> newPopulation;
  417.     newPopulation . resize ( oldPopulation . size() );
  418.     newPopulation[0] = oldPopulation[0]; //preserve the best individual
  419.     for ( size_t i = 1; i < newPopulation . size(); ++i )
  420.      {
  421.         newPopulation[i] . solution . resize ( oldPopulation[0] . solution . size() );
  422.         for ( size_t j = 0; j < newPopulation[0].solution.size(); ++j )
  423.          {
  424.             if ( j < newPopulation[0].solution.size() / 2 )
  425.              {
  426.                 newPopulation[i].solution[j] = oldPopulation[i] . solution[j];
  427.              }
  428.             else
  429.              {
  430.                 newPopulation[i].solution[j] = oldPopulation[ (oldPopulation.size() / 2) - (i/2) ] . solution[j];
  431.              }
  432.            
  433.          }
  434.      }
  435.     return newPopulation;
  436.  }
  437.  
  438. // mutation probability, 0-100%
  439. void ga_mutation ( vector<ga_individual> & population, int mutationProbability )
  440.  {
  441.     int upperBound = mutationProbability * (population . size() * population[0].solution.size() / 100.0);
  442.      
  443.     for ( size_t i = 0; i < upperBound ; ++i )
  444.      {
  445.             population[ 1 + (rand() % (population.size()-2) ) ].solution[ rand() % population[0].solution.size() ] = rand() % 2;
  446.      }
  447.  }
  448.  
  449. void printPopulation ( vector<ga_individual> & population )
  450.  {
  451.     for ( size_t i = 0; i < population . size(); ++i )
  452.      {
  453.         cout << "idx " << i << " fitness " << population[i].fitness << endl;
  454.      }
  455.     cout << endl;
  456.  }
  457.  
  458. int ga_knapsack ( CInstance & instance, int initPopSize, int mutationProbability, int numberOfGenerations )
  459.  {
  460.     vector<ga_individual> population;
  461.     population = ga_generateInitialPopulation ( initPopSize, instance . solution . size() );
  462.  
  463.     for ( int i = 0; i < numberOfGenerations; ++i )
  464.      {
  465.  
  466.         ga_evaulateFitness ( population, instance );
  467.         ga_sortPopulationByFitness ( population );        
  468.        
  469.         cout << "id " << instance.id << " fitness " << population[0] . fitness << endl;
  470.         //printPopulation ( population );
  471.        
  472.         population = ga_generateNewPopulation ( population );        
  473.         ga_mutation ( population, mutationProbability );
  474.      }
  475.      
  476.     cout << endl;
  477.     instance . solution = population[0] . solution;
  478.     instance . total_cost = population[0] . fitness;        
  479.  }
  480.  
  481. int processInstance ( CInstance & i )
  482.  {  
  483.     //vector<bool> initSol ( i . solution );
  484.     //recursiveBruteForce ( i . quantity - 1, 0, 0, initSol, i );
  485.     //greedyHeuristic ( i );
  486.     //branchAndBound ( i . quantity - 1, 0, 0, initSol, i );
  487.     //dynamicAlg ( i );
  488.     //fptas ( i, 0.3 );
  489.     //instance, population size, mutation probability in %, number of generations
  490.     ga_knapsack ( i, 100, 15, 1000 );
  491.     return 0;
  492.  }
  493.  
  494. int main ( int argc, char ** argv )
  495. {    
  496.     string line;
  497.     vector<CInstance> instances;
  498.     while ( getline ( cin, line ) )
  499.      {
  500.         instances . resize ( instances . size () + 1 );
  501.         readInstance ( instances [ instances . size () - 1 ], line );
  502.      }
  503.    
  504.     for ( size_t i = 0; i < instances . size(); ++i )
  505.      {
  506.         processInstance ( instances [ i ] );
  507.      }
  508.  
  509.     for ( size_t i = 0; i < instances . size(); ++i )
  510.      {
  511.         printSolution ( instances [ i ] );
  512.      }
  513.  
  514.  
  515.     return 0;
  516. }
Advertisement
Add Comment
Please, Sign In to add comment