Files
likemath.ru/posts/crossgen-v10/index.html
2017-06-04 22:29:39 +03:00

63 lines
11 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!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&nbsp;v1.0</h1></a></header><section class="post-content"><p>Начать, наверное, нужно с того, что реальную практическую значимость я осознал после того, как реализовал 90% того, что есть сейчас. Сейчас мне кажется, что единственное применение данного приложения лишь в том, чтобы создавать кроссворды очень сложной или необычной формы. Зачем это надо обычному человеку я вообще не&nbsp;знаю.</p><p>Собственно, алгоритм генерации изначально был примитивным: простой рекурсивный поиск с отсечением. Скорость генерации более-менее сложных сеток была ужасной (для перцентиля 30% это примерно 40 минут на <a href="https://github.com/AlekseyLobanov/CrossGen/blob/master/Data/grid1.cross">этой</a> сетке, в общем случае, время генерации&nbsp;непредсказуемо.</p><p>В дальнейшем были выполнены некоторые оптимизации. Первой более-менее значимой стала замена передачи сетки в юникоде (во внутреннем цикле) на передачу сетки в однобайтовой кодировке, таким образом, языки с алфавитом больше ~200 букв пролетают. Впрочем, мне кажется, что им не слишком сильно требуются кроссворды. Такая оптимизация дала ~35% прироста при значимом времени перебора (больше&nbsp;секунды).</p><p>В какой-то момент, мне показалось, что оптимизация структуры данных для хранения сетки тоже могла сильно увеличить производительность, но это будет заметно только на разряженных сетках, которые и так достаточно быстро генерируются. На сложных же плотных сетках, прирост скорости может быть минимальным, вплоть до отрицательного. Таким образом, используются просто двумерный&nbsp;массив.</p><p>Наибольший прирост, как и ожидалось, дало упорядочивание словаря по некоторому критерию. Таким образом, при переборе, &#8220;плохие&#8221; варианты будут попадаться редко. На это ушло немногим больше дня. В конечном итоге, целевой функцией, которая стала критерием сортировки, стала такая <span class="math">\(\sqrt[n]{\prod_{i=1}^{n}{f\left( a_i \right)}}\)</span> (иначе говоря, среднее геометрическое отлично подошло), где <span class="math">\(n\)</span> &#8212; количество букв в слове, <span class="math">\(a_i\)</span> &#8212; буквы слова, а <span class="math">\(f \left( x \right)\)</span> есть вероятность появления буквы <span class="math">\(x\)</span>. Я отсекаю примерно половину самых &#8220;плохих&#8221; слов, а из того, что осталось я составляю кроссворд. Производительность, в среднем, увеличилась в ~1000 раз. На тестовых сетках для перцентиля 90% длительность работы около&nbsp;секунды.</p><h2>Что&nbsp;реализовано</h2><ul><li>Прозрачная интернационализация (пока только русский и английский&nbsp;языки)</li><li>Быстрая&nbsp;генерация</li><li>Экспорт в текстовом&nbsp;формате</li><li>Простая смена&nbsp;словаря</li><li>Относительно простое редактирование&nbsp;сеток</li></ul><h2>Что может быть&nbsp;реализовано</h2><ul><li>Визуальный редактор&nbsp;сетки</li><li>Экспорт в <span class="caps">HTML</span>, <span class="caps">PDF</span>,&nbsp;Markdown</li><li>Экспорт сетки в файл&nbsp;картинки</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>