Os quatro algoritmos do TCC, executados ao vivo no seu navegador sobre os dados reais do Painel Oncologia Brasil. Rode, veja o passo a passo e valide cada afirmação do trabalho.
O pipeline completo roda no navegador. Cada etapa registra contadores e tempo de parede (ms) — exatamente as cinco etapas da Seção 3 do TCC.
Distância geodésica entre duas capitais, memorizada num cache bidirecional: (u,v) e (v,u) compartilham a mesma entrada. Troque as UFs e observe os cache hits.
const R = 6371; // raio médio da Terra (km)
const distCache = new Map(); // cache bidirecional
function haversine(u, v) {
const key = u < v ? u+'|'+v : v+'|'+u; // chave canônica → (u,v)≡(v,u)
if (distCache.has(key)) return distCache.get(key); // hit O(1)
const [la1,lo1]=rad(u), [la2,lo2]=rad(v);
const dphi=la2-la1, dlam=lo2-lo1;
const a = Math.sin(dphi/2)**2 + Math.cos(la1)*Math.cos(la2)*Math.sin(dlam/2)**2;
const c = 2*Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
const d = R*c; distCache.set(key, d); return d;
}Grafo dirigido ponderado G = (V, E) por percurso linear. Cada aresta (u → v) acumula pacientes que partiram da UF u e foram diagnosticados em v; a diagonal são os auto-loops.
function buildFlowGraph(registros) {
const G = {}; // lista de adjacências: G[u][v]=peso
for (const rec of registros) { // percurso linear único — O(n)
const {u, v, w} = rec;
if (!G[u]) G[u] = {};
G[u][v] = (G[u][v] || 0) + w; // acumula peso da aresta
}
return G;
}In-degree ponderado identifica os polos de recepção (hubs). Out-degree relativo mede a evasão. Auto-retenção mede a autossuficiência diagnóstica.
function weightedInDegree(G) {
const indeg = {};
for (const u in G)
for (const v in G[u]) indeg[v] = (indeg[v]||0) + G[u][v]; // O(|E|)
return indeg;
}
function outDegreeRel(G, u) {
let total=0, interno=G[u][u]||0;
for (const v in G[u]) total += G[u][v];
return { evasao:(total-interno)/total, retencao:interno/total };
}Árvore Geradora Mínima sobre o grafo de distâncias entre as 27 capitais. Clique em Animar e veja o algoritmo guloso decidir, aresta por aresta, ACEITAR (une componentes) ou REJEITAR (formaria ciclo — detectado pelo Union-Find).
class UnionFind {
constructor(n){ this.parent=[...Array(n).keys()]; this.rank=Array(n).fill(0); }
find(x){ while(this.parent[x]!==x){ this.parent[x]=this.parent[this.parent[x]]; x=this.parent[x]; } return x; } // compressão de caminho
union(a,b){ let ra=this.find(a), rb=this.find(b);
if(ra===rb) return false; // ciclo
if(this.rank[ra]<this.rank[rb]) [ra,rb]=[rb,ra]; // união por posto
this.parent[rb]=ra; if(this.rank[ra]===this.rank[rb]) this.rank[ra]++; return true; }
}
function kruskal(n, edges){
edges.sort((x,y)=>x.w-y.w); // O(|E| log |E|) — domina
const uf=new UnionFind(n), mst=[]; let total=0;
for(const e of edges){ if(uf.union(e.u,e.v)){ mst.push(e); total+=e.w; } if(mst.length===n-1) break; }
return {mst, total};
}Medição de tempo real para comprovar as classes de complexidade afirmadas na Seção 3.7 do TCC. A construção do grafo cresce linearmente com n (O(n)); Kruskal cresce como |E| log |E|.
tempo × nº de registros processados
tempo × |E| (grafos completos sintéticos)
Cada afirmação central do trabalho é verificada automaticamente contra a saída dos algoritmos. Tudo verde = os resultados do TCC são reproduzidos pelo código.
Os dados embutidos são a extração do Painel Oncologia Brasil (residência → diagnóstico). A banca pode carregar outra extração no mesmo formato e re-rodar todo o pipeline — provando que nada está pré-calculado.