Ich habe angefangen, den Code auszuprobieren und ein künstliches Beispiel erstellt - das Array ausgefüllt
Ich hab's:
Das heißt, wir haben eine Variante, aber wir erwarten auch eine andere Variante.
Kann der Algorithmus lernen, sie auch zu finden?
Und die Variante "0-1 3-6 7-9" ist nicht besser als die Variante "0 - 0-1 2-5 7-9" - beide gehen von 0 bis 1 und haben jeweils 2 Auslassungen der Länge 1.
In diesem Fall gibt es zwei Möglichkeiten:
1 - machen Sie dasselbe, aber ab dem Ende des Satzes von Überspringen.
2 - suchen Sie nicht gleich nach dem nächstgelegenen Segment, sondern mit einer Toleranz. Aber in diesem Fall werden es noch mehr sein, wenn es viele Daten und viele Andocksequenzen gibt.
Nach Variante 1 werden Sie jedoch damit beginnen wollen, Ketten aus allen möglichen Ausgangspositionen zu bilden. Das ist richtig, aber der Arbeitsaufwand für den Algorithmus steigt dadurch erheblich.
Ja! Es ist notwendig, die Konstruktion von Varianten von jedem der Segmente der Ausgangsmenge aus zu beginnen und die Konstruktion bis zum Anfang und Ende fortzusetzen.
Und die Option "0-1 3-6 7-9" ist nicht besser als die Option "0 - 0-1 2-5 7-9" - beide gehen von 0 bis 1 und haben jeweils 2 Auslassungen der Länge 1.
In diesem Fall sind sie gleich, da stimme ich zu, aber sie sind unterschiedlich, und gemäß der Aufgabenstellung müssen wir die Summe ihrer Punkte schätzen, und bis wir eine Linie bilden, werden wir die kombinierte Punktzahl aller Segmente nicht kennen.
Dmitry Fedoseev:
Nach Option 1 besteht jedoch der Wunsch, mit der Konstruktion von Zeichenketten von allen möglichen Ausgangspositionen aus zu beginnen. Das ist richtig, aber der Arbeitsaufwand für den Algorithmus steigt dadurch erheblich.
Ja! Es ist notwendig, die Konstruktion von Varianten von jedem der Segmente der Ausgangsmenge aus zu beginnen und die Konstruktion bis zum Anfang und Ende fortzusetzen.
Das scheint mir auch die richtigere Strategie zu sein! Ich denke jedoch, dass es möglicherweise doppelte Varianten gibt.
Können Sie helfen, indem Sie einen Code schreiben?
struct SAllVariants{
int m_cut[][2];
int len;
int m_cut1[][2]; // к концуint len1;
int li1;
int m_cut2[][2]; // с началуint len2;
int li2;
bool isDopel;
void Init(int aLen){
ArrayResize(m_cut1,aLen);
len1=0;
ArrayResize(m_cut2,aLen);
len2=0;
}
void AddCut1(int & a[][2],int i){
m_cut1[len1][0]=a[i][0];
m_cut1[len1][1]=a[i][1];
len1++;
li1=i;
}
void AddCut2(int & a[][2],int i){
m_cut2[len2][0]=a[i][0];
m_cut2[len2][1]=a[i][1];
len2++;
li2=i;
}
void Set(SAllVariants & a){
len1=a.len1;
li1=a.li1;
for(int i=0;i<len1;i++){
m_cut1[i][0]=a.m_cut1[i][0];
m_cut1[i][1]=a.m_cut1[i][1];
}
len2=a.len2;
li2=a.li2;
for(int i=0;i<len2;i++){
m_cut2[i][0]=a.m_cut2[i][0];
m_cut2[i][1]=a.m_cut2[i][1];
}
}
bool Eq(SAllVariants & a){
if(len1!=a.len1 || len2!=a.len2){
return(false);
}
for(int i=0;i<len1;i++){
if(m_cut1[i][0]!= a.m_cut1[i][0] || m_cut1[i][1]!= a.m_cut1[i][1]){
return(false);
}
}
for(int i=0;i<len2;i++){
if(m_cut2[i][0]!= a.m_cut2[i][0] || m_cut2[i][1]!= a.m_cut2[i][1]){
return(false);
}
}
return(true);
}
void Combine(){
len=len1+len2-1;
ArrayResize(m_cut,len);
int j=0;
for(int i=len2-1;i>0;i--){
m_cut[j][0]=m_cut2[i][0];
m_cut[j][1]=m_cut2[i][1];
j++;
}
for(int i=0;i<len1;i++){
m_cut[j][0]=m_cut1[i][0];
m_cut[j][1]=m_cut1[i][1];
j++;
}
}
};
SAllVariants av[];
int cut[][2];
voidOnStart(){
Print("=============================================================");
// заполняем массив сотней каких-нибудь отрезков
FillArray(cut,100);
//=== алгоритм ====================// поправить все отрезки, чтобы первая координата была меньше второй int itmp;
for(int i=0;i<ArrayRange(cut,0);i++){
if(cut[i][0]>cut[i][1]){
itmp=cut[i][0];
cut[i][0]=cut[i][1];
cut[i][1]=itmp;
}
}
// сортировка массива по первой координатеArraySort(cut);
ArrayPrint(cut);
// удалить отрезки нулевой длины и повтряющиеся отрезкиbool ex;
int ti=0;
for(int i=0;i<ArrayRange(cut,0);i++){
if(cut[i][0]!=cut[i][1]){
ex=false;
for(int j=i-1;j>=0 && cut[j][0]==cut[i][0];j--){
if(cut[j][0]==cut[i][0] && cut[j][1]==cut[i][1]){
ex=true;
break;
}
}
if(!ex){
cut[ti][0]=cut[i][0];
cut[ti][1]=cut[i][1];
ti++;
}
}
}
ArrayResize(cut,ti);
// добавить каждый отрезок в массив всех вариантовArrayResize(av,ArrayRange(cut,0));
for(int i=0;i<ArrayRange(cut,0);i++){
av[i].Init(ArrayRange(cut,0));
av[i].AddCut1(cut,i); // в массив, идущий к концу
av[i].AddCut2(cut,i); // в массив, идущий к началу
}
// а теперь самое интересное// к концуdouble r;
bool n;
for(int i=0;i<ArraySize(av) && !IsStopped();i++){ // для каждого варианта// найти ближайшее расстояние до следующего отрезка
r=DBL_MAX;
for(int j=av[i].li1+1;j<ArrayRange(cut,0);j++){
if(cut[j][0]>=av[i].m_cut1[av[i].len1-1][1]){
r=MathMin(r,cut[j][0]-av[i].m_cut1[av[i].len1-1][1]); // потому что допускаются пропуски (важнее составить ряд, чем чтобы он был непрерывным)
}
}
if(r!=DBL_MAX){
n=false;
for(int j=av[i].li1+1;j<ArrayRange(cut,0);j++){
if(cut[j][0]-av[i].m_cut1[av[i].len1-1][1]==r){
if(!n){
n=true;
av[i].AddCut1(cut,j);
}
else{
ArrayResize(av,ArraySize(av)+1);
av[ArraySize(av)-1].Init(ArrayRange(cut,0));
av[ArraySize(av)-1].Set(av[i]);
av[ArraySize(av)-1].AddCut1(cut,j);
}
}
}
if(n){
i--;
}
}
}
// к началуfor(int i=0;i<ArraySize(av) && !IsStopped();i++){ // для каждого варианта// найти ближайшее расстояние до следующего отрезка
r=DBL_MAX;
for(int j=av[i].li2-1;j>=0;j--){
if(cut[j][1]<=av[i].m_cut2[av[i].len2-1][0]){
r=MathMin(r,av[i].m_cut2[av[i].len2-1][0]-cut[j][1]); // потому что допускаются пропуски (важнее составить ряд, чем чтобы он был непрерывным)
}
}
if(r!=DBL_MAX){
n=false;
for(int j=av[i].li2-1;j>=0;j--){
if(av[i].m_cut2[av[i].len2-1][0]-cut[j][1]==r){
if(!n){
n=true;
av[i].AddCut2(cut,j);
}
else{
ArrayResize(av,ArraySize(av)+1);
av[ArraySize(av)-1].Init(ArrayRange(cut,0));
av[ArraySize(av)-1].Set(av[i]);
av[ArraySize(av)-1].AddCut2(cut,j);
}
}
}
if(n){
i--;
}
}
}
// пометить дублиfor(int i=0;i<ArraySize(av);i++){
av[i].isDopel=false;
for(int j=0;j<i;j++){
if(av[i].Eq(av[j])){
av[i].isDopel=true;
break;
}
}
}
// соединить два массива в 1for(int i=0;i<ArraySize(av);i++){
if(!av[i].isDopel){
av[i].Combine();
}
}
// выводint h=FileOpen("Выстраивание отрезков.txt",FILE_TXT|FILE_WRITE);
for(int i=0;i<ArrayRange(cut,0);i++){
FileWrite(h,(string)cut[i][0]+"-"+(string)cut[i][1]);
}
FileWrite(h,"");
string str="";
int vn=0;
for(int i=0;i<ArraySize(av) && !IsStopped();i++){
if(!av[i].isDopel){
str="";
for(int j=0;j<av[i].len;j++){
str=str+(string)av[i].m_cut[j][0]+"-"+(string)av[i].m_cut[j][1]+" ";
}
Print("Вариант ",vn," - ",str);
FileWrite(h,"Вариант ",vn," - ",str);
vn++;
}
}
FileClose(h);
}
//+------------------------------------------------------------------+void FillArray(int & a[][2],int cutCnt){
ArrayResize(a,cutCnt);
for(int i=0;i<cutCnt;i++){
a[i][0]=MathRand()%30;
a[i][1]=a[i][0]+MathRand()%15;
}
}
Da jede Variante die Segmente nun in zwei Arrays speichert, können diese der Einfachheit halber mit der MethodeCombine() zu einem Array zusammengefasst werden.
Da nun jede Variante die Segmente in zwei Arrays speichert, kann man sie mit der MethodeCombine() zu einem Array zusammenfassen, um es bequemer zu machen.
Dmitry, vielen Dank für den neuen Algorithmus!
Ja, es gibt in der Tat sehr viele Kopien.
2021.04.2216:55:43.829 Q_Podbor_02 (Si-6.21,M1) Вариант 0 - 0-12-57-92021.04.2216:55:43.829 Q_Podbor_02 (Si-6.21,M1) Вариант 1 - 0-12-57-92021.04.2216:55:43.829 Q_Podbor_02 (Si-6.21,M1) Вариант 2 - 0-13-67-92021.04.2216:55:43.829 Q_Podbor_02 (Si-6.21,M1) Вариант 3 - 0-13-67-9
So wie ich es verstehe, können sie nicht gezählt werden. Ich hatte es nicht geschafft, auf die Kombination von 1000 Elementen zu warten - meinem Netbook ging der Speicher aus :(
Und ist es möglich, beim Hinzufügen eines Segments nicht alle Kombinationen zu verwenden, sondern nur eine bestimmte Anzahl von möglichen im aktuellen Schritt, z. B. die besten 10?
Soweit ich weiß, kann man sie nicht zählen. Ich konnte die Kombination von 1000 Elementen nicht abwarten - meinem Netbook ging der Speicher aus :(
Ist es möglich, beim Hinzufügen eines Segments nicht alle Kombinationen zu verwenden, sondern nur eine bestimmte Anzahl von möglichen im aktuellen Schritt, z. B. die besten 10?
Um zu wissen, dass sie die besten sind, muss man sie mit anderen vergleichen, d. h. man muss sie erst einmal alle haben. Eine andere Sache ist, den Algorithmus irgendwie zu optimieren, aber ich habe nicht das Ziel, mein Leben diesem Algorithmus zu widmen).
Vielleicht entscheiden Sie sich für das Kriterium der Suffizienz und erhalten zunächst alle Optionen, ausgehend von nur einem Segment, das zufällig ausgewählt wird, und so weiter, bis eine zufriedenstellende Option erscheint.
Und die zweite Option kann beschleunigt werden - um das Array mit Varianten nicht ein Element zu einer Zeit, sondern mehrere Dutzend Elemente auf einmal zu skalieren, und am Ende zu trimmen es.
Um zu wissen, dass sie die besten sind, muss man sie mit anderen vergleichen, d. h. man muss sie erst einmal alle haben. Eine andere Sache ist, den Algorithmus irgendwie zu optimieren, aber ich habe nicht das Ziel, mein Leben diesem Algorithmus zu widmen).
Ich spreche über ein einzelnes Segment, sagen wir, es hat einen Koeffizienten, um seine Qualität zu bewerten, dann verzweigen wir nach jeder Iteration, zum Beispiel, nur auf die Top 10 dieser Koeffizienten.
Dmitry Fedoseev:
Vielleicht entscheiden Sie sich für ein Suffizienzkriterium und erhalten zunächst alle Varianten, ausgehend von nur einem Segment, das zufällig ausgewählt wird, und so weiter, bis eine zufriedenstellende Variante erscheint.
Leider ist die "Hinlänglichkeit" hier schwer einzuschätzen - dazu muss man eine Norm kennen, dann kann man daraus eine Toleranz definieren, und ich habe keine Norm.
Dmitry Fedoseev:
Und die zweite Option kann beschleunigt werden - zu skalieren Array mit Optionen nicht ein Element zu einer Zeit, aber mehrere Dutzend Elemente, und am Ende der es auszurichten.
Ich bin mir nicht ganz sicher, was Sie mit der Parallelisierung mit OpenCL meinen?
1. Ich spreche von einem einzelnen Segment, sagen wir, es hat einen Koeffizienten, um seine Qualität zu bewerten, dann verzweigen wir nach jeder Iteration zum Beispiel nur zu den Top 10 dieser Koeffizienten.
2. Leider lässt sich die "Hinlänglichkeit" hier nur schwer einschätzen - man muss die Benchmark kennen, dann kann man daraus die Toleranz bestimmen, und ich habe keine Benchmark.
3. ich bin mir nicht ganz sicher, was Sie mit Parallelisierung mittels OpenCL meinen?
1. wo liegt dieser Koeffizient?
2. Was ist mit Punkt 1?
3. Nein, es ist einfacher. Okay, ich werde versuchen, es morgen zu beschleunigen.
Wenn Sie kein Benutzerkonto haben, registrieren Sie sich
Erlauben Sie die Verwendung von Cookies, um sich auf der Website MQL5.com anzumelden.
Bitte aktivieren Sie die notwendige Einstellung in Ihrem Browser, da Sie sich sonst nicht einloggen können.
Sie sind angemeldet. Die Zwei-Faktor-Authentifizierung wurde deaktiviert. Richten Sie sie erneut ein und scannen Sie einen neuen QR-Code oder fahren Sie mit deaktivierter Zwei-Faktor-Authentifizierung fort.
Irgendwie...
Irgendwie...
Ich danke Ihnen! Man kann die Hand des Meisters sofort erkennen! Ich werde es morgen ausprobieren, um zu sehen, was dabei herauskommt.
Irgendwie...
Ich habe angefangen, den Code auszuprobieren und ein künstliches Beispiel erstellt - das Array ausgefüllt
Ich hab's:
Das heißt, wir haben eine Variante, aber wir erwarten auch eine andere Variante.
Ist es möglich, dem Algorithmus beizubringen, sie auch zu finden?
Ich habe angefangen, den Code auszuprobieren und ein künstliches Beispiel erstellt - das Array ausgefüllt
Ich hab's:
Das heißt, wir haben eine Variante, aber wir erwarten auch eine andere Variante.
Kann der Algorithmus lernen, sie auch zu finden?
Und die Variante "0-1 3-6 7-9" ist nicht besser als die Variante "0 - 0-1 2-5 7-9" - beide gehen von 0 bis 1 und haben jeweils 2 Auslassungen der Länge 1.
In diesem Fall gibt es zwei Möglichkeiten:
1 - machen Sie dasselbe, aber ab dem Ende des Satzes von Überspringen.
2 - suchen Sie nicht gleich nach dem nächstgelegenen Segment, sondern mit einer Toleranz. Aber in diesem Fall werden es noch mehr sein, wenn es viele Daten und viele Andocksequenzen gibt.
Nach Variante 1 werden Sie jedoch damit beginnen wollen, Ketten aus allen möglichen Ausgangspositionen zu bilden. Das ist richtig, aber der Arbeitsaufwand für den Algorithmus steigt dadurch erheblich.
Ja! Es ist notwendig, die Konstruktion von Varianten von jedem der Segmente der Ausgangsmenge aus zu beginnen und die Konstruktion bis zum Anfang und Ende fortzusetzen.
Und die Option "0-1 3-6 7-9" ist nicht besser als die Option "0 - 0-1 2-5 7-9" - beide gehen von 0 bis 1 und haben jeweils 2 Auslassungen der Länge 1.
In diesem Fall sind sie gleich, da stimme ich zu, aber sie sind unterschiedlich, und gemäß der Aufgabenstellung müssen wir die Summe ihrer Punkte schätzen, und bis wir eine Linie bilden, werden wir die kombinierte Punktzahl aller Segmente nicht kennen.
Nach Option 1 besteht jedoch der Wunsch, mit der Konstruktion von Zeichenketten von allen möglichen Ausgangspositionen aus zu beginnen. Das ist richtig, aber der Arbeitsaufwand für den Algorithmus steigt dadurch erheblich.
Ja! Es ist notwendig, die Konstruktion von Varianten von jedem der Segmente der Ausgangsmenge aus zu beginnen und die Konstruktion bis zum Anfang und Ende fortzusetzen.
Das scheint mir auch die richtigere Strategie zu sein! Ich denke jedoch, dass es möglicherweise doppelte Varianten gibt.
Können Sie helfen, indem Sie einen Code schreiben?
Da jede Variante die Segmente nun in zwei Arrays speichert, können diese der Einfachheit halber mit der MethodeCombine() zu einem Array zusammengefasst werden.
Da nun jede Variante die Segmente in zwei Arrays speichert, kann man sie mit der MethodeCombine() zu einem Array zusammenfassen, um es bequemer zu machen.
Dmitry, vielen Dank für den neuen Algorithmus!
Ja, es gibt in der Tat sehr viele Kopien.
So wie ich es verstehe, können sie nicht gezählt werden. Ich hatte es nicht geschafft, auf die Kombination von 1000 Elementen zu warten - meinem Netbook ging der Speicher aus :(
Und ist es möglich, beim Hinzufügen eines Segments nicht alle Kombinationen zu verwenden, sondern nur eine bestimmte Anzahl von möglichen im aktuellen Schritt, z. B. die besten 10?
Dmitry, vielen Dank für den neuen Algorithmus!
Ja, es gibt tatsächlich viele Kopien.
Soweit ich weiß, kann man sie nicht zählen. Ich konnte die Kombination von 1000 Elementen nicht abwarten - meinem Netbook ging der Speicher aus :(
Ist es möglich, beim Hinzufügen eines Segments nicht alle Kombinationen zu verwenden, sondern nur eine bestimmte Anzahl von möglichen im aktuellen Schritt, z. B. die besten 10?
Um zu wissen, dass sie die besten sind, muss man sie mit anderen vergleichen, d. h. man muss sie erst einmal alle haben. Eine andere Sache ist, den Algorithmus irgendwie zu optimieren, aber ich habe nicht das Ziel, mein Leben diesem Algorithmus zu widmen).
Vielleicht entscheiden Sie sich für das Kriterium der Suffizienz und erhalten zunächst alle Optionen, ausgehend von nur einem Segment, das zufällig ausgewählt wird, und so weiter, bis eine zufriedenstellende Option erscheint.
Und die zweite Option kann beschleunigt werden - um das Array mit Varianten nicht ein Element zu einer Zeit, sondern mehrere Dutzend Elemente auf einmal zu skalieren, und am Ende zu trimmen es.
Um zu wissen, dass sie die besten sind, muss man sie mit anderen vergleichen, d. h. man muss sie erst einmal alle haben. Eine andere Sache ist, den Algorithmus irgendwie zu optimieren, aber ich habe nicht das Ziel, mein Leben diesem Algorithmus zu widmen).
Ich spreche über ein einzelnes Segment, sagen wir, es hat einen Koeffizienten, um seine Qualität zu bewerten, dann verzweigen wir nach jeder Iteration, zum Beispiel, nur auf die Top 10 dieser Koeffizienten.
Vielleicht entscheiden Sie sich für ein Suffizienzkriterium und erhalten zunächst alle Varianten, ausgehend von nur einem Segment, das zufällig ausgewählt wird, und so weiter, bis eine zufriedenstellende Variante erscheint.
Leider ist die "Hinlänglichkeit" hier schwer einzuschätzen - dazu muss man eine Norm kennen, dann kann man daraus eine Toleranz definieren, und ich habe keine Norm.
Und die zweite Option kann beschleunigt werden - zu skalieren Array mit Optionen nicht ein Element zu einer Zeit, aber mehrere Dutzend Elemente, und am Ende der es auszurichten.
Ich bin mir nicht ganz sicher, was Sie mit der Parallelisierung mit OpenCL meinen?
1. Ich spreche von einem einzelnen Segment, sagen wir, es hat einen Koeffizienten, um seine Qualität zu bewerten, dann verzweigen wir nach jeder Iteration zum Beispiel nur zu den Top 10 dieser Koeffizienten.
2. Leider lässt sich die "Hinlänglichkeit" hier nur schwer einschätzen - man muss die Benchmark kennen, dann kann man daraus die Toleranz bestimmen, und ich habe keine Benchmark.
3. ich bin mir nicht ganz sicher, was Sie mit Parallelisierung mittels OpenCL meinen?
1. wo liegt dieser Koeffizient?
2. Was ist mit Punkt 1?
3. Nein, es ist einfacher. Okay, ich werde versuchen, es morgen zu beschleunigen.