Vektor Wert übergeben



  • Hallo.

    Ich habe ein Programm welches mir zwei CSV Dateien einliest und in Vektoren speichert. In der einen CSV Datei sind XYZ Koordinaten gegeben und in der anderen sind XY und andere Attribute gespeichert.
    Die XY-Koordinaten in den beiden CSV-Dateien haben eine kleine Abweichung. Ich habe bereits eine "nearest/ best Fit" Funktion mit der ich eine Verknüpfung erstelle zu den beiden Koordinaten. Ich möchte den Z-Wert der am nächsten zu der Koordinate dran ist von dem einen Vektor an den anderen Vektor anhängen, aber ich weiß nicht wie. Hätte einer einen Tipp für mich?

    #include <iostream> 
    #include <fstream> 
    #include <vector> 
    #include <math.h>
    #include <algorithm>
    #include <limits>
    #include <string>
    
    using namespace std;
    
    struct SAB
    	{
    		double a_x;
    		double a_y;
    		string name;
    		int id;
    		size_t bestFitIdxInCsv;
    	};
    
    	struct SCD
    	{
    		double b_x;
    		double b_y;
    		double b_z;
    	};
    
    int main (){
    
    //---------------------------------------------------------------Testdaten
    
    	vector<SAB> AB_Data;
    	for(int i=0; i<10; ++i)			
    	{
    		SAB ab = {i,i*2,"asd", i};
    		AB_Data.push_back(ab);
    	}
    
    	vector<SCD> CD_Data;			
    	for(int i=4; i<9; ++i)
    	{
    		SCD cd = {i,i*2,i*3};
    		CD_Data.push_back(cd);
    	}
    
    //------------------------------------------------------------
    	std::vector<double> dist;
    	dist.resize(CD_Data.size());                         
    
    	for(int i=0; i < AB_Data.size(); ++i)
    	{
    		// Write distances between AB_Data[i] and each entry CD_Data[j] into dst[j]
    		std::transform(CD_Data.begin(), CD_Data.end(), dist.begin(),
    			[&AB_Data,&i] (SCD s) { return pow(s.b_x - AB_Data[i].a_x,2) + pow(s.b_y - AB_Data[i].a_y,2);});
    		// Find pointer to minimum value of dst
    		auto ptr = std::min_element(dist.begin(),dist.end());
    		// Transform from pointer to index j* of minimum and set this index in the respective AB_Data[i] structure
    		AB_Data[i].bestFitIdxInCsv = ptr - dist.begin();
    	}
    
    	for(int i=0; i < AB_Data.size(); ++i)
    	{
    		size_t idx = AB_Data[i].bestFitIdxInCsv;
    		//printf("\nBest fit AB idx %d (x,y)= (%f,%f) at CD idx %d: (x,y)= (%f,%f)", i, AB_Data[i].a_x,AB_Data[i].a_y,idx,  CD_Data[idx].b_x, CD_Data[idx].b_y );
    	}
    
    	std::cin.get();
    }// main
    

    Ausgabe in der Konsole:

    Best fit AB idx 0 (x,y)= (0.000000,0.000000) at CD idx 0: (x,y)= (4.000000,8.000000)
    Best fit AB idx 1 (x,y)= (1.000000,2.000000) at CD idx 0: (x,y)= (4.000000,8.000000)
    Best fit AB idx 2 (x,y)= (2.000000,4.000000) at CD idx 0: (x,y)= (4.000000,8.000000)
    Best fit AB idx 3 (x,y)= (3.000000,6.000000) at CD idx 0: (x,y)= (4.000000,8.000000)
    Best fit AB idx 4 (x,y)= (4.000000,8.000000) at CD idx 0: (x,y)= (4.000000,8.000000)
    Best fit AB idx 5 (x,y)= (5.000000,10.000000) at CD idx 1: (x,y)= (5.000000,10.000000)
    Best fit AB idx 6 (x,y)= (6.000000,12.000000) at CD idx 2: (x,y)= (6.000000,12.000000)
    Best fit AB idx 7 (x,y)= (7.000000,14.000000) at CD idx 3: (x,y)= (7.000000,14.000000)
    Best fit AB idx 8 (x,y)= (8.000000,16.000000) at CD idx 4: (x,y)= (8.000000,16.000000)
    Best fit AB idx 9 (x,y)= (9.000000,18.000000) at CD idx 4: (x,y)= (8.000000,16.000000)



  • Du hast einen Vector mit Äpfeln und einen mit Birnen. Und jetzt willst du einen Apfel an den Birnenvector hängen?



  • @manni66 Ich wollte jetzt nicht einen zu großen Text schreiben mit warum wieso weshalb. Ich habe deshalb versucht die Erklärung und den Code so kurz wie möglich zu halten.
    Versteht man nicht was ich will? Soll ich ein Beispiel schreiben wie ich es mir vorstelle?



  • Entweder du machst in der XY-struct noch Platz für Z oder du machst einen extra Vector, nur mit Z Koordinaten.


  • Mod

    DirkB schrieb:

    Entweder du machst in der XY-struct noch Platz für Z oder du machst einen extra Vector, nur mit Z Koordinaten.

    Oder er macht einen vector<Obst>, um bei manni66s Analogie zu bleiben.



  • Wenn Dir die Laufzeit nicht egal ist, dann würde ich die XYZ Daten im Vector speziell sortieren und durch die Reihenfolge implizit einen 2D KD-Baum aufbauen (nach X und Y). Die Split-Ebenen kann man in einem zweiten Vektor vom Typ vector<double> derselben Länge halten. Das Sortieren des XYZ-Vektors kann man per std::nth_element machen und damit die Menge der Datenpunkte immer genau halbieren. Den nächsten Nachbarn findest Du dann über eine rekursive Funktion, die zunächst die Hälfte besucht, die näher dran ist und dann ggf die andere Hälfte durchsucht, falls da überhaupt ein näherer Kandidat drin sein kann. Meist kann man sich das Durchsuchen der 2. Hälfte sparen innerhalb eines Rekursionsaufrufs, so dass der ganze Suchaufwand in logarithmischer Zeit läuft.

    Oft ist auch x*x schneller als pow(x,2) . Ich würde mir eine square -Funktion basteln und das mal testen.

    Eine Nearest-Neighbour-Suche in einem KD-Baum ist auch nicht sooo schwer.

    So würde ich's jedenfalls machen. Die Lösung ist aber etwas komplizierter aufzuschreiben, als das, was Du bisher hast.



  • Danke für eure Antworten. Ich werde es mit einem neuen Vector nur mit z Koordinaten probieren.

    @krümelkacker Danke das du dir so viele Gedanken zum Thema gemacht hast, aber ich besitze nur die Basics in C++ und dein Vorschlag überschreitet meine Fähigkeiten. Aber die Funktion std::nth_element sieht recht praktisch aus. Diese werde ich mir bei gegebener Zeit nochmal anschauen.


Log in to reply