2010-07-29 11 views
2

Je suis actuellement en train de mettre en place un logiciel qui mesure certaines valeurs dans le temps. L'utilisateur peut choisir de mesurer la valeur 100 fois sur une durée de 28 jours. (Juste pour donner un exemple)Comment: Trouver un bon algorithme mathématique pour distribuer des points de mesure dans le temps?

La distribution linéaire n'est pas un problème, mais j'essaie actuellement d'obtenir une distribution logarithmique des points sur la durée.

L'implémentation directe serait d'itérer sur les points et donc j'ai besoin d'une fonction exponentielle. (! Je suis arrivé jusqu'ici)

Mon algorithme actuel (C#) est la suivante:

long tRelativeLocation = 0; 
double tValue; 
double tBase = PhaseTimeSpan.Ticks; 
int tLastPointMinute = 0; 
TimeSpan tSpan; 
for (int i = 0; i < NumberOfPoints; i++) 
{ 
    tValue = Math.Log(i + 1, NumberOfPoints); 

    tValue = Math.Pow(tBase, tValue); 
    tRelativeLocation = (long)tValue; 
    tSpan = new TimeSpan(tRelativeLocation); 
    tCurrentPoint = new DefaultMeasuringPointTemplate(tRelativeLocation); 
    tPoints.Add(tCurrentPoint); 
} 

cela me donne un résultat plutôt "bon" pendant 28 jours et 100 points.
Les 11 premiers points sont tous à 0 secondes,
points 12 à 1 sec,
20 à 50 sec,
50 à 390 min,
95e à 28605 min
99 e à 37697 minutes (ce qui rend 43 heures avant le dernier point)

Ma question est: Est-ce que quelqu'un a une bonne idée de comment séparer les premiers 20-30 points les uns des autres, peut-être en rapprochant les 20-30 derniers? ? Je comprends que je devrai éventuellement ajouter un algorithme qui sépare les premiers points d'au moins une minute, parce que je ne serai pas capable d'obtenir ce genre de comportement dans un algorithme strictement mathématique.

Quelque chose comme ceci:

if (((int)tSpan.TotalMinutes) <= tLastPointMinute) 
{ 
     tSpan = new TimeSpan((tLastPointMinute +1) * 600000000L); 
     tRelativeLocation = tSpan.Ticks; 
     tLastPointMinute = (int)tSpan.TotalMinutes; 
} 

Cependant, je voudrais obtenir une distribution légèrement mieux dans l'ensemble.

Toutes les idées géniales de votre part seraient grandement appréciées!

Répondre

1

D'un point de vue pratique, la fonction log consomme déjà votre point temporel proche de l'origine. Une fonction de puissance les serre encore plus. Que diriez-vous de la multiplication simple?

tValue = Math.Log(i + 1, NumberOfPoints); 
tValue = tBase * tValue; 

Une autre façon d'aplatir la courbe est de commencer plus loin de l'origine.

for (int i = 0; i < NumberOfPoints; i++) 
{ 
    tValue = Math.Log(i + 10, NumberOfPoints + 9); 

La gamme de tvalue est encore 0 à 1.

Que diriez-vous que cela ait un espace minimum de 1 seconde au début?

double nextTick = 0; 
for (int i = 0; i < NumberOfPoints; i++) 
{ 
    tValue = Math.Log(i + 1, NumberOfPoints); 

    tValue = Math.Pow(tBase, tValue); 

    if (tValue < nextTick) tValue = nextTick; 
    nextTick++; 
+0

Paul: Merci. L'idée avec le décalage m'a beaucoup aidé. Avec un peu plus de réglage, je vais faire ce travail assez décemment. Merci beaucoup – yas4891

1

La courbe de distribution que vous choisissez dépend de ce que vous mesurez.

Une ligne droite, une onde sinusoïdale, une courbe polynomiale ou une courbe exponentielle peuvent être individuellement la meilleure courbe de distribution pour un ensemble donné de mesures. Une fois que vous avez décidé de la courbe de distribution, vous calculez les points de données manquants en calculant la valeur y pour une valeur de temps donnée (valeur x), en utilisant la formule mathématique de la courbe. Par exemple, pour une ligne droite, tout ce dont vous avez besoin est un point de données et la pente de la ligne. Disons qu'à l'instant 0 la valeur mesurée est 10, et la mesure augmente de 2 toutes les minutes. La formule serait par y = 2 * x + 10. Si nous voulions calculer la mesure lorsque x = 5 (minutes), la formule nous donne une mesure de 20.

Pour une courbe logarithmique, vous utiliseriez un formule logarithmique. Pour simplifier, disons que les mesures réelles nous donnent une formule de y = 2 ** x + 12; Vous branchez les valeurs de temps (valeurs x) que vous souhaitez calculer et calculez les mesures (valeurs y).

Réalisez que vous introduisez des erreurs de calcul en calculant des points de données au lieu de mesurer.Vous devez marquer les points de données calculés d'une manière ou d'une autre pour aider la personne qui lit votre graphique à les différencier des mesures réelles.

+0

Salut Gilbert. Merci d'avoir pris le temps de me répondre. J'ai un algorithme de travail et j'ai une compréhension mathématique. Ce que je recherche est une version améliorée de mon algorithme actuel qui me fournit une courbe "meilleure" pour une courbe logarithmique (points dans le temps)/exponentielle (temps sur les points) que celle que j'utilise pour l'instant. Je sais que c'est une question plutôt difficile car il faut creuser plus profondément dans mon algorithme. S'il y a des questions ouvertes, n'hésitez pas à demander. Je n'ai peut-être pas clarifié toutes mes pensées et mes exigences. (Désolé pour ça!) – yas4891

+0

@ yas4891: Votre courbe va seulement être aussi bonne que vos points de données. Savoir quelle courbe utiliser est plus important. Voici un article de Wikipedia sur l'ajustement de la courbe: http://en.wikipedia.org/wiki/Curve_fitting –

+0

Oh OK. Je ne veux pas trouver la courbe parfaite pour un certain nombre de points de mesure pris. Je préfère avoir une "courbe/formule" qui me dit QUAND mieux prendre chaque point de mesure. Les données alors prises par l'application à ce moment-là ne concerne pas mon problème. J'espère que cela aidera à clarifier mon problème – yas4891

1

Je ne suis pas exactement sûr de ce que vous essayez de faire, votre code ne semble pas correspondre à votre exemple (il se peut que je vienne à bout de l'arithmétique). Si vous voulez que vos échantillons aient une séparation minimum de 1 sec, et chaque point à un emplacement de x fois le dernier point (excepté le premier) alors vous voulez trouver x tel que x^(n - 1) = span. C'est juste x = exp (log (span)/(n - 1)). Ensuite, vos points seront à x^i for(i = 0; i < n; i++)

+0

J'ai nettoyé le code (morceaux inutiles de dleeted). Le code me donne les résultats que j'ai écrits ci-dessus. – yas4891

Questions connexes