require('phplib/phplib.php');
require('common.php');
require('momsched.php');
ini_set('memory_limit', '128M');
ini_set('max_execution_time', 300);
check_personeel();
/* Roostergraaf met momsched: per collectie het minimale aantal kleuren
* (momenten), aangenomen dat elke toets in elk moment past en dat momenten
* niet overlappen, met een kleuring.
*
* Verschil met graph.php: de kleuring wordt niet door alle oplossingen te
* doorlopen gevonden, maar door momsched (zie momsched.php), dat
* - collecties die tijdens het zoeken uit elkaar vallen (als de toetsen op
* de 'bruggen' tussen clusters een kleur hebben) los van elkaar oplost,
* - kleuren die een al afgehandeld cluster gebruikt, voor het volgende
* cluster als onbenutte kleuren behandelt (symmetrie), zodat de clusters
* via de bruggen op elkaar aangesloten worden in plaats van door
* uitproberen,
* - een cluster dat met een equivalente rand terugkomt, niet opnieuw
* doorzoekt.
* Er wordt één oplossing getoond. Een toets die met de rest van de
* oplossing vast ook een andere kleur kan krijgen, krijgt een kleurverloop:
* eerst de gekozen kleur, dan de andere mogelijkheden. */
$db = mdb2_open($dsn);
$herinfo = get_better_herinfo($db, $_GET);
$period_id = $herinfo['period_id'];
$buiten_beschouwing = get_buiten_beschouwing($db, $period_id);
$samenvoegen = get_samenvoegen($db, $herinfo['period_id']);
if (isset($_GET['limit']))
$toetsen = get_toetsen_from_db($db, $period_id, $buiten_beschouwing, $samenvoegen, $_GET['limit']);
else $toetsen = get_toetsen_from_db($db, $period_id, $buiten_beschouwing, $samenvoegen);
$collections = array();
make_collections($collections, $toetsen);
momsched_kleuren($toetsen, $kleur, $nodig);
foreach ($collections as &$collection) {
// dezelfde volgorde als graph.php, zodat dot dezelfde .svg (cache) geeft
usort($collection['list'], function ($a, $b) use (&$toetsen) {
return count($toetsen[$a]['neighbors']) < count($toetsen[$b]['neighbors']);
});
$collection['indices'] = array();
for ($i = 0; $i < count($collection['list']); $i++) {
$collection['indices'][$collection['list'][$i]] = $i;
}
foreach ($collection['list'] as $toets) {
uksort($toetsen[$toets]['neighbors'], function ($a, $b) use (&$collection) {
return $collection['indices'][$a] > $collection['indices'][$b];
});
}
$dot = dot($collection['list'], $toetsen);
$collection['filename'] = $svg_filename = $datadir.md5($dot).'.svg';
if (!file_exists($svg_filename)) {
$dot_filename = tempnam(sys_get_temp_dir(), 'her');
if (file_put_contents($dot_filename, $dot) === FALSE) error_system('unable to write .dot file');
$out = system("dot -Tsvg -o$svg_filename $dot_filename", $ret);
if ($ret != 0) error_system("error $ret creating .svg from .dot: $out");
unlink($dot_filename);
}
$collection['max_colors'] = $nodig[$collection['list'][0]];
}
unset($collection);
$colors = array("#fbb4ae", "#b3cde3", "#ccebc5", "#decbe4", "#fed9a6", "#ffffcc", "#e5d8bd", "#fddaec", "#f2f2f2");
// meer dan 9 kleuren nodig: maak er een paar bij
function kleur($colors, $i) {
if (isset($colors[$i])) return $colors[$i];
return 'hsl('.(($i*47) % 360).',60%,80%)';
}
$gradients = array();
foreach ($collections as &$collection) {
$collection['solver']['scripts'] = array();
if ($collection['max_colors'] < 0) continue;
$colorset = '';
foreach ($collection['list'] as $naam) {
$eigen = $kleur[$naam];
// kleuren die deze toets ook kan krijgen als de rest blijft
$vrij = array_fill(0, $collection['max_colors'], 1);
foreach ($toetsen[$naam]['neighbors'] as $buur => $aantal) {
$vrij[$kleur[$buur]] = 0;
}
$color = array($eigen);
foreach ($vrij as $c => $ok) if ($ok && $c != $eigen) $color[] = $c;
$sel = "\$('#n".$toetsen[$naam]['id']." > polygon, #n".$toetsen[$naam]['id']." > ellipse')";
if (count($color) == 1) {
$colorset .= "$sel.attr('fill', '".kleur($colors, $eigen)."');\n";
} else {
$gradname = 'grad'.implode('_', $color);
$colorset .= "$sel.attr('fill', 'url(#$gradname)');\n";
if (!isset($gradients[$gradname])) {
$grad = ''."\n";
for ($j = 0; $j < count($color); $j++) {
$grad .= ''."\n";
$grad .= ''."\n";
}
$grad .= ''."\n";
$gradients[$gradname] = $grad;
}
}
}
$collection['solver']['scripts'][] = $colorset;
}
unset($collection); // disallow freak behavior in php with foreach and &
// de oplossingen meteen tonen
$alles = '';
foreach ($collections as $collection) {
foreach ($collection['solver']['scripts'] as $script) $alles .= $script;
}
html_start(<<
ST's die buiten beschouwing zijn gelaten:
print_r($buiten_beschouwing); ?>
ST's die gekoppeld zijn:
print_r($samenvoegen); ?>
De roostergraaf gaat ervan uit dat elke toetsduur bij elke kleur kan worden afgenomen
Een toets met een kleurverloop kan, als de rest van de oplossing blijft zoals hij is, ook de andere kleuren in het verloop krijgen (de eerste kleur is de gekozen kleur).
foreach ($collections as $collection) {
echo("
Toetsgroep
\n");
if ($collection['max_colors'] < 0) {
echo('Onbeslist: zoekgrens bereikt bij '.(-$collection['max_colors']).' kleuren, er zijn er minstens zoveel nodig.');
} else {
?>Oplossing:
$i = 0;
foreach ($collection['solver']['scripts'] as $script) {
$i++;
echo(' '.$i.'');
}
echo(', benodigd aantal kleuren '.$collection['max_colors'].'.');
}
?>