Location: PHPKode > scripts > Calculadora Escons > calculadora-escons/CalculadoraEscons.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 (hide@address.com)
 * Descripci—: Classe que permet calcular els vots corresponents a una llista de partits segons la llei d'Hondt
 *
 * Llicncia: Aquest programari es distribueix amb llicncia 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; // Nœmero d'escons
	private $aPartits = null; // Llista de partits
	private $aEsconsPartits = null; // Llista de partits, amb els quocients dels vots dels partits que han proporcionat algun esc—
	private $aTaulaTreball = null; // Taula de treball, on es van acumulant els quocients dels vots dels partits
	private $iNumEsconsProcessats = 0; // Nœmero d'escons processats en l'actual iteraci—

	/**
	 * Crea l'objecte 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;
	}
}
?>
Return current item: Calculadora Escons