📄 vektor.cc
字号:
} else if (x < Min[Index]) { MinNummer[Index] = Vektor; Min[Index] = x; } else if ((*Daten[Vektor])[Index] == Max[Index]) { /* War das Max ? */ if (x < Max[Index]) { /* neues Max aus allen suchen */ Max[Index] = -MAXDOUBLE; for (i = 0; i < Groesse; i++) if ((*Daten[i])[Index] > Max[Index]) { MaxNummer[Index] = i; Max[Index] = (*Daten[i])[Index]; } } } else if ((*Daten[Vektor])[Index] == Min[Index]) { /* War das Min ? */ if (x > Min[Index]) { /* neues Max aus allen suchen */ Min[Index] = MAXDOUBLE; for (i = 0; i < Groesse; i++) if ((*Daten[i])[Index] < Min[Index]) { MinNummer[Index] = i; Min[Index] = (*Daten[i])[Index]; } } }/*****************************************/ /* neuen Wert einsetzen *//*****************************************/ (*Daten[Vektor])[Index] = x;};void DVektorArray::Aktualisiere_Min_etc (){ int i, DatenNr; Durchschnitt.Setze_Dim (VektorDimension); Min.Setze_Dim (VektorDimension); Max.Setze_Dim (VektorDimension); MinNummer.Setze_Dim (VektorDimension); MaxNummer.Setze_Dim (VektorDimension); MinNummer = 0; MaxNummer = 0; if (Groesse != 0) { /* es gibt was zu tun */ Durchschnitt = (*Daten[0]); Max = *Daten[0]; Min = *Daten[0]; for (DatenNr = 1; DatenNr < Groesse; DatenNr++) { Durchschnitt += (*Daten[DatenNr]); for (i = 0; i < VektorDimension; i++) { if ((*Daten[DatenNr])[i] > Max[i]) { Max[i] = (*Daten[DatenNr])[i]; MaxNummer[i] = DatenNr; } if ((*Daten[DatenNr])[i] < Min[i]) { Min[i] = (*Daten[DatenNr])[i]; MinNummer[i] = DatenNr; } } } Durchschnitt /= Groesse; }};void DVektorArray::Quicksort (int a, int b, int Index){ int r, i, j; double x; DVektor *VBuffer; if (b > a) { i = a; j = b; /* Waehle r einmal in der Mitte */ r = (a + b) / 2; x = Daten[r]->Lese_i (Index); do { while (Daten[i]->Lese_i (Index) < x) i++; while (Daten[j]->Lese_i (Index) > x) j--; if (i <= j) { VBuffer = Daten[i]; Daten[i] = Daten[j]; Daten[j] = VBuffer; i++; j--; } } while (j >= i); Quicksort (a, j, Index); Quicksort (i, b, Index); }};void DVektorArray::print (){ int i; for (i = 0; i < Groesse; i++)#if 0 Daten[i].print ();#else Daten[i]->print ();#endif};void DVektorArray::print (int Anfang, int Ende){ int i; if ((Anfang <= Ende) && (Anfang >= 0) && (Ende < Groesse)) for (i = Anfang; i <= Ende; i++) Daten[i]->print ();};void DVektorArray::Tausche (DVektorArray & Damit){ DVektor **dBuffer; int i; dBuffer = Damit.Daten; Damit.Daten = Daten; Daten = dBuffer; i = Damit.VektorDimension; Damit.VektorDimension = VektorDimension; VektorDimension = i; i = Damit.Groesse; Damit.Groesse = Groesse; Groesse = i; Durchschnitt.Tausche (Damit.Durchschnitt); Min.Tausche (Damit.Min); Max.Tausche (Damit.Max); MinNummer.Tausche (Damit.MinNummer); MaxNummer.Tausche (Damit.MaxNummer);};void DVektorArray::neuer_Zufallspunkt (){ int i; DVektor Buffer (VektorDimension, 0, NULL); for (i = 0; i < VektorDimension; i++) { Buffer[i] = Lese_Min (i) + ((double) rand () / (double) MAXINT) * (Lese_Max (i) - Lese_Min (i)); } (*this) += Buffer;};DVektorArray DVektorArray::Mache_Konvex ()return Result;{ Result = this.Mache_Konvex (1, 0);};DVektorArray DVektorArray::Mache_Konvex (int Index, double Untergrenze)return Result;{ int i, j, k, Mitte; double Hoehe; BVektor Diese (Groesse, NULL), Loescher (Groesse, NULL); /* von links bis zum Maximum */ Hoehe = 0; Mitte = 0; for (i = 0; i < Groesse; i++) { if ((Daten[i]->Lese_i (Index) >= Hoehe) && (Daten[i]->Lese_i (Index) >= Untergrenze)) { Diese.Setze_i (i, TRUE); Hoehe = Daten[i]->Lese_i (Index); Mitte = i; } } /* von rechts bis zum Maximum */ Hoehe = 0; for (i = Groesse - 1; i > Mitte; i--) { if ((Daten[i]->Lese_i (Index) >= Hoehe) && (Daten[i]->Lese_i (Index) >= Untergrenze)) { Diese.Setze_i (i, TRUE); Hoehe = Daten[i]->Lese_i (Index); } } /* doppelte x-Positionen loeschen */ for (i = 0; i < Diese.Anzahl_gesetzt () - 1;) { if (Daten[Diese.Lese_gesetzte (i)]->Lese_i (0) == Daten[Diese.Lese_gesetzte (i + 1)]->Lese_i (0)) Diese.Setze_i (Diese.Lese_gesetzte (i + 1), FALSE); else i++; } /* 3-fache gleiche y-Werte loeschen */ Loescher = TRUE; for (i = 0; i < Diese.Anzahl_gesetzt (); i = j) { Hoehe = Daten[Diese.Lese_gesetzte (i)]->Lese_i (1); for (j = i + 1; j < Diese.Anzahl_gesetzt (); j++) { if (Hoehe != Daten[Diese.Lese_gesetzte (j)]->Lese_i (1)) break; } /* Die dazwischen loeschen */ for (k = i + 1; k < j - 1; k++) Loescher.Setze_i (Diese.Lese_gesetzte (k), FALSE); } Diese = Diese & Loescher; /* jetzt die gefundenen Daten uebernehmen */ Result.DVektorArray (2, Diese.Anzahl_gesetzt (), NULL); for (i = 0; i < Diese.Anzahl_gesetzt (); i++) { Result.Setze_Vektor (i, 0, Daten[Diese.Lese_gesetzte (i)]->Lese_i (0)); Result.Setze_Vektor (i, 1, Daten[Diese.Lese_gesetzte (i)]->Lese_i (Index)); }};IVektor *DVektorArray::Finde_Huegel (DVektor & Y, int &soviel, double Huegel_Grenze, int Naeher_erlaubt, double Winkel_Cosinus){ IVektor in_Huegel (Groesse, NULL); IVektor *Result; DVektor Abstand (Groesse, 0, NULL), Gerade1 (VektorDimension, 0, NULL), Gerade2 (VektorDimension, 0, NULL); int i = 0, j, k, Gruppe, aktuelleGruppe, Buffer, naeher, zugeordnet, Der = 0; char vorhanden, groessere; double Hoehe, DBuffer;/********************************************************//* Zunaechst Zugehoerigkeiten oberhalb Grenze bestimmen *//********************************************************/ Gruppe = 1; for (i = 0; i < Groesse; i++) { /* alle Punkte untersuchen */ if (Y[i] >= Huegel_Grenze) { /* ueber Grenze, dann alle in anderen Gruppen suchen */ /* zunaechst Abstaende berechnen */ for (j = 0; j < Groesse; j++) Abstand[j] = Daten[i]->Abstand (*(Daten[j])); if (in_Huegel.Lese_i (i) != 0) aktuelleGruppe = in_Huegel[i]; else aktuelleGruppe = Gruppe++; for (j = 0; j < Groesse; j++) { /* mit jedem anderen testen */ if ((in_Huegel.Lese_i (j) != aktuelleGruppe) && (j != i) && (Y[j] >= Huegel_Grenze)) { /* mit allen anderen testen, die nicht schon in selber Gruppe */ Gerade1 = (*(Daten[i])) - (*(Daten[j])); naeher = 0; for (k = 0; (k < Groesse) && (naeher <= Naeher_erlaubt); k++) { /* pruefen, ob unter den uebrigen naehere */ if ((k != i) && (k != j) && (in_Huegel[k] != aktuelleGruppe) && (Abstand[k] < Abstand[j])) { Gerade2 = (*(Daten[i])) - (*(Daten[k])); if (Gerade1.cos_Winkel (Gerade2) >= Winkel_Cosinus) { /* naeher und in aehnlicher Richtung */ if (Y[k] >= Huegel_Grenze) { naeher = MAXINT; break; } else { naeher++; } } } } if (naeher <= Naeher_erlaubt) { if (in_Huegel[j] == 0) in_Huegel[j] = aktuelleGruppe; else { /* alle der gefundenen Gruppen umnennen */ Buffer = in_Huegel[j]; for (k = 0; k < Groesse; k++) if (in_Huegel[k] == aktuelleGruppe) in_Huegel[k] = Buffer; aktuelleGruppe = Buffer; } } } } in_Huegel[i] = aktuelleGruppe; } /* if(Y[i] >= Huegel_Grenze) */ }/***************************************************//*** testen wieviele Huegel und durchnummerieren ***/ for (i = 0, soviel = 1; i < Groesse; i++) { k = 0; vorhanden = groessere = FALSE; for (j = 0; j < Groesse; j++) { if (in_Huegel.Lese_i (j) == soviel) vorhanden = TRUE; if (in_Huegel.Lese_i (j) > soviel) { groessere = TRUE; k = in_Huegel.Lese_i (j); } } /* irgendeinen hoeheren umbenennen */ if (vorhanden) soviel += 1; else { if (groessere) { /* Groesseren umbenennen */ for (j = 0; j < Groesse; j++) { if (in_Huegel[j] == k) in_Huegel[j] = soviel; } soviel += 1; } else { soviel -= 1; break; /* fertig */ } } }/*********************************************//* jetzt noch die unter der Grenzen zuordnen *//*********************************************/ /* zu welchem Huegel am naechsten */ zugeordnet = 0; for (i = 0; i < Groesse; i++) if (in_Huegel[i] != 0) zugeordnet += 1; while (zugeordnet != Groesse) { Hoehe = 0; /* zunaechst den hoechsten davon finden */ for (i = 0; i < Groesse; i++) if ((Y[i] > Hoehe) && (in_Huegel[i] == 0)) { Der = i; /* Der hoechste */ Hoehe = Y[i]; } /* worein damit ? */ Hoehe = MAXDOUBLE; for (i = 0; i < Groesse; i++) { if (in_Huegel[i] != 0) {#if 0 DBuffer = Daten[Der].Abstand (*(Daten[i]));#else DBuffer = Daten[Der]->Abstand (*(Daten[i]));#endif if (DBuffer < Hoehe) { Gruppe = in_Huegel[i]; Hoehe = DBuffer; } } } in_Huegel.Setze_i (Der, Gruppe); zugeordnet++; }/**********************************//* zum Schluss die Huegel basteln *//**********************************/ if (soviel != 0) { if ((Result = (IVektor *) malloc (sizeof (IVektor) * soviel)) == NULL) Fehlermeldung ("IVektor *DVektorArray::Finde_Huegel(...)", SPEICHERFEHLER); } else Result = NULL; for (i = 0; i < soviel; i++) { zugeordnet = 0; for (j = 0; j < Groesse; j++) { if (in_Huegel[j] == (i + 1)) zugeordnet += 1; } Result[i].IVektor (zugeordnet, NULL); Der = 0; for (k = 0; k < Groesse; k++) { if (in_Huegel[k] == (i + 1)) { Result[i][Der] = k; Der += 1; } } } return (Result);};/**************************************************************//* Separates Suchen in den einzelnen Dimensionen nacheinander *//**************************************************************/IVektor *DVektorArray::Finde_Huegel (DVektor & Y, int &soviele, double Huegel_Grenze, int Naeher_erlaubt){ int i = 0, j, k, Dim, Der = 0, aktueller_Huegel, dazwischen, rechts, links, Max_Index = 0; double Max; BVektor Huegel (Groesse, NULL); BVektorArray in_Huegel (Groesse, 1, NULL), Huegel_Ergebnis (Groesse, 1, NULL); IVektor *Result; DVektorArray Arbeits_Y (VektorDimension + 1, Groesse, NULL);/* Initialisierungen */ Huegel_Ergebnis = TRUE; for (i = 0; i < Groesse; i++) { for (j = 0; j < VektorDimension; j++) Arbeits_Y[i][j] = (*(Daten[i]))[j]; Arbeits_Y[i][VektorDimension] = Y[i]; Arbeits_Y[i].Setze_Nummer (i); /* sozusagen der Index */ }/* Los geht's */ for (Dim = 0; Dim < VektorDimension; Dim++) { links = 0; rechts = 0; Arbeits_Y = Arbeits_Y.Quicksort (Dim); aktueller_Huegel = 0; dazwischen = 0; in_Huegel.Setze_Groesse (1); in_Huegel[0] = FALSE; /* zunaechst vor dem ersten Huegel suchen */ for (i = 0; i < Groesse; i++) { /* Der Anfang */ in_Huegel[0].Setze_i (Arbeits_Y[i].Lese_Nummer (), TRUE); if (Arbeits_Y[i][VektorDimension] >= Huegel_Grenze) { i++; break; } } for (; i < Groesse; i++) { if (Arbeits_Y[i][VektorDimension] >= Huegel_Grenze) { if (dazwischen < Naeher_erlaubt) { /* bis hierher Luecke in Huegel fuellen */ for (; dazwischen != -1; dazwischen--) in_Huegel[aktueller_Huegel].Setze_i (Arbeits_Y[i - dazwischen].Lese_Nummer (), TRUE); links = i; } else { /* neuen Huegel beginnen */ in_Huegel++; in_Huegel[aktueller_Huegel + 1].Setze_i (Arbeits_Y[i].Lese_Nummer (), TRUE); rechts = i; /* jetzt dazwischen entscheiden */ dazwischen = rechts - links - 1; while (dazwischen) { Max = -1.0; /* Zunaechst den hoechsten ermitteln */ for (j = links + 1; j < rechts; j++) { if ((Arbeits_Y[j][VektorDimension] >= Max) && (!in_Huegel[aktueller_Huegel][Arbeits_Y[j].Lese_Nummer ()]) && (!in_Huegel[aktueller_Huegel + 1][Arbeits_Y[j].Lese_Nummer ()])) { /* ddie groesste Zugehoerigkeit finden */ Max = Arbeits_Y[j][VektorDimension]; Max_Index = j; } } /* und zuordnen */ if (Arbeits_Y[Max_Index][Dim] == Arbeits_Y[links][Dim]) { for (k = links + 1; k <= Max_Index; k++) in_Huegel[aktueller_Huegel].Setze_i (Arbeits_Y[k].Lese_Nummer (), TRUE); dazwischen -= Max_Index - links; links = Max_Index; } else if (Arbeits_Y[Max_Index][Dim] == Arbeits_Y[rechts][Dim]) { /* zum rechten Huegel zuordnen */ for (k = Max_Index; k < rechts; k++) in_Huegel[aktueller_Huegel + 1].Setze_i (Arbeits_Y[k].Lese_Nummer (), TRUE); dazwischen -= rechts - Max_Index; rechts = Max_Index; } else if (((Arbeits_Y[links][VektorDimension] - Arbeits_Y[Max_Index][VektorDimension]) / (Arbeits_Y[Max_Index][Dim] - Arbeits_Y[links][Dim])) >= ((Arbeits_Y[rechts][VektorDimension] - Arbeits_Y[Max_Index][VektorDimension]) / (Arbeits_Y[rechts][Dim] - Arbeits_Y[Max_Index][Dim]))) { /* bis zum Rand dem linken Huegel zuordnen */ for (k = links + 1; k <= Max_Index; k++) in_Huegel[aktueller_Huegel].Setze_i (Arbeits_Y[k].Lese_Nummer (), TRUE); dazwischen -= Max_Index - links; links = Max_Index; } else { /* zum rechten Huegel zuordnen */ for (k = Max_Index; k < rechts; k++) in_Huegel[aktueller_Huegel + 1].Setze_i (Arbeits_Y[k].Lese_Nummer (), TRUE); dazwischen -= rechts - Max_Index; rechts = Max_Index; } } aktueller_Huegel++; } dazwischen = 0; } else dazwischen++; } /* jetzt rechts vom letzten Huegel auffuellen */ if (dazwischen != 0) { for (i = Groesse - dazwischen - 1; i < Groesse; i++) { in_Huegel[aktueller_Huegel].Setze_i (Arbeits_Y[i].Lese_Nummer (), TRUE); } } /* jetzt mit den bisherigen Ergebnissen schneiden */ int Anzahl; Anzahl = Huegel_Ergebnis.Lese_Groesse (); for (i = 0; i < Anzahl; i++) { for (j = 0; j < in_Huegel.Lese_Groesse (); j++) { Huegel = Huegel_Ergebnis[i] & in_Huegel[j]; for (k = 0; k < in_Huegel.Lese_Dim (); k++) { if (Huegel[Arbeits_Y[k].Lese_Nummer ()]) { if (Arbeits_Y[k][VektorDimension] >= Huegel_Grenze) { Huegel_Ergebnis += Huegel; break; } } } } } /* jetzt die unterteilten loeschen */ Huegel_Ergebnis.Loesche (0, Anzahl - 1); }/**********************************//* zum Schluss die Huegel basteln *//**********************************/ soviele = Huegel_Ergebnis.Lese_Groesse (); if (Huegel_Ergebnis.Lese_Groesse () != 0) { if ((Result = (IVektor *) malloc (sizeof (IVektor) * Huegel_Ergebnis.Lese_Groesse ())) == NULL) Fehlermeldung ("IVektor *DVektorArray::Finde_Huegel(...)", SPEICHERFEHLER); } else Result = NULL; for (i = 0; i < Huegel_Ergebnis.Lese_Groesse (); i++) { Result[i].IVektor (Huegel_Ergebnis[i].Anzahl_gesetzt (), NULL); Der = 0; for (j = 0; j < Groesse; j++) { if (Huegel_Ergebnis[i][j]) { Result[i][Der] = j; Der += 1; } } } return (Result);}void DVektorArray::operator= (const DVektorArray & Das){ int i; if ((Groesse != Das.Groesse) || (VektorDimension != Das.VektorDimension)) {#if 0 this. ~ DVektorArray ();#else this-> ~ DVektorArray ();#endif Groesse = Das.Groesse; VektorDimension = Das.VektorDimension; if (Groesse != 0) { if ((Daten = (DVektor **) malloc (sizeof (DVektor *) * Groesse)) == NULL) Fehlermeldung ("void DVektorArray::operator=(DVektorArray *Das)", SPEICHERFEHLER); for (i = 0; i < Groesse; i++) Daten[i] = new DVektor (*(Das.Daten[i])); } else Daten = NULL; } else { for (i = 0; i < Groesse; i++) (*(Daten[i])) = *(Das.Daten[i]); } Min = Das.Min; Max = Das.Max; MinNummer = Das.MinNummer; MaxNummer = Das.MaxNummer; Durchschnitt = Das.Durchschnitt;};void DVektorArray::operator+= (const DVektor & Damit){ int i; DVektor **DatenBuffer; if ((VektorDimension != Damit.Lese_Dim ()) && (Groesse != 0)) Fehlermeldung ("DVektorArray::operator+=", DIMFEHLER); VektorDimension = Damit.Lese_Dim (); if ((DatenBuffer = (DVektor **) malloc (sizeof (DVektor *) * (Groesse + 1))) == NULL) Fehlermeldung ("DVektorArray::operator+=", SPEICHERFEHLER); for (i = 0; i < Groesse; i++) DatenBuffer[i] = Daten[i]; free (Daten); DatenBuffer[Groesse] = new DVektor (Damit); if (Groesse == 0) { Max.DVektor (Damit); Min.DVektor (Damit); Durchschnitt.DVektor (Damit); MaxNummer.IVektor (VektorDimension, NULL); MinNummer.IVektor (VektorDimension, NULL); } else { for (i = 0; i < VektorDimension; i++) { if (Damit[i] > Max[i]) { /* neues Maximum */ Max[i] = Damit[i]; MaxNummer[i] = Groesse; } if (Damit[i] < Min[i]) { /* neues Minimum */ Min[i] = Damit[i]; MinNummer[i] = Groesse; } Durchschnitt[i] = (Durchschnitt[i] * Groesse + Damit[i]) / (Groesse + 1); } } Groesse++; Daten = DatenBuffer;};void DVektorArray::operator-= (DVektor & Damit){ int i, j, Das = 0; DVektor **DatenBuffer; if (VektorDimension != Damit.Lese_Dim ()) Fehlermeldung ("DVektorArray::operator-=", DIMFEHLER); if ((DatenBuffer = (DVektor **) malloc (sizeof (DVektor *) * (Groesse - 1))) == NULL) Fehlermeldung ("DVektorArray::operator+=", SPEICHERFEHLER); j = 0; for (i = 0; i < Groesse; i++) { if (Daten[i] != &Damit) { /* Der is es nicht */ DatenBuffer[j++] = Daten[i]; } else Das = i; /* Merken */ } Groesse--; /* Jetzt Durchschnitt etc. neu berechnen */ if (Groesse == 0) { for (i = 0; i < VektorDimension; i++) { Max[i] = -MAXDOUBLE; MaxNummer[i] = 0; Min[i] = MAXDOUBLE; MinNummer[i] = 0; Durchschnitt[i] = 0; } } else { /* Groesse != 0 */ for (i = 0; i < VektorDimension; i++) { if (Damit[i] == Max[i]) { /* war das alte Maximum -> neues Maximum finden */ Max[i] = -MAXDOUBLE; for (j = 0; j < Groesse; j++) { if ((*Daten[j])[i] > Max[i]) { Max[i] = Damit[i]; MaxNummer[i] = j; } } } if (Damit[i] == Min[i]) { /* war das alte Minimum -> neues Minimum finden */ Min[i] = MAXDOUBLE; for (j = 0; j < Groesse; j++) { if ((*Daten[j])[i] < Min[i]) { Min[i] = Damit[i]; MinNummer[i] = j; } } } Durchschnitt[i] = (Durchschnitt[i] * (Groesse + 1) - (*Daten[Das])[i]) / Groesse; } } delete Daten[Das]; free (Daten); Daten = DatenBuffer;};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -