Advertisement
ASabry

Untitled

Mar 9th, 2020
132
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.74 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <cstdlib>
  4. #include <ctime>
  5. #include <algorithm>
  6.  
  7. using namespace std;
  8.  
  9. //Prototypes
  10. void printTable(vector<int> benefits,vector<int> table,int r,int index);
  11.  
  12. class Chromosome
  13. {
  14.  
  15. public:
  16. vector<int> bits;
  17. int benefit;
  18. int weight;
  19. int size;
  20.  
  21. Chromosome(){}
  22. Chromosome(int length)
  23. {
  24. size = length;
  25. }
  26. int getBenefit()
  27. {
  28. return benefit;
  29. }
  30. void setBenefit(int b)
  31. {
  32. benefit = b;
  33. }
  34. int getSize(){return size;}
  35. void setWeight(int w){weight = w;}
  36. int getWeight(){return weight;}
  37. void setBits(vector<int> v)
  38. {
  39. for(int i = 0 ; i < size; i++)
  40. bits[i] = v[i];
  41. }
  42. vector<int> getBits(){return bits;}
  43. void fill()
  44. {
  45. bits.clear();
  46. cout << "Enter Bits Of Chromosome" << endl;
  47. for(int i = 0; i < size; i++)
  48. {
  49. int num;
  50. cin >> num;
  51. bits.push_back(num);
  52. }
  53. }
  54. void randomFill()
  55. {
  56. for(int i = 0; i < size; i++)
  57. bits.push_back(rand()%2);
  58.  
  59. }
  60. void reRandomFill()
  61. {
  62. for(int i = 0; i < size; i++)
  63. bits[i]=(rand()%2);
  64. }
  65. void printBits()
  66. {
  67. for(int i = 0; i < bits.size(); i++)
  68. cout << bits[i];
  69. }
  70. void printFullChromosome()
  71. {
  72. for(int i = 0; i < bits.size(); i++)
  73. cout << bits[i];
  74. cout << endl;
  75. cout << "Weight " << weight << endl;
  76. cout << "Benefit " << benefit << endl;
  77. }
  78. bool checkIfValid(vector<int> weights, vector<int> benefits, int maxWeight)
  79. {
  80. int totalWeight =0, totalBenefit =0;
  81.  
  82. for(int i = 0 ; i < size ; i++)
  83. {
  84. if(bits[i] == 1)
  85. {
  86. totalWeight+= weights[i];
  87. totalBenefit+= benefits[i];
  88. }
  89. }
  90. if(totalWeight > maxWeight)
  91. return false;
  92. //
  93. weight = totalWeight;
  94. benefit = totalBenefit;
  95. return true;
  96. }
  97. Chromosome setChromosome(Chromosome c)
  98. {
  99. (*this).setBenefit(c.getBenefit());
  100. (*this).setBits(c.getBits());
  101. (*this).setWeight(c.getWeight());
  102. }
  103. };
  104.  
  105. //--------------------------------------------------------------------//
  106. vector<int> createCumulativeTable(vector<int> benefits, vector<Chromosome> population)
  107. {
  108. vector<int> CumBenefits;
  109. int temp;
  110.  
  111. CumBenefits.push_back(population[0].getBenefit());
  112.  
  113. temp = CumBenefits[0];
  114.  
  115. for(int i=1; i < population.size(); i++)
  116. {
  117. CumBenefits.push_back(population[i].getBenefit() + temp);
  118.  
  119. temp = CumBenefits[i];
  120.  
  121. }
  122. cout<<"return"<<endl;
  123. return CumBenefits;
  124. }
  125. //--------------------------------------------------------------------//
  126. void printTable(vector<Chromosome> population,vector<int> cumTable)
  127. {
  128. system("CLS");
  129. for(int i = 0; i < population.size(); i++)
  130. {
  131. cout << "[" ;
  132. population[i].printBits();
  133. cout << "] " << population[i].getBenefit() << "\t|" << "\t" << cumTable[i] << endl;
  134. }
  135. cout << endl;
  136.  
  137. //cout << "Random number: " << r << "\nExist in index " << index << endl;
  138. }
  139. //--------------------------------------------------------------------//
  140. void mutation (Chromosome ch,int maxWeight,vector<int> weights, vector<int> benefits)
  141. {
  142. double pm= 0.1,r;
  143.  
  144. r = (rand()%10 + 1.0)/10.0;
  145.  
  146. if (r<=pm)
  147. {
  148.  
  149. Chromosome child;
  150.  
  151. child.size = ch.size;
  152.  
  153. for(int k = 0; k < ch.size; k++)
  154. {
  155. child.bits.push_back(ch.bits[k]);
  156. }
  157.  
  158. child.benefit = ch.benefit;
  159. child.weight = ch.weight;
  160.  
  161.  
  162.  
  163. r = rand()%ch.size;
  164.  
  165. child.bits[r]=!child.bits[r];
  166.  
  167. if(child.checkIfValid(weights,benefits,maxWeight))
  168. {
  169. if(child.getBenefit() > ch.getBenefit())
  170. {
  171. ch.bits[r]=!ch.bits[r];
  172. ch.checkIfValid(weights,benefits,maxWeight);
  173. }
  174.  
  175. }
  176.  
  177.  
  178. }
  179.  
  180. }
  181. //--------------------------------------------------------------------//
  182. void crossOver(vector<Chromosome> ch,vector<int> Choosen,int maxWeight,
  183. Chromosome bestSoFar,vector<int> weights, vector<int> benefits)
  184. {
  185. Chromosome ch1,ch2;
  186. vector<int> ChoosenVector;
  187. int S = ch[0].size;
  188.  
  189. int splitSize = rand()%ch[0].size;
  190.  
  191. while(splitSize == 0 || splitSize == ch[0].size)
  192. splitSize = rand()%ch[0].size;
  193.  
  194. for(int i = 0; i < Choosen.size(); i++)
  195. {
  196. ChoosenVector.push_back(Choosen[i]);
  197. }
  198.  
  199. //cout << "splitSize : " << splitSize << endl;
  200.  
  201. for(int i = ChoosenVector.size()/2; i > 0 && !ChoosenVector.empty(); i--)
  202. {
  203. ch1.bits.clear();
  204. ch2.bits.clear();
  205.  
  206. int r = rand()%ChoosenVector.size();
  207. int r2 = rand()%ChoosenVector.size();
  208.  
  209. while(r2 == r)
  210. r2 = rand()%ChoosenVector.size();
  211.  
  212.  
  213. for(int k = 0; k < splitSize; k++)
  214. {
  215. ch1.bits.push_back(ch[r].bits[k]) ;
  216. ch2.bits.push_back(ch[r2].bits[k]) ;
  217. }
  218.  
  219. for(int k = splitSize; k < ch[0].size; k++)
  220. {
  221. ch1.bits.push_back(ch[r2].bits[k]);
  222. ch2.bits.push_back(ch[r].bits[k]);
  223. }
  224.  
  225. ch1.size = ch[0].size;
  226. ch2.size = ch[0].size;
  227.  
  228. // cout << "-------------------------" << endl;
  229. // cout << "r : " << r <<endl;
  230. // cout << "r2 : " << r2 << endl;
  231. //
  232. // ch[r].printFullChromosome();
  233. // ch[r2].printFullChromosome();
  234.  
  235. if(ch1.checkIfValid(weights,benefits,maxWeight))
  236. {
  237. if( bestSoFar.getBenefit() < ch1.getBenefit())
  238. {
  239. ch[r].bits.clear();
  240.  
  241. for(int k = 0; k < S; k++)
  242. ch[r].bits.push_back(ch1.bits[k]);
  243.  
  244. ch[r].weight = ch1.weight;
  245. ch[r].benefit = ch1.benefit;
  246.  
  247. //bestSoFar.setBenefit(ch1.getBenefit());
  248. }
  249. else
  250. mutation(ch[r],maxWeight,weights,benefits);
  251.  
  252. if(ch2.checkIfValid(weights,benefits,maxWeight))
  253. {
  254.  
  255. ch[r2].bits.clear();
  256.  
  257. for(int k = 0; k < S; k++)
  258. ch[r2].bits.push_back(ch2.bits[k]);
  259.  
  260. ch[r2].weight = ch2.weight;
  261. ch[r2].benefit = ch2.benefit;
  262.  
  263. //bestSoFar.setBenefit(ch1.getBenefit());
  264.  
  265. mutation(ch[r2],maxWeight,weights,benefits);
  266.  
  267. if(ch1.getBenefit() > ch2.getBenefit())
  268. bestSoFar.setBenefit(ch1.getBenefit());
  269. else
  270. bestSoFar.setBenefit(ch2.getBenefit());
  271.  
  272. }
  273. else
  274. bestSoFar.setBenefit(ch1.getBenefit());
  275.  
  276.  
  277.  
  278.  
  279. }
  280.  
  281. else if(ch2.checkIfValid(weights,benefits,maxWeight))
  282. {
  283. ch[r2].bits.clear();
  284.  
  285. for(int k = 0; k < S; k++)
  286. ch[r2].bits.push_back(ch2.bits[k]);
  287.  
  288. ch[r2].weight = ch2.weight;
  289. ch[r2].benefit = ch2.benefit;
  290.  
  291. bestSoFar.setBenefit(ch2.getBenefit());
  292.  
  293. mutation(ch[r2],maxWeight,weights,benefits);
  294. }
  295.  
  296. // ch[r].printFullChromosome();
  297. // ch[r2].printFullChromosome();
  298.  
  299. // for(int q = 0; q < ChoosenVector.size(); q++)
  300. // {
  301. // cout << ChoosenVector[q] << ",";
  302. // }
  303.  
  304. // cout << endl;
  305. // cout << "r : "<< r <<endl;
  306. // cout << "r2 : "<< r2 <<endl;
  307. // cout << "size : "<< ChoosenVector.size() <<endl;
  308.  
  309. // int q1 = ChoosenVector.begin() + r ;
  310. // int q2 = ChoosenVector.begin() + r2 ;
  311. // cout << ChoosenVector.begin() + r <<endl;
  312. // cout << ChoosenVector.begin() + r2 <<endl;
  313. // ChoosenVector.erase(ChoosenVector.begin() + r);
  314. // ChoosenVector.erase(ChoosenVector.begin() + r2);
  315. //
  316. // for(int q = 0; q < ChoosenVector.size(); q++)
  317. // {
  318. // cout << ChoosenVector[q] << "," ;
  319. // }
  320. // cout << endl;
  321.  
  322. }
  323.  
  324.  
  325. }
  326. //--------------------------------------------------------------------//
  327. Chromosome compute(int popSize, int chSize,
  328. vector<int> weights, vector<int> benefits, int maxWeight,
  329. int numOfIterations, Chromosome bestSoln)
  330. {
  331. //First we generate random solutions of size m
  332. vector<Chromosome> population;
  333. Chromosome bestSoFar(chSize);
  334. for(int i = 0; i < popSize; i++)
  335. {
  336. Chromosome c(chSize);
  337. c.randomFill();
  338. //Making sure of no invalid solution
  339. while( !c.checkIfValid(weights,benefits,maxWeight) )
  340. c.reRandomFill();
  341. //Keep our best
  342. if(i == 0)
  343. bestSoFar=c;
  344. else if(bestSoFar.getBenefit() < c.getBenefit() )
  345. bestSoFar.setChromosome(c);
  346. population.push_back(c);
  347. }
  348. vector<int> cumTable = createCumulativeTable(benefits,population);
  349.  
  350. //Using Elitism Algorithm, we choose only some fraction of the population to change(not all the population).
  351. //Let it be 40% of the population
  352. int chosenChromosomes = (popSize*40)/100;
  353. vector<int> indices;
  354.  
  355.  
  356. int counter = 0;
  357. while(counter < numOfIterations)
  358. {
  359. for(int i = 0; i < chosenChromosomes; i++)
  360. {
  361. int r = rand()%cumTable.back();
  362.  
  363. int index = 0;
  364. for(int k = cumTable.size()-1 ; k > 0; k--)
  365. if( r < cumTable[k] && r >= cumTable[k-1])
  366. {
  367. index = k;
  368. break;
  369. }
  370.  
  371. indices.push_back(index);
  372. }
  373.  
  374. sort( indices.begin(), indices.end() );
  375. indices.erase( unique( indices.begin(), indices.end() ), indices.end() );
  376.  
  377. double r = (rand()%10 + 1.0)/10.0;
  378.  
  379. if(r <= 0.7)
  380. crossOver(population,indices,maxWeight,bestSoFar,weights,benefits);
  381.  
  382. if(bestSoFar.getBenefit() >= bestSoln.getBenefit())
  383. counter++;
  384.  
  385. }
  386. cout << "Computation finished at iteration : " << counter+1 << endl;
  387. cout << "With best solution entered : ";
  388. bestSoln.printFullChromosome();
  389. cout << endl << "And best solution the algorithm reached : ";
  390. bestSoFar.printFullChromosome();
  391. cout << endl;
  392. return bestSoFar;
  393. }
  394. //--------------------------------------------------------------------//
  395. int main()
  396. {
  397. srand(time(0));
  398.  
  399. int chSize;
  400. cout << "Enter Size of the chromosome : ";
  401. cin >> chSize;
  402.  
  403. int popSize;
  404. cout << "Enter Size of the population : " ;
  405. cin >> popSize;
  406.  
  407.  
  408. int maxWeight;
  409. cout << "Enter Knapsack Maximum Weight of the problem : " ;
  410. cin >> maxWeight;
  411.  
  412. int numOfIterations;
  413. cout << "Enter Knapsack Maximum number of iterations of the problem : ";
  414. cin >> numOfIterations;
  415. cout << endl;
  416.  
  417. vector<int> benefits;
  418. cout << "Enter Benefits" << endl;
  419. for(int i = 0; i < chSize; i++)
  420. {
  421. int num;
  422. cin >> num;
  423. benefits.push_back(num);
  424. }
  425. vector<int> weights;
  426. cout << "Enter Weights" << endl;
  427. for(int i = 0; i < chSize; i++)
  428. {
  429. int num;
  430. cin >> num;
  431. weights.push_back(num);
  432. }
  433.  
  434. Chromosome bestSoln(chSize);
  435. bestSoln.fill();
  436. while( !bestSoln.checkIfValid(weights,benefits,maxWeight) )
  437. {
  438. cout << "Invalid Solution.., Please Re-enter" ;
  439.  
  440. bestSoln.fill();
  441. }
  442. //bestSoln.printBits();
  443.  
  444.  
  445. compute(popSize,chSize,weights,benefits,maxWeight,numOfIterations,bestSoln);
  446. return 0;
  447. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement