-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathConsoleApplication1.cpp
2851 lines (2764 loc) · 113 KB
/
ConsoleApplication1.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
// ConsoleApplication1.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include<math.h>
#include<iostream>
#include<time.h>
#include<string.h>
#include<stdio.h>
#include<list>
#include <stdlib.h>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <fstream>
#include <vector>
#include <complex>
#include <cmath>
#include<conio.h>
using namespace std;
#define M_A_X 9999
const double pi = 3.141592654;
int L = 12000;//模拟环境的大小
double turn_left_possibility = 0.3; //下个路口左转的几率30%
double turn_right_poosibility = 0.3; //下个路口右转的概率30%
class aodvjr_RREQ_packet { //aodvjr 的请求包
public:
int T;
int scource;
int destination;
int current;
int ID; //序列号 一个包又三个要素确定, scource destination ID
};
class aodvjr_RREP_packet { //aodvjr的返回包
public:
int T;
int scource;
int destination;
int current;
};
class packet {
public:
int T;
int scource;
int destination;
int current;
};
class cbc_packet {
public:
int T;
int scource;
int destination;
int next_gateway; //经由哪个网关
int next_head; //转发给哪个簇头
int current; //当前位置
int already_in_this_cluster;
int go_for_gateway; //表示正在从簇头发向网关
int ID; //这个就是时间,调试用
};
class lca_packet {
public:
int T;
int ID; //调试用,这个就是时间
int scource;
int destination;
int next_gateway; //经由哪个网关
int next_head; //转发给哪个簇头
int current; //当前位置
};
class cbc_head_annouce_packet
{
public:
int T;
int scource;
int current;
int degree; //本节点的度
vector<int> cbc_announce_path; //记录cbc簇头声明节点的路径
vector<int> is_passed_by; //记录哪些节点曾经经过了,上面那个的伴生数组 is_passed_by[4]=0;表示4号节点没有经过 is_passed_by[5]=1 ;表示曾经经过5号节点
int ID; //序列号 一个包又三个要素确定, scource ID
};
class cbc_deny_packet //cbc簇头请求的驳回包
{
public:
int destination; //驳回包的目的地址
int current;
vector<int> deny_path; //驳回包的路径
};
class cbc_agree_packet //cbc簇头请求的同意包
{
public:
int scource;
int destination; //同意包的目的地址
int depth; //同意节点对源节点的深度,depth=1认为是他的邻居 depth=2为2阶邻居
int current;
vector<int> control_neighbor; //与reachable是一样的,源节点支配了哪些节点
vector<int> agree_path; //同意包的路径
vector<int> report_path; //同意包返回的时候,把路径都记下来,用以回复簇头节点
};
class cbc_maintain_packet
{
public:
int scource;
int destination; //同意包的目的地址
int current;
vector<int> path_control_neighbor; //与reachable是一样的,把整个路径上支配哪些节点全部告诉簇头,用来维护簇头自己的内容
};
class cbc_routing_table_element //路由表的单个元素,我本人到特定节点的路由信息
{
public:
int cluster_head; //通过这个簇头可以找到,目的地
bool in_this_cluster; //是否在本簇可以直接送达
int gateway; //通过几号网关可以找到这个簇 gateway=-1;表示我可以直接联系上簇头
int gateway_mainstay_number; //骨干网的编号,0是说明簇首本身就可以够到网关,1说明1号展臂可以够到 2说明2号展臂可以够到(不论是网关还是目的地)
int time_stamp; //时间戳 这条信息的时间戳
int length; //距离,经过多少次网关才能到目的簇头
};
class lca_routing_table_element //路由表的单个元素
{
public:
int cluster_head; //通过这个簇头可以找到,目的地
int gateway; //通过几号网关可以找到这个簇 gateway=-1;表示我可以直接联系上簇头
int length; //距离 length=0表示就在本簇中
int time_stamp; //时间戳
};
class cbc_inform_packet //cbc簇建立后对全体簇头广播的名片
{
public:
int effective; //名片的有效性effective=0表示无效,effective=1表示有效,脱离簇以后名片无效
int near; //这个名片是哪个节点传过来的
int scource;
vector<cbc_routing_table_element> cbc_routing_table_packeted; //打成包的路由表
int time_stamp; //时间戳,时间戳太久自动作废
list<int> mainstay; //骨干网的拓扑信息
};
class max_announce_received //暂存下收到的最大请求包的ID
{
public:
int max_announce_node_ID; //暂存的最佳节点的id
int max_announce_node_degree; //暂存ID的度
int wait_time_window; //时间窗口
int is_hearing; //是否在接听请求包
vector<cbc_agree_packet> all_virtual_cbc_agree_packet;//对应节点的全部包,只要是他的我就返回,不是他的我就丢弃
};
class lca_routing_exchange_packet
{
public:
vector<lca_routing_table_element> packeted_lca_routing_table; //lca路由表
};
class node {
public:
int ID; //车的ID
int v;
int x;
int y;
double r; //通信距离
int direction; //当前方向 1 上(北) 2 右(东) 3 下(南) 4 左(西)
list <int> turn; //下个路口是否转弯 0直行 1左转 2 右转
vector<int> reachable;//可到达的节点
vector<int> is_reachable; //临接关系的另一种表示 is_reachable[5]=1;表示跟5号节点是邻居关系 is_reachable[6]=0 表示跟6号节点不是邻居关系
double distance(node p);//传一个对象指针进去
void move(int block_width, int N); //block width 指街区宽度,如果能被整除则处在路口应该转弯了
int virtual_move(node p,int block_width, int N, int time); //虚拟移动,用来预测节点的未来位置
//////////////////////////////////////////////////////////////////////////////////////////////////////aodvjr的所需的节点储存
list<packet> queue;//数据包的队列
list<aodvjr_RREP_packet> RREP_queue; //返回包的队列
list<aodvjr_RREQ_packet> RREQ_queue; //请求包的队列
//////// 这仨是虚拟队列,新的包总是先进虚拟队列,避免同一个时间步对数据包重复处理,等到每步结束的时候用虚拟队列覆盖真实队列
list<packet> virtual_queue;//虚拟队列
list<aodvjr_RREP_packet> virtual_RREP_queue; //虚拟返回包的队列
list<aodvjr_RREQ_packet> virtual_RREQ_queue; //虚拟请求包的队列
vector<int> aodvjr_table; //aodvjr的正向路由,aodvjr_table[3]=6 表示从当前位置到3号目的地 要走6号节点
vector<int> aodvjr_back_table; //aodvjr 协议的反向路由 aodvjr_back_table[5]=7 表示从当前位置到5号源 要走7号节点 -1表示反向路由尚未建立
vector<int> aodvjr_quest_times; //对某个节点的请求次数,即请求包的ID
vector<vector<int>> aodvjr_saved_ID; //表示每个节点存储过的请求包ID,即aodvjr_saved_ID[5][7]=4表示我存储着源为5目的端为7的请求包的最新ID为4
vector<int> aodvjr_table_expiry; //aodvjr的正向链路维护时间,若时间结束,链路自动断开aodvjr_table_expiry[3]=158表示从当前位置到3号目的地 链路剩余时间为 158
vector<int> aodvjr_back_expiry; //aodvjr的反向链路维护时间,若时间结束,链路自动断开aodvjr_back_expiry[5]=128 表示从当前位置到5号源节点 链路剩余时间为128
///////////////////////////////////////////////////////////////////////////////////////////////////////cbc协议的
int cbc_incluster;//是否在簇中的标志 cbc_incluster=0 不在簇中,cbc_incluster=1 在簇中
int cbc_ishead; //是否为簇头节点 cbc_ishead=1 是簇头 cbc_ishead=0 不是簇头
int cbc_isbone; //是否为骨干网 cbc_isbone=1 是骨干网 cbc_isbone=0 不是骨干网
int cbc_near; //作为骨干网近端邻居是谁
int cbc_far; //作为骨干网远端邻居是谁
list<cbc_packet> cbc_queue;//cbc的数据包的队列
list<cbc_packet> virtual_cbc_queue;//cbc的数据包的队列
list<cbc_head_annouce_packet> head_announce_queue; //返回包的队列
list<cbc_head_annouce_packet> virtual_head_announce_queue; //返回包的虚拟队列
list<cbc_deny_packet> cbc_deny_packet_queue; //驳回包的队列
list<cbc_deny_packet> virtual_cbc_deny_packet_queue; //驳回包的虚拟队列
list<cbc_agree_packet> cbc_agree_packet_queue; //同意包的队列
list<cbc_agree_packet> virtual_cbc_agree_packet_queue; //同意包的虚拟队列
int stop_announce; //簇头声明的暂停时间,如果收到deny包这个暂停时间增加,用以等待邻居成簇把他加进去
int wait_to_create_head; //等待多久建立簇头
vector<vector<int>> saved_path; //存着返回包的路径 saved_path[2]={6,8,10} 说明存着由第二个返回包来回来的一条路径,路径中包括节点(包括簇头,本节点)6(簇头).8.10
vector<vector<int>> node_control; //存着哪些节点被那个节点支配 node_control[6]={2,9,11} 表示6号节点支配着2,9,11三个节点
list<int> mainstay_1; //簇的骨干网
list<int> mainstay_2; //骨干网
int inform_interval;// 通知间隔,满足这个间隔才会广播通知信息
vector<int> cluster_control; //本簇控制多少个节点,包括了簇头跟骨干网
vector<int> mainstay_1_control; //一号展臂能控制的节点
vector<int> mainstay_2_control; //二号展臂控制的节点
cbc_inform_packet only_inform_packet; //通知包,用来广播路由信息,这个每个骨干节点只有一个,作为本簇的名片
cbc_inform_packet virtual_only_inform_packet; //通知包,用来广播路由信息,这个每个骨干节点只有一个,作为本簇的名片
list<cbc_inform_packet> exchange_packet_information_queue; //网关节点用以交换的路由信息的存储队列
list<cbc_inform_packet> virtual_exchange_packet_information_queue; //网关节点用以交换的路由信息的虚拟队列
vector<int> cbc_information_saved_ID; //本节点储存的全套路由信息的ID cbc_information_saved_ID[7]=564; 我储存着到7号簇头广播的最新的最新的ID为564
int hello_interval;
int cbc_tail_1_validity; //是否还能收到来自骨干网1的维护信息
int cbc_tail_2_validity; //是否还能收到来自骨干网1的维护信息
int cbc_lonely_validity; //如果这个簇头一个展臂都没有,不能让他一直活着
int bone_of_whom; //我作为骨干网的簇首编号
vector<cbc_routing_table_element> cbc_routing_table; //路由表
list<cbc_maintain_packet> cbc_maintain_packet_queue;//这是又臂展节点末尾发来的簇维护包,告知簇头现在的情况
list<cbc_maintain_packet> virtual_cbc_maintain_packet_queue;//维护包的虚拟队列
max_announce_received my_max_announce_received; //记录下一段时间内收到的最佳的请求包发来的度,只对他负责
///////////////////////////////////////////////////////////////////////////////////////////////////////////// LCA算法所需结构
int lca_ishead; // 是否为lca的簇头
vector<lca_routing_table_element> lca_routing_table; //lca路由表
list<lca_routing_exchange_packet> lca_routing_exchange_packet_queue; //接收到路由表信息的虚拟队列
list<lca_routing_exchange_packet> virtual_lca_routing_exchange_packet_queue; //接收到路由表信息的虚拟队列
list<lca_packet> lca_packet_queue;
list<lca_packet> virtual_lca_packet_queue;
int in_lca_cluster;
};
double node::distance(node p)
{
return sqrt((x - p.x)*(x - p.x) + (y - p.y)*(y - p.y));
}
void node::move(int block_width,int N)
{
reachable.clear();//把临接关系清空
is_reachable.clear();
for (int i = 0; i < N; i++)
{
is_reachable.push_back(0); //临接关系清空
}
///////////////////////////////行进
switch (direction)
{
case 1: //北行 左下角坐标0,0
{
y = y + v;
break;
}
case 2: //东行
{
x = x + v;
break;
}
case 3: //南行
{
y = y - v;
break;
}
case 4: //西行
{
x = x - v;
break;
}
}
////////////////////////////////////////////边界处理
if (x <=0 ) //贴左边了 模糊处理
{
x = 0;
direction = 2;
}
if (x >= L) //贴右边了
{
x = L;
direction = 4;
}
if (y <= 0) //贴下边了
{
y = 0;
direction = 1;
}
if (y >= L) //贴上边了
{
y = L;
direction = 3;
}
if (x%block_width == 0 && y%block_width ==0 && x != 0 && y != 0 && x != L&&y != L) //x y 都能被街区宽度整除 说明处于路口,改变方向
{
cout << "车ID:" << ID << "到达路口,路口坐标为" << x << "," << y << endl;
switch (turn.front())
{
case 0: //车辆直行不做操作
{
break;
}
case 1: //左转
{
direction = direction - 1;
if (direction == 0)
{
direction = 4; //北往左转是西
}
break;
}
case 2: //右转
{
direction = direction + 1;
if (direction == 5)
{
direction = 1; //西往右转是北
}
break;
}
}
double rand_num = (double)rand() / RAND_MAX;
if (rand_num < turn_left_possibility)
{
turn.push_back(1);
}
if (rand_num >= turn_left_possibility&&rand_num <= (turn_right_poosibility + turn_left_possibility))
{
turn.push_back(2);
}
if (rand_num > (turn_right_poosibility + turn_left_possibility))
{
turn.push_back(0);
}
turn.pop_front(); //转过弯了,第一个转弯预设抛弃
}
}
int node::virtual_move(node p,int block_width, int N,int time)
{
int is_keep_connected = 1;
int time_last = time;
int virtual_p_x = p.x;
int virtual_p_y = p.y;
int virtual_p_direction =p.direction;
list <int> virtual_p_turn = p.turn;
int virtual_x = x;
int virtual_y = y;
int virtual_direction = direction; //复制当前坐标,方向
list <int> virtual_turn=turn;
while (time_last>1)
{
time_last--;
///////////////////////////////行进
switch (virtual_direction)
{
case 1: //北行 左下角坐标0,0
{
virtual_y = virtual_y + v;
break;
}
case 2: //东行
{
virtual_x = virtual_x + v;
break;
}
case 3: //南行
{
virtual_y = virtual_y - v;
break;
}
case 4: //西行
{
virtual_x = virtual_x - v;
break;
}
}
////////////////////////////////////////////边界处理
if (virtual_x <= 0) //贴左边了 模糊处理
{
virtual_x = 0;
virtual_direction = 2;
}
if (virtual_x >= L) //贴右边了
{
virtual_x = L;
virtual_direction = 4;
}
if (virtual_y <= 0) //贴下边了
{
virtual_y = 0;
virtual_direction = 1;
}
if (virtual_y >= L) //贴上边了
{
virtual_y = L;
virtual_direction = 3;
}
if (virtual_x%block_width == 0 && virtual_y%block_width == 0 && virtual_x != 0 && virtual_y != 0 && virtual_x != L&&virtual_y != L) //x y 都能被街区宽度整除 说明处于路口,改变方向
{
//cout << "虚拟车ID:" << ID << "到达虚拟路口,路口坐标为" << virtual_x << "," << virtual_y << endl;
switch (virtual_turn.front())
{
case 0: //车辆直行不做操作
{
break;
}
case 1: //左转
{
virtual_direction = virtual_direction - 1;
if (virtual_direction == 0)
{
virtual_direction = 4; //北往左转是西
}
break;
}
case 2: //右转
{
virtual_direction = virtual_direction + 1;
if (virtual_direction == 5)
{
virtual_direction = 1; //西往右转是北
}
break;
}
}
virtual_turn.pop_front(); //转过弯了,第一个转弯预设抛弃
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////本节点运动完了,该p节点了
switch (virtual_p_direction)
{
case 1: //北行 左下角坐标0,0
{
virtual_p_y = virtual_p_y + v;
break;
}
case 2: //东行
{
virtual_p_x = virtual_p_x + v;
break;
}
case 3: //南行
{
virtual_p_y = virtual_p_y - v;
break;
}
case 4: //西行
{
virtual_p_x = virtual_x - v;
break;
}
}
////////////////////////////////////////////边界处理
if (virtual_p_x <= 0) //贴左边了 模糊处理
{
virtual_p_x = 0;
virtual_p_direction = 2;
}
if (virtual_x >= L) //贴右边了
{
virtual_p_x = L;
virtual_p_direction = 4;
}
if (virtual_p_y <= 0) //贴下边了
{
virtual_p_y = 0;
virtual_p_direction = 1;
}
if (virtual_p_y >= L) //贴上边了
{
virtual_p_y = L;
virtual_p_direction = 3;
}
if (virtual_p_x%block_width == 0 && virtual_p_y%block_width == 0 && virtual_p_x != 0 && virtual_p_y != 0 && virtual_p_x != L&&virtual_y != L) //x y 都能被街区宽度整除 说明处于路口,改变方向
{
//cout << "虚拟p车ID:" << ID << "到达虚拟路口,路口坐标为" << virtual_p_x << "," << virtual_p_y << endl;
switch (virtual_p_turn.front())
{
case 0: //车辆直行不做操作
{
break;
}
case 1: //左转
{
virtual_p_direction = virtual_p_direction - 1;
if (virtual_p_direction == 0)
{
virtual_p_direction = 4; //北往左转是西
}
break;
}
case 2: //右转
{
virtual_p_direction = virtual_p_direction + 1;
if (virtual_p_direction == 5)
{
virtual_p_direction = 1; //西往右转是北
}
break;
}
}
virtual_p_turn.pop_front(); //转过弯了,第一个转弯预设抛弃
}
if (sqrt((virtual_x - virtual_p_x)*(virtual_x - virtual_p_x) + (virtual_y - virtual_p_y)*(virtual_y - virtual_p_y))>r) // 距离比较长,已经链路断了
{
is_keep_connected = 0; //链路断了
break;
}
}
return is_keep_connected;
}
packet create_single_packet(int N)
{
packet realpacket;
realpacket.T = 0;
while (1)
{
realpacket.current = rand()%N;
realpacket.destination = rand()%N;
if (realpacket.destination != realpacket.current)
{
break;
}
else
{
continue;
}
}
realpacket.scource = realpacket.current; //数据包源地址
return realpacket;
}
cbc_packet create_single_cbc_packet(int N)
{
cbc_packet realpacket;
realpacket.T = 0;
realpacket.next_head = -1;
realpacket.next_gateway = -1;
realpacket.go_for_gateway = 0;
realpacket.already_in_this_cluster = 0;
while (1)
{
realpacket.current = rand() % N;
realpacket.destination = rand() % N;
if (realpacket.destination != realpacket.current)
{
break;
}
else
{
continue;
}
}
realpacket.scource = realpacket.current; //数据包源地址
return realpacket;
}
void create_node(node** car,int block_width,int v,double r,int N)
{
int pre_turn_time = 80; //预测转弯多少次
double rand_num = 0; //0-1 之间的随机小数
for (int start_node = 0; start_node < N; start_node++)
{
car[start_node] = new node();//node的实例初始化
car[start_node]->ID = start_node;
car[start_node]->v = v;
car[start_node]->r = r;
////////////////////////////////////////////////////以下是aodv协议所需的初始化
car[start_node]->aodvjr_back_table.clear();
car[start_node]->aodvjr_table.clear();
car[start_node]->aodvjr_quest_times.clear();
car[start_node]->aodvjr_back_expiry.clear();
car[start_node]->aodvjr_table_expiry.clear();
car[start_node]->is_reachable.clear();
vector <int> all_zero_line;
vector <int> nothing;
for (int i = 0; i < N; i++)
{
all_zero_line.push_back(0); //整个二维数组初始化为0
}
for (int i = 0; i < N; i++)
{
car[start_node]->aodvjr_back_table.push_back(-1); //反向路由都初始化为-1
car[start_node]->aodvjr_table.push_back(-1);
car[start_node]->aodvjr_quest_times.push_back(0);
car[start_node]->aodvjr_saved_ID.push_back(all_zero_line); //插入空列用来占座
car[start_node]->node_control.push_back(nothing); //插入空的来占位置
car[start_node]->aodvjr_table_expiry.push_back(0); //链路剩余时间的都置为0
car[start_node]->aodvjr_back_expiry.push_back(0); //置为0
car[start_node]->is_reachable.push_back(0); //全部不是邻居
}
////////////////////////////////////////////////////////下面是运行cbc协议要做的一些初始化
car[start_node]->cbc_incluster=0;//是否在簇中的标志 cbc_incluster=0 不在簇中,cbc_incluster=1 在簇中
car[start_node]->cbc_ishead=0; //是否为簇头节点 cbc_ishead=1 是簇头 cbc_ishead=0 不是簇头
car[start_node]->cbc_isbone=0; //是否为骨干网 cbc_isbone=1 是骨干网 cbc_isbone=0 不是骨干网
car[start_node]->bone_of_whom = -1; //他谁的簇头也不是
car[start_node]->cbc_near = -1; //作为骨干网近端邻居是谁
car[start_node]->cbc_far = -1; //作为骨干网远端邻居是谁
car[start_node]->my_max_announce_received.max_announce_node_degree = -1;
car[start_node]->my_max_announce_received.max_announce_node_ID = -1;
car[start_node]->my_max_announce_received.wait_time_window = -1;
car[start_node]->my_max_announce_received.is_hearing = 1;
car[start_node]->only_inform_packet.effective = 0;
for (int i = 0; i < N; i++)
{
car[start_node]->cbc_information_saved_ID.push_back(-1); //我储存着到所有簇头广播的最新的最新的ID为-1
}
car[start_node]->stop_announce=0;
car[start_node]->wait_to_create_head = M_A_X;
car[start_node]->inform_interval=0;// 通知间隔,满足这个间隔才会广播通知信息
/////////////////////////////////////////////////////////////////
rand_num = (double)rand() / RAND_MAX;
if (rand_num < 0.25)
{
car[start_node]->x = ((rand() % (L / block_width - 1)) + 1)*block_width; //从1000到9000之间的一个随机数
car[start_node]->y = ((rand() % (L / v - 1)) + 1)*v;
car[start_node]->direction = 1;
}
if (rand_num >= 0.25&&rand_num < 0.5)
{
car[start_node]->y = ((rand() % (L / block_width - 1)) + 1)*block_width;
car[start_node]->x = ((rand() % (L / v - 1)) + 1)*v;
car[start_node]->direction = 2;
}
if (rand_num >= 0.5&&rand_num < 0.75)
{
car[start_node]->x = ((rand() % (L / block_width - 1)) + 1)*block_width;
car[start_node]->y = ((rand() % (L / v - 1)) + 1)*v;
car[start_node]->direction = 3;
}
if (rand_num >= 0.75)
{
car[start_node]->y = ((rand() % (L / block_width - 1)) + 1)*block_width;
car[start_node]->x = ((rand() % (L / v - 1)) + 1)*v;
car[start_node]->direction = 4;
}
for (int i = 0; i < pre_turn_time - 1; i++) //将要拐弯的长度预测几次
{
rand_num = (double)rand() / RAND_MAX;
if (rand_num < turn_left_possibility)
{
car[start_node]->turn.push_back(1);
}
if (rand_num >= turn_left_possibility&&rand_num <= (turn_right_poosibility + turn_left_possibility))
{
car[start_node]->turn.push_back(2);
}
if (rand_num >(turn_right_poosibility + turn_left_possibility))
{
car[start_node]->turn.push_back(0);
}
}
//cout << start_node << "号节点初始分配的坐标是" << car[start_node]->x << "," << car[start_node]->y << "速度为" << car[start_node]->v << "方向为" << car[start_node]->direction << "下次转弯方向为" << car[start_node]->turn.front() << endl;
//////////////////////////////////////////////////////////////下面是lca协议的一些初始化
car[start_node]->lca_ishead = 0;
}
}
void cover_queue(node** car,int N)
{
for (int process_node = 0; process_node < N; process_node++)
{
car[process_node]->queue.clear();
car[process_node]->queue = car[process_node]->virtual_queue;
car[process_node]->virtual_queue.clear();
car[process_node]->RREQ_queue.clear();
car[process_node]->RREQ_queue = car[process_node]->virtual_RREQ_queue;
car[process_node]->virtual_RREQ_queue.clear();
car[process_node]->RREP_queue.clear();
car[process_node]->RREP_queue = car[process_node]->virtual_RREP_queue;
car[process_node]->virtual_RREP_queue.clear();
}
}
void cbc_cover_queue(node** car, int N)
{
for (int process_node = 0; process_node < N; process_node++)
{
car[process_node]->cbc_queue.clear();
car[process_node]->cbc_queue = car[process_node]->virtual_cbc_queue;
car[process_node]->virtual_cbc_queue.clear();
car[process_node]->head_announce_queue.clear();
car[process_node]->head_announce_queue = car[process_node]->virtual_head_announce_queue;
car[process_node]->virtual_head_announce_queue.clear();
car[process_node]->cbc_deny_packet_queue.clear();
car[process_node]->cbc_deny_packet_queue = car[process_node]->virtual_cbc_deny_packet_queue;
car[process_node]->virtual_cbc_deny_packet_queue.clear();
car[process_node]->cbc_agree_packet_queue.clear();
car[process_node]->cbc_agree_packet_queue = car[process_node]->virtual_cbc_agree_packet_queue;
car[process_node]->virtual_cbc_agree_packet_queue.clear();
car[process_node]->exchange_packet_information_queue.clear();
car[process_node]->exchange_packet_information_queue = car[process_node]->virtual_exchange_packet_information_queue;
car[process_node]->virtual_exchange_packet_information_queue.clear();
car[process_node]->cbc_maintain_packet_queue.clear();
car[process_node]->cbc_maintain_packet_queue = car[process_node]->virtual_cbc_maintain_packet_queue;
car[process_node]->virtual_cbc_maintain_packet_queue.clear();
car[process_node]->only_inform_packet = car[process_node]->virtual_only_inform_packet;
}
}
void aodvjr_calculate_connection(node** car, double r, int N, int aodvjr_route_expiry)
{
//////////////////////////////////////////////////////////////////计算临接关系
for (int process_node = 0; process_node < N; process_node++)
{
for (int toreach = 0; toreach < process_node; toreach++)
{
if (process_node != toreach)
{
if (r >= car[process_node]->distance(*car[toreach]))
{
car[process_node]->reachable.push_back(toreach);
car[process_node]->is_reachable[toreach] = 1;
car[toreach]->reachable.push_back(process_node);
car[toreach]->is_reachable[process_node] = 1;
car[process_node]->aodvjr_table[toreach] = toreach;
car[process_node]->aodvjr_table_expiry[toreach] = aodvjr_route_expiry;
car[toreach]->aodvjr_table[process_node] = process_node;
car[toreach]->aodvjr_table_expiry[process_node] = aodvjr_route_expiry;
//cout << process_node << "号节点可到达邻居为" << toreach << endl;
}
else{}
}
else {}
}
}
}
void cbc_calculate_connection(node** car, double r, int N)
{
//////////////////////////////////////////////////////////////////计算临接关系
for (int process_node = 0; process_node < N; process_node++)
{
for (int toreach = 0; toreach < process_node; toreach++)
{
if (process_node != toreach)
{
if (r >= car[process_node]->distance(*car[toreach]))
{
car[process_node]->reachable.push_back(toreach);
car[process_node]->is_reachable[toreach] = 1;
car[toreach]->reachable.push_back(process_node);
car[toreach]->is_reachable[process_node] = 1;
}
else{}
}
else {}
}
}
}
void net_work_draw(node** car, int N,int time)
{
char filename[100];
sprintf_s(filename, "%d_time_draw.net", time);
ofstream ftest(filename, ios::app);
ftest << "*Vertices " << N << endl;
for (int i = 0; i < N; i++)
{
ftest << i + 1 << " " << "\"" << i << "\"" << " " << car[i]->x << " " << car[i]->y << " " << "0.5" << endl;
}
ftest << "*Edges" << endl;
for (int i = 0; i < N; i++)
{
for (int j = 0; j < car[i]->reachable.size(); j++)
{
ftest << i + 1 << " " << car[i]->reachable[j] + 1 << endl;
}
}
ftest.close();
}
void net_work_situation(node** car, int N)
{
int RREQ_sum = 0;
int RREP_sum = 0;
int queue_sum = 0;
for (int i = 0; i < N; i++)
{
RREQ_sum = RREQ_sum + car[i]->RREQ_queue.size();
RREP_sum = RREP_sum + car[i]->RREP_queue.size();
queue_sum = queue_sum + car[i]->queue.size();
}
cout << "请求包总量" << RREQ_sum << "返回包总量" << RREP_sum << "数据包总量" << queue_sum << endl;
system("pause");
}
void cbc_net_work_situation(node** car, int N)
{
int head_sum = 0;
int RREP_sum = 0;
int queue_sum = 0;
for (int i = 0; i < N; i++)
{
if (car[i]->cbc_ishead == 1)
{
head_sum++;
//cout << i << "是簇头" << endl;
}
queue_sum = queue_sum + car[i]->cbc_queue.size();
}
cout << "簇头总量" << head_sum << "数据包总量" << queue_sum << endl;
//system("pause");
}
void lca_net_work_situation(node** car, int N)
{
int head_sum = 0;
int queue_sum = 0;
for (int i = 0; i < N; i++)
{
if (car[i]->lca_ishead == 1)
{
head_sum++;
//cout << i << "是簇头" << endl;
}
queue_sum = queue_sum + car[i]->lca_packet_queue.size();
}
cout << "簇头总量" << head_sum << "数据包总量" << queue_sum << endl;
//system("pause");
}
void create_packet(node** car,double packet_spawn_rate,int N)
{
for (int start_packet = 0; start_packet<(int)(packet_spawn_rate*N); start_packet++)
{
packet new_packet = create_single_packet(N);
//cout << new_packet.current << " " << new_packet.destination << endl;
car[new_packet.current]->queue.push_back(new_packet); //生成数据包
}
}
void calculate_route_life(node** car, int N)
{
for (int i = 0; i<N; i++) //
{
for (int j = 0; j < N; j++)
{
if (i != j)
{
car[i]->aodvjr_table_expiry[j]--; //又经过了一步,链路倒计时
if (car[i]->aodvjr_table_expiry[j] <= 0) //当前节点到目的节点已经很久没有数据包经过了
{
if (car[i]->aodvjr_table[j] != -1)
{
//cout << "从" << i << "到" << j << "经过" << car[i]->aodvjr_table[j] << "的正向路由失效" << endl;
car[i]->aodvjr_table[j] = -1; //链路失效
}
}
car[i]->aodvjr_back_expiry[j]--; //又经过了一步,反向链路倒计时
if (car[i]->aodvjr_back_expiry[j] <= 0) //当前节点到源节点已经很久没有数据包经过了
{
if (car[i]->aodvjr_back_table[j] != -1)
{
//cout << "从" << i << "到" << j << "经过" << car[i]->aodvjr_back_table[j] << "的反向路由失效" << endl;
car[i]->aodvjr_back_table[j] = -1; //链路失效
}
}
}
}
}
}
void use_RREP_maintain(node** car, int N, int aodvjr_route_expiry,long long int &control_packet)
{
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
if (i != j) //全部节点对,由i到j发送返回包,维持链路
{
aodvjr_RREP_packet new_RREP_packet;
new_RREP_packet.current = car[i]->aodvjr_back_table[j];
new_RREP_packet.scource = i;
new_RREP_packet.destination = j;
new_RREP_packet.T = 0;
if (new_RREP_packet.current!=-1) //不存在反向路由也就不用维护
{
if (car[i]->is_reachable[new_RREP_packet.current] == 1) //如果这条反向链路确实存在
{
control_packet++;
//car[new_RREP_packet.current]->RREP_queue.push_back(new_RREP_packet);
car[new_RREP_packet.current]->virtual_RREP_queue.push_back(new_RREP_packet);
if (car[new_RREP_packet.current]->aodvjr_table[i] = i)
{
//cout << "正向路由(只一跳):" << new_RREP_packet.current << "到目的地" << i << "的正向路由为" << car[new_RREP_packet.current]->aodvjr_table[i] << "匹配" << i << "更新存活时间" << endl;
car[new_RREP_packet.current]->aodvjr_table_expiry[i] = aodvjr_route_expiry;
}
}
}
}
}
}
}
void handle_aodvjr_RREP_packet(node** car, int N, int aodvjr_route_expiry)
{
for (int traversal_packet = 0; traversal_packet<N; traversal_packet++) //反向数据包
{
for (list<aodvjr_RREP_packet>::iterator i = car[traversal_packet]->RREP_queue.begin(); i != car[traversal_packet]->RREP_queue.end();) //这里i++ 写在下面,需要处理一些删除操作
{
//cout << traversal_packet << "号节点中有AODV返回包,源" << i->scource << "目的" << i->destination << "当前" << i->current << endl;
if (i->destination == i->current) //如果目的已经是当前
{
//cout << traversal_packet << "返回包已经送达源节点,路由建立" << endl;
car[traversal_packet]->RREP_queue.erase(i++); //返回包已经到达位置,删除
}
else
{ //返回包继续前进
int temp = car[i->current]->aodvjr_back_table[i->destination];
if (temp != -1) //不存在反向路由
{
aodvjr_RREP_packet new_RREP_packet = *i;
new_RREP_packet.current = temp;
if (car[traversal_packet]->is_reachable[temp]==1) //确实存在这么一条链路,可以返回数据包
{
//car[temp]->RREP_queue.push_back(new_RREP_packet);
car[temp]->virtual_RREP_queue.push_back(new_RREP_packet);
if (car[temp]->aodvjr_table[i->scource] == traversal_packet) //之前建立过的正向路由,由于反向数据包经过他了,更新一下存活时间
{
car[temp]->aodvjr_table_expiry[i->scource] = aodvjr_route_expiry;
//cout << "正向路由:" << temp << "到目的地" << i->scource << "的正向路由为" << car[temp]->aodvjr_table[i->scource] << "匹配" << traversal_packet <<"更新存活时间"<< endl;
}
if (car[temp]->aodvjr_table[i->scource] == -1)
{
car[temp]->aodvjr_table[i->scource] = traversal_packet;
//cout << "正向路由建立从当前位置:" << temp << "到目的地" << i->scource << "的正向路由为" << car[temp]->aodvjr_table[i->scource] << endl;
car[temp]->aodvjr_table_expiry[i->scource] = aodvjr_route_expiry; //新建立的路由,生存时间赋值
}
}
}
car[traversal_packet]->RREP_queue.erase(i++); //不管能不能送,删
}
}
}
}
void handle_aodvjr_RREQ_packet(node** car, int N, int aodv_RREQ_expiry,long int aodvjr_route_expiry,long long int &control_packet)
{
for (int traversal_packet = 0; traversal_packet<N; traversal_packet++) //请求
{
for (list<aodvjr_RREQ_packet>::iterator i = car[traversal_packet]->RREQ_queue.begin(); i != car[traversal_packet]->RREQ_queue.end();) //这里i++ 写在下面,需要处理一些删除操作
{
//cout << traversal_packet << "号节点中有AODV请求包,源" << i->scource << "目的" << i->destination << "当前" << i->current << " ID为" << i->ID << "时间为" << i->T << endl;
if (i->T>aodv_RREQ_expiry) //如果过期
{
//cout << traversal_packet << "号节点中有AODV请求包失效,给予删除" << endl;
car[traversal_packet]->RREQ_queue.erase(i++);
}
else
{
if (i->destination == i->current) //如果目的已经是当前
{
//cout << traversal_packet << "号节点中有AODV请求包到达目的,删除,发返回包" << endl;
aodvjr_RREP_packet new_RREP_packet;
new_RREP_packet.current = car[i->destination]->aodvjr_back_table[i->scource];
new_RREP_packet.scource = i->destination;
new_RREP_packet.destination = i->scource;
if (new_RREP_packet.current!=-1) //不存在反向路由 无需发返回包
{
if (car[i->destination]->is_reachable[new_RREP_packet.current] == 1) //如果这条反向链路确实存在
{
control_packet++;
//car[new_RREP_packet.current]->RREP_queue.push_back(new_RREP_packet);
car[new_RREP_packet.current]->virtual_RREP_queue.push_back(new_RREP_packet);
if (car[new_RREP_packet.current]->aodvjr_table[i->destination] = i->destination)
{
car[new_RREP_packet.current]->aodvjr_table_expiry[i->destination] = aodvjr_route_expiry;
}
}
}
car[traversal_packet]->RREQ_queue.erase(i++); //返回包已发,删除请求包
}
else
{ //再次广播请求包
for (int j = 0; j < car[i->current]->reachable.size(); j++)
{
if (car[i->current]->reachable[j] != i->scource)
{
aodvjr_RREQ_packet quest_packet = *i;
quest_packet.current = car[i->current]->reachable[j];
quest_packet.T = quest_packet.T + 1;
control_packet++;
//cout << "转发出请求报文" << "其源节点为" << quest_packet.scource << "目的节点为" << quest_packet.destination << "当前位置为" << quest_packet.current << "时间为" << quest_packet.T << "ID为" << quest_packet.ID<< endl;