우선 Colab을 이용하여 다음과 같은 과정으로 DT 를 이용해 Feature importance를 측정하고자 했다.
1. 100개의 데이터를 80 - 20 으로 Train - Test 분할한다.
2. PacketDropRatio를 Y-val로 하는 DecisionTreeRegression을 수행한다.
3. 중요도에 따라 Clustering에 사용할 Feature들을 결정한다.
=> 그러나 Regression의 결과 Score가 너무 좋지 않았다.
따라서, PacketDropRation를 0.25, 0.5, 0.75의 사분면으로 나누어 low-medium-medium2-high 로 범주화시키고, 이에 대한 DecisionTreeClassification을 하니 성능이 오르긴 했지만 충분하다고 생각되지 않았다.
따라서 Feature들이 의미가 없는 Feature들이 선정되었다고 결론을 지었다.
지금은 일단 개별 노드의 ThroughPut, Queue Length를 추가 파라미터로 더 제시하고 다시 학습을 해볼 생각을 하고 있다.
아래는 그냥 작성해둔 ns3 코드에 QueueLength ThroughPut을 구하는 부분만 추가한 단순한 코드이기 때문에 개별 포스팅이 필요 없을 것 같아 여기에 작성해두었다.
QueueLength 같은 부분은 찍히는 타이밍에 따라 PacketDrop은 기록되어있는데 어떤 노드는 막 Queue를 비운 직후고 어떤 노드는 전송 직전이라 쌓여있는 케이스가 발생할 수 있다고 생각하여 Average Queuelength를 쓰려고 한다.
#include <sstream>
#include <fstream>
#include <ns3/network-module.h>
#include <ns3/core-module.h>
#include <ns3/applications-module.h>
#include <ns3/mobility-module.h>
#include <ns3/internet-module.h>
#include <ns3/yans-wifi-helper.h>
#include "ns3/energy-module.h"
#include "ns3/wifi-radio-energy-model-helper.h"
#include "ns3/device-energy-model.h"
#include "ns3/adhoc-wifi-mac.h"
#include "ns3/aodv-helper.h"
#include "ns3/wifi-mac-queue.h"
#include <regex>
#include <cmath>
#include <vector>
#include <string>
#define DataRateVal 100000
#define TxRange 350
#define TotalTime 250
#define nodeNum 30
#define sinkNum 5
#define QueueLenS "80p"
#define QueueLen 80
#define IterNum 100
#define dataMode "VhtMcs8"
#define phyMode "OfdmRate54Mbps"
using namespace ns3;
int ja=0;
int ios = 0;
int PDC[nodeNum];
int PRC[nodeNum];
int PSC[nodeNum];
int PQC[nodeNum];
void
makeCsvFile(const std::vector<std::vector<std::string>>& data,std::ofstream* file1){
for(const auto& row : data){
for(auto it = row.begin(); it!=row.end(); ++it){
for(char c : *it){
file1->put(c);
}
if(next(it)!=row.end()){
file1->put(',');
}
}
file1->put('\n');
}
}
Vector
Normalize(const Vector& velocity){
double magnitude = std::sqrt(velocity.x * velocity.x + velocity.y * velocity.y + velocity.z * velocity.z);
// 크기가 0인 벡터는 정규화할 수 없으므로, 원본 벡터를 반환
if (magnitude == 0)
{
return velocity;
}
return ns3::Vector(velocity.x / magnitude, velocity.y / magnitude, velocity.z / magnitude);
}
double distance(double x1, double y1, double x2, double y2){
return sqrt(pow(x2 - x1, 2) + pow(y2 - y1, 2));
}
double CalculateRelativeSpeed(double vAx, double vAy, double vBx, double vBy) {
// 상대 속도 벡터의 각 성분을 계산
double relativeVx = vBx - vAx;
double relativeVy = vBy - vAy;
return sqrt(pow(relativeVx, 2) + pow(relativeVy, 2));
}
void MacRx(NetDeviceContainer* n,std::string context, Ptr<const Packet> packet){
std::regex rege("/NodeList/(\\d+)/");
std::smatch match;
std::regex_search(context,match,rege);
int index = std::stoi(match[1].str());
PointerValue ptr;
n->Get(index)->GetAttribute("Mac",ptr);
Ptr<AdhocWifiMac> mac = ptr.Get<AdhocWifiMac>();
Ptr<WifiMacQueue> txop = mac->GetTxopQueue(AC_BE);
if(txop->GetNPackets()>=QueueLen){
PDC[index]+=1;
}
PRC[index]+=1;
}
void MacTx(NetDeviceContainer* n,std::string context, Ptr<const Packet> packet){
std::regex rege("/NodeList/(\\d+)/");
std::smatch match;
std::regex_search(context,match,rege);
int index = std::stoi(match[1].str());
PSC[index]+=1;
}
void QueueChecking(NetDeviceContainer n){
for(int i=0; i<nodeNum; i++){
PointerValue ptr;
n.Get(i)->GetAttribute("Mac",ptr);
Ptr<AdhocWifiMac> mac = ptr.Get<AdhocWifiMac>();
Ptr<WifiMacQueue> txop = mac->GetTxopQueue(AC_BE);
PQC[i]+=txop->GetNPackets();
}
Simulator::Schedule(Seconds(0.5),&QueueChecking,n);
}
void
TracingParameter(NetDeviceContainer n, std::ofstream* os,std::vector<std::vector<std::string>> Data){
double variance[nodeNum]={};
double nodeX[nodeNum];
double nodeY[nodeNum];
double spdX[nodeNum];
double spdY[nodeNum];
int NN[nodeNum];
int GNN[nodeNum];
double mean1[nodeNum]={};
//각 노드들의 데이터 긁어오기, 0=PacketSinkApp, 1=OnOffApp
for(int i=0; i<nodeNum; i++){
//node들의 에너지 잔량,속도, 방향, 위치 정보 수집(Node x, Node y)
Ptr<Node> node = n.Get(i)->GetNode();
Ptr<MobilityModel> mobility = node->GetObject<MobilityModel>();
ApplicationContainer app = node->GetApplication(0);
Vector pos = mobility->GetPosition();
Vector velocity = mobility->GetVelocity();
nodeX[i] = pos.x;
nodeY[i] = pos.y;
spdX[i] = velocity.x;
spdY[i] = velocity.y;
}
//Node Strength 계산
for(int i=0; i<nodeNum; i++){
double totalLET=0;
int GNNN = 0;
int NNodeNum = 0;
double LET[nodeNum];
std::fill(LET,LET+nodeNum,-1000);
for(int j=0; j<nodeNum; j++){
//처리해줘야할 노드만 처리
if(i==j) continue;
double dis = distance(nodeX[i],nodeY[i],nodeX[j],nodeY[j]);
if(dis<=TxRange){
NNodeNum++;
if((spdX[i]*spdX[j]+spdY[i]*spdY[j])>=0){
GNNN++;
}//가까워짐
else{
LET[j] = dis / (CalculateRelativeSpeed(spdX[i],spdY[i],spdX[j],spdY[j]));
}
}
}//이 시점에서 모든 node i 에 대한 LET 정보 갱신 완료.
if(GNNN!=NNodeNum){
for(int k=0; k<nodeNum; k++){
if(LET[k] == -1000) continue;
else totalLET += LET[k];
}
double mean = totalLET / (NNodeNum-GNNN);
for(int k=0; k<nodeNum; k++){
if(LET[k] == -1000) continue;
variance[i] += (LET[k]-mean)*(LET[k]-mean);
}
variance[i] /= (NNodeNum-GNNN);
variance[i] = sqrt(variance[i]);
mean1[i]=mean;
}
GNN[i] = GNNN;
NN[i] = NNodeNum;
}
//"Second","NodeID","X","Y","AverageLET","Variance","NNeighbor","GoodNeighbor","Speed","Throughput","QueueLength","PacketDrop"
for(int i=0; i<nodeNum; i++){
double PDR = (double)(PDC[i])/(double)(PRC[i]);
Data.push_back({std::to_string(Simulator::Now().GetSeconds()),
std::to_string(i+1),
std::to_string(nodeX[i]),
std::to_string(nodeY[i]),
std::to_string(mean1[i]),
std::to_string(variance[i]),
std::to_string(NN[i]),
std::to_string(GNN[i]),
std::to_string(abs(spdX[i])+abs(spdY[i])),
std::to_string(PSC[i]/Simulator::Now().GetSeconds()),
std::to_string(PQC[i]),
std::to_string(PDR*100)
});
}
std::fill(PQC,PQC+nodeNum,0);
makeCsvFile(Data,os);
Data.clear();
std::cout<<Simulator::Now().GetSeconds()<<std::endl;
Simulator::Schedule(Seconds(1),&TracingParameter,n,os,Data);
}
int
main(int argc, char* argv[]){
for(ja = 0; ja<IterNum; ja++){
std::ostringstream oss1;
oss1<<"/home/kimjian/ns-allinone-3.41/ns-3.41/Result/result"<<ja<<".csv";
std::ofstream file1 (oss1.str());
std::vector<std::vector<std::string>> Data;
Ptr<UniformRandomVariable> x = CreateObject<UniformRandomVariable>();
x->SetAttribute("Min",DoubleValue(0));
RngSeedManager::SetSeed(ja+1);
RngSeedManager::SetRun(10);
Data.push_back({"Second","NodeID","X","Y","AverageLET","Variance","NNeighbor","GoodNeighbor","Speed","Throughput","QueueLength","PacketDrop"});
NodeContainer AdhocNodes;
AdhocNodes.Create(nodeNum);
NetDeviceContainer AdhocDevices;
MobilityHelper mobility;
ObjectFactory points;
points.SetTypeId("ns3::RandomRectanglePositionAllocator");
points.Set("X",StringValue("ns3::UniformRandomVariable[Min=-350.0|Max=350.0]"));
points.Set("Y",StringValue("ns3::UniformRandomVariable[Min=-350.0|Max=350.0]"));
Ptr<PositionAllocator> waypos = points.Create() -> GetObject<PositionAllocator>();
mobility.SetMobilityModel("ns3::RandomWaypointMobilityModel",
"Speed",StringValue("ns3::UniformRandomVariable[Min=0.0|Max=10]"),
"Pause",StringValue("ns3::UniformRandomVariable[Min=0.0|Max=2]"),
"PositionAllocator",PointerValue(waypos));
mobility.SetPositionAllocator("ns3::RandomRectanglePositionAllocator",
"X",StringValue("ns3::UniformRandomVariable[Min=-350.0|Max=350.0]"),
"Y",StringValue("ns3::UniformRandomVariable[Min=-350.0|Max=350.0]"));
mobility.Install(AdhocNodes);
//속도 pause time 방향 범위 내 랜덤.
WifiHelper wifi;
wifi.SetStandard(WIFI_STANDARD_80211ac);
YansWifiPhyHelper phy;
YansWifiChannelHelper channel;
phy.EnableAscii("my-wifi-trace-file",AdhocNodes);
WifiMacHelper mac;
mac.SetType("ns3::AdhocWifiMac");
phy.SetErrorRateModel("ns3::YansErrorRateModel");
channel.SetPropagationDelay("ns3::ConstantSpeedPropagationDelayModel");
wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager","DataMode",StringValue(dataMode),"ControlMode",StringValue(phyMode));
channel.AddPropagationLoss("ns3::RangePropagationLossModel","MaxRange",DoubleValue(TxRange));
phy.SetChannel(channel.Create());
AdhocDevices.Add(wifi.Install(phy,mac,AdhocNodes));
InternetStackHelper internet;
AodvHelper aodv;
internet.SetRoutingHelper(aodv);
internet.Install(AdhocNodes);
Ipv4AddressHelper ipv4;
ipv4.SetBase("10.1.1.0","255.255.255.0");
Ipv4InterfaceContainer ipv4Interface = ipv4.Assign(AdhocDevices);
uint64_t port = 9;
ApplicationContainer sink_app;
for(int i=0; i<sinkNum; i++){
PacketSinkHelper packetSink("ns3::UdpSocketFactory",InetSocketAddress(Ipv4Address::GetAny(),port));
sink_app.Add(packetSink.Install(AdhocNodes.Get(i)));
}
sink_app.Start(Seconds(0.0));
sink_app.Stop(Seconds(TotalTime));
for(int i=0; i<sinkNum; i++){
for(int j=0; j<nodeNum; j++){
if(i==j) continue;
InetSocketAddress sinkSocket (ipv4Interface.GetAddress(i),port);
OnOffHelper onoff("ns3::UdpSocketFactory",sinkSocket);
onoff.SetAttribute("StartTime",TimeValue(Seconds(3)));
onoff.SetAttribute("StopTime",TimeValue(Seconds(TotalTime)));
onoff.SetAttribute("OnTime", StringValue("ns3::UniformRandomVariable[Min=0.5|Max=1.5]")); // 전송 지속 시간
onoff.SetAttribute("OffTime", StringValue("ns3::UniformRandomVariable[Min=0|Max=0.5]")); // 전송 중단 시간
onoff.SetAttribute("DataRate", DataRateValue(DataRateVal)); // 데이터 전송률
onoff.Install(AdhocNodes.Get(j));
}
}
Simulator::Stop(Seconds(TotalTime));
for(int i=0; i<nodeNum; i++){
//Mac 버퍼 크기 줄이기
PointerValue ptr;
AdhocDevices.Get(i)->GetAttribute("Mac",ptr);
Ptr<AdhocWifiMac> mac = ptr.Get<AdhocWifiMac>();
Ptr<WifiMacQueue> txop = mac->GetTxopQueue(AC_BE);
txop->SetMaxSize(QueueSize(QueueLenS));
std::ostringstream oss1;
oss1<<"/NodeList/"<<i<<"/DeviceList/0/$ns3::WifiNetDevice/Mac/MacRx";
Config::Connect (oss1.str(), MakeBoundCallback (&MacRx,&AdhocDevices));
std::ostringstream oss;
oss<<"/NodeList/"<<i<<"/DeviceList/0/$ns3::WifiNetDevice/Mac/MacTx";
Config::Connect (oss.str(), MakeBoundCallback (&MacTx,&AdhocDevices));
}
Simulator::Schedule(Seconds(3),&TracingParameter,AdhocDevices,&file1,Data);
Simulator::Schedule(Seconds(0.5),&QueueChecking,AdhocDevices);
Simulator::Run();
Simulator::Destroy();
std::fill(PDC,PDC+nodeNum,0);
std::fill(PRC,PRC+nodeNum,0);
std::fill(PQC,PQC+nodeNum,0);
std::fill(PSC,PSC+nodeNum,0);
file1.close();
}
}
'학부연구생' 카테고리의 다른 글
Node Packet Drop Ratio를 예측하기 위한 Feature Selection-2 (0) | 2024.04.02 |
---|---|
Adhoc network에서 노드들을 clustering하기. (0) | 2024.03.26 |
문제 해결을 위한 시뮬레이션 제작 및 Tracing source 추출-完 (0) | 2024.03.20 |
문제 해결을 위한 시뮬레이션 제작 및 Tracing source 추출-3 (0) | 2024.03.17 |
현재까지 제시된 Routing protocol based on ML - 2 (0) | 2024.03.17 |