Código PHP:
<?
/**
* CalculadoraEscons.php
* Versi—: 1.1 (calcula el quocient sense arrodonir i ordena els partits per vots abans de calcular)
*
* Data de creaci—: 2007-05-20
* Autor: Manel Zaera ([email protected])
* Descripci—: Classe que permet calcular els vots corresponents a una llista de partits segons la llei d'Hondt
*
* Llicncia: Aquest programari es distribueix amb llicncia GNU GPL, la qual podeu consultar a http://www.gnu.org/copyleft/gpl.html
*
*
* òs:
*
* $aPartits = array('CiU' => 4367,'PSC' => 2252, 'ERC' => 2131,'ICV' => 403,'PP' => 287,'IPE' => 234);
* $aCalc = new CalculadoraEscons(17,array('CiU','PSC','ERC', 'ICV', 'PP', 'IPE'));
* $aEscons = $aCalc->calcula($aPartits);
*
*/
class CalculadoraEscons {
private $iNumEscons = 0; // Numero de escaños
private $aPartits = null; // Lista de partidos
private $aEsconsPartits = null; // Lista de partidos, con los cocientes de los votos de los partidos que han proporcionado algún escaño
private $aTaulaTreball = null; // Mesa de trabajo, donde se van acumulando los cocientes de los votos de los partidos
private $iNumEsconsProcessats = 0; // Número de escaños procesados en el actual iteración
/**
* Crea el objeto CalculadoraEscons
*/
public function __construct() {
}
/**
* Calcula els escons que toquen a cada partit
* @param $aVotsPartits Llista de vots de cada partit
* amb el format ['A' => XXXXX, 'B' => XXXXX,...]
* @param $iNumEscons Número d'escons per repartir
*
* @return Llista d'escons per partit, amb el format
* ['A' => 5, 'B =>4,...]
*/
public function calcula($aVotsPartits,$iNumEscons) {
$this->iNumEscons = $iNumEscons;
$aPartitsVots = array_flip($aVotsPartits);
sort($aPartitsVots);
$this->aPartits = array_keys(array_flip($aPartitsVots));
for ($i=0;($i<$this->iNumEscons && $this->iNumEsconsProcessats < $this->iNumEscons);$i++) {
$this->actualitzaTaulaTreball($aVotsPartits,$i+1);
$this->calculaPartitEsco();
}
return $this->escons();
}
/*
* Actualitza la taula de treball amb una nova iteraci— de quocients
* @param $aVotsPartits Dades dels vots obtinguts per cada partit
* @param $iDen Denominador del quocient que es calcularˆ
*/
private function actualitzaTaulaTreball($aVotsPartits,$iDen) {
$aClaus = $this->aPartits;
foreach ($aClaus as $aPartit) {
$this->aTaulaTreball[$aPartit][$iDen-1] = $aVotsPartits[$aPartit] / $iDen;
}
}
/*
* Cerca quin partit s'enduu l'esc— en aquesta iteraci—
*/
private function calculaPartitEsco() {
$aClaus = $this->aPartits;
$aVotsMax = -1;
$aPartitMax = '';
foreach ($aClaus as $aPartit) {
$aDadesPartit = $this->aTaulaTreball[$aPartit];
foreach ($aDadesPartit as $aQuocientVots) {
if ($aQuocientVots > $aVotsMax) {
$aVotsMax = $aQuocientVots;
$aPartitMax = $aPartit;
}
}
}
$this->eliminaQuocientPartit($aVotsMax,$aPartitMax);
$this->aEsconsPartits[$aPartitMax][] = $aVotsMax;
}
/*
* Actualitza el valor del quocient de vots d'un partit posant-hi
* el valor -1 per tal que en properes iteracions no sigui tingut
* en consideraci—
* @param $aQuocient Valor dels quocients d'un partit que es vol eliminar
* @param $aPartit Partit al qual pertany el valor del quocient
*/
private function eliminaQuocientPartit($aQuocient,$aPartit) {
$zTrobat = false;
$i = 0;
while ($i < count($this->aTaulaTreball[$aPartit]) && !$zTrobat) {
$zTrobat = $this->aTaulaTreball[$aPartit][$i] ==$aQuocient;
if ($zTrobat) {
$this->aTaulaTreball[$aPartit][$i] = -1;
}
$i++;
}
}
/*
* Calcula la taula que conté la relaci— de partits i escons
*
* @return Taula amb els escons de cada partit (['A'=>5, 'B'=>4,...])
*/
private function escons() {
$aClaus = array_keys($this->aEsconsPartits);
$aEscons = array();
foreach ($aClaus as $aPartit) {
$aEscons[$aPartit] = count($this->aEsconsPartits[$aPartit]);
}
return $aEscons;
}
}
?>