algoritmo ganancioso js (problema de spanning tree mínimo, problema de codificação de Huffman)

1. Problema da árvore geradora mínima (problema da árvore geradora mínima):

Suponha que exista um gráfico conectado não direcionado e que cada aresta do gráfico tenha um peso. O problema da árvore geradora mínima requer encontrar uma árvore que contenha todos os vértices do grafo, de modo que a soma dos pesos das arestas da árvore seja minimizada.

A seguir está um exemplo de código para resolver um problema de árvore geradora mínima usando o algoritmo de Prim:

function prim(graph) {
  const n = graph.length;
  const visited = Array(n).fill(false);
  const key = Array(n).fill(Number.MAX_VALUE);  // 记录每个顶点的最小权重
  const parent = Array(n).fill(-1);  // 记录每个顶点的父节点

  key[0] = 0;  // 从第一个顶点开始构建最小生成树
  for (let i = 0; i < n - 1; i++) {
    const u = findMinKey(key, visited);
    visited[u] = true;

    for (let v = 0; v < n; v++) {
      if (graph[u][v] !== 0 && !visited[v] && graph[u][v] < key[v]) {
        key[v] = graph[u][v];
        parent[v] = u;
      }
    }
  }

  return parent;
}

function findMinKey(key, visited) {
  const n = key.length;
  let minKey = Number.MAX_VALUE;
  let minIndex = -1;

  for (let v = 0; v < n; v++) {
    if (!visited[v] && key[v] < minKey) {
      minKey = key[v];
      minIndex = v;
    }
  }

  return minIndex;
}

const graph = [
  [0, 2, 0, 6, 0],
  [2, 0, 3, 8, 5],
  [0, 3, 0, 0, 7],
  [6, 8, 0, 0, 9],
  [0, 5, 7, 9, 0]
];

console.log(prim(graph));  // 输出:[ -1, 0, 1, 0, 1 ]

No exemplo acima, o algoritmo de Prim é usado para resolver o problema da árvore geradora mínima. A ideia central do algoritmo é começar a partir de um vértice, selecionar o vértice com a menor distância da árvore geradora atual a cada vez e adicioná-lo à árvore geradora até que a árvore geradora contenha todos os vértices. A função `prim` retorna um array `parent`, que representa o nó pai de cada vértice, construindo assim uma árvore geradora mínima.

2. Problema de codificação de Huffman (problema de codificação de Huffman):

A codificação Huffman é um método de codificação de comprimento variável que constrói uma árvore de código de prefixo de acordo com a frequência dos caracteres, de modo que caracteres com alta frequência tenham códigos mais curtos, enquanto caracteres com baixa frequência tenham códigos mais longos. A seguir está um exemplo de uso do algoritmo ganancioso para resolver o problema de codificação de Huffman:

class Node {
  constructor(value, freq) {
    this.value = value;
    this.freq = freq;
    this.left = null;
    this.right = null;
  }
}

function buildHuffmanCodingTree(arr) {
  const n = arr.length;
  const pq = new PriorityQueue((a, b) => a.freq - b.freq);

  for (let i = 0; i < n; i++) {
    pq.enqueue(new Node(arr[i].value, arr[i].freq));
  }

  while (pq.size() > 1) {
    const left = pq.dequeue();
    const right = pq.dequeue();
    const parent = new Node(null, left.freq + right.freq);
    parent.left = left;
    parent.right = right;
    pq.enqueue(parent);
  }

  return pq.dequeue();
}

function buildHuffmanCodeTable(root) {
  const codeTable = {};

  function traverse(node, code) {
    if (node.value) {
      codeTable[node.value] = code;
    } else {
      traverse(node.left, code + "0");
      traverse(node.right, code + "1");
    }
  }

  traverse(root, "");

  return codeTable;
}

const arr = [
  { value: "a", freq: 3 },
  { value: "b", freq: 6 },
  { value: "c", freq: 2 },
  { value: "d", freq: 1 }
];

const root = buildHuffmanCodingTree(arr);
const codeTable = buildHuffmanCodeTable(root);

console.log("Huffman Code Table:");
for (let key in codeTable) {
  console.log(key + ": " + codeTable[key]);
}

No exemplo acima, primeiro criamos uma classe `Node` para representar o nó da árvore de Huffman, onde `value` armazena o caractere, `freq` armazena a frequência, `left` e `right` armazenam o nó filho esquerdo e os nós filhos certos.

Em seguida, usamos uma Fila Prioritária (Priority Queue) para classificar os nós por frequência. No processo de construção da árvore de codificação de Huffman, retiramos os dois nós com menor frequência da fila a cada vez, mesclamos-os em um novo nó pai e reinserimos o nó pai na fila até que haja apenas um nó é o nó raiz.

Finalmente, percorremos a árvore recursivamente, geramos um código Huffman para cada caractere e armazenamos os códigos em `codeTable`.

No exemplo acima, tomamos a frequência dos caracteres `'a'`, `'b'`, `'c'` e `'d'` como `{ valor: "a", freq: 3 }`, `{ value : "b", freq: 6 }`, `{ value: "c", freq: 2 }` e `{ value: "d", freq: 1 }`, construa uma árvore Huffman e gere cada Codificação Huffman correspondente aos caracteres.

A saída é:

Huffman Code Table:
a: 01
b: 1
c: 00
d: 001

O exemplo acima é um exemplo do uso de um algoritmo ganancioso para resolver um problema de codificação de Huffman. Através da estratégia gananciosa, a solução ótima no estado atual é selecionada a cada vez para construir uma árvore de codificação, de modo a obter a codificação ótima de cada caractere.
 

Supongo que te gusta

Origin blog.csdn.net/weixin_39273589/article/details/132539717
Recomendado
Clasificación