Un ejercicio de calentamiento escolar para ocupar su tiempo - página 5

 
Aleksey Nikolayev:

1) Es difícil demostrar el hecho de que los vértices del área máxima deben estar en el mismo círculo (teorema de Cramer). No sé cómo demostrarlo ni dónde leer la prueba.

2) No creo realmente en la existencia de una fórmula analítica para el área o el radio máximos de un círculo.

3) La suma de los elementos del array se puede calcular con MathSum()

1) Creo que es un hecho evidente. Y es fácil demostrar entendiendo que el área máxima de un triángulo con un vértice dado A, una línea media h y un lado opuesto dado a es el área de un triángulo isósceles, cuando el ángulo en el vértice dado es máximo. Y el área de dicho triángulo es h*a/2

Imaginemos que todos los nodos entre los lados dados de los polígonos son flexibles (como en un juego de construcción infantil sobre imanes) y está claro que podemos disponer los lados de forma que todos los vértices tengan un centro común equidistante (siempre que el lado mayor sea menor que la suma de los otros lados, de lo contrario no se pueden conectar), es decir, que están inscritos en un círculo. Y ésta será el área máxima, ya que consiste en la suma de las áreas de los triángulos isósceles, con un lado igual al radio de esta circunferencia.

2) Creo que

3) No he encontrado dicha fórmula en MQL4 o MQL5

 
Nikolai Semko:

1) Creo que es un hecho evidente.

intuitivamente sí, pero no llega a ser una prueba rígida ni mucho menos.

2) Creo que

Si hubiera uno, se podría encontrar, sólo hay un sistema de ecuaciones

Aleksey Nikolayev:

1) La dificultad estriba en demostrar el hecho de que los vértices del mnc con el área máxima deben estar en la misma circunferencia (teorema de Cramer). No sé cómo demostrarlo ni dónde leer las pruebas.

No he encontrado tal teorema en absoluto, sólo referencias a esta propiedad.

como siempre, referencias inútiles y ni una sola palabra sobre el punto.

 
Andrei Trukhanovich:


como siempre referencias inútiles y ni una palabra de sustancia.

es realmente inútil para ti

 
Nikolai Semko:

1) Creo que es un hecho evidente. Y se demuestra fácilmente entendiendo que el área máxima de un triángulo con un vértice dado A, una línea media h y un lado opuesto dado a es el área de un triángulo isósceles cuando el ángulo en el vértice dado es máximo. Y el área de dicho triángulo es h*a/2

Imaginemos que todos los nodos entre los lados dados de los polígonos son flexibles (como en un juego de construcción infantil sobre imanes) y está claro que podemos disponer los lados de forma que todos los vértices tengan un centro común equidistante (siempre que el lado mayor sea menor que la suma de los otros lados, de lo contrario no pueden estar conectados), es decir, inscritos en un círculo. Y ésta será el área máxima, ya que consiste en la suma de las áreas de los triángulos isósceles, con un lado igual al radio de esta circunferencia.

2) Creo que

3) No he encontrado dicha fórmula en MQL4 o MQL5.

1) Tal vez se pueda formalizar de alguna manera como la igualdad a cero de la variación (derivada) del área de un mnc por coordenadas de vértices cuando están en una circunferencia. Sólo que ésta es una condición de extremidad local y necesitamos demostrar 1) que es un máximo y 2) que es global.

3) MathSum()

#include <Math\Stat\Math.mqh>
void OnStart()
{
  double a[] = {1.0, 2.0, 3.0}, s;
  s = MathSum(a);
  Print("s=", s);
}

s=6.0



 

Se obtiene un polinomio a partir de las raíces de los otros polinomios, y de todo esto baad over tomar tres derivadas. Fórmulas kilométricas. Y quién sabe, tal vez haya una sorpresa esperando al final. Tendremos que conseguir algún tipo de truco.

 
Andrei Trukhanovich:

intuitivamente sí, pero no llega a ser una prueba rígida ni mucho menos.

si hubiera uno, se podría encontrar, sólo hay un sistema de ecuaciones

No he podido encontrar tal teorema en absoluto, sólo menciones a esta propiedad.

como siempre referencias inútiles y ni una sola palabra sobre el punto.

Buscando en Google "polígono de área máxima dados los lados", sólo encontré que este resultado es "bien conocido") y soluciones numéricas como la dada por Nikolay.

Por lo visto, hay que consultar algunos libros antiguos de geometría; hoy en día no les gusta exponer esas cosas.

 

La solución anterior sólo es válida para los polígonos cuyo centro de la circunferencia se encuentra dentro del perímetro. Prueba el triángulo {2,2,3.9}

En términos generales (aproximación por doble precisión) se resuelve como sigue:

enum EEqual {LESS=-1,EQUALY,MORE};
//-------------------------------------------------------
struct SRes{
   double s;
   double r;
   double degDelta;
   SRes(){ZeroMemory(this);}
   SRes(double _s,double _r,double _degDelta):s(_s),r(_r),degDelta(_degDelta){}
   SRes(const SRes &other) {this=other;}
   bool operator !() {return !s;}
};
//-------------------------------------------------------
const double _2PI=2*M_PI;
//-------------------------------------------------------
EEqual Check(double &array[],int size){
   int ii=0;
   double max=0.0,
          tmp=0.0,
          sum=0.0;
   for (int i=0;i<size;++i){
      if (array[i]<=0.0) return false;
      max=MathMax(max,array[i]);
      if (max!=tmp){
         ii=i;
         tmp=max;}
      sum+=array[i];}
   EEqual ret=max<sum/2?MORE:LESS;
   if (ret==MORE){
      tmp=array[ii];
      array[ii]=array[--size];
      array[size]=tmp;}
   return ret;}
//---------------------------------------------------
SRes ComputeCenterOut(const double &array[], double deg){
   int size=ArraySize(array)-1;
   double r=array[size]/2.0/sin((deg-M_PI)/2.0);
   double sum=0.0,
          square=-r*cos(deg/2.0)*array[size]/2.0;
   for (int i=0;i<size;++i){
      double _deg=2.0*MathArcsin(array[i]/2.0/r);
      sum+=_deg;
      square+=r*cos(_deg/2.0)*array[i];}
   return SRes(square,r,deg-M_PI-sum);
}
//---------------------------------------------------
SRes ComputeCenterIn(const double &array[], double deg){
   int size=ArraySize(array)-1;
   double r=array[size]/2.0/sin(deg/2.0);
   double sum=deg,
          square=r*cos(deg/2.0)*array[size]/2.0;
   for (int i=0;i<size;++i){
      double _deg=2.0*MathArcsin(array[i]/2.0/r);
      sum+=_deg;
      square+=r*cos(_deg/2.0)*array[i]/2.0;}
   return SRes(square,r,_2PI-sum);
}
//---------------------------------------------------
SRes ComputeSquare(const double &array[],double min,double max,SRes &prev){
   double a=(min+max)/2.0;
   if (a==min||a==max) return prev;
   SRes res=a>M_PI?ComputeCenterOut(array,a):ComputeCenterIn(array,a);
   if (res.degDelta==0.0||res.s==prev.s) return res;
   if (res.degDelta>0.0) min=a;
   else max=a;
   return ComputeSquare(array,min,max,res);}
//---------------------------------------------------
SRes Square(const double &in[]){
   double tmp[];
   int size=ArrayCopy(tmp,in);
   if (Check(tmp,size)!=MORE) return SRes();
   double aMax=_2PI,
          a=aMax/size;
   return ComputeSquare(tmp,a,aMax,SRes());
}

void OnStart(void)
{
   double arr[]={2,3.9,2};
   ulong time=GetMicrosecondCount();
   SRes res=Square(arr);
   time=GetMicrosecondCount()-time;
   if (!res) Print("Многоугольника с заданными сторонами не существует");
   else PrintFormat("Time=%lli %ss\n"
                    "Square=%f\n"
                    "Radii=%f",time,"\xB5",res.s,res.r);
}
 
Vladimir Simakov:

La solución anterior sólo es válida para los polígonos cuyo centro de la circunferencia se encuentra dentro del perímetro. Prueba el triángulo {2,2,3.9}

...

¿Qué tiene que ver esto con un triángulo si el problema es encontrar un polígono con el área máxima dadas las dimensiones de los lados?

 

Uy. Yo mismo sólo tengo una de las variantes contando correctamente)))

UPD: Corregido.

 
Dmitry Fedoseev:

Se obtiene un polinomio a partir de las raíces de los otros polinomios, y de todo esto baad over tomar tres derivadas. Fórmulas kilométricas. Y quién sabe, tal vez haya una sorpresa esperando al final. Tendremos que conseguir algún tipo de truco.

Aquí está la función para la suma de todos los ángulos frente al radio. La zona de solución de 2p está resaltada en verde.

Tal vez esto ayude.
Soy demasiado perezoso para devanarme los sesos, sobre todo porque no soy muy bueno en la torre.

Archivos adjuntos:
Zadacha2.mq5  4 kb