Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
D
dct
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
ISC3
compression
dct
Commits
8d8fbe98
Verified
Commit
8d8fbe98
authored
1 month ago
by
iliya.saroukha
Browse files
Options
Downloads
Patches
Plain Diff
wip: wrote part about encoding
parent
8a55fcc8
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
report/report.qmd
+139
-0
139 additions, 0 deletions
report/report.qmd
with
139 additions
and
0 deletions
report/report.qmd
+
139
−
0
View file @
8d8fbe98
...
...
@@ -230,3 +230,142 @@ le résultat de la DCT, de son inverse, de la DCT quantifiée et finalement de
l'inverse quantifiée.
# Huffman Adaptatif
Dans ce travail pratique nous allons implémenter l'algorithme de compression
Huffman Adaptatif. Celui-ci aura pour but de construire un arbre binaire où
chaque noeud **externe** représentera un caractère dans la chaîne fournie pour
l'encodage et la valeur des noeuds **internes** correspondra à la somme des
poids de ses enfants (i.e. nombre d'occurrence du caractère).
## Structure de l'arbre
Pour la structure de l'arbre binaire, nous avons privilégié l'utilisation des
`dataclass` en `python` qui peuvent s'apparenter à de simples structures tels
qu'elles existent en `C`. Ceci nous permet d'éviter d'écrire des constructeurs
et des méthodes spécifiques à cette classe. Il est possible de se rendre compte
que la structure est bel et bien récursive du fait que les champs `left` et
`right` sont des références vers le même type `Node`.
```python
@dataclass
class Node:
weight: int = 0
nyt_code: str | None = None
value: str = "NYT"
left: Node | None = None
right: Node | None = None
```
## Encodage
Dans la phase d'encodage, le but sera donc de construire itérativement l'arbre
en y insérant au fur et à mesure les caractères rencontrés dans la chaîne
fournie à la fonction d'encodage. Celle-ci est présentée ci-dessous :
```python
def encode(input: str) -> str:
tree = Node()
encoded: list[str] = []
seen: set[str] = set()
for c in input:
insert_char(tree, c)
prefix = find_char(tree, c)
if c not in seen:
seen.add(c)
encoded.append(prefix.nyt_code)
encoded.append(compute_code(c))
else:
encoded.append(compute_prefix(tree, c))
pprint.pp(tree)
pprint.pp(tree)
print(f'Nombre de swaps: {swap_count}')
return ' '.join(encoded)[1:]
```
Nous allons donc commencer par insérer dans l'arbre le nouveau caractère
rencontré via la fonction `insert_char`. Suite à cela nous ferons une recherche
dans l'arbre pour calculer la partie NYT (_Not Yet Transmitted_) qui servira
de préfixe au code fixe du caractère. Si ce caractère n'a pas encore été
rencontré, il sera aussi inséré dans une structure de données de type `set` qui
permet de stocker des données sans doublons. Ceci est critique du fait que
le code NYT établi à l'insertion initiale du caractère a possiblement changé
suite aux divers _swaps_ qui ont possiblement eu lieu. Ces _swaps_ se produisent
lorsque le poids du sous-arbre gauche est supérieur à celui de droite. Par
conséquent, si nous allons insérer à nouveau un caractère connu au préalable
(i.e. présent dans le `set`), nous allons recalculer le préfixe NYT du caractère
via la fonction `compute_prefix` en parcourant l'arbre jusqu'à retrouvé ce
caractère.
### Résultat de l'encodage
Pour la chaîne de caractères "darkvador", le résultat de l'encodage sera le
suivant :
```bash
Nombre de swaps: 4
Code final: 000011 0 000000 00 01101 100 00110 1100 10001 10 0 11100 01010 110
```
Ci-dessous, le lecteur peut observer l'arbre qui fut construit dynamiquement au
moment de l'encodage. Il est nécessaire de mentionner le fait que le champ
`value` des noeuds internes est égale à `NYT` du fait que c'est la valeur par
défaut d'un noeud de type `Node`, cependant le **vrai** noeud NYT est celui dont
la valeur du champ `weight` est égale à 0. Celui-ci est donc aussi le noeud
terminal de l'arbre.
```bash
Node(weight=9,
nyt_code=None,
value='NYT',
left=Node(weight=2, nyt_code='', value='d', left=None, right=None),
right=Node(weight=7,
nyt_code=None,
value='NYT',
left=Node(weight=2,
nyt_code='0',
value='a',
left=None,
right=None),
right=Node(weight=5,
nyt_code=None,
value='NYT',
left=Node(weight=2,
nyt_code='00',
value='r',
left=None,
right=None),
right=Node(weight=3,
nyt_code=None,
value='NYT',
left=Node(weight=1,
nyt_code='100',
value='k',
left=None,
right=None),
right=Node(weight=2,
nyt_code=None,
value='NYT',
left=Node(weight=1,
nyt_code=None,
value='NYT',
left=Node(weight=0,
nyt_code=None,
value='NYT',
left=None,
right=None),
right=Node(weight=1,
nyt_code='11100',
value='o',
left=None,
right=None)),
right=Node(weight=1,
nyt_code='1100',
value='v',
left=None,
```
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment