Cine sunt oamenii dificili? Ce este dificultatea în minerit? Folosind Bitcoin ca exemplu, O(log n) este complexitatea logaritmică.

Ce este dificultatea în minerit? Folosind Bitcoin ca exemplu.

Exploatarea criptomonedei poate fi o investiție foarte profitabilă. Dar pentru a câștiga bani din minerit valutar, trebuie să înțelegeți bine nuanțele industriei. Unul dintre cele mai importante concepte pentru orice miner este dificultatea mineritului. Venitul depinde direct de dificultatea exploatării miniere. Acest articol descrie în detaliu ce este dificultatea de minerit, cum se formează și de ce depinde.

Ce înseamnă termenul „dificultate în minerit”?

Miningul criptomonedelor este un proces care implică generarea de noi blocuri ale lanțului blockchain și înregistrarea tranzacțiilor. Minerii pot fi comparați cu contabilii care lucrează în mod constant pentru a-și menține registrele la zi prin înregistrarea tuturor transferurilor. Dar orice muncă trebuie plătită. Minerii primesc o recompensă din partea sistemului sub formă de monede din moneda extrasă.

Una dintre caracteristicile criptomonedelor este natura lor deflaționistă. Aceasta înseamnă că numărul total de monede extrase nu poate depăși numărul specificat de codul programului. De exemplu, suma maxima Bitcoinii sunt egali cu 21 de milioane de monede. Mai mult, ultimul Bitcoin va fi extras abia în 2140. În ciuda numărului de mineri, doar 12,5 BTC sunt extrași la fiecare 10 minute. Aceste monede sunt distribuite între mineri în funcție de puterea de calcul cheltuită. Recompensa pentru un bloc semnat nu crește (și la fiecare 4 ani este chiar redusă la jumătate). Și dacă numărul de mineri crește, atunci venitul fiecărui miner individual scade proporțional. Odată cu apariția din ce în ce mai mulți criptomineri noi, concurența pentru recompense limitate este în creștere.

Pentru a demonstra în mod clar această situație, a fost introdus un parametru calculat al rețelei de criptomonede „dificultatea minării”. Dificultatea de minerit este o metrică care reflectă cât de dificil este să rezolvi problema matematică pentru a semna un bloc și a primi o recompensă pentru el. Dificultatea este recalculată automat după o anumită perioadă de timp. Este diferit pentru fiecare criptomonedă. De exemplu, dificultatea minării Bitcoin este recalculată la fiecare bloc din 2016, a căror extragere durează aproximativ 2 săptămâni. Conform codul programului, dificultatea este ajustată astfel încât căutarea următorului bloc durează aproximativ 10 minute, indiferent de numărul de mineri și de hashrate-ul total.

Dificultatea crește automat dacă căutarea ultimelor blocuri din 2016 a durat mai puțin de două săptămâni. Acest lucru sugerează că puterea totală de calcul a dispozitivelor miniere a crescut. În schimb, un semnal de reducere a complexității va fi o încetinire a căutării blocurilor din 2016, deoarece hashrate-ul tuturor dispozitivelor a scăzut. Rezultatul este un control strict asupra ratei cu care sunt emise monede noi.

Unde să găsești dificultăți în minerit. Dificultatea de a extrage primele 10 criptomonede.

Dificultatea de minerit este un indicator dinamic care este periodic recalculat. Pe măsură ce puterea de calcul a echipamentelor miniere crește, crește și complexitatea. Cel mai bine este să căutați informații actualizate cu privire la starea de dificultate a minării criptomonedei pe site-urile oficiale ale monedelor. Cu toate acestea, acest lucru poate fi dificil. Legăturile către statisticile miniere sunt uneori dificil de găsit chiar și pe site-urile web oficiale. Pentru a simplifica procesul, au fost create site-uri web agregatoare de informații statistice despre toate criptomonedele. Ei colectează, procesează și publică date actuale nu numai despre dificultatea exploatării miniere, ci și alte câteva zeci de indicatori: preț, capitalizare, hashrate, profitabilitate, număr de tranzacții și așa mai departe.

Informații actualizate despre peste 100 de criptomonede pot fi găsite pe următoarele site-uri web:

  • https://www.coinwarz.com/charts/difficulty-charts
  • https://bitinfocharts.com/ru/
Numele criptomonedeiCapitalizare (12.11.2017Link către diagrama de dificultate*
Bitcoin$102 337 870 442 https://blockchain.info/ru/charts/difficulty

https://bitinfocharts.com/ru/comparison/difficulty-btc-nmc.html

https://www.coinwarz.com/difficulty-charts/bitcoin-difficulty-chart

Bitcoin Cash $29 402 898 569 https://bitinfocharts.com/ru/comparison/bitcoin%20cash-difficulty.html

https://www.coinwarz.com/difficulty-charts/bitcoincash-difficulty-chart

Ethereum$28 727 632 599 https://bitinfocharts.com/ru/comparison/ethereum-dificulty.html

https://www.coinwarz.com/difficulty-charts/ethereum-difficulty-chart

Clipoci$7 559 040 243 Exploatarea minieră nu este disponibilă**
Litecoin$3 143 298 761 https://bitinfocharts.com/ru/comparison/litecoin-difficulty.html

https://www.coinwarz.com/difficulty-charts/litecoin-difficulty-chart

Dash$2 603 868 832 https://bitinfocharts.com/ru/comparison/dash-dificulty.html

https://www.coinwarz.com/difficulty-charts/dash-difficulty-chart

Ethereum Classic$1 867 386 337 https://bitinfocharts.com/ru/comparison/ethereum%20classic-difficulty.html

https://www.coinwarz.com/difficulty-charts/ethereum-classic-difficulty-chart

Monero$1 745 200 256 https://bitinfocharts.com/ru/comparison/monero-dificulty.html

https://www.coinwarz.com/difficulty-charts/monero-difficulty-chart

NEO$1 703 832 000 Exploatarea minieră nu este disponibilă**
NEM$1 595 538 000 Exploatarea minieră nu este disponibilă**

* Vă rugăm să rețineți că dificultatea extragerii se modifică în timp, astfel încât site-uri diferite pot furniza date diferite de dificultate. Uneori, diferența ajunge la 10-20% pe monedă pe două agregatoare diferite. Dacă căutați un indicator al dificultății miniere nu doar pentru a satisface curiozitatea, ci și în scopuri practice, atunci concentrați-vă pe cifrele medii. De exemplu, dacă faceți o prognoză a modificărilor dificultății miniere în viitor pe baza dinamicii istorice, atunci este mai logic să luați datele din ultimele șase luni până la un an, mai degrabă decât două până la patru săptămâni.

** Unele criptomonede nu pot fi extrase în sensul tradițional. Unii folosesc mineritul POS, în care se acumulează periodic dobândă pentru monedele din portofel. Pentru minerit POS, nu este nevoie să cumpărați echipamente specializate sau să cheltuiți bani pe energie electrică. Alte criptomonede (de exemplu, Ripple) au fost deja extrase complet și sunt redistribuite doar între proprietari.

Dificultatea mineritului: ce afectează și de ce crește.

Dificultatea minării determină venitul minerului. Numărul de monede extrase este invers proporțional cu dificultatea exploatării. Dacă dificultatea rețelei crește cu 20%, atunci venitul din criptomonede al fiecărui miner individual este redus cu 20%.

De exemplu, ASIC-ul pentru minerit bitcoin antminer s7 la mijlocul anului 2017 (mai precis, cu dificultate de la 1 iulie 2017) a extras 0,06 BTC pe lună. Dar complexitatea rețelei Bitcoin a crescut continuu. De la 1 noiembrie 2017, același echipament va produce deja 0,026 BTC pe lună. Venitul minerului a scăzut cu mai mult de jumătate în doar 4 luni.

Dar nici măcar o reducere săptămânală a veniturilor nu face investițiile miniere mai puțin atractive. Veniturile din criptomonede sunt parțial compensate de creșterea cursului de schimb la fiat. În exemplul nostru, pe 1 iulie, rata Bitcoin era de 2.400 USD, iar pe 1 noiembrie, cotațiile au crescut la aproape 6.700 USD. Se pare că veniturile minerilor fiat au crescut chiar și în ciuda creșterii rapide a complexității mineritului.

Aceasta este logica creatorilor de criptomonede cu complexitate dinamică. Și, deși nu există o relație directă între prețul unei monede și cât de dificil este să o mine, există totuși o relație indirectă. Se presupune că creșterea complexității înseamnă o creștere a popularității criptomonedei în rândul populației generale. Cineva care învață despre monedele descentralizate va încerca să mine. Acest lucru va duce la o complexitate crescută. Dar, în același timp, este foarte probabil să crească cererea și, prin urmare, cursul de schimb. Se pare că interesul tot mai mare pentru societate stimulează atât creșterea cursului de schimb, cât și creșterea complexității mineritului.

Din punct de vedere tehnic, indicatorul de dificultate în minerit depinde de:

  • hashrate de rețea (numărul și puterea de calcul a echipamentelor tuturor minerilor);
  • viteza de exploatare a blocurilor 2016;

Toți cei trei indicatori sunt direct legați. Creșterea hashrate-ului rețelei înseamnă că noi participanți s-au alăturat industriei miniere și concurența a crescut. Pe măsură ce numărul de mineri crește, timpul petrecut căutând următorul bloc scade. După blocul 2016, dificultatea de exploatare este recalculată. Modificarea indicatorului este descrisă de următorul model:

Dificultatea minării Bitcoin.

Creșterea complexității se datorează unui număr de factori care sunt strâns legați:

  • dezvoltarea cipurilor ASIC și intrarea pe piață a modelelor mai productive;
  • popularizarea Bitcoin și afluxul de noi mineri;
  • randament ridicat al investiției în minerit datorită creșterii rapide a cursului de schimb Bitcoin față de dolar;
  • transferul puterii de calcul din alte valute ale căror cotații scad sau cresc mai lent decât Bitcoin;
  • alti factori;

Dificultatea de a extrage Bitcoin a crescut de 5-6 ori din 2016. Creșterea a continuat aproape neîntrerupt. Abia în august 2017, pentru prima dată într-un an, s-a înregistrat o scădere a indicatorului. Poate că acest lucru a fost influențat de SegWit-ul din august al Bitcoin, care a forțat unii mineri să transfere puterea către altcoins.

Probabil ați întâlnit notații precum O(log n) de mai multe ori sau ați auzit expresii precum „logaritmic complexitate de calcul» la orice algoritm. Și dacă încă nu înțelegi ce înseamnă asta, acest articol este pentru tine.

Evaluare de dificultate

Complexitatea algoritmilor este de obicei măsurată prin timpul lor de execuție sau prin utilizarea memoriei. În ambele cazuri, complexitatea depinde de dimensiunea datelor de intrare: o matrice de 100 de elemente va fi procesată mai repede decât una similară de 1000. Cu toate acestea, puțini oameni sunt interesați de ora exactă: depinde de procesor, tipul de date. , limbaj de programare și mulți alți parametri. Numai complexitatea asimptotică este importantă, adică complexitatea când dimensiunea datelor de intrare tinde spre infinit.

Să presupunem că un algoritm trebuie să efectueze 4n 3 + 7n operații condiționate pentru a procesa n elemente ale datelor de intrare. Pe măsură ce n crește, timpul final de funcționare va fi semnificativ mai afectat prin ridicarea lui n la un cub decât prin înmulțirea lui cu 4 sau adăugarea lui 7n. Apoi ei spun că complexitatea de timp a acestui algoritm este O(n 3), adică depinde cub de dimensiunea datelor de intrare.

Utilizarea majusculului O (sau așa-numita notație O) provine din matematică, unde este folosită pentru a compara comportamentul asimptotic al funcțiilor. În mod formal, O(f(n)) înseamnă că timpul de rulare al algoritmului (sau cantitatea de memorie ocupată) crește în funcție de dimensiunea datelor de intrare nu mai repede decât o constantă înmulțită cu f(n) .

Exemple

O(n) - complexitate liniară

De exemplu, algoritmul pentru găsirea celui mai mare element dintr-o matrice nesortată are această complexitate. Va trebui să trecem prin toate cele n elemente ale matricei pentru a înțelege care dintre ele este maximul.

O(log n) - complexitate logaritmică

Cel mai simplu exemplu este căutarea binară. Dacă matricea este sortată, putem verifica dacă conține o anumită valoare folosind metoda de înjumătățire. Să verificăm elementul din mijloc, dacă este mai mare decât cel pe care îl căutăm, atunci vom arunca a doua jumătate a matricei - cu siguranță nu este acolo. Dacă este mai puțin, atunci invers - vom arunca jumătatea inițială. Și așa vom continua să împărțim în jumătate, iar la final vom verifica log n elemente.

O(n 2) - complexitate pătratică

De exemplu, algoritmul de sortare prin inserare are această complexitate. În implementarea canonică, constă din două bucle imbricate: una pentru a parcurge întreaga matrice, iar a doua pentru a găsi locul următorului element din partea deja sortată. Astfel, numărul de operații va depinde de dimensiunea matricei ca n * n, adică n 2.

Există și alte evaluări de dificultate, dar toate se bazează pe același principiu.

De asemenea, se întâmplă ca timpul de rulare al algoritmului să nu depindă deloc de dimensiunea datelor de intrare. Apoi complexitatea este notată ca O(1) . De exemplu, pentru a determina valoarea celui de-al treilea element al unui tablou, nu trebuie să vă amintiți elementele sau să le parcurgeți de multe ori. Întotdeauna trebuie să așteptați al treilea element din fluxul de date de intrare și acesta va fi rezultatul, care necesită același timp pentru a calcula pentru orice cantitate de date.

Același lucru este valabil și pentru evaluările de memorie atunci când acest lucru este important. Cu toate acestea, algoritmii pot folosi mult mai multă memorie atunci când măresc dimensiunea datelor de intrare decât alții, dar totuși rulează mai rapid. Si invers. Acest lucru ajută la alegerea celor mai bune modalități de rezolvare a problemelor pe baza condițiilor și cerințelor actuale.

6 răspunsuri

Complexitatea este întotdeauna specificată în raport cu o anumită variabilă sau un set de variabile. Deci, când standardul vorbește despre inserarea timpului constant, vorbim despre timp constant raportat la numărul de elemente din listă. Adică, inserarea O(1) înseamnă că numărul de elemente prezente în listă nu afectează complexitatea generală a inserărilor. Lista poate conține 500 sau 50000000 de elemente, iar complexitatea operației de inserare va fi aceeași.

De exemplu, std::list are inserții și ștergeri O(1); numărul de elemente din listă nu depinde de complexitatea inserărilor. Cu toate acestea, complexitatea alocării memoriei poate depinde de numărul de lucruri care au fost deja alocate. Dar din moment ce O(1) vorbește despre numărul de elemente din listă, nu acoperă asta. Și acest lucru nu este presupus, pentru că atunci am măsura complexitatea alocatorului de memorie, nu structura datelor.

Pe scurt: aceasta este o altă dimensiune.

Aceasta înseamnă că ne putem implementa algoritmul cât de puternic ne place, inclusiv unul în care timpul nu este de fapt constant în niciun sens pragmatic, dar în care am respectat numărul de „operații” asupra obiectelor conținute.

Complexitatea nu este specificată în raport cu implementările. Este specificat în raport cu algoritmi. Nu contează că contextul se poate schimba, deoarece timpul de execuție nu este o sarcină dificilă.

Ca mai sus, puteți implementa std::list cu un alocator de memorie care este O(log(n)) în ceea ce privește ștergerile (unde n este numărul de alocări). Cu toate acestea, ștergerea unui element din listă va fi în continuare O(1) în raport cu numărul de elemente din listă.

Nu confunda complexitatea cu performanța generală. Scopul complexității este de a avea o metrică comună pentru algoritmi cu privire la diferite variabile. Scopul unui programator care dorește ca codul să ruleze rapid este să găsească o implementare rezonabilă a algoritmului care să se potrivească cu complexitatea necesară pentru a atinge acea performanță.

Complexitatea este un instrument de evaluare a eficacității unui algoritm. Complexitatea nu înseamnă că te poți opri din gândire.

Ce înseamnă mai exact „depreciere”?

După cum am înțeles, complexitatea constantă înseamnă că operația este O(1): puteți spune în avans câte operații atomice (citire/scriere, instrucțiuni de asamblare, orice) vor fi efectuate. Și această estimare este o limită comună pentru toate stările posibile ale obiectului țintă. Există o captură aici: într-un mediu cu mai multe fire, nu puteți prezice comutatoarele de flux, așa că puteți doar să vă gândiți la timpul de rulare scurs într-un sistem de operare în timp real.

Despre complexitatea constantă amortizată, este și mai slabă. Prin scrierea unui rezumat al răspunsurilor, acest lucru vă asigură că, în medie, operațiunea dvs. este în desfășurare. Aceasta înseamnă că numărul de operații elementare pentru N operații ulterioare este O(N) . Aceasta înseamnă că numărul de operații elementare este de aproximativ O(1), dar permite unele salturi rare. De exemplu, adăugarea unui element la coada unui vector este de obicei permanentă, dar uneori este necesară ridicarea greutății suplimentare; a avea timp constant amortizat înseamnă că operațiunea suplimentară nu este efectuată la fel de des și durează o perioadă de timp previzibilă, astfel încât timpul total de operare N este încă O(N) . Desigur, aceeași captură se aplică aici.

Deci, pentru a vă răspunde la întrebări:

  • Garanțiile complexe ale standardului se aplică într-adevăr doar numărului de instrucțiuni de cod de mașină necesare pentru a efectua o operație și nu implică faptul că timpul de execuție este în vreun fel limitat. (Într-adevăr, până de curând C++ nu avea nici măcar un indicator de subiect legat de limbaj, așa că dintr-o perspectivă standard C++, până în acest moment programul era executat pe o mașină C++ specializată.)
  • Amortizarea este „limitată la o constantă în medie”, ceea ce apare de obicei în cazul unui timp de funcționare limitat aproape întotdeauna constant cu unele abateri destul de rare.

Editați | ×:
Puteți consulta, de exemplu, secțiunea 23.1 a standardului C++:

Toate cerințele de complexitate din această secțiune sunt specificate numai în ceea ce privește numărul de operații asupra obiectelor conținute.

când se spune că o operație are „complexitate constantă”, de obicei se referă în primul rând la complexitatea timpului. Aș putea să mă refer la complexitatea spațială, dar dacă acesta este cazul, ar fi declarat în mod explicit ca normal.

Acum, complexitatea unei operații se referă la cât de mult timp pentru a finaliza o operație va crește atunci când crește numărul de elemente procesate în operație. Pentru o operație de complexitate constantă, funcția va dura aceeași perioadă de timp indiferent dacă sunt procesate zero articole sau zece milioane de articole.

    swap() este o complexitate constantă, deoarece indiferent câte elemente sunt în vector, operația va dura același timp.

    faceți clic pe listă. este o complexitate constantă deoarece, deși poate dura ceva timp pentru a aloca un nou element, acest timp de alocare nu crește deoarece lista conține 10 milioane de elemente (cel puțin nu în sens algoritmic - desigur, dacă memorie libera devine mai mare și mai epuizată, alocarea poate dura mai mult, dar din punct de vedere algoritmic există o cantitate infinită de memorie).

    push_back() pe un vector se numește constanta „amortizată” deoarece, în cazul normal, când realocarea nu ar trebui să aibă loc, timpul pe care o va dura operația nu este legat de câte elemente sunt deja în vector - aceeași cantitate de este nevoie de timp pentru a adăuga un nou element la un vector de lungime zero în raport cu un vector de lungime de 10 milioane. Cu toate acestea, dacă vectorul trebuie realocat, va fi necesar să aveți o copie a elementelor existente și aceasta nu este o operație constantă - este o operație liniară. Dar vectorul ar trebui să fie proiectat în așa fel încât realocările să apară rar, astfel încât să poată fi amortizate pe mai multe operațiuni push_back().

dar a face push_back pe un vector este și mai imprevizibil. De cele mai multe ori acest lucru va fi foarte rapid, dar din când în când va trebui să realoce spațiul pentru toate datele și să copieze fiecare element într-o nouă locație. Deci este mai puțin previzibil în ceea ce privește timpul de execuție decât list::push_front singur, dar se numește totuși persistent (amortizat). În medie, adăugarea unei cantități mari de date la un vector va lua o complexitate care este independentă de cantitatea adăugată, motiv pentru care se numește timp „constantă amortizată”. (Dreapta?)

Complexitatea este O(1) - o constantă (ținând cont de complexitatea timpului) înseamnă că timpul de finalizare a algoritmului nu este legat de dimensiunea problemei.

Deci, căutarea unei valori într-o structură hashed este O(1), deoarece timpul necesar pentru a face acest lucru este independent de numărul valorilor sale. Cu toate acestea, nu același lucru se aplică unei liste legate, deoarece trebuie să scanăm valorile (al căror număr se modifică pe măsură ce numărul de elemente crește) pentru a ne găsi valoarea.

În cazul 3, când copiază fiecare element, nu este o operație O(1), ci o operație O(N) (dar de cele mai multe ori este O(1), deci este de obicei constantă). Amortizarea ia în considerare acest lucru observând că algoritmul se finalizează de obicei în timp O(1) și rareori se încadrează în acest caz O(N).



Se încarcă...
Top