Exemplo n.º 1
0
void ArrayList::operator=(const ArrayList& rhs)
{
    //Deep copy
    Clear();
    mList.resize(rhs.Count());
    for(u_int i = 0; i < rhs.Count(); i++)
    {
        ArrayListItemBase* ptr = const_cast<ArrayListItemBase*>(&rhs[i]);
        if(dynamic_cast<ArrayListItem<int>*>(ptr))
        {
            mList[i] = new ArrayListItem<int>(*(dynamic_cast<ArrayListItem<int>*>(ptr)));
        }
        else if(dynamic_cast<ArrayListItem<double>*>(ptr))
        {
            mList[i] = new ArrayListItem<double>(*(dynamic_cast<ArrayListItem<double>*>(ptr)));
        }
        else if(dynamic_cast<ArrayListItem<string>*>(ptr))
        {
            mList[i] = new ArrayListItem<string>(*(dynamic_cast<ArrayListItem<string>*>(ptr)));
        }
        else if(dynamic_cast<ArrayListItem<ArrayList>*>(ptr))
        {
            mList[i] = new ArrayListItem<ArrayList>(*(dynamic_cast<ArrayListItem<ArrayList>*>(ptr)));
        }

//        else if(dynamic_cast<ArrayListItem<ArrayListItem>*>(ptr))
//        {
//            mList[i] = new ArrayListItem<ArrayListItem>(*(dynamic_cast<ArrayListItem<ArrayListItem>*>(ptr)));
//        }
        else
        {
            mList[i] = NULL;
        }
    }
}
Exemplo n.º 2
0
ArrayList::ArrayList(const ArrayList& copyMe)
{
    //Deep copy
    Clear();
    mList.resize(copyMe.Count());
    for(u_int i = 0; i < copyMe.Count(); i++)
    {
        //const ArrayListItem<T>& item = copyMe[i];
        ArrayListItemBase* ptr = const_cast<ArrayListItemBase*>(&copyMe[i]);
        if(dynamic_cast<ArrayListItem<int>*>(ptr))
        {
            mList[i] = new ArrayListItem<int>(*(dynamic_cast<ArrayListItem<int>*>(ptr)));
        }
        else if(dynamic_cast<ArrayListItem<double>*>(ptr))
        {
            mList[i] = new ArrayListItem<double>(*(dynamic_cast<ArrayListItem<double>*>(ptr)));
        }
        else if(dynamic_cast<ArrayListItem<string>*>(ptr))
        {
            mList[i] = new ArrayListItem<string>(*(dynamic_cast<ArrayListItem<string>*>(ptr)));
        }
        else if(dynamic_cast<ArrayListItem<StringList>*>(ptr))
        {
            mList[i] = new ArrayListItem<StringList>(*(dynamic_cast<ArrayListItem<StringList>*>(ptr)));
        }
        else if(dynamic_cast<ArrayListItem<ArrayList>*>(ptr))
        {
            mList[i] = new ArrayListItem<ArrayList>(*(dynamic_cast<ArrayListItem<ArrayList>*>(ptr)));
        }
        else
        {
            mList[i] = NULL;
        }
    }
}
Exemplo n.º 3
0
        double CM::GetOneWayDistance(const ArrayList<PointList>& u, const ArrayList<cv::Mat>& v)
        {
            assert(u.Count() == v.Count());
            int uPointNum = u[0].Count();
            double uToV = 0;

            for (size_t i = 0; i < uPointNum; i++)
                uToV += v[0].at<double>(u[0][i].y, u[0][i].x);

            if (uPointNum == 0)
                return numeric_limits<double>::max();
            else
                return uToV / uPointNum;
        }
Exemplo n.º 4
0
StringList ArrayList::GetStringList(const string& lName)
{
    //Look for ann array list whose first item is a string with lName and second item is a stringlist, i.e. {{string, {string string string}}
    StringList aList;
    for(u_int i = 0; i < Count(); i++)
    {
        ArrayListItemBase* listPtr = const_cast<ArrayListItemBase*>(mList[i]);

        //Check for a list which first element is a string, i.e. a {{string}, {string, string}} list
        if(dynamic_cast< ArrayListItem<ArrayList> *>(listPtr))
        {
            ArrayList list = (ArrayList) *(dynamic_cast< ArrayListItem<ArrayList> *>(listPtr));
            if(list.Count())
            {
                ArrayListItemBase* anItem = &list[0];
                if(dynamic_cast<ArrayListItem<string>*>(anItem))
                {
                    string str = (string) *dynamic_cast<ArrayListItem<string>*>(anItem);

                    if(str == lName && list.Count() > 1)
                    {
                        ArrayListItemBase* anItem = &list[1];
                        if(dynamic_cast<ArrayListItem<StringList> *>(anItem))
                        {
                            //This is a stringList
                            StringList  list = (StringList) *(dynamic_cast<ArrayListItem<StringList>*>(anItem));
                            for(int i = 0; i < list.Count(); i++)
                            {
                                string str = list[i];
                                aList.add(str);
                            }
                        }
                        if(dynamic_cast<ArrayListItem<ArrayList> *>(anItem))
                        {
                            //Assume this list only contains strings!
                            ArrayList  list = (ArrayList) *(dynamic_cast<ArrayListItem<ArrayList>*>(anItem));
                            for(int i = 0; i < list.Count(); i++)
                            {
                                string str = list.GetString(i);
                                aList.add(str);
                            }
                        }

                    }
                }
            }
        }
    }
    return aList;
}
Exemplo n.º 5
0
        ArrayList<Mat> CM::GetTransforms(const Size& size, const ArrayList<PointList> channels)
        {
            ArrayList<Mat> result(channels.Count());
            Mat dt(size, CV_64F);

            for (int i = 0; i < dt.rows; i++)
                for (int j = 0; j < dt.cols; j++)
                    dt.at<double>(i, j) = maxDistance * maxDistance;

            for (size_t i = 0; i < channels[0].Count(); i++)
            {
                int left = (int)floor(channels[0][i].x - maxDistance),
                    right = (int)ceil(channels[0][i].x + maxDistance),
                    top = (int)floor(channels[0][i].y - maxDistance),
                    bottom = (int)ceil(channels[0][i].y + maxDistance);
                left = left < 0 ? 0 : left;
                right = right > dt.cols ? dt.cols : right;
                top = top < 0 ? 0 : top;
                bottom = bottom > dt.rows ? dt.rows : bottom;

                for (int m = top; m < bottom; m++)
                {
                    for (int n = left; n < right; n++)
                    {
                        double distance = (m - channels[0][i].y) * (m - channels[0][i].y) + 
                            (n - channels[0][i].x) * (n - channels[0][i].x);

                        dt.at<double>(m, n) = min(distance, dt.at<double>(m, n));
                    }
                }
            }

            result[0] = dt;
            return result;
        }
Exemplo n.º 6
0
void ArrayList::Add(const string& lbl, const ArrayList& lists)
{
    ArrayList temp;
    temp.Add(lbl);
    if (lists.Count())
        temp.Add(lists);
    Add(temp);
}
Exemplo n.º 7
0
void LogLegitimateTraffic(NetworkObject* ContactPoint)
{
	for(int i=0;i<Vehicles.Count();i++)
	{
		Vehicle* CurrentVehicle=Vehicles[i];
		if(!CurrentVehicle->CurrentlyWithinSimulation()||(SimulationTime>=CurrentVehicle->v_k_silent_t&&SimulationTime<=CurrentVehicle->v_k_resume_t)){continue;}
		LogTraffic(Vehicles[i],APPLICATION);
		if(ContactPoint!=NULL){LogTraffic(ContactPoint,APPLICATION);}
	}
}
Exemplo n.º 8
0
ArrayList<Vehicle*>* GetVehiclesInRange(NetworkObject* Transmitter)
{
	ArrayList<Vehicle*>* RetVal=new ArrayList<Vehicle*>();
	for(int i=0;i<Vehicles.Count();i++)
	{
		Vehicle* CurrentVehicle=Vehicles[i];
		if(!CurrentVehicle->CurrentlyWithinSimulation()){continue;}
		if(inrange(CurrentVehicle->x,CurrentVehicle->y,Transmitter->x,Transmitter->y,Transmitter->TransmissionRadius)){RetVal->PushObj(CurrentVehicle);}
	}
	return RetVal;//The data structure is owned by the caller and must be deleted after use.
}
Exemplo n.º 9
0
        double Hitmap::GetOneWayDistance(const ArrayList<PointList>& u, const ArrayList<cv::Mat>& v)
        {
            assert(u.Count() == v.Count());
            int orientNum = u.Count(), uPointNum = 0;
            double uToV = 0;

            for (int i = 0; i < orientNum; i++)
            {
                const PointList& uPoints = u[i];
                const Mat& vMat = v[i];

                for (int j = 0; j < uPoints.Count(); j++)
                    uToV += vMat.at<uchar>(uPoints[j].y, uPoints[j].x);

                uPointNum += uPoints.Count();
            }

            if (uPointNum == 0)
                return 1;
            else
                return 1 - uToV / uPointNum;
        }
Exemplo n.º 10
0
        double OCM::GetOneWayDistance(const ArrayList<PointList>& u, const ArrayList<cv::Mat>& v)
        {
            assert(u.Count() == v.Count());
            int orientNum = u.Count(), uPointNum = 0;
            double uToV = 0;

            for (int i = 0; i < orientNum; i++)
            {
                const ArrayList<Point>& uPoints = u[i];
                const Mat& vMat = v[i];

                for (size_t i = 0; i < uPoints.Count(); i++)
                    uToV += vMat.at<float>(uPoints[i].y, uPoints[i].x);

                uPointNum += uPoints.Count();
            }

            if (uPointNum == 0)
                return numeric_limits<double>::max();
            else
                return uToV / uPointNum;
        }
Exemplo n.º 11
0
        ArrayList<Mat> Hitmap::GetTransforms(const Size& size, const ArrayList<PointList> channels)
        {
            ArrayList<Mat> result(channels.Count());

            for (size_t i = 0; i < channels.Count(); i++)
            {
                Mat dt(size, CV_8U);
                dt = Scalar::all(0);

                for (size_t j = 0; j < channels[i].Count(); j++)
                {
                    int left = (int)floor(channels[i][j].x - maxDistance),
                        right = (int)ceil(channels[i][j].x + maxDistance),
                        top = (int)floor(channels[i][j].y - maxDistance),
                        bottom = (int)ceil(channels[i][j].y + maxDistance);
                    left = left < 0 ? 0 : left;
                    right = right > dt.cols ? dt.cols : right;
                    top = top < 0 ? 0 : top;
                    bottom = bottom > dt.rows ? dt.rows : bottom;

                    for (int m = top; m < bottom; m++)
                    {
                        for (int n = left; n < right; n++)
                        {
                            double distance = sqrt((m - channels[i][j].y) * (m - channels[i][j].y) + 
                                (n - channels[i][j].x) * (n - channels[i][j].x));

                            if (distance <= maxDistance)
                                dt.at<uchar>(m, n) = 1;
                        }
                    }
                }

                result[i] = dt;
            }

            return result;
        }
Exemplo n.º 12
0
void LogApplicationTraffic(NetworkObject* ContactPoint)
{
	LogLegitimateTraffic(ContactPoint);
	for(int i=0;i<AnonymitySets.Count();i++)
	{
		AnonymitySet* CurrentSet=AnonymitySets[i];
		if(SimulationTime<CurrentSet->k_resume_t){continue;}
		int VehiclesInSet=CurrentSet->Count();
		for(int io=0;io<VehiclesInSet;io++)
		{
			Vehicle* CurrentVehicle=CurrentSet->AnonymousVehicles[io];
			for(int ie=0;ie<VehiclesInSet-1;ie++)
			{
				if(io==ie){continue;}
				LogTraffic(CurrentVehicle,DUMMY);
				if(ContactPoint!=NULL){LogTraffic(ContactPoint,DUMMY);}
			}
			//Each vehicle sends one application message as a dummy event for every other vehicle in the same set, and one real message for itself.
		}
	}
}
Exemplo n.º 13
0
void SimulationRun(string RunParameterNames[])
{
	ifstream TraceFile;
	bool RunValid=true;
	if(PrimaryProtocol==NULL)
	{
		cerr<<"RUN ERROR: No protocol specified!"<<endl;
		RunValid=false;
	}
	if(TraceFileName=="")
	{
		cerr<<"RUN ERROR: No trace file specified!"<<endl;
		RunValid=false;
	}
	if(RunValid)
	{
		TraceFile.open(TraceFileName.c_str());
		if(!TraceFile.is_open())
		{
			cerr<<"RUN ERROR: Cannot open trace file!"<<endl;
			RunValid=false;
		}
		else if(TraceFile.bad()||TraceFile.fail())
		{
			cerr<<"RUN ERROR: Stream was corrupted!"<<endl;
			RunValid=false;
		}
	}
	if(!RunValid){return;}//Immediately break and cancel the run if there are execution errors.
	ResetGlobalVariables();
	int VehicleNum,BeginTime,EndTime;
	float x,y;
	int NextSimulationTime;
	int VehicleNumMask=1;//The modulo of the vehicle num and this value determines whether a vehicle is omitted to get a different set of vehicles in the simulation.
	int VehicleNumMaskOffset=0;
	bool MaskExists=CheckRunVariableExists("VehicleNumMask");
	bool OffsetExists=CheckRunVariableExists("VehicleNumMaskOffset");
	if(MaskExists!=OffsetExists){cerr<<"ERROR: Must specify both VehicleNumMask and VehicleNumMaskOffset for this input to be effective!"<<endl;}
	else if(MaskExists)
	{
		VehicleNumMask=GetRunVariableInteger("VehicleNumMask");
		VehicleNumMaskOffset=GetRunVariableInteger("VehicleNumMaskOffset");
	}
	while (TraceFile >> NextSimulationTime >> VehicleNum >> x >> y >> BeginTime >> EndTime)// loop through all input
	{
		TimeMax=max(NextSimulationTime+1,TimeMax);
		if((--VehicleNum)%VehicleNumMask==VehicleNumMaskOffset)
		{
			VehicleNum/=VehicleNumMask;
			VehicleMax=max(VehicleNum+1,VehicleMax);
			for(int i=Vehicles.Count();i<VehicleMax;i++){Vehicles.PushObj(new Vehicle("OBU#"+to_string((long long int)i)));}
			Vehicle* CurrentVehicle=Vehicles[VehicleNum];
			if(CurrentVehicle->v_begin_t==-1)
			{
				CurrentVehicle->v_begin_t=BeginTime;
				CurrentVehicle->v_begin_x=x;
				CurrentVehicle->v_begin_x=y;
				CurrentVehicle->v_end_t=EndTime;
			}
		}
	}
	OutputVariables.Set("VehicleMax",to_string((long long int)VehicleMax));
	OutputVariables.Set("TimeMax",to_string((long long int)TimeMax));
	OutputVariables.Set("TraceFile",TraceFileName);
	OutputVariables.Set("ProtocolName",ProtocolName);
	
	TraceFile.clear();
	TraceFile.seekg(0, TraceFile.beg);  // reposition to beginning of input file
	if(TraceFile.bad()||TraceFile.fail())
	{
		cerr<<"RUN ERROR: Could not reset stream!"<<endl;
		RunValid=false;
	}
	
	int PeakAnonymitySetSize=0;//Used to calculate one of our metrics later.
	float PeakAnonymityDistance=0;
	if(CheckRunVariableExists("GlobalMessageLimit")){NetworkObject::GlobalMessageLimit=GetRunVariableInteger("GlobalMessageLimit");}
	SetGlobalVehicleMaxMessagePerTick(CheckRunVariableExists("VehicleMessageLimit")?GetRunVariableInteger("VehicleMessageLimit"):0);
	time_t SimulationBeginTime=time(NULL);
	RunValid=RunValid&&PrimaryProtocol->SimulationBegin();
	bool TraceFileEOF=false;
	while(!TraceFileEOF)
	{
		TraceFile>>NextSimulationTime>>VehicleNum>>x>>y>>BeginTime>>EndTime;
		TraceFileEOF=TraceFile.eof();
		if(!TraceFileEOF&&(TraceFile.bad()||TraceFile.fail()))
		{
			cerr<<"RUN ERROR: Stream became corrupted during simulation!"<<endl;
			RunValid=false;
			break;
		}
		if(SimulationTime==-1){SimulationTime=NextSimulationTime;}//This prevents a logic error that causes a simulation tick before the first batch of tracefile data has been processed.
		if(TraceFileEOF||SimulationTime!=NextSimulationTime)
		{
			RunValid=RunValid&&PrimaryProtocol->SimulationTick();
			if(!RunValid){break;}//This short-circuits the execution if a critical error as occurred.
			//This loop adds to the average counters in each vehicle.
			//Average counters are processed after the simulation to get various anonymity statistics.
			//As such, these values are not menaingful until they have been finalized later.
			for(int i=0;i<VehicleMax;i++)
			{
				Vehicle* CurrentVehicle=Vehicles[i];
				if(!CurrentVehicle->CurrentlyWithinSimulation()){continue;}
				if(CurrentVehicle->AssignedSet!=NULL)
				{
					AnonymitySet* CurrentSet=CurrentVehicle->AssignedSet;
					int SetSize=CurrentSet->Count();
					CurrentVehicle->AverageAnonymitySetSizeCounter+=SetSize;
					PeakAnonymitySetSize=max(PeakAnonymitySetSize,SetSize);
					ArrayList<Vehicle*>* VehiclesInSet=&(CurrentSet->AnonymousVehicles);
					float SetDistance=0.0;
					for(int io=0;io<VehiclesInSet->Count();io++)
					{
						Vehicle* OtherVehicle=(*VehiclesInSet)[io];
						if(CurrentVehicle==OtherVehicle){continue;}
						float XDist=CurrentVehicle->x-OtherVehicle->x;
						float YDist=CurrentVehicle->y-OtherVehicle->y;
						float Dist=sqrt(XDist*XDist+YDist*YDist);
						SetDistance+=Dist;
						PeakAnonymityDistance=max(PeakAnonymityDistance,Dist);
					}
					CurrentVehicle->AverageAnonymityDistanceCounter+=SetDistance/SetSize;
				}
				else{CurrentVehicle->AverageAnonymitySetSizeCounter++;}
			}
			for(int i=0;i<VehicleMax;i++)
			{
				Vehicle* CurrentVehicle=Vehicles[i];
				if(SimulationTime==CurrentVehicle->v_end_t)
				{
					CurrentVehicle->v_end_x=CurrentVehicle->x;
					CurrentVehicle->v_end_y=CurrentVehicle->y;
					CurrentVehicle->v_terminated=SimulationTime;
					//We set ending data AFTER the protocol text so the set isn't prematurely decremented.
					if(CurrentVehicle->AssignedSet!=NULL){CurrentVehicle->AssignedSet->RemoveVehicle(CurrentVehicle);}
				}
			}
			if(TraceFileEOF){break;}
			SimulationTime=NextSimulationTime;
		}
		if((--VehicleNum)%VehicleNumMask==VehicleNumMaskOffset)
		{
			VehicleNum=VehicleNum/VehicleNumMask;
			Vehicle* CurrentVehicle=Vehicles[VehicleNum];//We decrement VehicleNum because trace files base their lists with 1 as the first index.
			CurrentVehicle->x=x;
			CurrentVehicle->y=y;
		}
	}
	if(RunValid)
	{
		PrimaryProtocol->SimulationEnd();
		time_t SimulationRunTime=time(NULL)-SimulationBeginTime;
		OutputVariables.Set("RunTime",to_string(((long double)SimulationRunTime)/60.0));
		
		//This loop adds inputs as outputs, so the resulting printed line can also reference parameters used in the run.
		for(int i=0;i<RunVariables.Count();i++){OutputVariables.Set(RunVariables.GetKey(i),RunVariables.Get(i));}
		
		//This loop calculates various averages.
		int AnonymousVehicleCount=0;
		int AverageAnonymitySamples=0;
		float AverageAnonymitySetSize=0.0;
		float AverageAnonymityDistance=0.0;
		float AverageAnonymityTime=0.0;
		float PeakAnonymityTime=0.0;
		for(int i=0;i<Vehicles.Count();i++)
		{
			Vehicle* CurrentVehicle=Vehicles[i];
			if(CurrentVehicle->v_terminated==-1)
			{
				cerr<<"TERMINATE ERROR: Vehicle#"<<i<<" was supposed to terminate at "<<CurrentVehicle->v_end_t<<"/"<<SimulationTime<<endl;
				CurrentVehicle->v_terminated=CurrentVehicle->v_end_t;
			}
			AverageAnonymitySamples+=(CurrentVehicle->v_terminated-CurrentVehicle->v_begin_t)+1;
			AverageAnonymitySetSize+=CurrentVehicle->AverageAnonymitySetSizeCounter;
			AverageAnonymityDistance+=CurrentVehicle->AverageAnonymityDistanceCounter;
			if(CurrentVehicle->v_k_assign_t!=-1)
			{
				AnonymousVehicleCount++;
				float AnonTime=CurrentVehicle->v_terminated-CurrentVehicle->v_k_silent_t;
				AverageAnonymityTime+=AnonTime;
				PeakAnonymityTime=max(PeakAnonymityTime,AnonTime);
			}
		}
		if(AnonymousVehicleCount>0){AverageAnonymityTime/=AnonymousVehicleCount;}
		if(AverageAnonymitySamples==0)
		{
			AverageAnonymitySetSize=0.0f;
			AverageAnonymityDistance=0.0f;
		}
		else
		{
			AverageAnonymitySetSize/=AverageAnonymitySamples;
			AverageAnonymityDistance/=AverageAnonymitySamples;
		}
		OutputVariables.Set("AverageAnonymitySetSize",to_string((long double)AverageAnonymitySetSize));
		OutputVariables.Set("PeakAnonymitySetSize",to_string((long long int)PeakAnonymitySetSize));
		OutputVariables.Set("AverageAnonymityDistance",to_string((long double)AverageAnonymityDistance));
		OutputVariables.Set("PeakAnonymityDistance",to_string((long double)PeakAnonymityDistance));
		OutputVariables.Set("AverageAnonymityTime",to_string((long double)AverageAnonymityTime));
		OutputVariables.Set("PeakAnonymityTime",to_string((long double)PeakAnonymityTime));
		OutputVariables.Set("AnonymousVehicleCount",to_string((long long int)AnonymousVehicleCount));
		OutputVariables.Set("TotalAnonymitySets",to_string((long long int)AnonymitySets.Count()));
		
		//This loop calculates the most congested networked unit.
		int CongestionCount=0;
		NetworkObject* CongestedUnit=NULL;
		for(int i=0;i<NetworkObjects.Count();i++)
		{
			NetworkObject* CurrentCounter=NetworkObjects[i];
			int MaxPackets=CurrentCounter->NetworkMessages.GetMostPacketsTransmitted();
			if(MaxPackets>CongestionCount)
			{
				CongestedUnit=CurrentCounter;
				CongestionCount=MaxPackets;
			}
		}
		if(CongestedUnit==NULL){OutputVariables.Set("PeakTrafficUnit","None");}
		else{OutputVariables.Set("PeakTrafficUnit",CongestedUnit->Title);}
		OutputVariables.Set("PeakTrafficAmount",to_string((long long int)CongestionCount));
		
		//This loop adds the traffic counters to the list of OutputVariables.
		for(int i=0;i<=TOTAL_TRAFFIC_TYPES;i++){OutputVariables.Set(string("Packet Count: ")+GetEnumName((TrafficType)i),to_string((long long int)GlobalTraffic[i]));}
		OutputVariables.Set(string("Packet Count: Overhead"),to_string((long long int)GlobalTraffic.Overhead()));
		OutputVariables.Set(string("Packet Count: Overhead Ratio"),to_string((long double)GlobalTraffic.OverheadRatio()));
		OutputVariables.Set(string("Packet Count: Successful"),to_string((long long int)GlobalTraffic.TotalTransmitted()));
		OutputVariables.Set(string("Packet Count: Lost"),to_string((long long int)GlobalTraffic.TotalLost()));
		OutputVariables.Set(string("PacketLoss"),to_string((long double)GlobalTraffic.PacketLoss()));
		OutputVariables.Set(string("Throughput"),to_string((long double)GlobalTraffic.TotalTransmitted()/TimeMax));
		
		//OUTPUT
		if(LegacyOutput)
		{
			cout<<"RUN:";
			for(int i=0;i<MAX_PARAMETERS_PER_LINE&&RunParameterNames[i].length()>0;i++)
			{
				if(i>0){cout<<",";}
				cout<<RunParameterNames[i]<<"="<<setw(3)<<RunVariables.Get(RunParameterNames[i]);
			}
			cout<<": ";
			cout<<fixed<<
				"K="<<setw(5)<<setprecision(2)<<AverageAnonymitySetSize<<"("<<AnonymitySets.Count()<<"), "<<
				"D="<<setw(6)<<setprecision(2)<<AverageAnonymityDistance<<", "<<
				"T="<<setw(5)<<setprecision(2)<<AverageAnonymityTime<<", "<<
				"Anonymous="<<setw(4)<<AnonymousVehicleCount<<"/"<<setw(4)<<VehicleMax;
			for(int i=0;i<=TOTAL_TRAFFIC_TYPES;i++){cout<<", "<<GetEnumName((TrafficType)i)<<":"<<GlobalTraffic[i];}
			if(CongestedUnit!=NULL){cout<<", Congested: "<<CongestedUnit->Title<<"("<<CongestionCount<<")";}
			cout<<endl;
		}
		else if(VerboseOutput)
		{
			for(int i=0;i<OutputVariables.Count();i++)
			{
				if(i!=0){cout<<", ";}
				cout<<OutputVariables.GetKey(i)<<"="<<OutputVariables.Get(i);
			}
			cout<<endl;
		}
		else
		{
			//TODO: Get the output to interpret different variable types.
			int FormatNeedle=0;//This advances through the format string as we process each section.
			while(FormatNeedle<OutputFormat->size())
			{
				//These first few lines find the next special character, or the end of the string, and OutputVariables any part of the string which was passed over.
				size_t FoundIndex=OutputFormat->find(OUTPUT_FORMAT_DELIMITER,FormatNeedle);
				if(FoundIndex==string::npos){FoundIndex=OutputFormat->size();}
				cout<<OutputFormat->substr(FormatNeedle,FoundIndex-FormatNeedle);
				FormatNeedle=FoundIndex+1;
				//If the end of the string was not reached, we then try to parse the next block of characters, which are special notation.
				if(FoundIndex<OutputFormat->size())
				{
					FoundIndex=OutputFormat->find(OUTPUT_FORMAT_DELIMITER,FormatNeedle);
					if(FoundIndex==string::npos)
					{
						cerr<<"ERROR: Misformatted Output String: No Closing '"<<OUTPUT_FORMAT_DELIMITER<<"'!"<<endl;
						break;
					}
					string FormatSpecifierArguments("s");
					size_t FoundSubIndex=OutputFormat->find(OUTPUT_FORMAT_SUB_DELIMITER,FormatNeedle);
					if(FoundSubIndex!=string::npos)
					{
						FormatSpecifierArguments=OutputFormat->substr(FormatNeedle,FoundSubIndex-FormatNeedle);
						FormatNeedle=FoundSubIndex+1;
					}
					string OutputValue("Unspecified");
					string VariableName=OutputFormat->substr(FormatNeedle,FoundIndex-FormatNeedle);
					if(OutputVariables.HasKey(VariableName)){OutputValue=OutputVariables.Get(VariableName);}
					string FormatSpecifier("%");
					FormatSpecifier=FormatSpecifier+FormatSpecifierArguments;
					char VariableTypeSpecifier=FormatSpecifier.at(FormatSpecifier.size()-1);
					switch(VariableTypeSpecifier)
					{
					case 'd': case 'i': case 'u':
						printf(FormatSpecifier.c_str(),atoi(OutputValue.c_str()));
						break;
					case 'f': case 'F':
						printf(FormatSpecifier.c_str(),atof(OutputValue.c_str()));
						break;
					default:
						printf(FormatSpecifier.c_str(),OutputValue.c_str());
						break;
					}
					FormatNeedle=FoundIndex+1;
				}
			}
			cout<<endl<<flush;//We have to use this operator to push a newline to cout, or the Cloud9 interface will cache it in a strange way.
		}
	}
	//CLEANUP
	fflush(NULL);
	TraceFile.close();
	while(AnonymitySets.Count()>0){delete AnonymitySets.PopObj();}
	while(Vehicles.Count()>0){delete Vehicles.PopObj();}
}