fork download
  1. #include <iostream>
  2. #include <cmath>
  3. #include <random>
  4. #include <vector>
  5. #include <cmath>
  6. #include <cstdlib>
  7. #include <ctime>
  8. using namespace std;
  9. int n;
  10. int m;
  11. int sen;
  12. int cover[100];
  13. int c[100];
  14. int sen1;
  15. struct Point{
  16. double x,y;
  17. } ;
  18. Point initial[100];
  19. int star[100];
  20. Point current1[100];
  21. Point best[100];
  22. Point newsol[100];
  23. Point finall[100];
  24. Point target[100];
  25. Point base;
  26. Point current2[100];
  27. Point m3;
  28. int reach[100];
  29. int b[100];
  30. double rs;
  31. int num;
  32. double rc;
  33. int k;
  34. int num2;
  35. int num3;
  36. double initial_temperature;
  37. double cooling_rate;
  38. int max_iterations;
  39. int canrun=1;
  40. void equall(Point m1[], Point m2[])
  41. {
  42. for(int i=1;i<=n;i++)
  43. {
  44. m1[i].x=m2[i].x;
  45. m1[i].y=m2[i].y;
  46. }
  47. }
  48. double distance(Point m1,Point m2)
  49. {
  50. return sqrt(pow((m1.x-m2.x),2)+pow((m1.y-m2.y),2));
  51. }
  52. double randomReal(double a, double b) {
  53. static std::random_device rd;
  54. static std::mt19937 gen(rd());
  55. std::uniform_real_distribution<double> dis(a, b);
  56. return dis(gen);
  57. }
  58. int randomInteger(int n) {
  59. static std::random_device rd;
  60. static std::mt19937 gen(rd());
  61. std::uniform_int_distribution<int> dis(1, n);
  62. return dis(gen);
  63. }
  64. double arg(Point m)
  65. {
  66. double k= m.y/m.x;
  67. double angle= atan(k);
  68. double q= (M_PI+ angle);
  69. if ((m.x==0)&&(m.y>=0)) return M_PI/2;
  70. if ((m.x==0)&&(m.y<0)) return -(M_PI/2);
  71. else if(m.x> 0) return angle;
  72. else if(m.x < 0)
  73. {
  74. if (q> M_PI) q=q-2*M_PI;
  75. }
  76. return q;
  77. }
  78. int coverage(int j,Point sensor[])
  79. {
  80. int res=0;
  81. if(j>0)
  82. {
  83. for(int i=1;i<=n;i++)
  84. {
  85. if (distance(target[j],sensor[i])<=rs) res++;
  86. }
  87. }
  88. else if (j==0)
  89. {
  90. for(int i=1;i<=n;i++)
  91. {
  92. if (distance(target[j],sensor[i])<=rc) res++;
  93. }
  94. }
  95. return res;
  96. }
  97. bool safe(int index,Point sensor[],int sen,int previousstate)
  98. {
  99. double dis2= distance(target[index],base);
  100. double dis3= distance(target[star[previousstate]],target[index]);
  101. double dis=dis2+dis3;
  102. int state= reach[0];
  103. int remain= k-state;
  104. int remainsensor= n-sen;
  105. int can3=ceil(dis2/rc)-1;
  106. int can4=ceil(dis3/rc)-1;
  107. int can=can3+can4+1;
  108. int can1= remain*can;
  109. if(remainsensor< can1) {return false;}
  110. else{ return true;}
  111. }
  112. void quayvebase(int index, Point sensor[],int sen)
  113. {
  114. canrun=1;
  115. // cout<<"QUAY VE BASE"<<endl;
  116. if(index==0)
  117. {
  118. if(sen>n)
  119. {
  120. canrun=0;
  121. }
  122. else
  123. {
  124. sensor[sen].x=base.x;
  125. sensor[sen].y=base.y;
  126. //cout<<"SENSOR thu "<<sen<<" : "<<sensor[sen].x<<" "<<sensor[sen].y<<endl;
  127. sen++;
  128. }
  129. }
  130. else
  131. {
  132. double dis= distance(target[index],base);
  133. Point m2;
  134. m2.x= -target[index].x+base.x;
  135. m2.y= -target[index].y+base.y;
  136. double theta= arg(m2);
  137. int state= coverage(0,sensor);
  138. int remain= k-state;
  139. int can=ceil(dis/rc)-1;
  140. //cout<<"CAN "<<remain*can<<"SENSORS DE VE BASE."<<endl;
  141. if((sen+can*remain)>n)
  142. {
  143. //cout<<"SAI: "<<sen+(can*remain)-1<<endl;
  144. canrun=0;
  145. }
  146. else
  147. {
  148. sensor[sen].x= target[index].x;
  149. sensor[sen].y=target[index].y;
  150. sen++;
  151.  
  152. // cout<<"SENSOR thu "<<sen<<" "<<sensor[sen].x<<" "<<sensor[sen].y<<endl;
  153. for(int i=1;i<=can;i++)
  154. {
  155. for(int j=sen;j<=sen+remain-1;j++)
  156. {
  157. sensor[j].x= target[index].x+i*rc*cos(theta);
  158. sensor[j].y= target[index].y+i*rc*sin(theta);
  159. // cout<<"SENSOR thu "<<j<<" "<<sensor[j].x<<" "<<sensor[j].y<<endl;
  160. }
  161. sen=sen+remain;
  162. }
  163. }
  164. }
  165. sen1=sen;
  166. }
  167. bool visited(int i,Point sensor[], double rs)
  168. {
  169. for( int j =1;j<=n;j++)
  170. {
  171. if(distance(sensor[j],target[i])<rs) return true;
  172. }
  173. return false;
  174. }
  175. void quet(Point sensor[],double rs)
  176. {
  177. //cout<<"Reach base: "<<reach[0]<<endl;
  178. num=1;
  179. for(int i=1;i<=m;i++)
  180. {
  181. //cout<<"reach:"<<i<<" la: "<<reach[i]<<endl;
  182. if(reach[i]<k)
  183. {
  184.  
  185. b[num]=i;
  186. num++;
  187. }
  188. }
  189. }
  190. void quetsafe(int sen,Point sensor[],double rc, int previousstate)
  191. {
  192. num2=1;
  193. for(int i=1;i<=num-1;i++)
  194. {
  195. if(safe(b[i],sensor,sen-1,previousstate)==true)
  196. {
  197. c[num2]=b[i];
  198. num2++;
  199. }
  200. }
  201. }
  202. void direct(Point m, Point m1, double angle, double radios)
  203. {
  204. Point m2;
  205. m2.x = m1.x - m.x;
  206. m2.y = m1.y - m.y;
  207. double theta = arg(m2);
  208. double bisec = angle / 2;
  209. double under = theta - bisec;
  210. double upper = theta + bisec;
  211. double phi = randomReal(under, upper);
  212. double newDistance = randomReal(rs, radios); // Changed variable name
  213. m3.x = m.x + newDistance * cos(phi); // Use newDistance here
  214. m3.y = m.y + newDistance * sin(phi); // Use newDistance here
  215. }
  216. void khoitao(Point current[])
  217. {
  218. for(int i=1;i<=n;i++)
  219. {
  220. current[i].x=-1e9;
  221. current[i].y=-1e9;
  222. }
  223. target[0].x=base.x;
  224. target[0].y=base.y;
  225. }
  226. int objective_function(Point current[])
  227. {
  228. if(canrun==0) return 0;
  229. else{
  230. num3=1;
  231. for(int i=1;i<=m;i++)
  232. {
  233. if((reach[i]>=k)&&(coverage(i,current))>=k) num3++;
  234. }
  235. return num3-1;
  236. }
  237. }
  238. void nhay(Point current[])
  239. {
  240. for(int i=0;i<=m;i++) reach[i]=0;
  241. khoitao(current);
  242. int sen=1;
  243. int state=1;
  244. star[0]=0;
  245. while(sen<=(n))
  246. {
  247. int i;
  248. quet(current,rs);
  249. if(reach[0]<k)
  250. {
  251. quetsafe(sen,current,rc,state-1);
  252. if(num2==1)
  253. {
  254. reach[star[state-1]]++;
  255. quayvebase(star[state-1],current,sen);
  256. if(canrun==1)
  257. {
  258. reach[0]=k;
  259. sen=sen1;
  260. star[state]=0;
  261. state++;
  262. }
  263. else if(canrun==0)
  264. {
  265. // cout<<"KHONG NHAY DC!";
  266. sen=(n+1);
  267. }
  268. }
  269. else if(num2>1)
  270. {
  271. i=randomInteger(num2-1);
  272. if(c[i]==star[state-1])
  273. {
  274. if(num2>2)
  275. {
  276. if(i==(num2-1)) i=1;
  277. else i++;
  278. star[state]= c[i];
  279. // cout<<"NHAY TU "<<star[state-1]<<" DEN "<<star[state]<<endl;
  280. reach[star[state-1]]++;
  281. int temp= coverage(star[state],current);
  282. // cout<<"TEMP CUA TARGET "<<star[state]<<" : "<<temp<<endl;
  283. Point m2;
  284. Point m;
  285. Point m1;
  286. m.x=target[star[state-1]].x;
  287. m.y=target[star[state-1]].y;
  288. m1.x=target[star[state]].x;
  289. m1.y=target[star[state]].y;
  290. m2.x = m1.x - m.x;
  291. m2.y = m1.y - m.y;
  292. double theta = arg(m2);
  293. double bisec = (M_PI/4)/2;
  294. double under = theta - bisec;
  295. double upper = theta + bisec;
  296. double phi = randomReal(under, upper);
  297. double newDistance = rs;
  298. m3.x = m.x + newDistance * cos(phi);
  299. m3.y = m.y + newDistance * sin(phi);
  300. current[sen].x=m3.x;
  301. current[sen].y=m3.y;
  302. sen++;
  303. int sen0=sen;
  304. for(int i=sen0;i<=n;i++)
  305. {
  306. if(coverage(star[state],current)>temp)
  307. {
  308. //cout<<"COVER MOI: "<<coverage(star[state],current)<<endl;
  309. reach[star[state]]++;
  310. break;
  311.  
  312. }
  313. else{
  314. Point m2;
  315. Point m;
  316. Point m1;
  317. m.x=current[i-1].x;
  318. m.y=current[i-1].y;
  319. m1.x=target[star[state]].x;
  320. m1.y=target[star[state]].y;
  321. m2.x = m1.x - m.x;
  322. m2.y = m1.y - m.y;
  323. double theta = arg(m2);
  324. double bisec = (M_PI/4)/2;
  325. double under = theta - bisec;
  326. double upper = theta + bisec;
  327. double phi = randomReal(under, upper);
  328. double newDistance = randomReal(rs, rc);
  329. m3.x = m.x + newDistance * cos(phi);
  330. m3.y = m.y + newDistance * sin(phi);
  331. current[i].x=m3.x;
  332. current[i].y=m3.y;
  333. sen=i+1;
  334. if(sen==(n+1)) break;
  335. }
  336. }
  337. state++;
  338. for(int j=sen0-1;j<=sen-1;j++)
  339. {
  340. // cout<<"SENSOR thu "<<j<<" "<<current[j].x<< " "<<current[j].y<<endl;
  341. }
  342. }
  343. else if(num2==2)
  344. {
  345. reach[star[state-1]]++;
  346. quayvebase(star[state-1],current,sen);
  347. if(canrun==1)
  348. {
  349. reach[0]=k;
  350. sen=sen1;
  351. star[state]=0;
  352. state++;
  353. }
  354. else if(canrun==0)
  355. {
  356. // cout<<"KHONG NHAY DC!";
  357. sen=(n+1);
  358. }
  359.  
  360. }
  361. }
  362. else
  363. {
  364. star[state]= c[i];
  365. // cout<<"NHAY TU "<<star[state-1]<<" DEN "<<star[state]<<endl;
  366. reach[star[state-1]]++;
  367. int temp= coverage(star[state],current);
  368. // cout<<"TEMP CUA TARGET "<<star[state]<<" : "<<temp<<endl;
  369. Point m2;
  370. Point m;
  371. Point m1;
  372. m.x=target[star[state-1]].x;
  373. m.y=target[star[state-1]].y;
  374. m1.x=target[star[state]].x;
  375. m1.y=target[star[state]].y;
  376. m2.x = m1.x - m.x;
  377. m2.y = m1.y - m.y;
  378. double theta = arg(m2);
  379. double bisec = (M_PI/4)/2;
  380. double under = theta - bisec;
  381. double upper = theta + bisec;
  382. double phi = randomReal(under, upper);
  383. double newDistance = rs;
  384. m3.x = m.x + newDistance * cos(phi);
  385. m3.y = m.y + newDistance * sin(phi);
  386. current[sen].x=m3.x;
  387. current[sen].y=m3.y;
  388. sen++;
  389. int sen0=sen;
  390. for(int i=sen0;i<=n;i++)
  391. {
  392. if(coverage(star[state],current)>temp)
  393. {
  394. // cout<<"COVER MOI: "<<coverage(star[state],current)<<endl;
  395. reach[star[state]]++;
  396. break;
  397.  
  398. }
  399. else{
  400. Point m2;
  401. Point m;
  402. Point m1;
  403. m.x=current[i-1].x;
  404. m.y=current[i-1].y;
  405. m1.x=target[star[state]].x;
  406. m1.y=target[star[state]].y;
  407. m2.x = m1.x - m.x;
  408. m2.y = m1.y - m.y;
  409. double theta = arg(m2);
  410. double bisec = (M_PI/4)/2;
  411. double under = theta - bisec;
  412. double upper = theta + bisec;
  413. double phi = randomReal(under, upper);
  414. double newDistance = randomReal(rs, rc);
  415. m3.x = m.x + newDistance * cos(phi);
  416. m3.y = m.y + newDistance * sin(phi);
  417. current[i].x=m3.x;
  418. current[i].y=m3.y;
  419. sen=i+1;
  420. if(sen==(n+1)) break;
  421. }
  422. }
  423. state++;
  424. for(int j=sen0-1;j<=sen-1;j++)
  425. {
  426. // cout<<"SENSOR thu "<<j<<" "<<current[j].x<< " "<<current[j].y<<endl;
  427. }
  428.  
  429. }
  430. }
  431. }
  432. else{
  433. if(num==1)
  434. {
  435. reach[star[state-1]]++;
  436. quayvebase(star[state-1],current,sen);
  437. if(canrun==1)
  438. {
  439. reach[0]=k;
  440. sen=sen1;
  441. star[state]=0;
  442. state++;
  443. }
  444. else if(canrun==0)
  445. {
  446. // cout<<"KHONG NHAY DC!";
  447. sen=(n+1);
  448. }
  449. }
  450. else if(num>1)
  451. {
  452. i=randomInteger(num-1);
  453. if(b[i]==star[state-1])
  454. {
  455. if(num>2)
  456. {
  457. if(i==(num-1)) i=1;
  458. else i++;
  459. star[state]= b[i];
  460. // cout<<"NHAY TU "<<star[state-1]<<" DEN "<<star[state]<<endl;
  461. reach[star[state-1]]++;
  462. int temp= coverage(star[state],current);
  463. // cout<<"TEMP CUA TARGET "<<star[state]<<" : "<<temp<<endl;
  464. Point m2;
  465. Point m;
  466. Point m1;
  467. m.x=target[star[state-1]].x;
  468. m.y=target[star[state-1]].y;
  469. m1.x=target[star[state]].x;
  470. m1.y=target[star[state]].y;
  471. m2.x = m1.x - m.x;
  472. m2.y = m1.y - m.y;
  473. double theta = arg(m2);
  474. double bisec = (M_PI/4)/2;
  475. double under = theta - bisec;
  476. double upper = theta + bisec;
  477. double phi = randomReal(under, upper);
  478. double newDistance = rs;
  479. m3.x = m.x + newDistance * cos(phi);
  480. m3.y = m.y + newDistance * sin(phi);
  481. current[sen].x=m3.x;
  482. current[sen].y=m3.y;
  483. sen++;
  484. int sen0=sen;
  485. for(int i=sen0;i<=n;i++)
  486. {
  487. if(coverage(star[state],current)>temp)
  488. {
  489. // cout<<"COVER MOI: "<<coverage(star[state],current)<<endl;
  490. reach[star[state]]++;
  491. break;
  492.  
  493. }
  494. else{
  495. Point m2;
  496. Point m;
  497. Point m1;
  498. m.x=current[i-1].x;
  499. m.y=current[i-1].y;
  500. m1.x=target[star[state]].x;
  501. m1.y=target[star[state]].y;
  502. m2.x = m1.x - m.x;
  503. m2.y = m1.y - m.y;
  504. double theta = arg(m2);
  505. double bisec = (M_PI/4)/2;
  506. double under = theta - bisec;
  507. double upper = theta + bisec;
  508. double phi = randomReal(under, upper);
  509. double newDistance = randomReal(rs, rc);
  510. m3.x = m.x + newDistance * cos(phi);
  511. m3.y = m.y + newDistance * sin(phi);
  512. current[i].x=m3.x;
  513. current[i].y=m3.y;
  514. sen=i+1;
  515. if(sen==(n+1)) break;
  516. }
  517. }
  518. state++;
  519. for(int j=sen0-1;j<=sen-1;j++)
  520. {
  521. // cout<<"SENSOR thu "<<j<<" "<<current[j].x<< " "<<current[j].y<<endl;
  522. }
  523. }
  524. else if(num==2)
  525. {
  526. reach[star[state-1]]++;
  527. quayvebase(star[state-1],current,sen);
  528. if(canrun==1)
  529. {
  530. reach[0]=k;
  531. sen=sen1;
  532. star[state]=0;
  533. state++;
  534. }
  535. else if(canrun==0)
  536. {
  537. // cout<<"KHONG NHAY DC!";
  538. sen=(n+1);
  539. }
  540. }
  541. }
  542. else
  543. {
  544. star[state]= b[i];
  545. // cout<<"..NHAY TU "<<star[state-1]<<" DEN "<<star[state]<<endl;
  546. reach[star[state-1]]++;
  547. int temp= coverage(star[state],current);
  548. // cout<<"TEMP CUA TARGET "<<star[state]<<" : "<<temp<<endl;
  549. Point m2;
  550. Point m;
  551. Point m1;
  552. m.x=target[star[state-1]].x;
  553. m.y=target[star[state-1]].y;
  554. m1.x=target[star[state]].x;
  555. m1.y=target[star[state]].y;
  556. m2.x = m1.x - m.x;
  557. m2.y = m1.y - m.y;
  558. double theta = arg(m2);
  559. double bisec = (M_PI/4)/2;
  560. double under = theta - bisec;
  561. double upper = theta + bisec;
  562. double phi = randomReal(under, upper);
  563. double newDistance = rs;
  564. m3.x = m.x + newDistance * cos(phi);
  565. m3.y = m.y + newDistance * sin(phi);
  566. current[sen].x=m3.x;
  567. current[sen].y=m3.y;
  568. sen++;
  569. int sen0=sen;
  570. for(int i=sen0;i<=n;i++)
  571. {
  572. if(coverage(star[state],current)>temp)
  573. {
  574. // cout<<"COVER MOI: "<<coverage(star[state],current)<<endl;
  575. reach[star[state]]++;
  576. break;
  577.  
  578. }
  579. else{
  580. Point m2;
  581. Point m;
  582. Point m1;
  583. m.x=current[i-1].x;
  584. m.y=current[i-1].y;
  585. m1.x=target[star[state]].x;
  586. m1.y=target[star[state]].y;
  587. m2.x = m1.x - m.x;
  588. m2.y = m1.y - m.y;
  589. double theta = arg(m2);
  590. double bisec = (M_PI/4)/2;
  591. double under = theta - bisec;
  592. double upper = theta + bisec;
  593. double phi = randomReal(under, upper);
  594. double newDistance = randomReal(rs, rc);
  595. m3.x = m.x + newDistance * cos(phi);
  596. m3.y = m.y + newDistance * sin(phi);
  597. current[i].x=m3.x;
  598. current[i].y=m3.y;
  599. sen=i+1;
  600. if(sen==(n+1)) break;
  601. }
  602. }
  603. state++;
  604. for(int j=sen0-1;j<=sen-1;j++)
  605. {
  606. // cout<<"SENSOR thu "<<j<<" "<<current[j].x<< " "<<current[j].y<<endl;
  607. }
  608.  
  609. }
  610. }
  611.  
  612. }
  613. }
  614. quet(current,rs);
  615. //cout<<"SEN DANG LA: "<<sen<<endl;
  616. equall(current2,current);
  617. // cout<<"GIA TRI: ";
  618. // cout<<objective_function(current)<<endl;
  619. khoitao(current);
  620. }
  621. void SA()
  622. {
  623. khoitao(initial);
  624. equall(current1,initial);
  625. double current_temperature = initial_temperature;
  626. equall(best,current1);
  627. double best_value = objective_function(current1);
  628. for (int i = 0; i < max_iterations; ++i) {
  629. double fcurrent= objective_function(current1);
  630. nhay(current1);
  631. equall(newsol,current2);
  632. double new_value = objective_function(newsol);
  633. if (new_value > best_value) {
  634. equall(best,newsol);
  635. equall(current1,newsol);
  636. best_value = new_value;
  637. }
  638. double delta = new_value - fcurrent;
  639. if (delta > 0 || ((double)rand() / RAND_MAX) < exp(delta / current_temperature)) {
  640. equall(current1,newsol);
  641. }
  642. current_temperature *= cooling_rate;
  643. }
  644. cout << "Best objective function value: " << best_value << endl;
  645. equall(finall,best);
  646. }
  647.  
  648. void input()
  649. {
  650. cout<<"NHAP SO LUONG TARGET: ";
  651. cin>>m;
  652. for(int i=1;i<=m;i++)
  653. {
  654. cout<<"NHAP TOA DO TARGET "<<i<<" : ";
  655. cin>>target[i].x>>target[i].y;
  656. }
  657. cout<<"NHAP TOA DO BASE: ";
  658. cin>>base.x>>base.y;
  659. cout<<"NHAP SO LUONG SENSOR: ";
  660. cin>>n;
  661. cout<<"NHAP BAN KINH CAM BIEN: ";
  662. cin>>rs;
  663. cout<<"NHAP BAN KINH TRUYEN TIN: ";
  664. cin>>rc;
  665. cout<<"NHAP SO K: ";
  666. cin>>k;
  667. }
  668. int main()
  669. {
  670. initial_temperature = 1000;
  671. cooling_rate = 0.99;
  672. max_iterations = 10000;
  673.  
  674. input();
  675. SA();
  676. for(int i=1;i<=n;i++)
  677. {
  678. cout<<"SENSOR THU "<<i<<" : "<<finall[i].x<<" "<<finall[i].y<<endl;
  679. }
  680. for(int i=1;i<=m;i++)
  681. {
  682. cout<<"DO COVERAGE CUA TARGET "<<i<<" : "<<coverage(i,finall)<<endl;
  683. }
  684. // for(int i= 1;i<=40;i++)
  685. //{
  686. // cout<<"NHAY LAN : "<<i<<endl;
  687. //khoitao(current1);
  688. //star[1]=2;
  689. //cout<<"SAFE KHI NHAY TU 2 TOI 3: "<<safe(3,current1,8,1);
  690. //nhay(current1);
  691. //}
  692. //}
  693. // cout<<" COVERAGE CUA BASE: "<<coverage(0,current)<<endl;
  694. //quayvebase(1,current,1);
  695. // for(int i=1;i<7;i++)
  696. //{
  697. // cout<<"NHAY LAN: "<<i<<endl;
  698. //nhay(current1);
  699. //} //cout<<safe(2,current,6)<<endl;
  700. //for(int i=1;i<=7;i++) cout<< randomInteger(0)<<endl;
  701. }
  702.  
  703.  
  704.  
Success #stdin #stdout 0.01s 5300KB
stdin
2
2 2
5 5
0 0
2
1
1
2
stdout
NHAP SO LUONG TARGET: NHAP TOA DO TARGET 1 : NHAP TOA DO TARGET 2 : NHAP TOA DO BASE: NHAP SO LUONG SENSOR: NHAP BAN KINH CAM BIEN: NHAP BAN KINH TRUYEN TIN: NHAP SO K: Best objective function value: 0
SENSOR THU 1 : -1e+09 -1e+09
SENSOR THU 2 : -1e+09 -1e+09
DO COVERAGE CUA TARGET 1 : 0
DO COVERAGE CUA TARGET 2 : 0