2015-05-14 3 views
5

Я пытаюсь сделать подделку download count. Он должен постепенно увеличиваться со временем. Некоторые шаблоны, похожие на скачивание, были бы хороши.Функция для генерации случайно увеличивающегося числа с течением времени

Возможно ли это без использования базы данных или хранения счетчика в любом месте?

Моя идея - проверить количество секунд, прошедших с момента выхода моего приложения. Затем просто бросьте это в формулу, которая выплевывает поддельный подсчет загрузки. Пользователи могут запрашивать счетчик загрузки в любое время.

Есть ли математическая функция, которая постепенно увеличивается? Я мог бы просто передать мой secondsPassed туда и масштабировать его, как хотелось бы.

Что-то вроде этого: getDownloadCount(secondsPassed)

enter image description here

Edit: вот пример решения. Но со временем производительность ухудшается.

downloadCount = 0 
loop secondsPassed/60 times // Loop one more time for every minute passed 
    downloadCount += seededRandom(0, 10) 
+0

y = sin (x) + x может сделать что-то вроде того, что вы ищете. не очень случайный. Кроме того, если у вас нет вопросов программирования, это не подходит для stackoverflow. – mstbaum

+1

Это не полное решение, но вы можете каким-либо образом включить функцию Prime-counting * π (x) *] (https://en.wikipedia.org/wiki/Prime-counting_function). –

+0

Почему вы думаете, что база данных поможет? Все компьютерные языки имеют какую-то случайную функцию.Все, что вам нужно сделать, это сохранить накопленное общее количество в переменной, возможно статической переменной, и добавить к ней случайную сумму. Но нам нужен больше контекста. Это даже вопрос программирования. –

ответ

0

Для некоторой детерминированной функции f (возможно f(x) = x, или если ваше фальшивое приложение действительно удивительный f(x) = 2^x), и случайная функция r, которая выводит случайное число, которое иногда отрицательный, а иногда и положительные.

Ваша функция изображая g может быть:

g(x) = f(x) + r

EDIT

Как об этом: https://gamedev.stackexchange.com/questions/26391/is-there-a-family-of-monotonically-non-decreasing-noise-functions

+0

Иногда количество скачиваний будет снижаться. Если бы я продолжал обновлять счет, это выглядело бы безумным. –

+0

Ха-ха, хорошие моменты! – user12341234

+0

Добавлена ​​ссылка на аналогичный Q/A, который имеет крутые ответы – user12341234

-1

Вы можете использовать Unix временную метку. Что-то вроде:

Downloads = constant + (unix time/another constant) 

Вы можете изменить обе константы, чтобы получить разумное число.

P.S: То, если вы хотите линейную функцию, в противном случае вы можете сделать:

Downloads = (unix time)^constant 

и так далее.

+0

Это слишком линейно, хотя –

+0

Моя ошибка. Я отредактировал ответ. Я имел в виду использование unix-времени в качестве переменной. – zeratulmdq

+0

Теперь это слишком экспоненциально: p Счет загрузки в конечном итоге будет слишком высоким –

0

Вы после последовательности, которая всегда увеличивается на случайную величину, в зависимости от того, как долго вы последний раз запрашивали последовательность.

Это можно сделать с помощью случайной последовательности, которая всегда высевается одинаково.

Затем мы каждый раз перебираем одну и ту же последовательность, чтобы получить график.

Нам нужна функция, которая увеличивает наш счетчик, сохраняет новое время и количество и возвращает счетчик.

В идеале мы будем моделировать увеличение как процесс пуассона, но здесь будет линейный.

class Counter { 
    private static int counter = 0; 
    private static int time = 0; 

    private static double rate = 5.0; 

    private Random r; 

    public Counter(int seed){ 
     counter = 0; 
     r = new Random(seed); 
    } 

    private int poisson(double rate, int diff){ 
    // We're gonna cheat here and sample uniformly 
     return r.Next(0, (int)Math.Round(rate * diff)); 
    } 

    public int getNext(int t){ 
     var diff = t - time; 
     time = t; 
     if (diff <= 0) return counter; 

     counter += this.poisson(rate, diff); 
     return counter; 
    } 
} 
void Main() 
{ 
    var c = new Counter(1024); 
    for(var i = 0; i< 10; i++){ 
     Console.WriteLine(String.Format("||{0}\t|{1}\t||",i,c.getNext(i))); 
    } 
} 

Эти выходы (например):

||t |hit|| 
||0 |0 || 
||1 |3 || 
||2 |4 || 
||3 |6 || 
||4 |6 || 
||5 |8 || 
||6 |10 || 
||7 |13 || 
||8 |13 || 
||9 |16 || 
+1

Почему downvote? Это делает именно то, что происходит после OP. Он производит произвольно возрастающую последовательность, которая всегда генерируется одинаково. (И можно обновить, изменив конструктор на Counter) – Eterm

0

Ну это не "случайный", но вы могли бы использовать (масштабируется на некоторое число), чтобы ввести некоторый шум. Вы можете настроить A и B, чтобы изменить масштаб результата и частоту циклов «шума».

Действительно, любая периодическая функция, имеющая первую производную в некоторых границах, может работать.

1

Выполнение поддельного подсчета загрузки не похоже на приятную вещь. Однако при разработке защищенных протоколов связи существуют законные варианты использования монотонно растущих функций с некоторой случайностью в их значениях.

Я предполагаю, что у вас есть:

  • модель роста дается как монотонно возрастающая функция, обеспечивающей приблизительные значения для искомой функции.
  • Доступ к отметке времени, которая никогда не уменьшается.
  • Возможность хранения постоянного случайного семени вместе с определением функции.
  • Способы хранения обновленных данных при запросе функции.

Сначала вы определяете длину окна, которая будет контролировать, насколько случайность будет в конечном выходе. Я ожидаю, что вы захотите, чтобы это было порядка одного часа или нескольких.

Укажите, в каком окне находится текущее время. Оцените ссылочную функцию в начале и в конце этого окна. Рассмотрим прямоугольник, данное временем начала и окончания окна, а также мин и максимальным значением заданной опорной функции. Подайте углы этого прямоугольника и ваши постоянные семена в PRNG. Используйте PRNG для выбора случайной точки внутри прямоугольника. Эта точка будет на конечной кривой.

Выполните одно и то же вычисление для одного из соседних окон. Какое соседнее окно использовать, зависит от того, находится ли первая вычисленная точка на кривой слева или справа от текущего времени.

Теперь, когда у вас есть две точки на кривой (которые воспроизводимы и согласованы), вам придется выполнить следующую процедуру.

На конечной кривой вы получаете две точки. Рассмотрим прямоугольник, заданный этими углами. Кормите углы и ваши постоянные семена в PRNG. Используйте этот PRNG для выбора случайной точки внутри прямоугольника. Эта точка будет на конечной кривой. Отбросьте одну из внешних точек, которая больше не нужна.

Поскольку значения Y ограничены целыми числами, эта процедура в конечном итоге прекратится, как только ваши две точки на кривой будут иметь идентичную координату Y, и вы будете знать, что функция должна быть постоянной между этими двумя точками.

1

Вы можете реализовать Morris Counter.

Он работает следующим образом: начните с установки счетчика на 1.Каждый раз, когда вы хотите увеличить счет (который может быть любой итерацией какого-либо цикла или каждый раз, когда событие происходит, но не обязательно должно быть определено случайным образом), вы произвольно выполняете процедуру, чтобы определить эффект, который он имеет на счетчике.

Это может быть, возможно, неэффективно, или оно может иметь эффект увеличения порядка величины счета. Вероятность основана на том, будут ли n последовательных флагов честной монеты поворачивать головки, где n - количество бит, необходимое для кодирования текущего значения счетчика в двоичном формате. В результате, как только счетчик стал довольно высоким, очень сложно сделать его еще выше (состояние счетчика моделирует явление, когда вы уже завышаете счет, так что теперь вам нужно много ничего - происходит события для компенсации, делая счет более точным).

Это используется как дешевый способ хранения приблизительного подсчета очень большой коллекции, но нет причин, по которым вы не можете использовать его как своеобразно увеличивающееся встречное устройство.

Если вам нужна более высокая точность или вы хотите, чтобы выходы счетчика были более «нормальными» числами вместо всех степеней 2, вы можете просто создать несколько счетчиков Morris и на каждом шаге усреднить совокупность текущих значений через них всех.

0

, как быстрое решение вы можете использовать что-то вроде этого (код в Java):

static long f(final int x) { 
    long r = 0; // initial counter 
    long n = 36969L; // seed 
    for (int i = 0; i <= x; i++) { 
     n = 69069L * n + 1234567L; // generate Ith random number 
     r += (n & 0xf); // add random number to counter 
    } 
    return r; 
} 

, играя с номерами 36969L и 0xf вы можете получить различные результаты

числа 69069L и 1234567L взяты из стандартного LCG

Основная идея - создать простой случайный, с тем же семенем и для каждого пройденного x (количество секунд) repl ay случайные дополнения к счетчику

0

Хорошая модель случайных событий, таких как загрузки, - это распределение Пуассона. Вы должны оценить среднее количество загрузок за определенный период времени (час, скажем), а затем инвертировать распределение Пуассона, чтобы получить количество загрузок за период времени, учитывая равномерно распределенное случайное число. Для дополнительного реализма вы можете изменить среднее значение в зависимости от времени суток, времени недели и т. Д. Примеры алгоритмов доступны по адресу http://en.m.wikipedia.org/wiki/Poisson_distribution#Generating_Poisson-distributed_random_variables.

0

Ниже приведена javascript-реализация "поддельного" загрузочного счетчика, которая кажется одинаковым для всех. Это всегда возвращает одинаковые результаты для каждого каждый раз и не требует для этого базы данных или файлов. Он также грациозно обрабатывает случай, когда вы не запрашиваете новые данные одновременно, он будет выглядеть естественным в следующий раз, когда вы запросите день. enter image description here https://jsfiddle.net/Lru1tenL/1/

Counter = { 
     time:Date.now(), 
     count:0, 
     rate:0.45 
    }; 

Counter.seed = function(seed, startTime) 
{ 
    this.time = startTime, 
    this.count = 0, 
    this.prng = new Math.seedrandom(seed); 
    this.prng.getRandomInt = function(min, max) { 
     return Math.floor(this() * (max - min)) + min; 
    }; 
}; 

Counter.getNext = function(t){ 

    var diff = t - this.time; 
    console.log(diff); 


    if(diff <= 0) return this.count; 

    this.time = t; 
    var max = Math.ceil(diff/100 * this.rate); 

    console.log("max: " + max); 
    this.count += this.prng.getRandomInt(0,max); 
    return this.count; 
}; 

var results = []; 

var today = Date.now(); 

Counter.seed("My Random Seed", today); 


for (var i = 0; i < 7; i++) { 
    if(i === 4) 
    { 
     results.push(null); 
    } else { 
     var future = today + 86400000 * i; 
     results.push(Counter.getNext(future)); 
    } 
} 

console.log(results); 

    var data = { 
    labels: ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday","Sunday"], 
    datasets: [ 
     { 
      label: "My Second dataset", 
      fillColor: "rgba(151,187,205,0.2)", 
      strokeColor: "rgba(151,187,205,1)", 
      pointColor: "rgba(151,187,205,1)", 
      pointStrokeColor: "#fff", 
      pointHighlightFill: "#fff", 
      pointHighlightStroke: "rgba(151,187,205,1)", 
      data: results 
     } 

    ] 
}; 

var ctx = document.getElementById("myChart").getContext("2d"); 
var myLineChart = new Chart(ctx).Line(data); 

Является JavaScript. Он создает объект-счетчик, который увеличивается при запросе в зависимости от времени предыдущего запроса. Повторимость поступает через библиотеку третьей стороны «seedrandom», и диаграмма рисуется с использованием диаграмм.

<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/1.0.2/Chart.js"></script> 
<script src="https://cdnjs.cloudflare.com/ajax/libs/seedrandom/2.4.0/seedrandom.min.js"> 
</script> 
<body> 
    <canvas id="myChart" width="600" height="400"></canvas> 

</body> 
</html>