2017-09-12 4 views
0

J'ai une fonction qui retourne un objet avec la meilleure note parmi un ensemble d'objets. Maintenant, je veux obtenir l'objet avec la meilleure note qui est la plus proche d'un certain point. Fondamentalement, je veux permettre à une petite violation de la formule, de sorte que si O_1 est plus proche du point donné que O_2 même si enter image description hereargmax d'une fonction permettant de petites violations

enter image description here

si

enter image description here

pour quelques petits et fixe $\epsilon$.

Actuellement, je réalise avec environ 5 instructions if dans un programme, mais je me demandais s'il y avait un moyen de représenter cela d'une manière plus propre et plus élégante avec une formule mathématique peut-être? Si vous avez déjà eu un problème comme celui-ci, comment l'avez-vous codé?

Voici un extrait du code que j'ai, je sais qu'il y a quelques refactorisations qui pourraient être faites aux instructions if, je voulais rendre les cas plus clairs. Y a-t-il une manière plus élégante de résoudre ceci?

public VisualDevice MostSuitableDevice(GameObject u, GameObject t, List<VisualDevice> D) 
{ 
    float maxSuitability = 0; 
    VisualDevice mostSuitableDevice = null; 
    float epsMaxSuitability = 0; 
    VisualDevice epsMSD = null; 


    foreach (VisualDevice d in D) 
    { 
     float suitability = Rating(d, u, t); 
     bool closerDevice = mostSuitableDevice != null ? Vector3.Distance(d.GetLightPosition(), t.transform.position) < Vector3.Distance(mostSuitableDevice.GetLightPosition(), t.transform.position) : false; 

     if (suitability > maxSuitability && closerDevice) 
     { 
      maxSuitability = suitability; 
      mostSuitableDevice = d; 
     } 
     else if (suitability > maxSuitability + epsilon) 
     { 
      maxSuitability = suitability; 
      mostSuitableDevice = d; 
     } 
     else if (suitability + epsilon > maxSuitability && closerDevice) 
     { 
      closerDevice = epsMSD != null ? Vector3.Distance(d.GetLightPosition(), t.transform.position) < Vector3.Distance(epsMSD.GetLightPosition(), t.transform.position) : false; 
      if (suitability > epsMaxSuitability && closerDevice) 
      { 
       epsMaxSuitability = suitability; 
       epsMSD = d; 
      } 
      else if (suitability > epsMaxSuitability + epsilon) 
      { 
       epsMaxSuitability = suitability; 
       epsMSD = d; 
      } 
      else if (suitability + epsilon > epsMaxSuitability && closerDevice) 
      { 
       epsMaxSuitability = suitability; 
       epsMSD = d; 
      } 
     }    

    } 
    bool epsCloser = epsMSD != null && mostSuitableDevice!=null ? Vector3.Distance(epsMSD.GetLightPosition(), t.transform.position) < Vector3.Distance(mostSuitableDevice.GetLightPosition(), t.transform.position) : false; 
    if (epsMaxSuitability + epsilon > maxSuitability && epsCloser) 
    { 
     maxSuitability = epsMaxSuitability; 
     mostSuitableDevice= epsMSD; 
    } 

    return mostSuitableDevice; 
} 
+0

Qu'est-ce qu'une mesure pour "proximité"? – MBo

+0

Votre question n'est pas claire, comme le laisse entendre le commentaire précédent. S'il vous plaît montrez votre "environ 5" if "déclarations" pour clarifier la question et pour montrer que vous avez fait un travail important sur le problème. Plus d'explications sur "plus proche d'un certain point" aiderait aussi. –

+0

@MBo disjoncteur euclédien juste à un objet cible/emplacement – Girauder

Répondre

0

Première trouvaille maximale rmax. Sélectionnez ensuite l'objet le plus proche du point donné parmi tous les objets o avec Rating(o) >= rmax - epsilon. Comme ça:

float maxSuitability = D.Max(d => Rating(d, u, t)); 
float minDistance = float.PositiveInfinity; 
VisualDevice mostSuitableDevice = null; 
foreach (VisualDevice d in D) 
{ 
    float suitability = Rating(d, u, t); 
    if (suitability < maxSuitability - epsilon) 
     continue; 
    float distance = Vector3.Distance(... 
    if (distance < minDistance) 
    { 
     minDistance = distance; 
     mostSuitableDevice = d; 
    } 
} 
+0

Je pense que je fais exactement cela, juste d'une manière compliquée. Vous avez des conseils sur la façon d'améliorer le code? – Girauder

+0

@Girauder voir mon edit – Henrik

+0

Je n'étais pas entièrement convaincu à ce sujet au début, mais plus j'y pense, plus ça fait de sens. Je reçois des résultats légèrement différents de ce que j'avais avant, mais il se pourrait très bien que ce que j'avais avant n'était pas tout à fait correct. Voyez-vous une différence évidente? Je vais tester votre solution un peu plus et accepter votre réponse. – Girauder