Prawie równomierny rozkład losowy.

Odpowiedz Nowy wątek
2020-07-31 17:28

Rejestracja: 2 miesiące temu

Ostatnio: 6 godzin temu

0

Witam,

W każdym miesiącu chciałbym przeprowadzać audyt komputerów.
Ilość audytów (1 komputer = 1 audyt) miała by być losowa, ale zawsze powinien istnieć jakiś cel w danym miesiącu np. 5, 10, 15 lub 30szt. (+-5 szt. lub +-10%).
Dodatkowo rozkład tych audytów miałby być nieregularny i w miarę równomiernie rozłożony (ale nie idealnie równomiernie) np. przy 30 audytach nie chciałbym, aby był 1 audyt dziennie lub wszystkie 30.
Celem tego jest przygotowanie takiego harmonogramu, aby audytor i audytowany nie wiedzieli kiedy i jakich rozmiarów będą audyty przy jednoczesnym wykonaniu ich określonej ilości (cel).

[30 audytów w 30 dniowym miesiącu]
Nieprawidłowy |1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1| - (nazbyt równomierny rozkład)
screenshot-20200731165432.png
Nieprawidłowy |30,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0| - (brak rozkładu)
screenshot-20200731165506.png
Nieprawidłowy |0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,2,3,4,5,6,7| - (możliwy do przewidzenia rozkład)
screenshot-20200731170941.png
Prawidłowy |2,0,1,1,2,1,0,1,3,1,0,0,1,1,0,1,2,1,0,1,1,2,1,0,1,3,1,0,1,1| - (nierównomierny, ale też ciężki do przewidzenia rozkład)
screenshot-20200731165234.png
[3 audyty w 29 dniowym miesiącu]
Prawidłowy |0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0|
screenshot-20200731172011.png

Taki rozkład również odpada:
[30 audytów w 30 dniowym miesiącu]
Nieprawidłowy |0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,4,3,2,1,0,0,0,0,0,0,0,0,0,0,0|
screenshot-20200731172248.png

Proszę o pomoc w utworzeniu algorytmu, który będzie generował harmonogram zgodny z powyższymi założeniami.

edytowany 2x, ostatnio: Babbage, 2020-07-31 17:40
Pracujecie w weekendy? - tsz 2020-07-31 17:33
Myślałem o tym i szczerze to weekendy są nawet lepsze bo nie ma użyszkodników, ale na razie niech pozostanie bez uwzględniania lepszych i gorszych dni. - Babbage 2020-07-31 17:37

Pozostało 580 znaków

2020-07-31 17:48
Moderator Kariera

Rejestracja: 2 lata temu

Ostatnio: 7 godzin temu

Lokalizacja: Poznań

2

Skoro ma być układ w miarę losowy, ale nie idealnie po równo, to wytłumaczę jak ja bym to zrobił na przykładzie miseczek z ziarenkami grochu ;)

1) stawiasz na stole tyle miseczek, ile jest Ci potrzebne (czyli po miseczce na każdy dzień roboczy, w którym jest możliwość planowania kontroli)
2) określasz, ile chcesz w danym miesiącu przeprowadzić kontroli - tyle ziarenek grochu wyciągasz ze stolika i kładziesz na stole
3) rozkładasz ziarenka po równo do miseczek, uzyskując rozkład zbliżony do tego, który pokazałeś na rysunku pierwszym
4) określasz, jak bardzo chcesz go urozmaicić
5) w oparciu o to, co ustaliłeś w pkt. 4, wykonujesz X razy sekwencję polegającą na wylosowaniu miseczki, z które bierzesz ziarenko oraz miseczki, do której je przełożysz
6) jeśli chcesz uniknąć zbyt dużych różnic między miseczkami, możesz w pkt. 5 dodać dodatkowe warunki - np. że jeśli w miseczce, z której wyciągasz jest mniej o Y niż było pierwotnie, to ponawiasz losowanie miseczki źródłowej, albo że jeśli miseczka docelowa ma o Z więcej niż stan startowy, to losujesz inną, do której przełożysz ziarenko.
7) w ramach dodatkowych warunków możesz dodać sprawdzenie, czy któraś miska nie przekroczyła jakiegoś z zadanych parametrów - wartość max, min albo czy została wylosowana więcej niż ileś razy, a jeśli tak, to wypada z dalszych losowań.
8) możesz także uwzględnić dni weekendowe - poprzez nadanie specjalnych warunków dla wybranych miseczek - np. weekend może mieć większą ilość ziarenek niż pozostałe dni, albo nie może zejść poniżej jakiejś wartości, która jest wyższa niż Y.

Operując tymi parametrami, czyli ilością losowań oraz wartościami limitów możesz dość precyzyjnie ustalić zakres wartości/rozrzut, który otrzymasz na końcu działania algorytmu groszkowego ;)


Naczelny forumowy hejter Apple

That game of life is hard to play, I'm gonna lose it anyway
The losing card I'll someday lay, So this is all I have to say
edytowany 4x, ostatnio: cerrato, 2020-07-31 22:05

Pozostało 580 znaków

2020-07-31 18:41

Rejestracja: 13 lat temu

Ostatnio: 20 minut temu

1

To daje w miarę sensowne wyniki dla dużej liczby audytów i dużej liczby dni. Przy małej liczbie audytów ma tendencję do skupiania się na pierwszych dniach, ale to można poprawić wagą przejścia do nowego dnia:

using System;
using System.Threading.Tasks;

public class Program
{
    public static void Main()
    {
        int days = 30;
        int audits = 30;

        int filled = 0;
        int day = 1;
        Random random = new Random();

        int auditsToday = 0;
        while(filled < audits){
            if(random.NextDouble() < 1.0 / 2){
                auditsToday ++;
                filled ++;
            }

            if(day < days && random.NextDouble() < 0.5){
                Console.WriteLine($"{auditsToday}");
                day ++;
                auditsToday = 0;
            }
        }

        while(day <= days){
            Console.WriteLine($"{auditsToday}");
            day ++;
            auditsToday = 0;
        }
    }
}

Idea: każdego dnia losuję, czy robię audyt z szansą 1/2, a potem losuję z tą samą szansą, czy idę do następnego dnia, czy zostaję tutaj. Prawdopodobieństwa można zmieniać i dowodzić sensowności rozkładu, ale dla prostego przypadku działa okej.

screenshot-20200731184124.png

edytowany 1x, ostatnio: cerrato, 2020-07-31 22:03

Pozostało 580 znaków

2020-07-31 23:03

Rejestracja: 13 lat temu

Ostatnio: 20 minut temu

2

Problem można też zredukować do losowania ze zwracaniem. Dopóki nie mamy wszystkich audytów, dopóty losujemy dzień z rozkładu jednostajnego i dodajemy audyt. To w sumie spełnia chyba wszystkie warunki, nie ma problemów z dużą/małą liczbą dni lub dużą/małą liczbą audytów.

using System;
using System.Threading.Tasks;
using System.Linq;

public class Program
{
    public static void Main()
    {
        int days = 30;
        int audits = 30;

        Random random = new Random();
        int[] auditsPerDay = Enumerable.Range(0, days).Select(i => 0).ToArray();

        int filled = 0;
        while(filled < audits){
            int day = random.Next(0, days - 1);
            auditsPerDay[day]++;
            filled ++;
        }

        foreach(var i in auditsPerDay){
            Console.WriteLine(i);
        }
    }
}

screenshot-20200731230332.png

edytowany 1x, ostatnio: Afish, 2020-07-31 23:04
Najlepsze rozwiazanie. - Julian_ 2020-08-01 08:03

Pozostało 580 znaków

2020-07-31 23:28
Moderator

Rejestracja: 12 lat temu

Ostatnio: 11 godzin temu

0

A to nie wystarczyłoby użyć rozkładu Poissona z \lambda = \frac{n}{30}?


Pokaż pozostałe 2 komentarze
Nie jestem przekonany, że da to równomierny rozkład, chyba będzie miało tendencję do wrzucania zbyt wielu audytów na ostatni dzień. Przykładowo, dla jednego audytu i 30 dni ten kod sum(map(lambda x: x == 0, [np.random.poisson(1.0/30, 29).sum() for i in range(10000)])) zwraca mi około 3800. Robię 10000 prób, w każdej próbie losuję 29 razy z Poissona z Twoim współczynnikiem, potem sumuję wszystkie wylosowane liczby, a następnie sprawdzam, czy ta suma dała 0 - jeżeli tak, to w tej próbie musiałbym na siłę wrzucić audyt na ostatni dzień... - Afish 2020-08-01 15:27
Gdyby wszystko było równomierne, to powinienem dostać około 333 prób, a dostaję ponad 10 razy więcej. - Afish 2020-08-01 15:27
@Afish: nie uwzględniłeś ±5. Bo jeśli założymy, że dana ilość absolutnie musi być, to im bliżej końca miesiąca tym audytor dokładniej wie, ile jeszcze testów będzie robił. Jeśli chcemy założyć, że w żadnym momencie nie może wiedzieć ile testów ma jeszcze do zrobienia, to Poisson jest tutaj dokładnie tym czego szukamy. Oczywiście nie w każdym miesiącu cel będzie zrobiony w 100 (a w innych będzie więcej niż oczekiwano), ale taka jest natura losowości. - hauleth 2020-08-01 17:30
Więc "Celem tego jest przygotowanie takiego harmonogramu, aby audytor i audytowany nie wiedzieli kiedy i jakich rozmiarów będą audyty przy jednoczesnym wykonaniu ich określonej ilości" bez pewnych ograniczeń jest niemożliwe do osiągnięcia. - hauleth 2020-08-01 17:31
Ach, racja, pominąłem ten fragment. - Afish 2020-08-01 21:29

Pozostało 580 znaków

2020-08-01 06:50

Rejestracja: 3 lata temu

Ostatnio: 2 minuty temu

3

Co Wy wyprawiacie to nie czaje. Z czym Wy macie problem.

Boerzesz laczna oczekiwana liczbe audytow i dzirlisz przez ilosc dni audytow. To jest srednia Teojego rozkladu.
Nastepnir z wybranym odhyleniem standardowym i ewebtualnie wartoscia max i min se losujesz codziennie, pod warunkiem ze suma audytow nie przekroczyla oczekiwanej sumy, a w oststnim dniu juz nie losujesz tylko dobierasz taka liczbe by suma sie zgadzala.

Ewentualnie na kazdy dzoen se aktualizujesz srednia rozkladu = pozostala oczekiwana ilosc fni audytu / pozostsle dni audytu.

julian na porannym kacu wyłożył wam te statystykę, plusik - WeiXiao 2020-08-01 14:12
@Julian_ Zerknij na moje komentarze to posta wyżej. - Afish 2020-08-01 15:29
@Afish: a nie porkęciłeś z parametrami? [np.random.poisson(1.0/30, 29).sum() for i in range(10000)])) Z tego co rozumiem z dokumentacji numpy to 1 parametr to jest lambda (liczba oczekiwanych zdarzeń), a ten drugi parametr to nie wiem co, liczba prób? - Julian_ 2020-08-01 23:42
Zrobiłem taki rozkład, jak sugerował hauleth. - Afish 2020-08-02 00:16
x = [np.random.poisson(1.0/30, 29).sum() for i in range(10000)] daje srednio 29/30*10000. Wszystko sie zgadza. - Julian_ 2020-08-02 00:31

Pozostało 580 znaków

2020-08-04 14:35

Rejestracja: 12 lat temu

Ostatnio: 2 minuty temu

2

Mały offtopic: po co robić algorytm na audyt ręczny, skor takie rzeczy sie automatyzuje.

Przykładowo: https://www.eset.com/pl/business/enterprise-inspector/
Wszystkie komputery są monitorowane automatycznie, a dziwne zachowanie procesów jest zgłaszane analitykowi, który dodaje/poprawia reguły co jest dziwnym zachowaniem, co jest zagrożeniem, a co normalne.
Bez wątpienie będzie to skuteczniejsze, niż losowy harmonogram inspekcji maszyn.


Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.
edytowany 1x, ostatnio: MarekR22, 2020-08-04 14:36

Pozostało 580 znaków

2020-08-05 21:43

Rejestracja: 15 lat temu

Ostatnio: 1 minuta temu

0
Julian_ napisał(a):

... a w oststnim dniu juz nie losujesz tylko dobierasz taka liczbe by suma sie zgadzala.

Np minus 10, czyli w ostatnim dniu masz odkręcić 10 audytów zrobionych w dniach poprzednich :D


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
edytowany 1x, ostatnio: _13th_Dragon, 2020-08-05 21:44

Pozostało 580 znaków

2020-08-05 22:44

Rejestracja: 3 lata temu

Ostatnio: 2 minuty temu

1
_13th_Dragon napisał(a):
Julian_ napisał(a):

... a w oststnim dniu juz nie losujesz tylko dobierasz taka liczbe by suma sie zgadzala.

Np minus 10, czyli w ostatnim dniu masz odkręcić 10 audytów zrobionych w dniach poprzednich :D

[Julian_ napisał(a)]

se losujesz codziennie, pod warunkiem ze suma audytow nie przekroczyla oczekiwanej sumy

Pozostało 580 znaków

2020-08-06 13:51

Rejestracja: 15 lat temu

Ostatnio: 1 minuta temu

0

Ja wykorzystałem pewien algorytm do generowania danych wejściowych do testowania innego algorytmu.
Miałem do dyspozycji kilkanaście przebiegów zanotowanych wcześniej z realnych pomiarów.

  1. Wyliczam sumaryczny wynik dla całości (w twoim przypadku liczbę audytów)
  2. Dziele okres (w twoim przypadku liczba dni) na pół, dla każdego dostępnego realnego przebiegu notuje ile procent jest po lewej
  3. Jedno z: Wylosowuje jeden z procentów z punktu; 2. Wylosowuje trzy procenty i liczę średnią; 3. Aproksymuje do funkcji i losuję z takim rozkładem.
  4. Z wartości z punktu 2 pobieram procent z punktu 3 i przypisuje do lewej polowy, resztę do prawej.
  5. W pkt 4 dostałem dwa zakresy z przypisanymi wartościami, rekurencyjnie dla obu połówek powtarzam od punktu 2

Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
W sumie można typową funkcję rozkładu zadać w postaci serii liczb (np aby przypominało rozkład normalny) oraz dla pkt 3 dać losowanie w pewnych okolicach podanej wartości. Na dodatek po zakończeniu przydzielania ilości audytów na każdy dzień można wymieszać ilości pomiędzy dniami. - _13th_Dragon 2020-08-06 13:55

Pozostało 580 znaków

Odpowiedz

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0