J; aș dori să scriu un algoritm „shuffle final” pentru a-mi sorta colecția de mp3

Caut sugestii de pseudocod pentru sortează fișierele mele mp3 pentru a evita repetarea titlurilor și a artiștilor . Ascult crooneri - Frank Sinatra, Tony Bennett, Ella Fitzgerald etc., cântând standarde vechi. Fiecare artist înregistrează mai multe dintre aceleași melodii - Fly Me To The Moon, What You Watch Tonight, Stardust etc. Scopul meu este să organizez melodiile (sau să comand lista de redare) cu spațiul maxim dintre artiști și titlurile melodiilor. Deci, dacă am 2000 de melodii și 20 sunt de la Ella, aș vrea să o aud doar o dată din 100 de melodii. Dacă 10 artiști cântă Fly Me To The Moon, aș vrea să o aud o dată în 200 de melodii. Desigur, vreau să combin aceste două cerințe pentru a crea „amestecul final”.

algoritm

Știu că întrebarea este destul de deschisă. Nu am început încă să îl programez, așa că caut doar sugestii pentru o abordare bună. De fapt, am alte cerințe pentru spațierea regulată a celorlalte atribute ale melodiei, dar nu voi intra în detalii aici.

Ca punct de plecare, modific codul pe care l-am găsit aici pentru a manipula fișiere mp3 și a citi etichete ID3.

Am scris o mică aplicație care răspunde nevoilor mele folosind răspunsul lui parsifal de mai jos. Am scris aici și o întrebare de urmărire. Vă mulțumim pentru toate răspunsurile corecte!

Doriți să rulați programul o dată și să generați o listă de redare sau să alegeți live melodia următoare?

În cazul din urmă, răspunsul este simplu:

  • Creați un tabel care conține toate melodiile dvs., cu artist și titlu.
  • Creați o listă (o listă legată este mai bună) pentru a conține titlurile pieselor redate recent. Această listă este goală la început și de fiecare dată când redați o melodie o adăugați la listă. Când lista afișează dimensiunea dorită „fără melodie repetată”, ștergeți cea mai veche (prima) intrare.
  • Idem pentru o listă de artiști.

Alegerea unei melodii devine apoi următoarea secvență de pași:

  1. Alegeți aleatoriu o melodie din tabelul „toate melodiile”. Acesta este doar un număr aleatoriu între 0 și dimensiunea matricei.
  2. Vedeți dacă această melodie este deja în lista melodiilor redate. Dacă da, reveniți la pasul 1.
  3. Vedeți dacă artistul este deja în lista artiștilor jucați. Dacă da, reveniți la pasul 1.
  4. Adăugați artistul/titlul melodiilor la listele corespunzătoare, ștergând intrările vechi, dacă este necesar.
  5. Redați melodia.

Există mai multe probleme posibile, dar acestea ar trebui să conteze doar dacă faceți acest lucru ca o misiune și nu ca un proiect real.

  • Așa cum a spus @Dukeling într-un comentariu, dacă colecția dvs. este în mod dramatic dezechilibrată în favoarea unui singur artist sau a unui titlu de melodie, s-ar putea să vă pierdeți într-o buclă în care respingeți în mod constant melodiile. În practică, aceasta nu va fi o problemă. Soluția este de a reduce dimensiunea listelor „deja văzute”. Și adăugarea contoarelor în pașii 2 și 3 vă poate spune dacă aceasta este o problemă (dacă vedeți 10 eșecuri la rând, declanșați un avertisment și/sau reduceți dimensiunea listei).
  • Dacă încercați să creați o listă de redare care să redea toate melodiile o dată, trebuie să eliminați melodiile din matricea sursă. De asemenea, va schimba modul în care vă confruntați cu prea mulți șahuri „jucate recent” (pentru că ați putea ajunge doar cu un singur artist în placa sursă).
  • Dacă etichetele dvs. ID3 arată ca ale mele, acestea conțin o mulțime de erori de ortografie. „Duke Ellington” trebuie să fie diferit de „Duke Elingten”? Dacă da, luați în considerare utilizarea unui potrivitor Levenstein atunci când navigați pe listele „jucate recent”.

Am făcut deja așa ceva înainte de a folosi un generator (în C #, o buclă infinită care se potrivește cu fiecare iterație de buclă). Fiecare iterație își examinează grupul de melodii (sau orice altceva) și le elimină pe cele care au fost redate prea recent (sau indiferent de criteriile negative). Apoi alegeți una din lista filtrată și vă actualizați starea. Pe măsură ce starea ta evoluează (cânți melodii care nu sunt Sinatra), criteriile se prăbușesc și melodiile tale excluse încep să fie reincluse.

Desigur, există cazuri de rezolvat:

  • Ce se întâmplă dacă arunci toate melodiile? (de obicei alegeți unul la întâmplare, în speranța destabilizării statului)
  • Există criterii care ar trebui preferate? (De obicei, s-ar putea să nu doriți să jucați Fly Me to the Moon din spate în spate și preferați să nu jucați Sinatra, dar dacă asta este tot ce aveți.)
  • Ce se întâmplă dacă colecția dvs. de melodii este actualizată în timpul unei lupte? (în general ușor de gestionat, dar concurența poate fi o problemă în funcție de utilizare)

Ignorând valorile aberante din întrebarea dvs. ridicată de Telastyn, se pare că aveți o variantă a problemei rucsacului. Din fericire, acesta este un algoritm destul de bine documentat.

Pentru un set de articole, fiecare cu o greutate și o valoare, determinați numărul de articole care trebuie incluse într-o colecție, astfel încât greutatea totală să fie mai mică sau egală cu o anumită limită și valoarea totală să fie cât mai mare posibil.

Unele variante potențial relevante sunt enumerate în acest articol, împreună cu o listă suplimentară de probleme legate de rucsac.

O variantă a problemei rucsacului este problema rucsacului multifuncțional. Algoritmul coloniilor de furnici este sugerat ca o modalitate de a rezolva această problemă. Abordarea „coloniei de furnici” ar putea fi cea mai ușoară cale de a evita aspectele dificile ale întrebării dvs.