mirror of
https://github.com/AlekseyLobanov/AlekseyLobanov.github.io.git
synced 2026-01-11 20:52:01 +03:00
63 lines
11 KiB
HTML
63 lines
11 KiB
HTML
<!DOCTYPE html>
|
||
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]--><!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]--><!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]--><!--[if gt IE 8]><!--><html class="no-js"> <head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"><title>CrossGen v1.0</title><meta name="description" content><meta name="viewport" content="width=device-width"><link rel="stylesheet" href="../../theme/css/normalize.css"><link href="http://fonts.googleapis.com/css?family=Philosopher&subset=latin,cyrillic" rel="stylesheet" type="text/css"><link href="http://fonts.googleapis.com/css?family=Forum&subset=cyrillic" rel="stylesheet" type="text/css"><link href="//fonts.googleapis.com/css?family=Oswald" rel="stylesheet" type="text/css"><link href="http://fonts.googleapis.com/css?family=Ubuntu+Mono" rel="stylesheet" type="text/css"><link href="http://fonts.googleapis.com/css?family=PT+Sans" rel="stylesheet" type="text/css"><link rel="stylesheet" href="../../theme/css/font-awesome.min.css"><link rel="stylesheet" href="../../theme/css/main.css"><link rel="stylesheet" href="../../theme/css/blog.css"><link rel="stylesheet" href="../../theme/css/github.css"><link href="http://likemath.ru/feeds/all.atom.xml" type="application/atom+xml" rel="alternate" title="Блог 529 Atom Feed"><link href="http://likemath.ru/feeds/all.rss.xml" type="application/rss+xml" rel="alternate" title="Блог 529 RSS Feed"><script src="../../theme/js/vendor/modernizr-2.6.2.min.js"></script></head><body><!--[if lt IE 7]>
|
||
<p class="chromeframe">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> or <a href="http://www.google.com/chromeframe/?redirect=true">activate Google Chrome Frame</a> to improve your experience.</p>
|
||
<![endif]--><div id="wrapper"><header id="sidebar" class="side-shadow"><hgroup id="site-header"><a id="site-title" href="../.."><h2><i class="icon-pencil"></i> Блог 529</h2></a><p id="site-desc"> Project Euler и остальное </p></hgroup><nav><ul id="nav-links"><li><a href="../../">Главная</a></li><li><a href="../../pages/projects.html">Мои проекты</a></li><li><a href="../../pages/about.html">Об авторе</a></li><li><a href="../../feeds/feed.atom.xml">Atom feed</a></li></ul></nav><footer id="site-info"><p> Powered by Pelican. </p></footer></header><div id="post-container"><ol id="post-list"><li><article class="post-entry"><header class="entry-header"><time class="post-time" datetime="2015-08-02T17:40:00+03:00" pubdate> Вс 02 Август 2015 </time><a href="../../posts/crossgen-v10/" rel="bookmark"><h1>CrossGen v1.0</h1></a></header><section class="post-content"><p>Начать, наверное, нужно с того, что реальную практическую значимость я осознал после того, как реализовал 90% того, что есть сейчас. Сейчас мне кажется, что единственное применение данного приложения лишь в том, чтобы создавать кроссворды очень сложной или необычной формы. Зачем это надо обычному человеку я вообще не знаю.</p><p>Собственно, алгоритм генерации изначально был примитивным: простой рекурсивный поиск с отсечением. Скорость генерации более-менее сложных сеток была ужасной (для перцентиля 30% это примерно 40 минут на <a href="https://github.com/AlekseyLobanov/CrossGen/blob/master/Data/grid1.cross">этой</a> сетке, в общем случае, время генерации непредсказуемо.</p><p>В дальнейшем были выполнены некоторые оптимизации. Первой более-менее значимой стала замена передачи сетки в юникоде (во внутреннем цикле) на передачу сетки в однобайтовой кодировке, таким образом, языки с алфавитом больше ~200 букв пролетают. Впрочем, мне кажется, что им не слишком сильно требуются кроссворды. Такая оптимизация дала ~35% прироста при значимом времени перебора (больше секунды).</p><p>В какой-то момент, мне показалось, что оптимизация структуры данных для хранения сетки тоже могла сильно увеличить производительность, но это будет заметно только на разряженных сетках, которые и так достаточно быстро генерируются. На сложных же плотных сетках, прирост скорости может быть минимальным, вплоть до отрицательного. Таким образом, используются просто двумерный массив.</p><p>Наибольший прирост, как и ожидалось, дало упорядочивание словаря по некоторому критерию. Таким образом, при переборе, “плохие” варианты будут попадаться редко. На это ушло немногим больше дня. В конечном итоге, целевой функцией, которая стала критерием сортировки, стала такая <span class="math">\(\sqrt[n]{\prod_{i=1}^{n}{f\left( a_i \right)}}\)</span> (иначе говоря, среднее геометрическое отлично подошло), где <span class="math">\(n\)</span> — количество букв в слове, <span class="math">\(a_i\)</span> — буквы слова, а <span class="math">\(f \left( x \right)\)</span> есть вероятность появления буквы <span class="math">\(x\)</span>. Я отсекаю примерно половину самых “плохих” слов, а из того, что осталось я составляю кроссворд. Производительность, в среднем, увеличилась в ~1000 раз. На тестовых сетках для перцентиля 90% длительность работы около секунды.</p><h2>Что реализовано</h2><ul><li>Прозрачная интернационализация (пока только русский и английский языки)</li><li>Быстрая генерация</li><li>Экспорт в текстовом формате</li><li>Простая смена словаря</li><li>Относительно простое редактирование сеток</li></ul><h2>Что может быть реализовано</h2><ul><li>Визуальный редактор сетки</li><li>Экспорт в <span class="caps">HTML</span>, <span class="caps">PDF</span>, Markdown</li><li>Экспорт сетки в файл картинки</li></ul><h2>Скриншоты</h2><ul><li>Версия для Xubuntu: <img alt="alt text" src="../../images/crossgen_lin_1_0.png" title="Xubuntu скриншот"></li><li>Версия для Windows 7: <img alt="alt text" src="../../images/crossgen_win7_1_0.png" title="Windows скриншот"></li></ul><script type="text/javascript">if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
|
||
var align = "center",
|
||
indent = "0em",
|
||
linebreak = "false";
|
||
|
||
if (false) {
|
||
align = (screen.width < 768) ? "left" : align;
|
||
indent = (screen.width < 768) ? "0em" : indent;
|
||
linebreak = (screen.width < 768) ? 'true' : linebreak;
|
||
}
|
||
|
||
var mathjaxscript = document.createElement('script');
|
||
mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
|
||
mathjaxscript.type = 'text/javascript';
|
||
mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
|
||
mathjaxscript[(window.opera ? "innerHTML" : "text")] =
|
||
"MathJax.Hub.Config({" +
|
||
" config: ['MMLorHTML.js']," +
|
||
" TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
|
||
" jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
|
||
" extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
|
||
" displayAlign: '"+ align +"'," +
|
||
" displayIndent: '"+ indent +"'," +
|
||
" showMathMenu: true," +
|
||
" messageStyle: 'normal'," +
|
||
" tex2jax: { " +
|
||
" inlineMath: [ ['\\\\(','\\\\)'] ], " +
|
||
" displayMath: [ ['$$','$$'] ]," +
|
||
" processEscapes: true," +
|
||
" preview: 'TeX'," +
|
||
" }, " +
|
||
" 'HTML-CSS': { " +
|
||
" styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
|
||
" linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
|
||
" }, " +
|
||
"}); " +
|
||
"if ('default' !== 'default') {" +
|
||
"MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
|
||
"var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
|
||
"VARIANT['normal'].fonts.unshift('MathJax_default');" +
|
||
"VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
|
||
"VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
|
||
"VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
|
||
"});" +
|
||
"MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
|
||
"var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
|
||
"VARIANT['normal'].fonts.unshift('MathJax_default');" +
|
||
"VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
|
||
"VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
|
||
"VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
|
||
"});" +
|
||
"}";
|
||
(document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
|
||
}
|
||
</script></section><hr><aside class="post-meta"><p>Категория: <a href="../../category/proekty.html">Проекты</a></p><p>Теги: <a href="../../tag/proekt.html">проект</a>, <a href="../../tag/c.html">c++</a>, <a href="../../tag/wxwidgets.html">wxWidgets</a>, </p></aside><hr></article></li></ol></div></div><script>
|
||
var _gaq=[['_setAccount','UA-62001537-1'],['_trackPageview']];
|
||
(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];
|
||
g.src=('https:'==location.protocol?'//ssl':'//www')+'.google-analytics.com/ga.js';
|
||
s.parentNode.insertBefore(g,s)}(document,'script'));
|
||
</script><script src="../../theme/js/main.js"></script></body></html> |