鱼C论坛

 找回密码
 立即注册
查看: 3067|回复: 5

[学习笔记] 立志造福后来人--Sensornetwork 1.0 beta (VS2017)

[复制链接]
发表于 2020-6-15 10:07:53 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 MFwxy 于 2020-7-9 06:54 编辑

这玩意儿网上都没什么现成的资源,估计得自个儿实现了。

如果需要使用的话,希望能够做更进一步的改进,最好能将成果传递下去(想桃子)
(1)问题描述
Sensornetwork 是一种新型的网络,其基本结构如下图所示:该网络由两部
分组成,Sensornode 集和 DataCollector。Sensornode(可简称为 Sensor)能够完
成感知环境数据并将其发往 DataCollector 的功能。DataCollector 完成 Sensor 采
集数据的收集,它就是一台带有无线接收功能的计算机。

Sensornetwork 图示
Sensornetwork 可应用到很多实际领域中,如在战争中将 Sensor 散播在防线
的前沿,可以收集敌人的一些情报(如大规模的部队转移等)。Sensor 散播的地
方称为 Interestedarea,Sensor 在这个区域内采集各自所在位置的数据,然后将采
集到的数据传送到DataCollector。各个Sensor之间通过无线广播通讯,由于Sensor
广播能力的限制,它只能和位于自身的一定广播半径内的 Sensor 进行通讯,所
以有些 Sensor 就需通过其它 Sensor,经过多次路由后才能到达 DataCollector(如
上图)。如何路由由 Sensor 内保存的简单路由表来决定。DataCollector 的位置就
在 InterstedArea 的边缘,且固定不动。
(2)课程设计目的
应用数据结构知识模拟一个新型网络系统。
(3)基本要求
①应用数据结构在单机上模拟 Sensornetwork 的工作。
②用 VC++(C 也可以)实现模拟系统,N 个 Sensor 和 1 个 DataCollector,
其具体位置随机确定,InterestArea 就是屏幕。N 可配置,缺省为 100。
③Sensor 进行周期性采集,其采集周期可配置。
④Sensor 的广播半径固定,也是可配置的参数。
⑤路由算法自行选择或设计。
(4)实现提示
Sensor 集可组织成数组,它采集及收到的数据包用队列存储。具体细节也可
参阅有关资料。
.cpp

  1. //#pragma once
  2. #include "sensor.h"
  3. #include<iostream>
  4. #include<stdlib.h>
  5. #include<time.h>
  6. #include<math.h>
  7. #include <iomanip>
  8. #include <windows.h>
  9. using namespace std;

  10. //#pragma comment(lib,"sensor.lib")
  11. int hand = 0;

  12. //拷贝构造
  13. sensor::sensor(const sensor&s)
  14. {
  15.                 this->radius = s.radius;
  16.                 this->span = s.span;
  17.                 this->databags = s.databags;
  18.                 this->x = s.x;
  19.                 this->y = s.y;
  20.                 this->lyb = s.lyb;
  21. }


  22. sensor::sensor(double ra, double sp,int i)
  23. {

  24.         radius = ra;
  25.         span = sp;
  26.         srand((unsigned)time(NULL)+hand);                //+hand
  27.        
  28.         int x1;
  29.         x1 = rand()%800;
  30.         this->x = (x1+hand)%800;
  31.         this->x = this->x / 10.0;
  32.        
  33.         int y1;
  34.         y1 = rand()%250;
  35.         this->y = (y1 + hand) % 250;
  36.         this->y = this->y / 10.0;

  37.         hand += int((radius / sqrt(2)) + 0.5);                       
  38.        
  39.         //这里实现了x,y的随机生成
  40.         /*
  41.         cout.setf(ios::fixed);
  42.         cout << fixed << setprecision(1) << x << " " << fixed << setprecision(1) << y << endl;
  43.         */
  44.         lyb.CC = i;
  45. }

  46. //搜集数据
  47. void sensor::data_collect(double data)
  48. {
  49.        



  50.         databags.push(data);

  51. }






  52. //展示重要数据(或参数)
  53. void sensor::show()
  54. {
  55.         queue<double>p;
  56.         p = databags;
  57.         while (!(p.empty()))
  58.         {
  59.                 cout << p.front() << " ";
  60.                 p.pop();
  61.         }
  62. }

  63. void sensor::get(double ge)
  64. {
  65.         databags.push(ge);
  66. }

  67. double sensor::give()
  68. {
  69.         double p = databags.front();
  70.         databags.pop();
  71.         return p;
  72. }

  73. bool sensor::is_empty()
  74. {
  75.         return databags.empty();
  76. }

  77. void sensor::popout()
  78. {
  79.         if(!(this->is_empty()))
  80.                 databags.pop();
  81.         //cout << "\n数据弹出!" << endl;
  82. }

  83. sensor::~sensor()
  84. {

  85. }

复制代码

.h
  1. //#pragma once
  2. #include<iostream>
  3. #include<queue>
  4. #include<Windows.h>
  5. #include<Cstring>

  6. using namespace std;
  7. /*
  8. 定义sensor,行为是路由广播传输信息、采集周围环境信息,数值有广播半径、采集周期间隔
  9. (看做整体的话还有个数)
  10. sensor集 组织成数组,采集的数据包 用队列存储;

  11. */

  12. //简易路由表。重要信息:https://blog.csdn.net/sinat_36118270/article/details/73850346
  13. struct Lu_Youbiao                       
  14. {
  15.         /*
  16.         终点的地址是255; 254作为保留。
  17.         通常的与是A电脑IP和B电脑子网掩码相与,B电脑IP与A电脑子网掩码相与。得到同一个网段就可以相通信
  18.         */

  19.         int Network_Destination = 255;
  20.         //默认0--253;网络地址(目的地
  21.         int Netmask;                         
  22.         /*
  23.         默认0--253;
  24.         网络掩码(与网址计算得到目的网络地址,将某个IP地址划分成网络地址和主机地址两部分
  25.         简单来说就是用来区分子网络以及
  26.         */
  27.         int Gateway;                          
  28.         /*
  29.         默认0--253;网关(途经地址
  30.         设置默认网关来将匹配错误的数据包回收
  31.         否则将直接丢弃数据
  32.         */
  33.         int Interface;           
  34.         //默认0--253;接口(到达网关的出口
  35.         int Metric;              
  36.         //跃点数(高低代表到达目的地址的成本
  37.         int CC;                       
  38.         /*
  39.         自身地址,好像跟实际的地址有关,(可以同化成一个二维坐标来使用)暂时用整数表示坐标
  40.         int CC_x;
  41.         int CC_y;
  42.         */
  43. };

  44. class sensor
  45. {
  46. public:
  47.         sensor(double ra = 5, double sp = 100,int i=254);
  48.         sensor(const sensor&s);
  49.         void data_collect(double data);//周期性采集,周期是span
  50.         void show();
  51.         double give();
  52.         void get(double ge);
  53.         bool is_empty();
  54.         void popout();
  55.         ~sensor();

  56.         double span;//单位是ms毫秒
  57.        
  58.         double x;
  59.         double y;
  60.         //位置参数,二维的,范围是屏幕之内;位置赋予方式是屏幕范围内的随机生成(想要保留一位小数的值)
  61.        
  62. private:
  63.         double radius;//单位是m米
  64.         //要在sensor里面保存路由表了,这玩意儿好像很难,那我先设置地址最多255的好了
  65.         Lu_Youbiao lyb;
  66.        
  67.     //https://blog.csdn.net/zyboy2000/article/details/50528253
  68.        
  69.         queue<double> databags;
  70.        
  71.        
  72.        
  73.         //辅助生成随机数
  74. };

复制代码

.main
  1. #include<cstdio>
  2. #include<iostream>
  3. #include<time.h>
  4. #include "sensor.h"
  5. #include<stdlib.h>
  6. #include <windows.h>
  7. #include<math.h>
  8. #define inf -1
  9. using namespace std;


  10. //#pragma comment(lib,"sensor.lib")


  11. int main()
  12. {
  13.                 /*
  14.                 1要预知传感器总数目N(默认100),并且将传感器都存入一个数组当中。
  15.                 如果没办法实现自定义类的数组的话就把数目作为一个内部的参数使用
  16.                 采集和收集到的数据包队列要一个系统一个还是一个传感器一个呢?(作为优化可以区分一下数据来源以及数据未来去向)
  17.                 */

  18.                
  19.         cout << "创建传感器基本数据(输入有效的相应半径与周期):" << endl;//八成是一样的,但是还是可以考虑优化一下
  20.         double a1, a2;
  21.         cin >> a1 >> a2;
  22.         cout << "传感器个数确定:(默认为100)" << endl;
  23.         int n_collector;
  24.         cin >> n_collector;
  25.         if (n_collector==NULL||n_collector<=0)
  26.         {
  27.                 n_collector = 100;
  28.         }
  29.         //cout << n_collector << endl;
  30.         sensor** col;
  31.         col = new sensor*[n_collector];

  32.         for (int i = 0; i < n_collector; i++)
  33.         {
  34.                 col[i] = new sensor(a1,a2,i);       
  35.                 //col[i]                                                //老实说我不知道这个是做什么的了
  36.         }


  37.         /****************************************************************************************************************************************************************/               
  38.        
  39.         /****************************************************************************************************************************************************************/

  40.         //返回的是存储好数据的队列,一个全部工作元件公用的队列,不可以轻易的销毁;
  41.         /*
  42.         周期性采集,广播范围也固定;
  43.         广播范围固定了之后,按照预定的范围先搜索可以交流的传感器
  44.         然后再考虑通过什么样的路径来让数据收集器能接收到
  45.         极限范围是屏幕(电脑屏幕:1920×1080;控制台默认:80*25)
  46.         */
  47.         //控制时间(来个控制采集周期运行的片段

  48.         int n_need,nd0;                //一个是需求周期数,另一个是辅助用的
  49.         int aslp;                        //休眠用的计时
  50.         int slp=0;                        //需要休眠与否0:不需要
  51.         cout << "请输入希望执行的周期总次数" << endl;
  52.         //这里输入需要执行的周期个数,优化的话可以考虑输入执行的总时间 然后经过计算得到执行的周期数
  53.         cin >> n_need;
  54.         n_need++;
  55.         nd0 = n_need+1;
  56.         /*
  57.         疑点:
  58.         虽然使用的时候是一直执行...
  59.         但是这岂不是要用到多线程?
  60.         一直搜集数据到关闭,还要传输数据,以及终端要得到数据
  61.         考虑成优化的点吧
  62.         周期到了数据没收集全怎么办???还是说等待它磨磨蹭蹭收集完再说
  63.         */
  64.         clock_t start, finish;
  65.         start = clock();
  66.         if (n_need>0)
  67.                 do
  68.                 {
  69.                         //这里按周期执行采集函数(可以考虑接口,先用随机数代替吧。)

  70.                         for (int i = 0; i < n_collector; i++)
  71.                         {
  72.                                 srand((unsigned)time(NULL)+i);
  73.                                 int random_num = rand();                        //用随机来模拟生成的数字,可以的话 加一下接收实际情况数据的接口(这他妈是啥???)
  74.                                 col[i]->data_collect(random_num);
  75.                                 finish = clock() - start;
  76.                                 if ((double(finish) / CLOCKS_PER_SEC - n_need * col[0]->span >= 0))                //严格检查|| (int(finish) % 1000 == 999)
  77.                                 {
  78.                                         cout << "周期结束!提前终止收集" << endl;
  79.                                         break;
  80.                                 }
  81.                                 else if ( double(finish) / CLOCKS_PER_SEC > (nd0-n_need)*col[0]->span)//一次全体采集没有完成一个周期是不是应该等待满一个周期
  82.                                 {
  83.                                         cout << "已完成 " << nd0 - n_need << " 个周期" << endl;
  84.                                         n_need--;
  85.                                 }
  86.                                 else
  87.                                 {
  88.                                         cout << "当前尚未完成周期。" << endl;
  89.                                         cout<< double(finish) / CLOCKS_PER_SEC <<" : "<< (nd0 - n_need)*col[0]->span <<endl;
  90.                                 }
  91.                                
  92.                                
  93.                                        
  94.                         }
  95.                        
  96.                         //采集完成,休眠开始
  97.                         aslp = 1000*((nd0 - n_need)*col[0]->span - double(finish) / CLOCKS_PER_SEC);       
  98.                         if (aslp>0)
  99.                         {
  100.                                 cout << "已完成一次采集,正在等待周期 " << nd0 - n_need << " 结束" << endl;
  101.                                 cout << double(finish) / CLOCKS_PER_SEC << " : " << (nd0 - n_need)*col[0]->span << endl;
  102.                                 cout << "休眠 " << aslp << endl;
  103.                                 Sleep(aslp);
  104.                                 finish += aslp;
  105.                                 if (int(finish) % 1000 == 999)
  106.                                 {
  107.                                         Sleep(1);
  108.                                         aslp++;                //尊重形式
  109.                                         finish++;
  110.                                 }
  111.                                 cout << double(finish) / CLOCKS_PER_SEC << " : " << (nd0 - n_need)*col[0]->span << endl;
  112.                                 if (double(finish) / CLOCKS_PER_SEC >= (nd0 - n_need)*col[0]->span)                //判定完成周期 (int(finish) % 10 == 9)
  113.                                 {
  114.                                         n_need--;
  115.                                 }
  116.                                 else
  117.                                 {
  118.                                         cout << "警告!休眠时间不足!" << endl;
  119.                                         cout << double(finish) / CLOCKS_PER_SEC << " : " << (nd0 - n_need)*col[0]->span << endl;
  120.                                 }
  121.                         }
  122.                        
  123.                         finish = clock()-start;
  124.                         if(!(double(finish) / CLOCKS_PER_SEC - n_need * col[0]->span < 0))                //采集耗时检测严格程度不如等待耗时
  125.                                 cout << "采集结束!周期等待完成" << endl;
  126.                 } while (double(finish)/ CLOCKS_PER_SEC -n_need*col[0]->span < 0);
  127.         /****************************************************************************************************************************************************************/
  128.        
  129.         /****************************************************************************************************************************************************************/
  130.                
  131.                 //cout << "与的正确用法" << endl;cout << (224 & 240) << " :" << (255 & 255) << endl;可以正式使用地址了(输入的网络地址和网络掩码相与后的结果必须等于网络地址
  132.                 /*
  133.                 所以应该建立一个数组,一个用自身路由表的地址寻找的数组;
  134.                 这个数组要存储一个数据队列,或者甚至直接存储sensor;
  135.                 数据收集器可以在数组里,也可以在外边;
  136.                 路由算法默认dijkstra
  137.                 */
  138.                 /*
  139.                 所谓广播到:就是指两者距离小于广播半径,要让col[0]--col[n]挨个对比
  140.                 默认终端收集器在(0,0)
  141.                 如何路由由 Sensor 内保存的简单路由表来决定
  142.                 大概分三种形式:
  143.                 1.不知道连接状况直接摸黑前进;2.情况完全了解之后再考虑传输方式;3.了解和传输都随机应变
  144.                 空想:
  145.                 可以标明数据的来源以及目的地,就像快递那样;至于中转点怎么设置。
  146.                 最简单的方法是多次实验的经验 or 把坐标靠中心的几个点和紧挨收集器的几个点设置成线路中转点
  147.                 几个核心点之间形成一个干线,让其他末支的点连接到干线上就行了

  148.                 */

  149.         //嘤嘤嘤,实现了周期性还要记得广播半径也要考虑(用于路由传播交流)
  150.         //5路由方式???是什么?暂定为之前看到的迪杰斯特拉算法吧。
  151.         /*
  152.         跟路由方式息息相关的是之前得到的广播半径、位置,估计要画小地图来帮助理解
  153.         既然是人为投放的sensor,那么默认直接跟终端接收器相关的那个sensor是一定能找得到的吧。
  154.         个人理解的路由方式是 尽量高效的传输+尽量全面的搜集 吧
  155.         路由的时候还要接收其他sensor给予的数据,可能目的地和来源(可以仅考虑上一个?甚至是多个?也可能必须知道来源)
  156.         */
  157.        
  158.         /*
  159.         设计的是静态路由表(内容经现场情况决定后固定)
  160.         建立的时候从数据收集器开始往回溯源,因为数据是单向流动的(其实TCP/IP协议是需要双向的)
  161.         */
  162.                 /*
  163.                 for (int i = 0; i < n_collector; i++)
  164.                 {
  165.                         col[i]->Lyb(n_collector);
  166.                 }
  167.                 */
  168.                 double **col_distance;//二维数组
  169.                 col_distance = new double*[(n_collector + 1)*n_collector / 2];
  170.                 for (int i = 0; i < n_collector; i++)
  171.                 {
  172.                         col_distance[i] = new double[n_collector];
  173.                 }

  174.                 for (int j = 0; j < n_collector; j++)
  175.                 {
  176.                         for (int k = 0; k < n_collector; k++)
  177.                         {
  178.                                 double dis;
  179.                                 dis = sqrt(pow((col[j]->x-col[k]->x),2) + pow((col[j]->y - col[k]->y),2));
  180.                                 if (dis > a2)
  181.                                 {
  182.                                         col_distance[j][k] = inf;
  183.                                 }
  184.                                 else
  185.                                 {
  186.                                         col_distance[j][k] = dis;
  187.                                 }
  188.                                        
  189.                         }
  190.                 }
  191.                 //到这里两传感器的距离有了。
  192.                 cout << "展示" << endl;
  193.                 for (int j = 0; j < n_collector; j++)
  194.                 {
  195.                         for (int k = 0; k < n_collector; k++)
  196.                         {
  197.                                 cout << col_distance[j][k] << " ";

  198.                         }
  199.                         cout << endl;
  200.                 }
  201.                 //(0,0)是收集器最近的传感器1的位置,例子5432中能到达 2 , 3是孤立的了.输出效果是警告孤立出来的点,以及将数据按线路传送回收集器
  202.                 //1.根据表格连接线路
  203.                 int *road2home1 = new int[n_collector] {0};                //num可能要加一
  204.                 int n_r2h = 1;
  205.                 road2home1[0] = 1;
  206.                 for (int i = 0; i < n_collector; i++)
  207.                 {
  208.                         for (int k = i; k < n_collector; k++)
  209.                         {
  210.                                 if (col_distance[i][k]>0)
  211.                                 {
  212.                                         road2home1[n_r2h] = k + 1;
  213.                                         n_r2h++;
  214.                                 }

  215.                         }
  216.                 }
  217.                 cout << "数据流向" << endl;                                //大概率有BUG
  218.                 for (int i = 0; i < n_collector && road2home1[i]!=NULL; i++)
  219.                 {
  220.                        
  221.                         cout << road2home1[i] << " ";
  222.                 }
  223.                 cout<<endl;
  224.                 //2.警示孤立的点
  225.                 int *flag = new int[n_collector] {0};
  226.                 int flag2 = 1;
  227.                 for (int i = 0; i < n_collector; i++)
  228.                 {
  229.                         for (int k = 0; k < n_collector; k++)
  230.                         {
  231.                                 if (i+1 == road2home1[k])
  232.                                 {
  233.                                         flag2 = 0;
  234.                                         break;
  235.                                 }
  236.                         }
  237.                         if (flag2)
  238.                         {
  239.                                 cout << i+1 << "为孤立点!" << endl;
  240.                                 flag[i] = 1;
  241.                         }
  242.                         flag2 = 1;
  243.                 }

  244.        
  245.                 //3.将数据传回收集器。到了1 直接输出就行了.
  246.                
  247.                 int num_r2l = 0;
  248.                 for (int i = 0; i < n_collector; i++)
  249.                 {
  250.                        
  251.                         if (flag[i])                        //数据无法达到的可以警示
  252.                         {
  253.                                 cout<<i+1<<" 号信号丢失!"<<endl;
  254.                         }
  255.                         else
  256.                         {
  257.                                 col[0]->show(); //用输出模拟传入数据收集终端
  258.                                 while (!(col[0]->is_empty()))
  259.                                 {
  260.                                         col[0]->popout();
  261.                                 }
  262.                                 cout << " ---- ";

  263.                                 if (road2home1[i] != n_collector)
  264.                                 {
  265.                                         while (road2home1[i] > 0 && !(col[road2home1[i]]->is_empty()))
  266.                                         {
  267.                                                 col[0]->get(col[road2home1[i]]->give());
  268.                                         }
  269.                                 }
  270.                                 cout << road2home1[i] << " 号数据到达终端!" << endl;
  271.                         }
  272.                        

  273.                 }

  274.         /****************************************************************************************************************************************************************/
  275.        
  276.         /****************************************************************************************************************************************************************/
  277.         //展示环节
  278.         /*
  279.         我理想的展示是
  280.         既能立刻显示出所需要的单个sensor的所有数据
  281.         也能将总的数据生成为一份excel,至少得是txt文本吧
  282.         */


  283.         return 0;
  284. }
复制代码




太久没写,连min函数,class都要百度。。。
写程序要连贯,要尽快;不然思路忘的挺快的。另外还要加注释和思路说明
新问题解决不了就要考虑:A。装在一起,之前这样没有出问题;B。重新填写,希望没事。
试了几种常见的,没办法解决。发现ctrl点击头文件的时候无法找到。试了下将文件手动添加,依旧没办法解决。
找到了问题的点:
使用了函数,但是参数的类型或数量与函数定义不匹配
函数声明必须匹配定义。 请确保函数调用与声明匹配,并且声明与定义匹配。 调用模板函数的代码还必须拥有包括与定义相同的模板参数的匹配模板函数声明。 有关模板声明不匹配的示例,请参阅示例部分中的示例 LNK2019e。
问题出在
  1. cin >> n_collector;
  2.        
  3.         sensor* col = new sensor[n_collector];

  4.         for (int i = 0; i < n_collector; i++)
  5.         {
  6.                 sensor at();
  7.                 col[i] = at();                        //问题在这里。。。
  8.         }
  9.         sensor a(a1, a2);
  10.         //sensor* b = new sensor[20];
  11.        
  12.         a.data_collect(5);
复制代码

看了文档之后确定了问题,然后尝试创建自定义的对象的数组,根据提示加了几个*就不报错了。。。莫名其妙的

水完了。。。
数据一大就有bug,晚上还要改,没得跑。。。
问题就是路由算法跟图形界面设计
铺设传感器的时候发现问题很大,可能因为没有连接到终端导致整个系统没有意义,所以我打算用斜线拼凑菱形(长度是0.8*r)来直接铺设,留1%半径的误差距离来模拟不确定因素带来的地理位置的影响
可以考虑根据最大半径划分三个区域——强信号区5绿,中信号区3黄和弱信号区2红。(连线时跟终端在同一主线上的才有资格染,其余的都必须蓝线连)
大改失败了。。。就只有一些小修小补

差在随机数的人工管控+路由算法+代码规范

第一个难关

第一个难关

课设.zip

606.53 KB, 下载次数: 16

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2020-6-21 12:03:31 | 显示全部楼层
事情越来越多,久违的兴奋感
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-6-21 12:09:11 | 显示全部楼层
标记一下,好像是新思想
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-6-21 15:26:16 | 显示全部楼层
java2python 发表于 2020-6-21 12:09
标记一下,好像是新思想

感谢关注
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-7-5 16:26:01 | 显示全部楼层
本帖最后由 MFwxy 于 2020-7-6 09:45 编辑

ddl杀过来的时候我甚至都不知道我写的什么玩意儿,只知道功能实现了。。。
看到其他人拿练习题来提交。。。那感觉挺复杂的,有点点累
虽然很简陋,但是看到自己儿子的时候还是会感慨别人的作品 “就这?”
为了宝贝,冲!
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-7-6 09:37:45 | 显示全部楼层
本帖最后由 MFwxy 于 2020-7-9 06:51 编辑


遗产,估计续写不了了
Random.h
  1. #include<iostream>
  2. #include<ctime>
  3. #include<algorithm>

  4. using namespace std;

  5. class Random {

  6. public:

  7.         Random(int a, int b);

  8.         Random();

  9.         int random();

  10.         int random(int a, int b);

  11.         double randomf(int a, int b);

  12. private:

  13.         double random1();
  14.         int low;
  15.         int high;
  16. };

复制代码

sensor.h
  1. //#pragma once
  2. #include<iostream>
  3. #include<queue>
  4. #include<Windows.h>
  5. #include<Cstring>

  6. using namespace std;
  7. /*
  8. 定义sensor,行为是路由广播传输信息、采集周围环境信息,数值有广播半径、采集周期间隔
  9. (看做整体的话还有个数)
  10. sensor集 组织成数组,采集的数据包 用队列存储;

  11. */

  12. //简易路由表。重要信息:https://blog.csdn.net/sinat_36118270/article/details/73850346
  13. struct Lu_Youbiao                       
  14. {
  15.         /*
  16.         终点的地址是255; 254作为保留。
  17.         通常的与是A电脑IP和B电脑子网掩码相与,B电脑IP与A电脑子网掩码相与。得到同一个网段就可以相通信
  18.         */

  19.         int Network_Destination = 255;
  20.         //默认0--253;网络地址(目的地
  21.         int Netmask;                         
  22.         /*
  23.         默认0--253;
  24.         网络掩码(与网址计算得到目的网络地址,将某个IP地址划分成网络地址和主机地址两部分
  25.         简单来说就是用来区分子网络以及
  26.         */
  27.         int Gateway;                          
  28.         /*
  29.         默认0--253;网关(途经地址
  30.         设置默认网关来将匹配错误的数据包回收
  31.         否则将直接丢弃数据
  32.         */
  33.         int Interface;           
  34.         //默认0--253;接口(到达网关的出口
  35.         int Metric;              
  36.         //跃点数(高低代表到达目的地址的成本
  37.         int CC;                       
  38.         /*
  39.         自身地址,好像跟实际的地址有关,(可以同化成一个二维坐标来使用)暂时用整数表示坐标
  40.         int CC_x;
  41.         int CC_y;
  42.         */
  43. };

  44. class sensor
  45. {
  46. public:
  47.         sensor(double ra = 5, double sp = 100,int i=254);
  48.         sensor(const sensor&s);
  49.         void data_collect(double data);//周期性采集,周期是span
  50.         void show();
  51.         double give();
  52.         void get(double ge);
  53.         bool is_empty();
  54.         void popout();
  55.         ~sensor();

  56.         double span;//单位是ms毫秒
  57.        
  58.         double x;
  59.         double y;
  60.         //位置参数,二维的,范围是屏幕之内;位置赋予方式是屏幕范围内的随机生成(想要保留一位小数的值)
  61.         double radius;//单位是m米

  62. private:
  63.        
  64.         //要在sensor里面保存路由表了,这玩意儿好像很难,那我先设置地址最多255的好了
  65.         Lu_Youbiao lyb;
  66.        
  67.     //https://blog.csdn.net/zyboy2000/article/details/50528253
  68.        
  69.         queue<double> databags;
  70.        
  71.        
  72.        
  73.         //辅助生成随机数
  74. };

复制代码


Random.cpp
  1. #include<math.h>
  2. #include<algorithm>
  3. #include<iostream>
  4. #include<ctime>
  5. #include "Random.h"

  6. Random::Random()
  7. {
  8.         low = 0;
  9.         high = 1000;
  10.         srand((unsigned)clock());
  11. }

  12. Random::Random(int a, int b)
  13. {
  14.         low = min(a, b);
  15.         high = max(a, b);
  16.         srand((unsigned)clock());
  17. }

  18. int Random::random(int a, int b)
  19. {
  20.         int t = rand();

  21.         return a + t % (b - a) + 1;}

  22. int Random::random()
  23. {
  24.         return random(low, high);
  25. }

  26. double Random::random1() //0-1的随机数
  27. {
  28.         double m = (double)random();
  29.         double n = (double)random();

  30.         if (m == 0 && n == 0)return 0;
  31.         else return (m < n) ? (m / n) : (n / m);
  32. }

  33. double Random::randomf(int a, int b)
  34. {
  35.         return a + (b - a)*random1();
  36. }
复制代码

sensor.cpp
  1. //#pragma once
  2. #include "sensor.h"
  3. #include<iostream>
  4. #include<stdlib.h>
  5. #include<time.h>
  6. #include<math.h>
  7. #include <iomanip>
  8. #include <windows.h>
  9. #include"Random.h"
  10. #define X 200
  11. #define Y 120

  12. using namespace std;

  13. //#pragma comment(lib,"sensor.lib")
  14. int hand = 0;
  15. double xflag = 1;
  16. double yflag = 1;

  17. //拷贝构造
  18. sensor::sensor(const sensor&s)
  19. {
  20.                 this->radius = s.radius;
  21.                 this->span = s.span;
  22.                 this->databags = s.databags;
  23.                 this->x = s.x;
  24.                 this->y = s.y;
  25.                 this->lyb = s.lyb;
  26. }


  27. sensor::sensor(double ra, double sp,int i)
  28. {
  29.         Random rdm;
  30.         radius = ra;
  31.         span = sp;
  32.        
  33.         double x1;
  34.         x1 = rdm.randomf(0,X/10.0);
  35.         if (x + xflag * hand >= X)
  36.         {
  37.                 //xflag=-1*rdm.randomf(0.2,0.8);
  38.                 xflag = -1;
  39.                 while (x >= X)
  40.                 {
  41.                         this->x = x1 + xflag * hand;
  42.                 }
  43.         }
  44.         else if (x + xflag * hand <=0)
  45.         {
  46.                 //xflag=1 * rdm.randomf(0.2, 0.8);
  47.                 xflag = 1;
  48.                 while (x <=0)
  49.                 {
  50.                         this->x = x1 + xflag * hand;
  51.                 }
  52.         }
  53.         else
  54.         {
  55.                 this->x = x1 + xflag * hand;
  56.         }
  57.        
  58.        
  59.         double y1;
  60.         y1 = rdm.randomf(0, Y/10.0);
  61.         if (0>=y+ yflag * hand)
  62.         {
  63.                 //yflag = 1 * rdm.randomf(0.2, 0.8);
  64.                 yflag = 1;
  65.                 while (0>=y )
  66.                 {
  67.                         this->y = y1 + yflag * hand;
  68.                 }
  69.         }
  70.         else if (y+ yflag * hand >=Y)
  71.         {
  72.                 //yflag = -1 * rdm.randomf(0.2, 0.8);
  73.                 yflag = -1;
  74.                 while (y>=Y)
  75.                 {
  76.                         this->y = y1 + yflag * hand;
  77.                 }
  78.         }
  79.         else
  80.         {
  81.                 this->y = y1 + yflag * hand;
  82.         }
  83.        
  84.        
  85.         hand += int(0.8*(radius / sqrt(2)) );                       
  86.         cout << "x: " << x << "   y: " << y << endl;
  87.         //这里实现了x,y的随机生成
  88.         /*
  89.         cout.setf(ios::fixed);
  90.         cout << fixed << setprecision(1) << x << " " << fixed << setprecision(1) << y << endl;
  91.         */
  92.         lyb.CC = i;
  93. }

  94. //搜集数据
  95. void sensor::data_collect(double data)
  96. {
  97.        



  98.         databags.push(data);

  99. }






  100. //展示重要数据(或参数)
  101. void sensor::show()
  102. {
  103.         queue<double>p;
  104.         p = databags;
  105.         while (!(p.empty()))
  106.         {
  107.                 cout << p.front() << " ";
  108.                 p.pop();
  109.         }
  110. }

  111. void sensor::get(double ge)
  112. {
  113.         databags.push(ge);
  114. }

  115. double sensor::give()
  116. {
  117.         double p = databags.front();
  118.         databags.pop();
  119.         return p;
  120. }

  121. bool sensor::is_empty()
  122. {
  123.         return databags.empty();
  124. }

  125. void sensor::popout()
  126. {
  127.         if(!(this->is_empty()))
  128.                 databags.pop();
  129.         //cout << "\n数据弹出!" << endl;
  130. }

  131. sensor::~sensor()
  132. {

  133. }
复制代码


main.cpp
  1. #include<cstdio>
  2. #include<iostream>
  3. #include<time.h>
  4. #include "sensor.h"
  5. #include<stdlib.h>
  6. #include <windows.h>
  7. #include<math.h>
  8. #include <graphics.h>
  9. #include"Random.h"
  10. #define inf -1
  11. #define X 1000
  12. #define Y 600

  13. //        极限范围是屏幕(电脑屏幕:1920×1080;控制台默认:80*25)
  14. using namespace std;




  15. int main()
  16. {
  17.         /*
  18.         1要预知传感器总数目N(默认100),并且将传感器都存入一个数组当中。
  19.         如果没办法实现自定义类的数组的话就把数目作为一个内部的参数使用
  20.         采集和收集到的数据包队列要一个系统一个还是一个传感器一个呢?(作为优化可以区分一下数据来源以及数据未来去向)
  21.         */


  22.         cout << "创建传感器基本数据(输入有效的相应半径与周期):" << endl;//八成是一样的,但是还是可以考虑优化一下
  23.         double a1, a2;
  24.         cin >> a1 >> a2;
  25.         cout << "传感器个数确定:(默认为100)" << endl;
  26.         int n_collector;
  27.         cin >> n_collector;
  28.         if (n_collector == NULL || n_collector <= 0)
  29.         {
  30.                 n_collector = 100;
  31.         }
  32.         //cout << n_collector << endl;
  33.         sensor** col;
  34.         col = new sensor*[n_collector];

  35.         col[0] = new sensor(a1, a2, 0);
  36.         col[0]->x = 0;
  37.         col[0]->y = 0;

  38.         for (int i = 1; i < n_collector; i++)
  39.         {
  40.                 col[i] = new sensor(a1, a2, i);

  41.         }


  42.         /****************************************************************************************************************************************************************/

  43.         /****************************************************************************************************************************************************************/

  44.         //返回的是存储好数据的队列,一个全部工作元件公用的队列,不可以轻易的销毁;
  45.         /*
  46.         周期性采集,广播范围也固定;
  47.         广播范围固定了之后,按照预定的范围先搜索可以交流的传感器
  48.         然后再考虑通过什么样的路径来让数据收集器能接收到

  49.         */
  50.         //控制时间(来个控制采集周期运行的片段

  51.         int n_need, nd0;                //一个是需求周期数,另一个是辅助用的
  52.         int aslp;                        //休眠用的计时
  53.         int slp = 0;                        //需要休眠与否0:不需要
  54.         cout << "请输入希望执行的周期总次数" << endl;
  55.         //这里输入需要执行的周期个数,优化的话可以考虑输入执行的总时间 然后经过计算得到执行的周期数
  56.         cin >> n_need;
  57.         n_need++;
  58.         nd0 = n_need + 1;
  59.         /*
  60.         疑点:
  61.         虽然使用的时候是一直执行...
  62.         但是这岂不是要用到多线程?
  63.         一直搜集数据到关闭,还要传输数据,以及终端要得到数据
  64.         考虑成优化的点吧
  65.         周期到了数据没收集全怎么办???还是说等待它磨磨蹭蹭收集完再说
  66.         */
  67.         clock_t start, finish;
  68.         start = clock();
  69.         if (n_need > 0)
  70.                 do
  71.                 {
  72.                         //这里按周期执行采集函数(可以考虑接口,先用随机数代替吧。)

  73.                         for (int i = 0; i < n_collector; i++)
  74.                         {
  75.                                 Random rdm;
  76.                                 double random_num = rdm.randomf(0,100000)/100;                        //用随机来模拟生成的数字,可以的话 加一下接收实际情况数据的接口
  77.                                 col[i]->data_collect(random_num);
  78.                                 finish = clock() - start;
  79.                                 if ((double(finish) / CLOCKS_PER_SEC - n_need * col[0]->span >= 0))                //严格检查|| (int(finish) % 1000 == 999)
  80.                                 {
  81.                                         cout << "周期结束!提前终止收集" << endl;
  82.                                         break;
  83.                                 }
  84.                                 else if (double(finish) / CLOCKS_PER_SEC > (nd0 - n_need)*col[0]->span)//一次全体采集没有完成一个周期是不是应该等待满一个周期
  85.                                 {
  86.                                         cout << "已完成 " << nd0 - n_need << " 个周期" << endl;
  87.                                         n_need--;
  88.                                 }
  89.                                 else
  90.                                 {
  91.                                         cout << "当前尚未完成周期。" << endl;
  92.                                         cout << double(finish) / CLOCKS_PER_SEC << " : " << (nd0 - n_need)*col[0]->span << endl;
  93.                                 }



  94.                         }

  95.                         //采集完成,休眠开始
  96.                         aslp = 1000 * ((nd0 - n_need)*col[0]->span - double(finish) / CLOCKS_PER_SEC);
  97.                         if (aslp > 0)
  98.                         {
  99.                                 cout << "已完成一次采集,正在等待周期 " << nd0 - n_need << " 结束" << endl;
  100.                                 cout << double(finish) / CLOCKS_PER_SEC << " : " << (nd0 - n_need)*col[0]->span << endl;
  101.                                 cout << "休眠 " << aslp << endl;
  102.                                 Sleep(aslp/10);                                        //休眠时间过长
  103.                                 finish += aslp;
  104.                                 if (int(finish) % 1000 == 999)
  105.                                 {
  106.                                         Sleep(1);
  107.                                         aslp++;                //尊重形式
  108.                                         finish++;
  109.                                 }
  110.                                 cout << double(finish) / CLOCKS_PER_SEC << " : " << (nd0 - n_need)*col[0]->span << endl;
  111.                                 if (double(finish) / CLOCKS_PER_SEC >= (nd0 - n_need)*col[0]->span)                //判定完成周期 (int(finish) % 10 == 9)
  112.                                 {
  113.                                         n_need--;
  114.                                 }
  115.                                 else
  116.                                 {
  117.                                         cout << "警告!休眠时间不足!" << endl;
  118.                                         cout << double(finish) / CLOCKS_PER_SEC << " : " << (nd0 - n_need)*col[0]->span << endl;
  119.                                 }
  120.                         }

  121.                         finish = clock() - start;
  122.                         if (!(double(finish) / CLOCKS_PER_SEC - n_need * col[0]->span < 0))                //采集耗时检测严格程度不如等待耗时
  123.                                 cout << "采集结束!周期等待完成" << endl;
  124.                 } while (double(finish) / CLOCKS_PER_SEC - n_need * col[0]->span < 0);
  125.                 /****************************************************************************************************************************************************************/

  126.                 /****************************************************************************************************************************************************************/

  127.                                 //cout << "与的正确用法" << endl;cout << (224 & 240) << " :" << (255 & 255) << endl;可以正式使用地址了(输入的网络地址和网络掩码相与后的结果必须等于网络地址
  128.                                 /*
  129.                                 所以应该建立一个数组,一个用自身路由表的地址寻找的数组;
  130.                                 这个数组要存储一个数据队列,或者甚至直接存储sensor;
  131.                                 数据收集器可以在数组里,也可以在外边;
  132.                                 路由算法默认dijkstra
  133.                                 */
  134.                                 /*
  135.                                 所谓广播到:就是指两者距离小于广播半径,要让col[0]--col[n]挨个对比
  136.                                 默认终端收集器在(0,0)
  137.                                 如何路由由 Sensor 内保存的简单路由表来决定
  138.                                 大概分三种形式:
  139.                                 1.不知道连接状况直接摸黑前进;2.情况完全了解之后再考虑传输方式;3.了解和传输都随机应变
  140.                                 空想:
  141.                                 可以标明数据的来源以及目的地,就像快递那样;至于中转点怎么设置。
  142.                                 最简单的方法是多次实验的经验 or 把坐标靠中心的几个点和紧挨收集器的几个点设置成线路中转点
  143.                                 几个核心点之间形成一个干线,让其他末支的点连接到干线上就行了

  144.                                 */

  145.                                 //嘤嘤嘤,实现了周期性还要记得广播半径也要考虑(用于路由传播交流)
  146.                                 //5路由方式???是什么?暂定为之前看到的迪杰斯特拉算法吧。
  147.                                 /*
  148.                                 跟路由方式息息相关的是之前得到的广播半径、位置,估计要画小地图来帮助理解
  149.                                 既然是人为投放的sensor,那么默认直接跟终端接收器相关的那个sensor是一定能找得到的吧。
  150.                                 个人理解的路由方式是 尽量高效的传输+尽量全面的搜集 吧
  151.                                 路由的时候还要接收其他sensor给予的数据,可能目的地和来源(可以仅考虑上一个?甚至是多个?也可能必须知道来源)
  152.                                 */

  153.                                 /*
  154.                                 设计的是静态路由表(内容经现场情况决定后固定)
  155.                                 建立的时候从数据收集器开始往回溯源,因为数据是单向流动的(其实TCP/IP协议是需要双向的)
  156.                                 */
  157.                                 /*
  158.                                 for (int i = 0; i < n_collector; i++)
  159.                                 {
  160.                                                 col[i]->Lyb(n_collector);
  161.                                 }
  162.                                 */
  163.                 double **col_distance;//二维数组
  164.                 col_distance = new double*[n_collector];
  165.                 for (int i = 0; i < n_collector; i++)
  166.                 {
  167.                         col_distance[i] = new double[n_collector];
  168.                 }

  169.                 for (int j = 0; j < n_collector; j++)
  170.                 {
  171.                         for (int k = 0; k < n_collector; k++)
  172.                         {
  173.                                 double dis;
  174.                                 dis = sqrt(pow((col[j]->x - col[k]->x), 2) + pow((col[j]->y - col[k]->y), 2));
  175.                                 if (dis > a1)
  176.                                 {
  177.                                         col_distance[j][k] = inf;
  178.                                 }
  179.                                 else
  180.                                 {
  181.                                         col_distance[j][k] = dis;
  182.                                 }

  183.                         }
  184.                 }
  185.                 //到这里两传感器的距离有了。

  186.                 //(0,0)是收集器最近的传感器1的位置,例子5432中能到达 2 , 3是孤立的了.输出效果是警告孤立出来的点,以及将数据按线路传送回收集器
  187.                 //1.根据表格连接线路
  188.                 int *road2home1 = new int[(n_collector + 1)*n_collector / 2] {0};                //num可能要加一
  189.                 int n_r2h = 1;
  190.                 road2home1[0] = 1;
  191.                 for (int i = 0; i < n_collector; i++)
  192.                 {
  193.                         for (int k = i; k < n_collector; k++)
  194.                         {
  195.                                 if (col_distance[i][k] > 0)
  196.                                 {
  197.                                         road2home1[n_r2h] = k + 1;
  198.                                         n_r2h++;
  199.                                 }

  200.                         }
  201.                 }
  202.                 cout << "数据流向" << endl;                                //大概率有BUG
  203.                 for (int i = 0; i < n_collector && road2home1[i] != NULL; i++)
  204.                 {
  205.                         if (i!=n_collector - 1 && road2home1[n_collector-1]!=0)
  206.                         {
  207.                                 cout << road2home1[i] << " ";
  208.                         }
  209.                         else
  210.                         {
  211.                                 cout << road2home1[i] << " ";
  212.                         }
  213.                         //可以加箭头,稍微麻烦
  214.                 }
  215.                 cout << endl;
  216.                 //2.警示孤立的点
  217.                 int *flag = new int[n_collector] {0};
  218.                 int flag2 = 1;
  219.                 for (int i = 0; i < n_collector; i++)
  220.                 {
  221.                         for (int k = 0; k < n_collector; k++)
  222.                         {
  223.                                 if (i + 1 == road2home1[k])
  224.                                 {
  225.                                         flag2 = 0;
  226.                                         break;
  227.                                 }
  228.                         }
  229.                         if (flag2)
  230.                         {
  231.                                 cout << i + 1 << "为孤立点!" << endl;
  232.                                 flag[i] = 1;
  233.                         }
  234.                         flag2 = 1;
  235.                 }


  236.                 //3.将数据传回收集器。到了1 直接输出就行了.

  237.                 int num_r2l = 0;
  238.                 for (int i = 0; i < n_collector; i++)
  239.                 {

  240.                         if (flag[i])                        //数据无法达到的可以警示
  241.                         {
  242.                                 cout << i + 1 << " 号信号丢失!" << endl;
  243.                         }
  244.                         else
  245.                         {
  246.                                 col[0]->show(); //用输出模拟传入数据收集终端
  247.                                 while (!(col[0]->is_empty()))
  248.                                 {
  249.                                         col[0]->popout();
  250.                                 }
  251.                                 cout << " ---- ";

  252.                                 if (road2home1[i] != n_collector)
  253.                                 {
  254.                                         while (road2home1[i] > 0 && !(col[road2home1[i]]->is_empty()))
  255.                                         {
  256.                                                 col[0]->get(col[road2home1[i]]->give());
  257.                                         }
  258.                                 }
  259.                                 cout << road2home1[i] << " 号数据到达终端!" << endl;
  260.                         }


  261.                 }                                                                                                                                        //读数据时出错

  262.                 /****************************************************************************************************************************************************************/

  263.                 /****************************************************************************************************************************************************************/
  264.                 //展示环节
  265.                 /*
  266.                 我理想的展示是
  267.                 既能立刻显示出所需要的单个sensor的所有数据
  268.                 也能将总的数据生成为一份excel,至少得是txt文本吧
  269.                 */
  270.                 //#include "pch.h"

  271.                
  272.                         initgraph(X, Y);                //画纸大小
  273.                        
  274.                         //setcolor(WHITE);
  275.                         cleardevice();

  276.                
  277.                         //这里想要把所有点画出,并且用另一种颜色画出半径

  278.                         putpixel(col[0]->x, col[0]->y, WHITE);
  279.                         int px, py;
  280.                         for (int i = 0; i < 400; i++) {
  281.                                 if (i < 100) {
  282.                                         px = 200+col[0]->x + i;
  283.                                         py = col[0]->y+50;
  284.                                 }
  285.                                 else if (i < 200) {
  286.                                         px = 300 + col[0]->x;
  287.                                         py = col[0]->y + 50 + (i - 100);
  288.                                 }
  289.                                 else if (i < 300) {
  290.                                         px = 300 + col[0]->x - (i - 200);
  291.                                         py = 150+ col[0]->y;
  292.                                 }
  293.                                 else {
  294.                                         px = 200+col[0]->x;
  295.                                         py = 150+ col[0]->y - (i - 300);
  296.                                 }
  297.                                 putpixel(px, py, GREEN);
  298.                                
  299.                         }

  300.                         for (int i = 1; i < n_collector; i++)
  301.                         {
  302.                                 //绘制点
  303.                                 putpixel(col[i]->x, col[i]->y, WHITE);
  304.                                 //绘制半径
  305.                                 double pi = 3.1415926;

  306.                                 for (int j = 0; j < 1000; j++) {
  307.                                         int x = col[i]->x + col[i]->radius * cos(j*pi / 500);
  308.                                         int y = col[i]->y + col[i]->radius * sin(j*pi / 500);
  309.                                         putpixel(x, y, BROWN);
  310.                                        
  311.                                 }
  312.                         }
  313.                        
  314.                         for (int j = 0; j < n_collector; j++)
  315.                         {
  316.                                 for (int k = 0; k < n_collector; k++)
  317.                                 {
  318.                                         double dis;
  319.                                         dis = sqrt(pow((col[j]->x - col[k]->x), 2) + pow((col[j]->y - col[k]->y), 2));
  320.                                         if (dis < a1 && dis>0)
  321.                                         {
  322.                                                 if (!j)
  323.                                                         setlinecolor(GREEN);
  324.                                                 else
  325.                                                 {
  326.                                                         setlinecolor(YELLOW);
  327.                                                 }                                               
  328.                                                 setlinestyle(PS_SOLID, 1);
  329.                                                 line(col[j]->x, col[j]->y, col[k]->x, col[k]->y);
  330.                                         }
  331.                                         cout << "dis(" << dis << ")" << " : " << "rds(" << a1 << ")" << endl;

  332.                                 }
  333.                         }
  334.                        
  335.                         system("pause");
  336.                         closegraph();          // 关闭绘图窗口
  337.                


  338.                   return 0;
  339. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-6-8 22:25

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表