W-gent and ObBot / Архив / Архив публикаций / Фальсификации при подсчёте голосов на выборах
Фальсификации при подсчёте голосов на выборах
Действующий пример по выборам 4 декабря 2011 года в Калужской области
Это тот же самый метод, который описан по адресу http://lleo.me/dnevnik/2011/12/07_gauss.html, с небольшими отличиями:
1. Подсчёт ведётся на примере Калужской области, а не всей РФ.
2. Добавлен детектор эффекта квантования, отдельно выводящий (серым цветом) УИКи с результатами, равные дробям малых целых чисел: 1/2, 1/3, 2/3, 1/4, 3/4, 1/5, 2/5, 3/5, 4/5, 1/6, 5/6. Теперь сторонники Чурова уже не смогут сослаться на "обусловленность пиков квантованием при построении гистограммы", им придётся придумывать какую-нибудь другую причину возникновения пика в районе 50%. Что же до остальных людей, то им причина возникновения этого пика понятна: подтасовка выборов председателями некоторых УИКов с целью "натянуть" результаты "Единой России" на заказанные им проценты - 50% или 51% (т.н. "контрольный пакет"), или 97% - смотря, кому какие дали установки.
В остальном метод выявления фальсификаций - тот же: их наличие выявляется по не-гауссову распределению избирательных участков по процентам голосов, насчитанных за ЕР и по подозрительным аномальным пикам на красивых цифрах.
Действующий скрипт с самораспечатывающимся кодом находится здесь: http://wgent.com/elect.php
Результаты его работы:
File: elect.php
<?
printcode("elect.php"); // Распечатываем собственный исходный код
$bin=1.0; // Шаг построения гистограммы
$quants=array( 1./2., 1./3., 2./3., 1./4., 3./4., 1./5., 2./5., 3./5., 4./5., 1./6., 5./6. ); // Таблица "квантованных" результатов, в которых возможно самопроизвольное возникновение пиков
for($i=0; $i<count($quants); $i++) $quants[$i]=$quants[$i]*100.; // Переводим таблицу квантов в проценты
$eps=0.0001; // Заведомо большая (по сравнению с точностью операции деления float-чисел) граница возможного пика
function DetectQuant($p){ // Функция-детектор попадания результата в окрестности возможного пика
global $quants, $eps;
foreach($quants as $quant) if( $quant-$eps <= $p && $p <= $quant+$eps ) return true; // Если число попало в $eps-окрестность целочисленной дроби, возвращаем "Квантование возможно!"
return false; // А если ни в какую окрестность заданных целочисленных дробей оно не попало, то возвращаем "Квантования нет".
} //function DetectQuant($p)
$vibids=array( // Задаём части адресов веб-страниц Избиркома, меняющиеся для различных районных избирательных комиссий
2402000196098, //Бабынинская
2402000196099, //Барятинская
2402000196097, //Боровская
2402000196106, //Дзержинская
2402000196105, //Думиничская
2402000196123, //Жиздринская
2402000196103, //Жуковская
2402000196102, //Износковская
2402000196104, //Ленинская
2402000196100, //Московская
2402000196101, //Октябрьская
2402000196113, //Кировская
2402000196112, //Козельская
2402000196114, //Куйбышевская
2402000196110, //Людиновская
2402000196111, //Малоярославецкая
2402000196109, //Медынская
2402000196108, //Мещовская
2402000196124, //Мосальская
2402000196107, //Обнинская городская
2402000196122, //Перемышльская
2402000196121, //Спас-Деменская
2402000196119, //Сухиничская
2402000196118, //Тарусская
2402000196120, //Ульяновская
2402000196117, //Ферзиковская
2402000196115, //Хвастовичская
2402000196116 //Юхновская
);
$StringKeys=array( // Задаём значимые для подсчёта строки таблицы результатов
"all"=>1, // Зарегистрировано избирателей
"bad"=>9, // Испорченных бюллетеней
"voted"=>10, // Действительныхбюллетеней
"CP"=>20, // Голосов за "Справедливую Россию"
"LDPR"=>21, // Голосов за ЛДПР
"PR"=>22, // Голосов за "Патриоты России"
"KPRF"=>23, // Голосов за коммунистов
"Yabloko"=>24, // Голосов за "Яблоко"
"ER"=>25, // Голосов за "Единую Россию"
"PD"=>26); // Голосов за "Правое Дело"
$Parties=array("CP", "LDPR", "PR", "KPRF", "Yabloko", "ER", "PD"); // Отдельный массив индексов списка партий
$Colors=array("CP"=>"#990000", "LDPR"=>"#8888FF", "PR"=>"#FF8800", "KPRF"=>"#FF0000", "Yabloko"=>"#00CC00", "ER"=>"#0000FF", "PD"=>"#00CCCC"); // Цвета, которыми будут выводиться гистограммы для партий
$d=array(); //Инициализируем массив данных
foreach($vibids as $vibid){ // По каждой окружной избирательной комиссии...
$url="http://www.kaluga.vybory.izbirkom.ru/region/region/kaluga?action=show&tvd=100100028713379&vrn=100100028713299®ion=40&global=1&sub_region=40&prver=0&pronetvd=null&vibid=".$vibid."&type=233";
$s=file_get_contents($url); // Скачиваем страницу с сайта Избиркома
$s=substr( $s, strpos($s, "overflow:scroll") ); // Обрезаем её HTML-код до начала таблицы результатов, чтобы не нагружать зазря процессороёмкую функцию preg_match_all
$s=substr($s, 0, strpos($s, "</table>")+strlen("</table>")+2 ); // Обрезаем HTML-код от конца таблицы результатов с той же целью
if( !preg_match_all("/<tr[^>]*>(.*)<\/tr>/Usi", $s, $mats) ) die ("Не могу найти строки результатов на странице $url<br />"); // Выбираем все строки таблицы в массив $mats
$mat=$mats[1]; // Берём из него собственно содержимое строк
reset($StringKeys); //Для организации цикла строкой ниже
while( list($StringKey, $StringNo) = each($StringKeys) ){ // Цикл по каждому из значимых для нас столбцов. Перебираем только нужные нам ячейки.
if( !preg_match_all("/<b>(\d+)<\/b>/Usi", $mat[$StringNo], $mats) ) die("Не могу найти цифры в строке $StringKey страницы $url"); // Ищем в ячейке цифры. Они выделены тэгом <b> (т.е., жирным)
$N=count($mats[1]); // Определяем, сколько у нас нашлось ячеек
for($i=0; $i<$N; $i++) $d[$StringKey][]=$mats[1][$i]; // И записываем найденные в них цифры в массив данных $v
} // while значимые строки
} // foreach избирательные округа
$Nprec=count($d["all"]); echo "<br />Участков: ".$Nprec; // Сколько всего в регионе нашлось избирательных участков
for($i=0; $i<$Nprec; $i++) { // Для каждого участка...
foreach($Parties as $Party) { // Для каждой партии...
$d["p".$Party][$i] = 100.0 * $d[$Party][$i] / $d["voted"][$i]; // Считаем процент голосов за партию
// $d["p".$Party][$i] = 100.0 * $d[$Party][$i] / ($d["voted"][$i]+$d["bad"][$i]); // Раскомментируйте эту строку и закомментируйте предыдущую, чтобы посчитать проценты с учётом недействительных бюллетеней
} //foreach
} // for
// На этом формирование массива данных закончено.
foreach($Parties as $Party){ // Теперь для каждой партии строим гистограмму
?><hr style="clear:both;" /><?
echo "<br />".$Party;
for($i=5; $i<=100; $i+=5){ ?><div class="v" style=""><? echo $i;?></div> <? } // Выводим заголовок гистограммы
?><div style="clear:both; width:1020px;"> <? // Далее строим собственно гистограмму
for($v=0.0; $v<100.0; $v+=$bin) { // Идём от 0% до 100% с шагом $bin%...
$PartyVoteNprec=0; // Обнуляем счётчик избирательных участков, на которых партия набрала данный процент
$PartyVoteProbablyQuants=0; // Обнуляем счётчик участков, которые могут создавать пики из-за квантования
for($i=0; $i<$Nprec; $i++) { // И считаем по всем участкам...
if( $v <= $d["p".$Party][$i] && $d["p".$Party][$i] < $v+$bin ) { // Если результат по участку попал в промежуток от $v до $v+bin
if( DetectQuant($d["p".$Party][$i]) ) $PartyVoteProbablyQuants++; // Если результат мог быть квантован, плюcуем участок к "возможно, квантованным"
else $PartyVoteNprec++; // Иначе плюсуем участок к обычным, не-квантованным
} // if участок в интервале
} //for все участки
?><div class="b" style="background-color:#888888; height:<? echo ($PartyVoteNprec+$PartyVoteProbablyQuants)*10+1; ?>px;"><div class="b" style="background-color:<? echo $Colors[$Party]; ?>; height:<? echo $PartyVoteNprec*10+1; ?>px;"></div></div><?
} //for($v
?></div><?
} //foreach($Parties as $Party){
?><hr style="clear:both;" /><?
function printcode($filename){
$s=implode( "", file($filename) );
$s=htmlspecialchars($s);
$s=str_replace(" ", " ", $s);
$s=str_replace("\n", "<br />", $s);
echo "<hr />File: ".$filename."<hr />";
echo $s;
}
?>
<style type="text/css">
.b{
background-image:url(/img/elect.gif);
background-position:bottom right;
float:left;
width:<? echo (int)(10*$bin); ?>px;
text-align:right;
margin:0;
padding:0;
}
.v {
background-image:url(/img/elect1.gif);
background-position:bottom right;
text-align:right;
float:left;
width:50px;
height:20px;
margin:0;
padding:0;
overflow:hidden;
}
body{font-face:Verdana}
</style>
Участков: 725
CP
5
10
15
20
25
30
35
40
45
50
55
60
65
70
75
80
85
90
95
100
LDPR
5
10
15
20
25
30
35
40
45
50
55
60
65
70
75
80
85
90
95
100
PR
5
10
15
20
25
30
35
40
45
50
55
60
65
70
75
80
85
90
95
100
KPRF
5
10
15
20
25
30
35
40
45
50
55
60
65
70
75
80
85
90
95
100
Yabloko
5
10
15
20
25
30
35
40
45
50
55
60
65
70
75
80
85
90
95
100
ER
5
10
15
20
25
30
35
40
45
50
55
60
65
70
75
80
85
90
95
100
PD
5
10
15
20
25
30
35
40
45
50
55
60
65
70
75
80
85
90
95
100
Как видите, те 2 участка, которые могли бы сыграть роль в образовании "половинного пика" на 50% за ЕР, никакой роли не сыграли.
Зато явно виден пик на промежутке "51% - 52%". Это - след от "натягивания" процента голосов за ЕР на "контрольный пакет" в 51% председателями УИКов.