<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-8781383461061929571</id><updated>2012-02-24T16:26:11.471-05:00</updated><category term='education'/><category term='whimsy'/><category term='Beamer'/><category term='LyX'/><category term='Thunderbird'/><category term='programming'/><category term='industrial engineering'/><category term='constraint programming'/><category term='Mint'/><category term='WIndows'/><category term='analytics'/><category term='NetBeans'/><category term='Blogger'/><category term='Java'/><category term='operations research'/><category term='INFORMS'/><category term='AMPL'/><category term='applications'/><category term='Firefox'/><category term='current events'/><category term='software'/><category term='Linux'/><category term='healthcare'/><category term='INFORMS blog challenge'/><category term='mathematics'/><category term='math programming'/><category term='CPLEX'/><category term='job market'/><category term='Ubuntu'/><category term='statistics'/><category term='Android'/><category term='LaTeX'/><category term='blogs'/><category term='conferences'/><category term='hardware'/><category term='computing'/><category term='rant'/><category term='R'/><category term='science'/><category term='reporting'/><category term='presentations'/><title type='text'>OR in an OB World</title><subtitle type='html'>A mix of operations research items and software tricks that I'll probably forget if I don't write them down somewhere.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default?start-index=101&amp;max-results=100'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>130</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-9151795621706095838</id><published>2012-02-21T14:44:00.000-05:00</published><updated>2012-02-23T18:11:27.101-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='operations research'/><category scheme='http://www.blogger.com/atom/ns#' term='current events'/><title type='text'>OR and Base Voters: Common Pitfalls</title><content type='html'>My adopted state of Michigan is currently afflicted with the Republican presidential primary. (Symptoms include repetitious attack ads on television, robocalls to one's house, and the general malaise associated with staring at any crop of candidates for political office.) Primaries tend to draw out "base" voters (those committed to one party or the other); we swing voters just stay at home, hiding under the covers until it is over.&lt;br /&gt;&lt;br /&gt;Last night the local TV news included a sound bite from a generic Republican voter, an apparently intelligent and articulate woman (to the extent one can judge these attributes from a two sentence interview) who said she was still undecided because she wanted to vote for the "most conservative" candidate. The logic, or lack of logic, behind that statement caused me to take notice of the similarities between how some "base" voters think and common errors in operations research.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;b&gt;A single criterion is easy, but multiple criteria may be correct.&lt;/b&gt;&lt;/i&gt; There are quite a few pressing issues these days, ranging from foreign policy to budget deficits to global warming to unemployment to ... (I'll stop there; I'm starting to depress myself). Our base voter, henceforth Mme. X, has apparently condensed these criteria down to a single value, on a scale from hard core liberal (arbitrarily 0) to hard core conservative (arbitrarily 1). What is not apparent is &lt;i&gt;how&lt;/i&gt; the multiple dimensions were collapsed to a single one. OR people know that multiple criterion optimization is hard, more from a conceptual standpoint than from a computational one. Using a single composite criterion (weighted sum of criteria, distance from a Utopia point in some arbitrary metric, ...) makes the computational part easier, but there are consequences (frequently hidden) to the choice of the single criterion. Goal programming has its own somewhat arbitrary choices (aspiration levels, priorities) which again can have surprising consequences. Picking the "most conservative" candidate simplifies the cognitive process but may lead to buyer's remorse. Similarly, arbitrarily collapsing multiple objectives into a single objective may simplify modeling, but may produce solutions that do not leave the client happy.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;b&gt;Averages can be deceptive.&lt;/b&gt;&lt;/i&gt; Point estimates also make modeling and decision making easier, but they can mask important things. (A colleague has a favorite, if politically incorrect, quotation: "Statistics are like bikinis. What they reveal is interesting, but what they conceal is critical.")&lt;br /&gt;&lt;br /&gt;Suppose that Mme. X has narrowed her choices down to two candidates, and that they have both weighed in on five important issues (A through E). If candidate 1 is consistently to the right of candidate 2 on all issues, we have a dominated solution: Mme. X can eliminate candidate 2 and vote for candidate 1. On the other hand, consider the following scenario, where each candidate's position is rated on a scale from 0 (liberal) to 1 (conservative).&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-_oNBg9GAuMk/T0PpCApq2cI/AAAAAAAAAHc/bZZye9yHg9s/s1600/basevoters.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-_oNBg9GAuMk/T0PpCApq2cI/AAAAAAAAAHc/bZZye9yHg9s/s1600/basevoters.png" /&gt;&lt;/a&gt;&lt;/div&gt;Candidate 1 is more conservative than candidate 2 in both mean (0.780 versus 0.756) and median (0.80 versus 0.75); yet candidate 2 is to the right of candidate 1 on two of five issues (A and B), and close to a wash on a third (C).&amp;nbsp; So if Mme. X truly wants a conservative candidate, it is not all that clear which she should prefer. Likewise, OR models that consider only point estimates without taking dispersion into account can result in solutions that should do well "on average" but sometimes do quite poorly.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;b&gt;A solution that goes unimplemented is not a solution.&lt;/b&gt;&lt;/i&gt; Missing in Mme. X's search for the most conservative candidate is the quality referred to by pundits as "electability". Neither major political party claims a majority of registered voters in the U.S., so to win a general election, a candidate &lt;i&gt;must&lt;/i&gt; capture a significant number of moderates and independents. The most ideologically pure candidate (for either party) may not be able to do so. This is a bit of a paradox in recent elections, where candidates find that they must appeal to "base" voters at one end of the political spectrum to get the nomination, then appeal to voters in the middle of the spectrum to win the election. Ideological "base" voters may not grasp this particular reality; they expect the "correctness" of their candidate's views (which are also their views) to triumph. [This may be at least partly explained by the &lt;a href="http://arstechnica.com/science/news/2012/02/in-politics-were-convinced-that-our-candidate-is-a-shoo-in.ars" target="_blank"&gt;false consensus&lt;/a&gt; fallacy.]&lt;br /&gt;&lt;br /&gt;OR modelers sometimes have a similar blind spot. We can pursue perfection at the expense of good answers. We can opt for the approach that uses the most sophisticated or "elegant" mathematics or the most high-powered solution technique available. We may try for more scope or more scale in a project than what we can accomplish in a reasonable time frame (or what users can realistically cope with, in terms of data requirements and solution complexity). Professional journals often encourage this trend by &lt;a href="http://orinanobworld.blogspot.com/2010/08/sting-of-rejection.html" target="_blank"&gt;requiring "novel" solution methods&lt;/a&gt; in order to publish a paper. The end result can be a really impressive solution that sits on a shelf because the client is unwilling or unable to implement it, or because it is too complex for the client to understand and trust.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;b&gt;Garbage in, garbage out.&lt;/b&gt;&lt;/i&gt; OR models rely on data, as inputs to the decision process or to calibrate parameters of the model. Feed &lt;a href="https://reflectionsonor.wordpress.com/2011/03/23/a-side-effect-of-optimization-a-spring-cleaning-for-your-data/" target="_blank"&gt;bad data&lt;/a&gt; to an otherwise correct model and no good will come of it.&amp;nbsp; I have seen estimates that as much as 60% of the time in an OR project can be spent cleaning the data.&lt;br /&gt;&lt;br /&gt;Meanwhile, Mme. X has to rely on a variety of unreliable sources to gauge how conservative each candidate may be. Candidates famously say things they may not entirely believe, or express intentions they may not carry out, either in an overt effort to curry voters or because their views change between campaigning and governing. Historical data may be faked or misreported, and sometimes facts may not be what they seem. For instance, a generally pro-military candidate might vote against a military appropriation bill because there is a rider on it that would fund an inordinately wasteful project, or something unpalatable to the candidate and/or the candidate's constituents. Opponents will characterize this as an anti-military stance. Budget projections, and indeed any sort of projections, are subject to forecast errors, so a candidate's magical plan to fix deficits/unemployments/Mme. X's dripping kitchen faucet may turn out not to be so magical after all. Unfortunately for Mme. X, she probably has less ability to filter and correct bad data than an OR analyst typically does.&lt;br /&gt;&lt;br /&gt;So, in conclusion, voters and OR analysts face similar challenges ... but OR analysts do not have to cope with a glut of robocalls.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-9151795621706095838?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/9151795621706095838/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2012/02/or-and-base-voters-common-pitfalls.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/9151795621706095838'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/9151795621706095838'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2012/02/or-and-base-voters-common-pitfalls.html' title='OR and Base Voters: Common Pitfalls'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-_oNBg9GAuMk/T0PpCApq2cI/AAAAAAAAAHc/bZZye9yHg9s/s72-c/basevoters.png' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-5889527205451036206</id><published>2012-02-13T17:57:00.001-05:00</published><updated>2012-02-13T19:08:16.044-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><category scheme='http://www.blogger.com/atom/ns#' term='Firefox'/><title type='text'>Java Plugin for Firefox 10</title><content type='html'>Today marked yet another upgrade in &lt;a href="http://www.mozilla.org/en-US/firefox/fx/" target="_blank"&gt;Firefox&lt;/a&gt;, from version 10.0 to 10.0.1.&amp;nbsp; Whether it was this upgrade or the previous one I cannot be sure, but I discovered (the hard way) that one of them broke the use of Java applets on my office PC.&amp;nbsp; Specifically, the &lt;a href="http://www.java.com/en/" target="_blank"&gt;Java&lt;/a&gt; plugin (which I use infrequently, but which had worked a while back) was simply gone.&lt;br /&gt;&lt;br /&gt;Well, the plugin itself (which comes from the portion of Oracle that once was Sun) couldn't be gone -- Firefox can't delete chunks of my JRE.&amp;nbsp; Only the link to it was gone.&amp;nbsp; There is a handy Synaptic meta-package (sun-java6-plugin) in one of the Ubuntu repositories, intended (I think) to make the connection between plugin and browser.&amp;nbsp; I reinstalled it, to no avail. I'll skip the full litany of web search results (many out of date) and failed attempts, and cut to the chase scene.&amp;nbsp; Besides having a recent Oracle/Sun Java JRE installed (and, of course, Firefox), you need to do something to tell Firefox where to find the Java browser plugin.&amp;nbsp; The rest of this is specific to Linux; Windows and Mac users will have a somewhat different task.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;You need to find a Firefox plugins directory, in which to place a symbolic link to the plugin.&amp;nbsp; There are multiple choices, and more than one of them may be suitable. Some documents refer to a plugins folder under &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;~/.mozilla&lt;/span&gt; (although I suspect this now should be &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;~/.mozilla/firefox/&amp;lt;your configuration&amp;gt;&lt;/span&gt;).&amp;nbsp; I didn't have such a folder, so I created one (although I ended up not using it). Another possibility is &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;/usr/lib/firefox/plugins&lt;/span&gt;. I'm not sure if that one is scanned, or if it's just vestigial from some earlier version. I ended up using &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;/usr/lib/firefox-10.0.1/plugins&lt;/span&gt; ... which I may regret if I have to go through this again with the next upgrade.&lt;/li&gt;&lt;li&gt;You need to find the right plugin file. This is where I wasted most of my time. Older documentation refers to &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;libjavaplugin_oji.so&lt;/span&gt;, which I found in &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;/usr/lib/jvm/java-6-sun/jre/plugin/i386/ns7&lt;/span&gt;. It's in a folder named "plugin", so it must be the right file, mustn't it? Oops, no. It turns out there's a "next generation" plugin named &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;libnpjp2.so&lt;/span&gt;, and apparently FF 10 will only recognize the new plugin. Oracle's installation docs refer to it, but I could not find it in the plugin directory. That's because it's not in the plugin directory. I guess they thought that would be too obvious. It's in &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;/usr/lib/jvm/java-6-sun/jre/lib/i386&lt;/span&gt;.&lt;/li&gt;&lt;li&gt;Once the targets are in sight, shut down Firefox, go to the directory you selected in step 1 (in a terminal), delete any symlinks to older plugins, then&amp;nbsp; execute &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;sudo ln -s /usr/lib/jvm/java-6-sun/jre/lib/i386libnpjp2.so&lt;/span&gt;, adjusting the path as needed if your JVM is installed elsewhere. (The &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;sudo&lt;/span&gt; is unnecessary if you chose a folder in your home partition in step 1.) Restart Firefox and check the plugins tab (or enter &lt;span style="font-family: Verdana,sans-serif;"&gt;about:plugins&lt;/span&gt; in the URL bar) and make sure Firefox acknowledges the plugin.&lt;/li&gt;&lt;/ol&gt;&lt;b&gt;Update&lt;/b&gt;: I just checked my home PC (same configuration as the office PC, other than being 64 bit rather than 32 bit). There's no problem with the Java plugin at home. So perhaps I was wrong in blaming a FF update at the office for zapping the connection to the plugin ... but if not an update, then what?&lt;br /&gt;&lt;ol&gt;&lt;/ol&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-5889527205451036206?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/5889527205451036206/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2012/02/java-plugin-for-firefox-10.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/5889527205451036206'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/5889527205451036206'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2012/02/java-plugin-for-firefox-10.html' title='Java Plugin for Firefox 10'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-3247676591850563162</id><published>2012-02-11T11:32:00.001-05:00</published><updated>2012-02-11T11:32:54.571-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Mint'/><category scheme='http://www.blogger.com/atom/ns#' term='Thunderbird'/><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><category scheme='http://www.blogger.com/atom/ns#' term='hardware'/><title type='text'>The Case of the Dormant Function Keys</title><content type='html'>There's an intermittent problem on my home PC (&lt;a href="http://linuxmint.com/" target="_blank"&gt;Linux Mint&lt;/a&gt;) that's been driving me slightly buggy (okay, slightly buggier).&amp;nbsp; My mail client is &lt;a href="https://www.mozilla.org/en-US/thunderbird/" target="_blank"&gt;Thunderbird&lt;/a&gt;, and when composing messages I frequently hit the F9 key, which &lt;i&gt;should&lt;/i&gt; open the "Contacts Sidebar", from which I can select recipients.&amp;nbsp; Usually it does.&amp;nbsp; On my office PC and laptop it always does.&amp;nbsp; At home, though, it sometimes doesn't -- the F9 key goes mysteriously dead in T-bird.&amp;nbsp; I can work around it by opening the contacts sidebar from a menu, and eventually the problem disappears (for a while).&lt;br /&gt;&lt;br /&gt;Today, though, it happened again and I decided to try to sort it out.&amp;nbsp; Testing with other programs showed that all the function keys, not just F9, were dead, and in all applications.&amp;nbsp; I checked system settings in the control panel, and could find nothing that would be remapping the F keys.&amp;nbsp; A bit of work with Google, though, turned up the culprit: my keyboard.&lt;br /&gt;&lt;br /&gt;I have a &lt;a href="http://www.urbandictionary.com/define.php?term=Devil%27s%20Spawn" target="_blank"&gt;Microsoft&lt;/a&gt; ergonomic keyboard at home (and only on the home PC). Microsoft decided to assign alternate functions to all the F keys, so that, for example, F9 does double duty as the "Send" key (with a different key code).&amp;nbsp; At the end of the row of function keys is an "F Lock" key.&amp;nbsp; (For reasons that will become clear, I cannot get out of my head another name for it, also starting with "F" and ending with "ck".)&amp;nbsp; The F Lock key toggles function keys between their normal key codes and the alternate codes.&amp;nbsp; It apparently cannot be controlled by the operating system -- or at least nobody has figured out how.&amp;nbsp; Microsoft being Microsoft, they decided that the F Lock key has to be &lt;i&gt;on&lt;/i&gt; for function keys to act as function keys (which seems to suggest that the being a function key is not the normal role of the function key).&amp;nbsp; Whatever.&lt;br /&gt;&lt;br /&gt;The problem, as reported by various people, is that the F Lock apparently toggles randomly, without the key being struck.&amp;nbsp; In my case, this may mean that the state of the function keys at startup is random -- the keyboard sometimes wakes with F Lock on and sometimes with F Lock off.&amp;nbsp; With the culprit identified, there are two possible resolutions.&amp;nbsp; For now, I'll try the lazy approach: do nothing special, but keep an eye on the F Lock status light.&amp;nbsp; If it becomes too hard for me to remember this (the problem is, after all, intermittent), the more involved solution is to use the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;xev&lt;/span&gt; utility (which displays keyboard events, including key codes) to make a list of the key codes of the 12 function keys, both with and without F Lock engaged, and then use the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;xmodmap&lt;/span&gt; utility to map the key codes for the non-standard functions (undo, redo, reply, send, ...) back to the same virtual keys as the function keys (so that F9 looks like F9 to the system, regardless of the status of F Lock).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-3247676591850563162?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/3247676591850563162/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2012/02/case-of-dormant-function-keys.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/3247676591850563162'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/3247676591850563162'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2012/02/case-of-dormant-function-keys.html' title='The Case of the Dormant Function Keys'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-8416994837099915831</id><published>2012-02-04T14:51:00.000-05:00</published><updated>2012-02-04T14:51:01.865-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software'/><category scheme='http://www.blogger.com/atom/ns#' term='Firefox'/><title type='text'>Slaying a Zombie Browser Extension</title><content type='html'>I just finished a marathon session (on &lt;a href="http://linuxmint.com/" target="_blank"&gt;Linux Mint&lt;/a&gt; Katya) trying to uninstall &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/stylish/" target="_blank"&gt;Stylish&lt;/a&gt;, a zombie extension for the &lt;a href="https://www.mozilla.org/en-US/firefox/fx/" target="_blank"&gt;Firefox&lt;/a&gt; web browser. I have nothing against Stylish, and I don't think it was the culprit in this story, but I'm recording my methods here both to preserve them for myself and in case anyone else is locked in this battle.&lt;br /&gt;&lt;br /&gt;Somewhere along the line, I must have installed a version of Stylish, although I don't recall when or why.&amp;nbsp; As Firefox went to its current whirlwind upgrade cycle, the installed version of Stylish (1.0.7) became incompatible.&amp;nbsp; With each upgrade, I would instruct Firefox to look for a compatible version, and it would either report failure or find one, attempt to install it, and report that the upgrade attempt had failed (with no explanation why).&amp;nbsp; Either way, the browser would open with Stylish 1.0.7 installed and disabled.&lt;br /&gt;&lt;br /&gt;This dance got boring after a while, and I could not think of a reason for keeping Stylish, so when Firefox upgraded itself to version 10.0 today I decided to uninstall Stylish ... which is when I discovered it was now a zombie.&amp;nbsp; If you know anything about &lt;a href="https://en.wikipedia.org/wiki/Zombie" target="_blank"&gt;zombies&lt;/a&gt;, you know that they are difficult to kill.&amp;nbsp; The instructions for uninstalling an extension are simple: open the extensions tab, find the one you no longer want, and click the uninstall link.&amp;nbsp; If there is an uninstall link -- and with Stylish, there was not.&amp;nbsp; Further searching revealed the helpful session that one boot Firefox in safe mode and then click the previously disabled uninstall link ... except there was no uninstall link, disabled or otherwise (nor did one magically appear when I switched to safe mode).&lt;br /&gt;&lt;br /&gt;One can invoke &lt;span style="font-family: &amp;quot;Trebuchet MS&amp;quot;,sans-serif;"&gt;Help &amp;gt; Troubleshooting Information&lt;/span&gt; in Firefox and find the file or directory name of the extension, then track the file or directory down in the Firefox extensions folder and nuke it manually.&amp;nbsp; I was able to find the folder name this way (a hex string inside braces), but no folder or file of that name existed in my profile's extensions folder.&amp;nbsp; This may mean it is installed globally, and sure enough, I found a folder of the correct name in&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt; /opt/firefox/extensions&lt;/span&gt;.&amp;nbsp; I nuked it (as root) and restarted Firefox.&amp;nbsp; The zombie still lived (still listed as disabled).&lt;br /&gt;&lt;br /&gt;Upon further searching, I found an &lt;a href="http://www.sqlite.org/" target="_blank"&gt;SQLite&lt;/a&gt; database belonging to Stylish:&amp;nbsp; &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;/opt/firefox/defaults/profile/stylish.sqlite&lt;/span&gt;.&amp;nbsp; I nuked it (as root) and restarted Firefox.&amp;nbsp; The zombie persisted.&lt;br /&gt;&lt;br /&gt;Well, perhaps I was overthinking this.&amp;nbsp; With Firefox in safe mode, I installed the latest version of Stylish (1.2.5), then restarted Firefox.&amp;nbsp; Although Firefox had failed to do the upgrade on its own, this worked.&amp;nbsp; The new version was installed and not disabled ... which meant it had a functioning uninstall link ... and there was no mention of version 1.0.7.&amp;nbsp; So I clicked the uninstall link.&amp;nbsp; After restarting Firefox, I found that Stylish 1.2.5 had successfully uninstalled ... and the 1.0.7 zombie had reappeared.&lt;br /&gt;&lt;br /&gt;So I closed Firefox and opened the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;extensions.sqlite&lt;/span&gt; database (in my Firefox profile folder) using the &lt;a href="http://sqlitebrowser.sourceforge.net/" target="_blank"&gt;SQLite database browser&lt;/a&gt;.&amp;nbsp; Here I was able to find an entry for Stylish 1.0.7.&amp;nbsp; It pointed to a directory (with the same hex string name as the one I'd nuked from &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;/opt/firefox/extensions&lt;/span&gt;), this time located in &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;/usr/lib/firefox-10.0/extensions&lt;/span&gt;.&amp;nbsp; Nothing I'd turned up in any of my Google searches pointed to &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;/usr/lib&lt;/span&gt; (other than perhaps references to "globally installed" extensions, with no indication of where that would be -- hence my earlier search of &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;/opt/firefox&lt;/span&gt;).&amp;nbsp; I deleted the newly found subdirectory (as root), restarted Firefox, and woo-hoo!&amp;nbsp; No sign of the zombie.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-8416994837099915831?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/8416994837099915831/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2012/02/slaying-zombie-browser-extension.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/8416994837099915831'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/8416994837099915831'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2012/02/slaying-zombie-browser-extension.html' title='Slaying a Zombie Browser Extension'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-2316992946709811843</id><published>2012-01-30T17:56:00.000-05:00</published><updated>2012-01-30T17:56:05.826-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='INFORMS blog challenge'/><category scheme='http://www.blogger.com/atom/ns#' term='operations research'/><title type='text'>OR in Restaurants</title><content type='html'>The topic for this month's &lt;a href="http://www.informs.org/About-INFORMS/News-Room/O.R.-Analytics-at-Work-Blog/Jan.-Blog-Challenge-Results-O.R.-and-Resolutions" target="_blank"&gt;INFORMS blog challenge&lt;/a&gt; is "OR and Food". I suspect that a number of my fellow bloggers will jump on the diet problem example, also known as the &lt;a href="https://en.wikipedia.org/wiki/Stigler_diet" target="_blank"&gt;Stigler diet&lt;/a&gt;. That also happens to be the name of &lt;a href="http://www.stiglerdiet.com/" target="_blank"&gt;Tim Hopper's &lt;span id="goog_447777901"&gt;&lt;/span&gt;blog&lt;span id="goog_447777902"&gt;&lt;/span&gt;&lt;/a&gt;, so I'm inclined to leave it to him. Also, while LP diet models may be suitable for selecting animal feed, I think the &lt;a href="https://en.wikipedia.org/wiki/Geneva_convention" target="_blank"&gt;Geneva Conventions&lt;/a&gt; prohibit their use on humans.&lt;br /&gt;&lt;br /&gt;My expanding circumference and history at restaurants (*, **) makes it reasonable for me to write, instead, about applications of OR to food &lt;i&gt;service&lt;/i&gt;. There are, in fact, a surprising (at least to me) number and variety of these.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Here at &lt;a href="http://www.msu.edu/" target="_blank"&gt;Michigan State University&lt;/a&gt; we have &lt;a href="http://hospitalitybusiness.broad.msu.edu/" target="_blank"&gt;&lt;i&gt;The&lt;/i&gt; School of Hospitality Business&lt;/a&gt; (SHB), the second-ranked hospitality business school in the country (behind Cornell's). Years ago, one of my colleagues from SHB, Dr. &lt;a href="http://broad.msu.edu/facultystaff/kasavana/" target="_blank"&gt;Michael Kasavana&lt;/a&gt;, told me that restaurant chains (and perhaps individual restaurants) use linear programming as part of &lt;a href="https://en.wikipedia.org/wiki/Menu_engineering" target="_blank"&gt;menu engineering&lt;/a&gt;.&amp;nbsp; (***) That's Mike getting credit in the first footnote of the Wikipedia entry, putting him one up on me in the Internet fame competition.&amp;nbsp; See, for instance, "&lt;a href="http://smallbusiness.chron.com/restaurants-use-linear-programming-menu-planning-37132.html" target="_blank"&gt;How Do Restaurants Use Linear Programming for Menu Planning?&lt;/a&gt;" for a (very) non-technical introduction. Unfortunately, I couldn't find a more suitable link for an OR-savvy audience.&lt;/li&gt;&lt;li&gt;Researching this entry, I tripped over a few papers using &lt;a href="https://en.wikipedia.org/wiki/Data_envelopment_analysis" target="_blank"&gt;Data Envelopment Analysis&lt;/a&gt; to determine whether restaurants in general, and specifically their use of IT in at least one case, are operating "efficiently".&lt;/li&gt;&lt;li&gt;I found a doctoral dissertation entitled "&lt;a href="http://www.google.com/url?sa=t&amp;amp;rct=j&amp;amp;q=&amp;amp;esrc=s&amp;amp;source=web&amp;amp;cd=1&amp;amp;ved=0CEkQFjAA&amp;amp;url=http%3A%2F%2Ftidel.mie.utoronto.ca%2Fpubs%2FTheses%2Fvidotto.phd.pdf&amp;amp;ei=hBYnT97GMdOmsALSyrCMAg&amp;amp;usg=AFQjCNEoDcWpstpd2jR8eEAvcobVznVRYg" target="_blank"&gt;Managing Restaurant Tables Using Constraint Programming&lt;/a&gt;", whose connection to OR should be self-explanatory. The problem encompasses the assignment of tables to diners, both via reservations and walk-in traffic, the possible combination of tables for larger parties, negotiation of reservation start times, and possible on-the-fly reallocation of tables.&lt;/li&gt;&lt;li&gt;Linear programming has been applied to staffing problems, including the staffing of restaurants (where service personnel, including cooks, are assigned to shifts).&lt;/li&gt;&lt;li&gt; The "Caterer Problem" is a classic LP/IP application, in which a hypothetical caterer using linen napkins has to plan how to cover demand at minimum cost by acquiring new napkins and laundering soiled napkins (typically via either of two methods with differing lead times and costs). I don't know how often LP models are actually used by caterers or restaurants, but "it's the thought that counts".&lt;/li&gt;&lt;li&gt;It is well-known that simulation is used to help design both facilities and production systems. Simulation modeling at &lt;a href="http://www.bk.com/" target="_blank"&gt;Burger King&lt;/a&gt; was documented in an &lt;a href="http://www.jstor.org/pss/25060171" target="_blank"&gt;Interfaces article&lt;/a&gt;, and they apparently went so far as to &lt;a href="http://www.hsor.org/case_studies.cfm?name=burger_king" target="_blank"&gt;distribute a simulation model&lt;/a&gt; to restaurant operators as part of a "Productivity for Planning for Profit Kit". Although I can't find the articles documenting it, BK famously redesigned their restaurants (quite a while back) using a simulation model.&amp;nbsp; At that time I was a fairly regular BK customer.&amp;nbsp; Originally, when I walked up to the counter inside, there would be multiple production lines oriented orthogonal to the counter, so that beef patties started at the back of the store and, in the process of moving toward me, magically transformed into ready-to-eat hamburgers.&amp;nbsp; One day I entered a BK and discovered that there was now a single, U-shaped production line, with the long sides parallel to the counter. A patty started at one end of the line and morphed into a burger by the time it reached the other end of the line. Apparently this redesign was the result of a simulation study.&lt;/li&gt;&lt;/ul&gt;So OR has its fingerprints all over the food service industry ... and is therefore to blame for the steepest ascent trajectory of my waistline. (This being an election year, I will join the candidates in abdicating all personal responsibility.)&lt;br /&gt;&lt;br /&gt;(*) True story #1: In graduate school, friends would invite me to dine with them at a local all-you-can-eat buffet restaurant just to watch the carnage.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;(**) True story #2: A local sub shop once experimented with pizza sales. Someone posted a handwritten sign on the wall: "Pizza by the slice, Sunday noon to 4:00, all you can eat".&amp;nbsp; So I stopped by on Sunday. The following week, the sign was amended: "Pizza by the slice, Sunday noon to 4:00, all you can eat &lt;i&gt;except Paul&lt;/i&gt;".&lt;br /&gt;&lt;br /&gt;(***) True story #3: Early in my career, I was teaching linear programming to MBA students.&amp;nbsp; This being before the advent of free or affordable optimization software, I was in fact teaching them the simplex algorithm, by hand.&amp;nbsp; (I have since realized the error of my ways.)&amp;nbsp; At the end of one term, a young lady in the class came up to me, identified herself as a hospitality business major, and proceeded to "&lt;a href="http://forum.wordreference.com/showthread.php?t=1941538" target="_blank"&gt;chew me a new one&lt;/a&gt;", pointing out to me in graphic detail just how useless all this simplex stuff was for her, particularly given her concentration.&amp;nbsp; I later learned that, the very next term, she had a course in her major from the aforementioned Prof. Kasavana ... in which she had to solve linear programs ... by hand.&amp;nbsp; The universe does, in fact, have a sense of humor.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-2316992946709811843?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/2316992946709811843/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2012/01/or-in-restaurants.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/2316992946709811843'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/2316992946709811843'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2012/01/or-in-restaurants.html' title='OR in Restaurants'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-968772928388604632</id><published>2012-01-19T18:06:00.000-05:00</published><updated>2012-01-19T18:06:55.391-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='statistics'/><category scheme='http://www.blogger.com/atom/ns#' term='rant'/><category scheme='http://www.blogger.com/atom/ns#' term='reporting'/><title type='text'>The Most Desperately Needed Degree Program</title><content type='html'>This morning I stumbled across an article on Yahoo! Eduction with the provocative title "&lt;a href="http://education.yahoo.net/articles/most_useless_degrees.htm?kid=1KWNU" target="_blank"&gt;College Majors That Are Useless&lt;/a&gt;". Curiosity made me look at the article. What I saw made me double down on my morning coffee intake, since I assumed my brain was not yet functioning.&lt;br /&gt;&lt;br /&gt;Two disclaimers are warranted. First, my majors were mathematics and mathematics (with a little statistics in between), so I have no personal attachment to the listed majors. Second, and somewhat contrary, I've spent almost 39 years at &lt;a href="http://www.msu.edu/" target="_blank"&gt;Michigan State University&lt;/a&gt; (the former Michigan Agricultural College), a &lt;a href="https://www.msu.edu/%7Esimonsjo/history/edisonhistory/landgrant/template.html" target="_blank"&gt;land-grant&lt;/a&gt; institution with a very strong &lt;a href="http://canr.msu.edu/" target="_blank"&gt;College of Agriculture and Natural Resources&lt;/a&gt; (CANR) and a respected agricultural &lt;a href="http://msue.anr.msu.edu/msue/agriculture_and_agribusiness" target="_blank"&gt;extension service&lt;/a&gt;. While we are a typical, well-rounded university (strong in physics, education and a variety of other fields), we're very proud here of both our land-grant tradition and our strength in agricultural fields. (Note to snobs: Cornell University is another land-grant university.)&lt;br /&gt;&lt;br /&gt;CANR is not hurting for majors, and I have not heard of any problems with placement of those majors, so I was rather shocked to see that the first, fourth and fifth "most useless" majors (agriculture, animal science and horticulture) all came from their domain. As a sidebar, we also offer the other two listed majors, apparel design and theater, albeit in different colleges. The article cites the "&lt;a href="http://www.naceweb.org/Research/Job_Outlook/Job_Outlook.aspx" target="_blank"&gt;National Association of Colleges and Employers' (NACE) 2012 Job Outlook study&lt;/a&gt;", which is free to members (whoever they may be), and which apparently "surveyed almost 1,000 employers on their future hiring plans". Our library system does not have it, so I can comment on neither their methods of data acquisition and analysis nor the accuracy with which their findings were reported in the article. Naturally, that won't stop me from commenting on the article itself.&lt;br /&gt;&lt;br /&gt;First, as a colleague pointed out to me, the article states that 24,988 agriculture degrees (baccalaureate? all levels?) were awarded (in the United States?) in 2008-2009. Amazingly, again according to the article, 24,988 horticulture degrees were awarded that same year.&amp;nbsp; (I should have gone to commencement exercises. Do you suppose that the two majors paraded together in pairs, as if boarding the ark?) The article reports 89,140 degrees awarded in fashion design that year, which in another coincidence is exactly the number of theater degrees awarded.&amp;nbsp; Two cosmic coincidences in the same article ... I wonder what the probability of that is?&lt;br /&gt;&lt;br /&gt;For what it's worth, the article cites the source of the degree counts as The Daily Beast's list of "&lt;a href="http://www.thedailybeast.com/galleries/2011/04/27/20-most-useless-degrees.html" target="_blank"&gt;20 Most Useless Degrees&lt;/a&gt;". The first "useless degree" cited on that list, in what I consider to be a multilayered bit of irony (and with an apology to yet more of my colleagues), is journalism.&lt;br /&gt;&lt;br /&gt;Second, referring to the NACE study, the article states that "[m]any areas of study, such as fashion design and the performing arts, didn't even make the list". Does this mean that two of the five "useless" majors were designated that way because there was little or no data in the study on them?&amp;nbsp; The article does quote job growth or decline projections for all five majors, including fashion design and theater, obtained from the U.S. Department of Labor.&lt;br /&gt;&lt;br /&gt;Third, the criterion of "uselessness" of a major is not clearly spelled out in the article. From the focus on numbers of jobs and projected trends in those numbers, I infer that "uselessness" relates in some way to job prospects.&amp;nbsp; Operations researchers know that if you are going to develop a normative model, you need to define your criterion or criteria carefully.&amp;nbsp; This is what drove me to blog about the article: not just that the criterion is at best implicitly specified, but that it is not tied to the data in any logical way that I can see.&lt;br /&gt;&lt;br /&gt;Is a major "useless" if the number of related jobs is declining?&amp;nbsp; That is suggested in the discussion of agriculture, the first (and therefore most?) "useless" major on the list. "... That means less [&lt;i&gt;sic&lt;/i&gt;] jobs. In fact, the U.S. Department of Labor projects 64,000 fewer jobs in this field over the next seven years."&amp;nbsp; Okay, then why is theater (with projected job &lt;i&gt;growth&lt;/i&gt; of 11% in the same time frame) third on the list of "useless" majors.&lt;br /&gt;&lt;br /&gt;Is "uselessness" based on a glut of applicants?&amp;nbsp; You might speculate that from the inclusion of fashion design, where the government says there were 22,700 jobs in 2008 (with a projected 1% growth over the next seven years) and the article claims that 89,140 students (all with a dual major in theater?) graduated with degrees.&amp;nbsp; That would be rather scary &lt;i&gt;if&lt;/i&gt; the only relevant job for someone with a fashion or apparel design degree were as a fashion designer (and assuming that fashion designers had a projected career span of more than three months).&amp;nbsp; My impression, though, is that retail chains like to hire fashion/apparel design majors as buyers, because they bring an understanding of the product to their work.&amp;nbsp; Similarly, agriculture majors are in demand for more than managing farms; food safety inspectors, sales representatives and marketers for firms selling agricultural equipment or products, buyers for grocery chains etc. may all benefit from that degree.&amp;nbsp; In any case, if the ratio of jobs to graduates is the concern (and I assume that jobs here include occupied positions, not just open positions), then agriculture (25,000 degrees in '08-'09 versus 1,234,000 "agricultural managers" in 2008) would seem to be a pretty appealing choice.&amp;nbsp; That's roughly one graduate for every 49 positions, which would be about replacement rate if you assumed 2% turnover per year.&amp;nbsp; For comparison purposes, if you ran a company with a fixed number of positions, and your employees stayed for life and retired after an average of 40 years on the job, that would be 2.5% turnover.&amp;nbsp; (By the way, in an article full of statistical "coincidences", I have to look at the first four digits of "1,234,000" and wonder if that's another one.)&lt;br /&gt;&lt;br /&gt;I've ranted long enough, so let's just conclude this with two thoughts.&amp;nbsp; The first is that I am, shall we say, unpersuaded by the article.&amp;nbsp; The second, referring back to the title of this post, and tying into recent posts by &lt;a href="http://mat.tepper.cmu.edu/blog/?p=1596" target="_blank"&gt;Mike Trick&lt;/a&gt; and others, is that if I were trying to devise a new college major today, based on need, it would be titled something like "journalistic analytics", and it would focus not on parsing server logs at a site like the Daily Beast but rather on how to draw and present meaningful conclusions from the analysis of data.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-968772928388604632?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/968772928388604632/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2012/01/most-desperately-needed-degree-program.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/968772928388604632'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/968772928388604632'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2012/01/most-desperately-needed-degree-program.html' title='The Most Desperately Needed Degree Program'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-783861023341465641</id><published>2012-01-15T13:41:00.000-05:00</published><updated>2012-01-15T13:41:26.659-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><category scheme='http://www.blogger.com/atom/ns#' term='computing'/><title type='text'>Donating a Computer? Wipe the Drive!</title><content type='html'>Months ago I replaced my old single-core PC&amp;nbsp; with a new quad-core machine. Being a champion procrastinator, I'm only now getting around to donating the old box to charity. The easy part is assembling all the documentation, peripherals, etc. (I'm also a bit anal-retentive about storing documents.) The hard part turns out to be wiping the drive.&lt;br /&gt;&lt;br /&gt;It &lt;i&gt;should&lt;/i&gt; be common knowledge that you never give away a computer without first wiping its hard drive. Over the years, your various user IDs and passwords are stored on the computer in all sorts of places, some of which (at least with Windows) are a bit arcane. Stories have been written on the subject (see, for instance, &lt;a href="http://www.computer-realm.net/the-dangers-donating-discarding-old-computer/"&gt;"The Dangers of Donating or Discarding Your Old Computer"&lt;/a&gt;, or &lt;a href="https://www.pcworld.com/article/110012/hard_drives_exposed.html" target="_blank"&gt;"Hard Drives Exposed"&lt;/a&gt;), although I was unable to find any statistics on actual instances of identity theft from discarded drives. (I found lots of general discussion of the threat, much of it shockingly coming from companies that sell disk wiping software or services.) The same caution also applies to smart phones and USB (thumb) drives, and I suspect people are even less cautious about cleaning out their phones before recycling them. Anything that still works and has ever held a password is a candidate for scrubbing before you recycle or donate it, or before you hand it off to someone that you &lt;i&gt;think&lt;/i&gt; is going to toss it in a landfill.&lt;br /&gt;&lt;br /&gt;There is quite a variety of software, both free and commercial, designed to delete files and wipe drives "securely" from PC disks.&amp;nbsp; I put "securely" in quotes because security is a matter of degree. The only 100% secure way to eliminate sensitive information is to physically destroy the drive (break the platters into pieces, bathe them in acid, launch the remnants into the core of the sun, ...). Runner up is to run a shredder program that overwrites each disk block with various random patterns. The &lt;i&gt;least&lt;/i&gt; secure approach is reformatting the drive, which typically does &lt;i&gt;not&lt;/i&gt; wipe out old contents.&lt;br /&gt;&lt;br /&gt;I'm not worried about an identity thief going over my donated hard drive with forensic equipment, so I'm satisfied with shredding all the files. For reasons unclear to me, though, that turned out to be problematic on the old machine. In fact, just booting the bugger turned out to be problematic. In my years of fighting with PCs, thermal expansion has usually been a problem when the machine was turned on and off, not when it was serving as an unplugged doorstop. Nonetheless, it took three tries reseating memory and PC cards before the old machine would boot, and a fourth try to get it to recognize the keyboard and mouse. Whether that relates to the subsequent adventures, I'm not sure.&lt;br /&gt;&lt;br /&gt;My plan was to wipe the lone hard drive entirely and then reinstall Windows XP. To do so, I downloaded &lt;a href="http://www.dban.org/"&gt;Darik's Boot And Nuke&lt;/a&gt;, which seems to be a highly regarded solution. Burn it to a CD or DVD, boot from the disk, follow a few simple instructions and watch your disk get wiped. Unfortunately, it consistently failed with a sequence of error messages that did not tell me what was going on. The old computer has a bunch of media readers (which I explicitly did &lt;i&gt;not&lt;/i&gt; select for wiping); maybe they were causing problems. Maybe not.&lt;br /&gt;&lt;br /&gt;As at least an interim measure, I installed &lt;a href="http://linuxmint.com/" target="_blank"&gt;Linux Mint&lt;/a&gt; Katya, using the entire hard drive and overwriting the Windows installation. That does not wipe all the data, although I feel moderately confident that the portion of the disk containing actual Linux files is sufficiently overwritten to defeat the casual data thief. The problem is all the unused space on the disk, which still contains whatever it held before I loaded Katya. After a bit of searching, I found the Linux &lt;span style="font-family: &amp;quot;Trebuchet MS&amp;quot;,sans-serif;"&gt;shred&lt;/span&gt; command. The suggestion was to boot from a CD or DVD (I used the Katya installation CD) and run &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;shred -vzf /dev/sda&lt;/span&gt; (replacing &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;/dev/sda&lt;/span&gt; with the name of the actual hard drive partition). Small problem: the hard drive was not showing up in &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;/dev&lt;/span&gt;. The Katya installation disk lets you mount the existing hard drive, so I did that.&amp;nbsp; It mounted as &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;/media/&amp;lt;long number&amp;gt;&lt;/span&gt;.&amp;nbsp; Okay, fine, I would just shred &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;/media/&amp;lt;long number&amp;gt;&lt;/span&gt; ... except I couldn't: the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;shred&lt;/span&gt; command said it was a directory and not writable (even with the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;-f&lt;/span&gt; flag, which should force things to be writable). Running &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;shred&lt;/span&gt; with administrator privileges via &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;sudo&lt;/span&gt; did not help.&lt;br /&gt;&lt;br /&gt;After more searching, I found a &lt;a href="http://superuser.com/questions/19326/how-to-wipe-free-disk-space-in-linux" target="_blank"&gt;helpful answer&lt;/a&gt; by &lt;a href="http://superuser.com/users/4129/david-spillett"&gt;David Spillett&lt;/a&gt;. Booting the clunker from the hard drive (Mint Katya), I opened a terminal in &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;/tmp&lt;/span&gt; and entered the following commands:&lt;br /&gt;&lt;blockquote class="tr_bq"&gt;&lt;pre&gt;&lt;code&gt;dd if=/dev/zero of=zero.small.file bs=1024 count=102400&lt;br /&gt;cat /dev/zero &amp;gt; zero.file&lt;br /&gt;rm zero.small.file&lt;br /&gt;rm zero.file&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;The drive capacity is 165 GB, and Katya's footprint is not all that large, so the second line was quite time consuming. The second line eventually ended in an abort due to lack of free memory. I'm not sure that was an intended result, but it does not seem like a bad thing.&lt;br /&gt;&lt;br /&gt;Overwriting with one layer of zeros is not a very secure shred, but (again) I'm not that worried about someone using forensic hardware to recover my drive. If they do, they'll find their investment of time not well rewarded.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-783861023341465641?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/783861023341465641/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2012/01/donating-computer-wipe-drive.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/783861023341465641'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/783861023341465641'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2012/01/donating-computer-wipe-drive.html' title='Donating a Computer? Wipe the Drive!'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-7015002086728198284</id><published>2012-01-04T14:19:00.000-05:00</published><updated>2012-02-23T09:39:21.521-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='math programming'/><title type='text'>Max/Min Bounds</title><content type='html'>&lt;script type="text/x-mathjax-config"&gt;MathJax.Hub.Config({  tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}});&lt;/script&gt;&lt;script src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML" type="text/javascript"&gt;&lt;/script&gt;Motivated by a &lt;a href="http://www.or-exchange.com/questions/4318/transform-non-linear-to-linear-constraints-manually" target="_blank"&gt;recent question&lt;/a&gt; on &lt;a href="http://or-exchange.com/" target="_blank"&gt;OR-Exchange&lt;/a&gt;, this post expands on a &lt;a href="http://orinanobworld.blogspot.com/2011/01/max-and-min-functions-in-mip.html" target="_blank"&gt;previous post&lt;/a&gt; about constraints that set a variable &lt;i&gt;equal&lt;/i&gt; to the maximum or minimum of other variables in a mathematical program. Here I'll deal with inequality bounds (and with more than two variables involved in the maximum/minimum).&lt;br /&gt;&lt;br /&gt;The setting is a mathematical programming model containing variables \(x_1,\dots,x_n\) and \(y\), where you want to bound \(y\) either above or below by either \(\max_{i=1,\dots,n} x_i\) or \(\min_{i=1,\dots,n}x_i\). Let's dispense with the easy cases first. Since \begin{eqnarray*}y\ge\max_{i=1,\dots,n}x_{i} &amp;amp; \iff &amp;amp; y\ge x_{i}\forall i=1,\dots,n\\y\le\min_{i=1,\dots,n}x_{i} &amp;amp; \iff &amp;amp; y\le x_{i}\forall i=1,\dots,n\end{eqnarray*}those two cases are handled by expanding one nonlinear inequality into \(n\) linear inequalities, with no requirement that the variables be bound and no introduction of integer variables.&lt;br /&gt;&lt;br /&gt;Now let's consider the case \(y\le\max_{i=1,\dots,n}x_i\). (The case \(y\ge\min_{i=1,\dots,n}x_i\) is symmetric and left to the reader as an exercise.) The key to our approach is that \[y\le\max_{i=1,\dots,n}x_i\iff \exists i \ni y\le x_i.\]To handle this case, we need &lt;i&gt;a priori&lt;/i&gt; bounds on the \(x\) variables, say \(L_i\le x_i\le U_i\ \ \forall i\). Let \(\bar{U}=\max_{i=1,\dots,n}U_i\), and note that if the constraint  \(y\le\max_{i=1,\dots,n}x_i\) is to hold, then clearly \(y\le\bar{U}\).&lt;br /&gt;&lt;br /&gt;We introduce binary variables \(\delta_1,\dots,\delta_n\) and the constraint \[\delta_1+\cdots+\delta_n=1.\]Depending on the solver being used, it may be beneficial to specify to the solver that the \(\delta\) variables form a type 1 special ordered set (&lt;a href="https://en.wikipedia.org/wiki/Special_ordered_set" target="_blank"&gt;SOS1&lt;/a&gt;). Now add the following \(n\) constraints:\[y\le x_i + (\bar{U}-L_i)(1-\delta_i)\ \ \forall i=1,\dots,n.\]If \(\delta_i=0\), the right hand side becomes \(x_i+\bar{U}-L_i\ge\bar{U}\), and the constraint is vacuous. For the one index where \(\delta_i=1\), the constraint reduces to \(y\le x_i\), which is all we need.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Addendum 1&lt;/b&gt;: It belatedly occurred to me that it would be equally valid to replace \(\delta_1+\cdots+\delta_n=1\) with \(\delta_1+\cdots+\delta_n\ge 1\) (in which case it is no longer an SOS1 constraint). Requiring \(y\le \max_{i=1,\dots,n} x_i\) is equivalent to saying \(y\le x_1\) OR \(y\le x_2\) OR ... OR \(y\le x_n\), with the ors being inclusive. I have no idea whether this second version is more or less efficient computationally than using the SOS1 constraint.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Addendum 2&lt;/b&gt;: Erwin Kalvelagen posted some alternative, possibly tighter, formulations on &lt;a href="http://yetanothermathprogrammingconsultant.blogspot.com/2012/02/max-tricks.html" target="_blank"&gt;his blog&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-7015002086728198284?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/7015002086728198284/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2012/01/maxmin-bounds.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/7015002086728198284'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/7015002086728198284'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2012/01/maxmin-bounds.html' title='Max/Min Bounds'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-5690191156813082200</id><published>2012-01-01T11:00:00.001-05:00</published><updated>2012-01-15T09:56:43.019-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='INFORMS blog challenge'/><category scheme='http://www.blogger.com/atom/ns#' term='operations research'/><category scheme='http://www.blogger.com/atom/ns#' term='whimsy'/><title type='text'>Resolutions, Seasonality and Transient Effects</title><content type='html'>Today is New Year's Day (at least on the &lt;a href="https://en.wikipedia.org/wiki/Gregorian_calendar" target="_blank"&gt;Gregorian calendar&lt;/a&gt;), and it is traditional for some people to usher in the new year by making personal resolutions. The theme for this month's &lt;a href="http://www.informs.org/About-INFORMS/News-Room/O.R.-Analytics-at-Work-Blog/Jan.-Blog-Challenge-O.R.-and-Resolutions-Dec.-Blog-Challenge-Results-O.R.-and-Families" target="_blank"&gt;INFORMS blog challenge&lt;/a&gt; is "O.R. and Resolutions", and to an O.R. person "resolutions" frequently implies "&lt;a href="https://en.wikipedia.org/wiki/Transient_response" target="_blank"&gt;transient responses&lt;/a&gt;".&amp;nbsp; We make a resolution, attempt to adhere to it for a while (introducing a transient change in our behavior), then eventually revert to what we were doing pre-resolution (return to &lt;a href="https://en.wikipedia.org/wiki/Steady_state" target="_blank"&gt;steady state&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;I work out at a local &lt;a href="http://www.ymca.net/" target="_blank"&gt;YMCA&lt;/a&gt;. The Y does its programs in seven week sessions for the most part, with one- or two-week gaps sprinkled around near holidays. I'm not privy to enrollment data, but through decades of empirical study I and other members have identified a distinct seasonal pattern. Building use spikes at the start of the first session of the year (which will be tomorrow). Regulars who come in the evening will discover that parking spots are suddenly quite scarce. The spike is visible but considerably smaller in the mornings. Morning attendance skews toward retirees and the odd academic (pardon the redundancy). I suspect that retirees are less inclined to make resolutions, or alternatively more inclined to stick with them. Academics probably simply forget to make resolutions (just as we forget about matching socks, etc. -- we're too occupied with "profound" thoughts).&lt;br /&gt;&lt;br /&gt;After the initial spike in attendance, there is a bit of gradual erosion, as "resolvers" discover that exercise is in fact a euphemism for physical exertion.&amp;nbsp; There's an abrupt drop (think step function) right around the end of the first seven-week session, and then a bit more erosion as attendance returns to a new steady state, barely distinguishable from the pre-New Year's steady state. Other seasonal patterns occur later in the year: a drop in building use during the summer, when outdoor activities and vacation trips lure people away; and a modest increase (noted only in the evening) between mid-April and perhaps mid-May (which I think of as "preparation for bikini season", and which does not seem to involve any retirees).&lt;br /&gt;&lt;br /&gt;Besides offering an example of seasonality, the New Year's resolution phenomenon offers a metaphor for O. R. practice. The "resolver" diets, exercises, stops smoking or whatever for a while because the "boss" (their conscience) is paying attention.&amp;nbsp; When the "boss" stops watching, the "resolver" makes excuses for why the new regime is too difficult, and reverts to previous behavior.&amp;nbsp; An O. R. solution to a business problem that is implemented top-down, without genuine commitment by the people who actually have to apply the solution (and change behaviors in doing so), is likely to end up a transient response leading to a return to the previous steady state.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Addendum&lt;/b&gt;: Thanks to &lt;a class="c-W-yq" href="https://plus.google.com/u/0/103198324848421501815" target="_blank"&gt;Mary Leszczynski&lt;/a&gt; for pointing out an article in Atlantic Monthly titled "&lt;a href="http://m.theatlantic.com/business/archive/2012/01/this-is-why-you-dont-go-to-the-gym/251332/" target="_blank"&gt;This Is Why You Don't Go to the Gym&lt;/a&gt;". The article suggests that penalizing yourself for skipped workouts is a way to motivate follow-through on that New Year's resolution to get in shape. I've occasionally given some thought to why I'm as regular with my workouts as I am. One factor, which fits with the article, is that a little voice in the back of my head reminds me that I've already paid for the workout. (I'm a bit of a cheapskate, so that little voice gets heard.) Another factor is that I mainly do group workouts (aerobics, Tae Kwon Do), with occasional solo forays to the weight room or stationary bicycle. Group workouts can be more fun, but they also mean that slacking will be noticed by someone other than yourself. At my age, though, the principal motivator is fear of the alternative (what my body will turn into if I don't work out).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-5690191156813082200?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/5690191156813082200/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2012/01/resolutions-seasonality-and-transient.html#comment-form' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/5690191156813082200'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/5690191156813082200'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2012/01/resolutions-seasonality-and-transient.html' title='Resolutions, Seasonality and Transient Effects'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-4804021573887643619</id><published>2011-12-29T16:01:00.000-05:00</published><updated>2011-12-29T16:12:01.199-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Mint'/><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><category scheme='http://www.blogger.com/atom/ns#' term='WIndows'/><category scheme='http://www.blogger.com/atom/ns#' term='Ubuntu'/><title type='text'>Launching Windows Apps with Wine</title><content type='html'>Although I work almost 100% with Linux these days, I have a few Windows applications I find useful (including &lt;a href="http://www.irfanview.com/" target="_blank"&gt;IrfanView&lt;/a&gt; for quick image edits and OCR -- much simpler, albeit less powerful, than &lt;a href="http://www.gimp.org/" target="_blank"&gt;GIMP&lt;/a&gt;) and &lt;a href="http://www.cockos.com/pathsync/" target="_blank"&gt;PathSync&lt;/a&gt; for synchronizing local directories with my thumb drives. I also find &lt;a href="http://www.tracker-software.com/product/pdf-xchange-viewer" target="_blank"&gt;PDF-XChange Viewer&lt;/a&gt; handy for adding annotations to PDF files.&amp;nbsp; All these programs run fine under &lt;a href="http://www.winehq.org/" target="_blank"&gt;Wine&lt;/a&gt;, with one small "gotcha".&amp;nbsp; When I install them (by downloading the Windows installer and then running "&lt;span style="font-family: &amp;quot;Trebuchet MS&amp;quot;,sans-serif;"&gt;wine name-of-installer.exe&lt;/span&gt;" in a terminal), shortcuts to them are added to the Wine submenu of the GNOME menu ... but the shortcuts are often&amp;nbsp; dysfunctional.&amp;nbsp; They attempt to launch the Windows &lt;span style="font-family: &amp;quot;Trebuchet MS&amp;quot;,sans-serif;"&gt;.lnk&lt;/span&gt; file added to the (virtual) Windows start menu, and typically I either get a "file not found" pop-up or the launch simply fails silently.&lt;br /&gt;&lt;br /&gt;The solution I have found is to manually edit the shortcuts.&amp;nbsp; Suppose that I am logged in as user "paul" and I've just installed IrfanView.&amp;nbsp; My first step is to track down the Windows path to the executable.&amp;nbsp; Assuming defaults were used (generally a good thing when installing software under Wine), I open a terminal and drill down to &lt;span style="font-family: &amp;quot;Trebuchet MS&amp;quot;,sans-serif;"&gt;/home/paul/.wine/drive-c/Program\ Files&lt;/span&gt;, where I find the &lt;span style="font-family: &amp;quot;Trebuchet MS&amp;quot;,sans-serif;"&gt;IrfanView&lt;/span&gt; directory and, in that, the &lt;span style="font-family: &amp;quot;Trebuchet MS&amp;quot;,sans-serif;"&gt;i_view32.exe&lt;/span&gt; executable.&lt;br /&gt;&lt;br /&gt;The next step is to run&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;env WINEPREFIX="/home/paul/.wine" wine "C:\Program Files\IrfanView\i_view32.exe"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;in a terminal and make sure that it launches correctly.&amp;nbsp; Note that the path to the executable is written Windows-style (backslashes, no escaping things) in quotation marks.&amp;nbsp; If the program launches properly, I close it, copy the entire line to the clipboard, find the launcher in the GNOME menu, right-click and choose "Edit properties", and replace the contents of the "Command:" field with the contents of the clipboard.&amp;nbsp; I also confirm that launcher type is "Application" and &lt;i&gt;not&lt;/i&gt; "Application in Terminal".&amp;nbsp; With that done, I close the launcher edit panel and test it.&amp;nbsp; Sometimes it seems to take a while before the menu detects and adopts the change I just made.&amp;nbsp; I'm not sure, shy of logging out (overkill?), what the best way to impose the change immediately is.&amp;nbsp; I've tried "&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;killall gnome-panel&lt;/span&gt;" (possibly also overkill) with mixed success.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-4804021573887643619?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/4804021573887643619/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/12/launching-windows-apps-with-wine.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/4804021573887643619'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/4804021573887643619'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/12/launching-windows-apps-with-wine.html' title='Launching Windows Apps with Wine'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-7185224045063079029</id><published>2011-12-22T15:55:00.000-05:00</published><updated>2011-12-22T15:55:43.122-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='math programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='CPLEX'/><title type='text'>Extracting Variables in CPLEX</title><content type='html'>It's never happened to me, but apparently some CPLEX users (working with one of the programming APIs) inherit a fully formed problem, an instance of &lt;span style="font-family: &amp;quot;Trebuchet MS&amp;quot;,sans-serif;"&gt;IloCplex&lt;/span&gt; or perhaps &lt;span style="font-family: &amp;quot;Trebuchet MS&amp;quot;,sans-serif;"&gt;IloModel&lt;/span&gt;, without having access to the Concert code that constructed it.&amp;nbsp; You only need the problem object to solve it and get the solution status and objective value; but in order to get the values of the variables in an optimal solution, you need to pass either an array of variables (&lt;span style="font-family: &amp;quot;Trebuchet MS&amp;quot;,sans-serif;"&gt;IloNumVar[]&lt;/span&gt;) or individual variables in function calls (so that CPLEX can return values matched to the corresponding variables).&amp;nbsp; If all you have is the problem object, how do you know what the variables are?&lt;br /&gt;&lt;br /&gt;This has been asked more than once on help forums, so I list below a Java function that I believe will extract all variables from an instance of &lt;span style="font-family: &amp;quot;Trebuchet MS&amp;quot;,sans-serif;"&gt;IloCplex&lt;/span&gt;.&amp;nbsp; Something quite similar should work in the C++ API, and hopefully if you use the C API you can make the leap from the Java code.&amp;nbsp; The Python API seems to provide a &lt;span style="font-family: &amp;quot;Trebuchet MS&amp;quot;,sans-serif;"&gt;VariablesInterface&lt;/span&gt; class that I think provides a mechanism (if it's even needed in Python -- I don't really know).&amp;nbsp; I'm blissfully ignorant about the Matlab API.&lt;br /&gt;&lt;br /&gt;I've tried to stress-test the Java code, but nonetheless you use it at your own peril.&lt;br /&gt;&lt;style type="text/css"&gt;&lt;!--body.hl { background-color:#ffffff; }pre.hl { color:#000000; background-color:#ffffff; font-size:10pt; font-family:'Courier New';}.hl.num { color:#2928ff; }.hl.esc { color:#ff00ff; }.hl.str { color:#ff0000; }.hl.dstr { color:#818100; }.hl.slc { color:#838183; font-style:italic; }.hl.com { color:#838183; font-style:italic; }.hl.dir { color:#008200; }.hl.sym { color:#000000; }.hl.line { color:#555555; }.hl.mark { background-color:#ffffbb;}.hl.kwa { color:#000000; font-weight:bold; }.hl.kwb { color:#830000; }.hl.kwc { color:#000000; font-weight:bold; }.hl.kwd { color:#010181; }//--&gt;&lt;/style&gt;&lt;br /&gt;&lt;pre class="hl"&gt;  &lt;span class="hl kwa"&gt;private&lt;/span&gt; IloNumVar&lt;span class="hl sym"&gt;[]&lt;/span&gt; &lt;span class="hl kwd"&gt;parse&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;IloCplex cplex&lt;span class="hl sym"&gt;)&lt;/span&gt; &lt;span class="hl kwa"&gt;throws&lt;/span&gt; IloException &lt;span class="hl sym"&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class="hl kwc"&gt;HashSet&lt;/span&gt;&lt;span class="hl sym"&gt;&amp;lt;&lt;/span&gt;IloNumVar&lt;span class="hl sym"&gt;&amp;gt;&lt;/span&gt; vars &lt;span class="hl sym"&gt;=&lt;/span&gt; &lt;span class="hl kwa"&gt;new&lt;/span&gt; &lt;span class="hl kwc"&gt;HashSet&lt;/span&gt;&lt;span class="hl sym"&gt;&amp;lt;&lt;/span&gt;IloNumVar&lt;span class="hl sym"&gt;&amp;gt;();&lt;/span&gt;&lt;br /&gt;    &lt;span class="hl kwc"&gt;Iterator&lt;/span&gt; it &lt;span class="hl sym"&gt;=&lt;/span&gt; cplex&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;iterator&lt;/span&gt;&lt;span class="hl sym"&gt;();&lt;/span&gt;&lt;br /&gt;    IloLinearNumExpr expr&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;    IloLinearNumExprIterator it2&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class="hl kwa"&gt;while&lt;/span&gt; &lt;span class="hl sym"&gt;(&lt;/span&gt;it&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;hasNext&lt;/span&gt;&lt;span class="hl sym"&gt;()) {&lt;/span&gt;&lt;br /&gt;      IloAddable thing &lt;span class="hl sym"&gt;= (&lt;/span&gt;IloAddable&lt;span class="hl sym"&gt;)&lt;/span&gt; it&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;next&lt;/span&gt;&lt;span class="hl sym"&gt;();&lt;/span&gt;&lt;br /&gt;      &lt;span class="hl kwa"&gt;if&lt;/span&gt; &lt;span class="hl sym"&gt;(&lt;/span&gt;thing &lt;span class="hl kwa"&gt;instanceof&lt;/span&gt; IloRange&lt;span class="hl sym"&gt;) {&lt;/span&gt;&lt;br /&gt;        expr &lt;span class="hl sym"&gt;= (&lt;/span&gt;IloLinearNumExpr&lt;span class="hl sym"&gt;) ((&lt;/span&gt;IloRange&lt;span class="hl sym"&gt;)&lt;/span&gt; thing&lt;span class="hl sym"&gt;).&lt;/span&gt;&lt;span class="hl kwd"&gt;getExpr&lt;/span&gt;&lt;span class="hl sym"&gt;();&lt;/span&gt;&lt;br /&gt;        it2 &lt;span class="hl sym"&gt;=&lt;/span&gt; expr&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;linearIterator&lt;/span&gt;&lt;span class="hl sym"&gt;();&lt;/span&gt;&lt;br /&gt;        &lt;span class="hl kwa"&gt;while&lt;/span&gt; &lt;span class="hl sym"&gt;(&lt;/span&gt;it2&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;hasNext&lt;/span&gt;&lt;span class="hl sym"&gt;()) {&lt;/span&gt;&lt;br /&gt;          vars&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;add&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;it2&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;nextNumVar&lt;/span&gt;&lt;span class="hl sym"&gt;());&lt;/span&gt;&lt;br /&gt;        &lt;span class="hl sym"&gt;}&lt;/span&gt;&lt;br /&gt;      &lt;span class="hl sym"&gt;}&lt;/span&gt; &lt;span class="hl kwa"&gt;else if&lt;/span&gt; &lt;span class="hl sym"&gt;(&lt;/span&gt;thing &lt;span class="hl kwa"&gt;instanceof&lt;/span&gt; IloObjective&lt;span class="hl sym"&gt;) {&lt;/span&gt;&lt;br /&gt;        expr &lt;span class="hl sym"&gt;= (&lt;/span&gt;IloLinearNumExpr&lt;span class="hl sym"&gt;) ((&lt;/span&gt;IloObjective&lt;span class="hl sym"&gt;)&lt;/span&gt; thing&lt;span class="hl sym"&gt;).&lt;/span&gt;&lt;span class="hl kwd"&gt;getExpr&lt;/span&gt;&lt;span class="hl sym"&gt;();&lt;/span&gt;&lt;br /&gt;        it2 &lt;span class="hl sym"&gt;=&lt;/span&gt; expr&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;linearIterator&lt;/span&gt;&lt;span class="hl sym"&gt;();&lt;/span&gt;&lt;br /&gt;        &lt;span class="hl kwa"&gt;while&lt;/span&gt; &lt;span class="hl sym"&gt;(&lt;/span&gt;it2&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;hasNext&lt;/span&gt;&lt;span class="hl sym"&gt;()) {&lt;/span&gt;&lt;br /&gt;          vars&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;add&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;it2&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;nextNumVar&lt;/span&gt;&lt;span class="hl sym"&gt;());&lt;/span&gt;&lt;br /&gt;        &lt;span class="hl sym"&gt;}&lt;/span&gt;&lt;br /&gt;      &lt;span class="hl sym"&gt;}&lt;/span&gt; &lt;span class="hl kwa"&gt;else if&lt;/span&gt; &lt;span class="hl sym"&gt;(&lt;/span&gt;thing &lt;span class="hl kwa"&gt;instanceof&lt;/span&gt; IloSOS1&lt;span class="hl sym"&gt;) {&lt;/span&gt;&lt;br /&gt;        vars&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;addAll&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwc"&gt;Arrays&lt;/span&gt;&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;asList&lt;/span&gt;&lt;span class="hl sym"&gt;(((&lt;/span&gt;IloSOS1&lt;span class="hl sym"&gt;)&lt;/span&gt; thing&lt;span class="hl sym"&gt;).&lt;/span&gt;&lt;span class="hl kwd"&gt;getNumVars&lt;/span&gt;&lt;span class="hl sym"&gt;()));&lt;/span&gt;&lt;br /&gt;      &lt;span class="hl sym"&gt;}&lt;/span&gt; &lt;span class="hl kwa"&gt;else if&lt;/span&gt; &lt;span class="hl sym"&gt;(&lt;/span&gt;thing &lt;span class="hl kwa"&gt;instanceof&lt;/span&gt; IloSOS2&lt;span class="hl sym"&gt;) {&lt;/span&gt;&lt;br /&gt;        vars&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;addAll&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwc"&gt;Arrays&lt;/span&gt;&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;asList&lt;/span&gt;&lt;span class="hl sym"&gt;(((&lt;/span&gt;IloSOS2&lt;span class="hl sym"&gt;)&lt;/span&gt; thing&lt;span class="hl sym"&gt;).&lt;/span&gt;&lt;span class="hl kwd"&gt;getNumVars&lt;/span&gt;&lt;span class="hl sym"&gt;()));&lt;/span&gt;&lt;br /&gt;      &lt;span class="hl sym"&gt;}&lt;/span&gt; &lt;span class="hl kwa"&gt;else if&lt;/span&gt; &lt;span class="hl sym"&gt;(&lt;/span&gt;thing &lt;span class="hl kwa"&gt;instanceof&lt;/span&gt; IloLPMatrix&lt;span class="hl sym"&gt;) {&lt;/span&gt;&lt;br /&gt;        vars&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;addAll&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwc"&gt;Arrays&lt;/span&gt;&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;asList&lt;/span&gt;&lt;span class="hl sym"&gt;(((&lt;/span&gt;IloLPMatrix&lt;span class="hl sym"&gt;)&lt;/span&gt; thing&lt;span class="hl sym"&gt;).&lt;/span&gt;&lt;span class="hl kwd"&gt;getNumVars&lt;/span&gt;&lt;span class="hl sym"&gt;()));&lt;/span&gt;&lt;br /&gt;      &lt;span class="hl sym"&gt;}&lt;/span&gt;&lt;br /&gt;    &lt;span class="hl sym"&gt;}&lt;/span&gt;&lt;br /&gt;    IloNumVar&lt;span class="hl sym"&gt;[]&lt;/span&gt; varray &lt;span class="hl sym"&gt;=&lt;/span&gt; vars&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;toArray&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwa"&gt;new&lt;/span&gt; IloNumVar&lt;span class="hl sym"&gt;[&lt;/span&gt;&lt;span class="hl num"&gt;1&lt;/span&gt;&lt;span class="hl sym"&gt;]);&lt;/span&gt;&lt;br /&gt;    &lt;span class="hl kwa"&gt;return&lt;/span&gt; varray&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class="hl sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-7185224045063079029?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/7185224045063079029/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/12/extracting-variables-in-cplex.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/7185224045063079029'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/7185224045063079029'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/12/extracting-variables-in-cplex.html' title='Extracting Variables in CPLEX'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-7190740656833032272</id><published>2011-12-07T20:49:00.001-05:00</published><updated>2011-12-07T21:29:44.216-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='math programming'/><category scheme='http://www.blogger.com/atom/ns#' term='constraint programming'/><title type='text'>Indexing an Array with a Variable</title><content type='html'>&lt;script type="text/x-mathjax-config"&gt;MathJax.Hub.Config({  tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}});&lt;/script&gt;&lt;script src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML" type="text/javascript"&gt;&lt;/script&gt;Sometimes, in the context of a mathematical program, someone wants to use a variable $x$ to index a vector $y$, as in \[z = y[x].\] As a starting point, we should assume that $x$ is an integer variable whose domain equals, or at least is a subset of, the index set of $y$. If you try to set $z=y[2.71828]$, or $z=y[5]$ when $y$ is indexed by ${1,\dots,4}$, you should expect Bad Things To Happen.&lt;br /&gt;&lt;br /&gt;With that stipulation, $z=y[x]$ poses no problem in a &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/Constraint_programming" target="_blank"&gt;constraint program&lt;/a&gt;. It cannot, however, be expressed directly in a &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/Optimization_%28mathematics%29" target="_blank"&gt;mathematical program&lt;/a&gt;. If the domain of $x$ is not too large, it can be implemented somewhat obliquely in a mathematical program using binary variables.&lt;br /&gt;&lt;br /&gt;Let's assume that $y$ is indexed over $1,\dots,N$ (with $N$ known at the outset), and that $y$ is a parameter. (We'll treat the case where $y$ is a variable in a minute.) Create $N$ binary variables $x_1,\dots,x_N$ and add the constraint \[x_1+\dots+x_N=1,\] which makes $\{x_1,\dots,x_N\}$ a type 1 &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/Special_ordered_set" target="_blank"&gt;special ordered set &lt;/a&gt;(SOS1). Then define $z$ via \[z=\sum_{i=1}^N y[i]*x_i.\]&lt;br /&gt;&lt;br /&gt;You can do exactly this when $y$ is a vector of variables, but it adds a nonconvex quadratic constraint to the model, which likely prevents you from finding a guaranteed optimum, and greatly restricts what algorithms/software you can use. If we know &lt;i&gt;a priori&lt;/i&gt; lower and upper bounds for $y$, say \[L_i \le y[i] \le U_i \forall i\in {1,\dots,N}\] with $L_i$ and $U_i$ parameters, we can add the $x_i$ as above and use the following set of constraints to define $z$: \[\begin{eqnarray*}y[i] -z \le (U_i - \hat{L})(1-x_i)&amp;nbsp; \forall i\in {1,\dots,N}\\ y[i] - z \ge (L_i - \hat{U})(1-x_i)&amp;nbsp; \forall i\in {1,\dots,N}\end{eqnarray*}\]where $\hat{L}=\min_{i=1,\dots,N} L_i$ and $\hat{U}=\max_{i=1,\dots,N} U_i$.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-7190740656833032272?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/7190740656833032272/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/12/indexing-array-with-variable.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/7190740656833032272'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/7190740656833032272'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/12/indexing-array-with-variable.html' title='Indexing an Array with a Variable'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-6267252154457786575</id><published>2011-11-26T17:32:00.001-05:00</published><updated>2011-11-26T17:59:33.477-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='whimsy'/><title type='text'>Charlotte's Literary Park</title><content type='html'>Across the street from the Charlotte (NC) Convention Center, site of the recent &lt;a href="http://www.informs.org/" target="_blank"&gt;INFORMS&lt;/a&gt; conference, is a small park/shopping area that I think is known as "The Green". It contains a bit of statuary and some rather amusing "street signs" that I thought were worth remembering. In no particular order (and demonstrating no photographic skill whatsoever), here are some shots I snapped with my tablet's camera.&lt;br /&gt;&lt;br /&gt;These two sculptures flank the entrance to the park:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-0zD9XsrwrX8/TtBiRcrklvI/AAAAAAAAAHA/lMfn9ZErvlo/s1600/book_tower.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;" target="_blank"&gt;&lt;img border="0" height="320" src="http://4.bp.blogspot.com/-0zD9XsrwrX8/TtBiRcrklvI/AAAAAAAAAHA/lMfn9ZErvlo/s320/book_tower.jpg" width="240" /&gt;&lt;/a&gt;&lt;a href="http://2.bp.blogspot.com/-RpAo2zWIp2g/TtBiP-ZWGLI/AAAAAAAAAG8/E42MqrlHwxE/s1600/book_tower2.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;" target="_blank"&gt;&lt;img border="0" height="320" src="http://2.bp.blogspot.com/-RpAo2zWIp2g/TtBiP-ZWGLI/AAAAAAAAAG8/E42MqrlHwxE/s320/book_tower2.jpg" width="240" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;(Sorry about the largely illegible engraving; the sun deserted me in my hour of need.) Toward the middle of the park, we have this somewhat curious choice:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-lg4afHxdrr0/TtBiKvggF0I/AAAAAAAAAGw/OJB5-E1hkLc/s1600/three_fish.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;" target="_blank"&gt;&lt;img border="0" height="240" src="http://3.bp.blogspot.com/-lg4afHxdrr0/TtBiKvggF0I/AAAAAAAAAGw/OJB5-E1hkLc/s320/three_fish.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;I'm not sure what (if anything) they have to do with literature, and I could swear they were extras in an episode of &lt;a href="https://en.wikipedia.org/wiki/Voyage_to_the_Bottom_of_the_Sea_%28TV_series%29" target="_blank"&gt;Voyage to the Bottom of the Sea&lt;/a&gt; (a major contributor to my aversion to fish in restaurants).&lt;br /&gt;&lt;br /&gt;Now for the lamp posts:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-XzNdlqbis88/TtBh7Sw5V9I/AAAAAAAAAGM/rPlB1-I15F0/s1600/LewisCarroll.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;" target="_blank"&gt;&lt;img border="0" height="320" src="http://1.bp.blogspot.com/-XzNdlqbis88/TtBh7Sw5V9I/AAAAAAAAAGM/rPlB1-I15F0/s320/LewisCarroll.jpg" width="240" /&gt;&lt;/a&gt;&lt;a href="http://1.bp.blogspot.com/-ylIoNzwUG-s/TtBh9HvWpYI/AAAAAAAAAGQ/e2QTZl5lPh8/s1600/EmilyBronte.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;" target="_blank"&gt;&lt;img border="0" height="320" src="http://1.bp.blogspot.com/-ylIoNzwUG-s/TtBh9HvWpYI/AAAAAAAAAGQ/e2QTZl5lPh8/s320/EmilyBronte.jpg" width="240" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-d1cJB1XmGb8/TtBh-7EkmhI/AAAAAAAAAGU/bVzwIcThzJI/s1600/HemanMelville.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;" target="_blank"&gt;&lt;img border="0" height="320" src="http://1.bp.blogspot.com/-d1cJB1XmGb8/TtBh-7EkmhI/AAAAAAAAAGU/bVzwIcThzJI/s320/HemanMelville.jpg" width="240" /&gt;&lt;/a&gt;&lt;a href="http://1.bp.blogspot.com/-ilVHwETUpUU/TtBiAgmcUHI/AAAAAAAAAGY/4oJ18UPBcdg/s1600/PearlBuck.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;" target="_blank"&gt;&lt;img border="0" height="320" src="http://1.bp.blogspot.com/-ilVHwETUpUU/TtBiAgmcUHI/AAAAAAAAAGY/4oJ18UPBcdg/s320/PearlBuck.jpg" width="240" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-fNJEkL5zPmI/TtBiBy_GylI/AAAAAAAAAGc/W_K8F5vIqIU/s1600/EdgarAllanPoe.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;" target="_blank"&gt;&lt;img border="0" height="320" src="http://1.bp.blogspot.com/-fNJEkL5zPmI/TtBiBy_GylI/AAAAAAAAAGc/W_K8F5vIqIU/s320/EdgarAllanPoe.jpg" width="240" /&gt;&lt;/a&gt;&lt;a href="http://4.bp.blogspot.com/-32brm9EmDxw/TtBiDyJwIpI/AAAAAAAAAGg/_OT_0phkABk/s1600/AliceWalker.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;" target="_blank"&gt;&lt;img border="0" height="320" src="http://4.bp.blogspot.com/-32brm9EmDxw/TtBiDyJwIpI/AAAAAAAAAGg/_OT_0phkABk/s320/AliceWalker.jpg" width="240" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-vlrv7Dyqrbw/TtBiFvHdqXI/AAAAAAAAAGk/YJN_AHZZda0/s1600/EdgarRiceBurroughs.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;" target="_blank"&gt;&lt;img border="0" height="320" src="http://1.bp.blogspot.com/-vlrv7Dyqrbw/TtBiFvHdqXI/AAAAAAAAAGk/YJN_AHZZda0/s320/EdgarRiceBurroughs.jpg" width="240" /&gt;&lt;/a&gt;&lt;a href="http://4.bp.blogspot.com/-_h4rn8YuHhw/TtBiHEhVkWI/AAAAAAAAAGo/xXQlWOLSrQo/s1600/MarkTwain.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;" target="_blank"&gt;&lt;img border="0" height="320" src="http://4.bp.blogspot.com/-_h4rn8YuHhw/TtBiHEhVkWI/AAAAAAAAAGo/xXQlWOLSrQo/s320/MarkTwain.jpg" width="240" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-E45z0qsAiMk/TtBiI64-5gI/AAAAAAAAAGs/rpJF20QNCR0/s1600/ZaneGrey.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;" target="_blank"&gt;&lt;img border="0" height="320" src="http://4.bp.blogspot.com/-E45z0qsAiMk/TtBiI64-5gI/AAAAAAAAAGs/rpJF20QNCR0/s320/ZaneGrey.jpg" width="240" /&gt;&lt;/a&gt;&lt;a href="http://1.bp.blogspot.com/-y0QOZ5FrGio/TtBiMr0rKVI/AAAAAAAAAG0/kFGAmpuQKbw/s1600/JamesJoyce.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;" target="_blank"&gt;&lt;img border="0" height="320" src="http://1.bp.blogspot.com/-y0QOZ5FrGio/TtBiMr0rKVI/AAAAAAAAAG0/kFGAmpuQKbw/s320/JamesJoyce.jpg" width="240" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-gJlIFjIRhwM/TtBiORezVTI/AAAAAAAAAG4/cEHH0fs1Jh0/s1600/OgdenNash.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;" target="_blank"&gt;&lt;img border="0" height="320" src="http://3.bp.blogspot.com/-gJlIFjIRhwM/TtBiORezVTI/AAAAAAAAAG4/cEHH0fs1Jh0/s320/OgdenNash.jpg" width="240" /&gt;&lt;/a&gt;&lt;a href="http://2.bp.blogspot.com/-GdZBHnWYnZo/TtBiTBluw7I/AAAAAAAAAHE/OQwvRHrVA2g/s1600/JamesBaldwin.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;" target="_blank"&gt;&lt;img border="0" height="320" src="http://2.bp.blogspot.com/-GdZBHnWYnZo/TtBiTBluw7I/AAAAAAAAAHE/OQwvRHrVA2g/s320/JamesBaldwin.jpg" width="240" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;There was one other signpost, which I did not shoot because no angle did it justice. It had a half dozen or so signs pointing to other cities and towns named "Charlotte" (including Michigan's Charlotte, mispronounced "shar-LOT" by the locals). I have to wonder whether having a sign already devoted to the name "Charlotte" is why &lt;a href="https://en.wikipedia.org/wiki/Charlotte_Bront%C3%AB" target="_blank"&gt;Charlotte Bronte&lt;/a&gt; did not earn a lamp post. (Alternate theories: Texas has the only town named "Bronte" in the U.S.; or Emily's shade bribed someone to one-up her sister.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-6267252154457786575?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/6267252154457786575/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/11/charlottes-literary-park.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/6267252154457786575'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/6267252154457786575'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/11/charlottes-literary-park.html' title='Charlotte&apos;s Literary Park'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-0zD9XsrwrX8/TtBiRcrklvI/AAAAAAAAAHA/lMfn9ZErvlo/s72-c/book_tower.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-2544421783386711448</id><published>2011-11-25T18:53:00.001-05:00</published><updated>2011-11-25T19:07:45.699-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><category scheme='http://www.blogger.com/atom/ns#' term='Ubuntu'/><title type='text'>Android-Linux File Transfers</title><content type='html'>I recently acquired a &lt;a href="http://us.toshiba.com/tablets/thrive/10-inch/" target="_blank"&gt;Toshiba Thrive&lt;/a&gt; tablet (&lt;a href="https://en.wikipedia.org/wiki/Android_%28operating_system%29" target="_blank"&gt;Android Honeycomb&lt;/a&gt;, currently version 3.2.1), in part because it comes with two USB ports (one full size, one mini).&amp;nbsp; The USB ports theoretically allow me to move files between my Ubuntu PC and the tablet by mounting the tablet as a disk drive on the PC.&amp;nbsp; I say "theoretically" because Google recently moved to &lt;a href="https://en.wikipedia.org/wiki/Media_Transfer_Protocol" target="_blank"&gt;Media Transfer Protocol&lt;/a&gt; for handling connections over USB. This seems to be okay for Windows PCs and Macs, but for Ubuntu (and other Linux systems) it requires using the &lt;span style="font-family: &amp;quot;Trebuchet MS&amp;quot;,sans-serif;"&gt;mtpfs&lt;/span&gt; package. I've found connections to be excruciating slow, and for some reason (probably a setting I'm missing), when I do get connected, all I see is an empty root and an empty &lt;span style="font-family: &amp;quot;Trebuchet MS&amp;quot;,sans-serif;"&gt;Playlists&lt;/span&gt; subdirectory. Trust me, there are tons of files on the Thrive.&lt;br /&gt;&lt;br /&gt;Fortunately, I found &lt;a href="https://market.android.com/details?id=nextapp.websharing" target="_blank"&gt;WebSharingLite File/Media Sync&lt;/a&gt;, a free app in the Android Market. (As one might expect from the "Lite" part, there is a paid version, rather economically priced.) I have a WiFi DSL gateway at home (and of course my laptop has WiFi). Running WebSharingLite on the tablet, I can connect via a web browser from my PC or laptop and upload/download files considerably faster than what &lt;span style="font-family: &amp;quot;Trebuchet MS&amp;quot;,sans-serif;"&gt;mtpfs&lt;/span&gt; over USB seems to allow. (Again, though, I should stress that there's no guarantee I'm setting up &lt;span style="font-family: &amp;quot;Trebuchet MS&amp;quot;,sans-serif;"&gt;mtpfs&lt;/span&gt; correctly, despite hours of poking around the web looking for help.) The connection requires a password; coupled with the fact that it's on a nonroutable segment, behind the firewall in my gateway, I think the security is adequate.&lt;br /&gt;&lt;br /&gt;I can definitely recommend WebSharingLite.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-2544421783386711448?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/2544421783386711448/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/11/android-linux-file-transfers.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/2544421783386711448'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/2544421783386711448'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/11/android-linux-file-transfers.html' title='Android-Linux File Transfers'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-5028055687849936837</id><published>2011-11-25T09:29:00.001-05:00</published><updated>2011-11-25T09:54:15.781-05:00</updated><title type='text'>Back to Back Conferences</title><content type='html'>I'm back from two conferences in consecutive weeks: &lt;a href="http://meetings2.informs.org/charlotte2011/" target="_blank"&gt;INFORMS&lt;/a&gt; (Charlotte NC) and &lt;a href="http://www.decisionsciences.org/annualmeeting/" target="_blank"&gt;DSI&lt;/a&gt; (Boston). (The link to the DSI meeting is a bit ephemeral -- it will eventually point to the 2012 meeting.) Two conferences in two weeks is a bit hard on both the waistline and the brain.&amp;nbsp; I have a few odds and ends to share.&lt;br /&gt;&lt;br /&gt;Repeating something I posted on the INFORMS conference blog, I found out from Peter Horner (editor of Analytics Magazine) that a recent change in the magazine’s URL (from analytics-magazine.com to &lt;a href="http://analytics-magazine.org/"&gt;analytics-magazine.org&lt;/a&gt;) may have broken some people’s RSS subscriptions to the web site, as well as screwing up the site's Google ranking. If you subscribe to the magazine's RSS feed, you might want to test the feed and resubscribe if necessary. If you're unfamiliar with the magazine, it is worth taking a look (and, if you choose, using the RSS button at the lower left to subscribe). For readers of this blog who are active on social networks, please help spread the word.&lt;br /&gt;&lt;br /&gt;Changing gears, in a &lt;a href="http://orinanobworld.blogspot.com/2010/03/presentation-software.html" target="_blank"&gt;previous post&lt;/a&gt;&amp;nbsp; I wrote about PowerPoint users suffering from invisible math formulas when they ran their presentations on someone else's laptop at a conference. Out of curiosity, I made a list at the INFORMS meeting of how many presenters I saw using different types of software. My classification system was a bit fuzzy.&amp;nbsp; Beamer presentations tend to be distinctive, but PowerPoint presentations are not as obviously PowerPoint unless you see the presenter launching them from the PowerPoint program. Similarly, the only ways I have to determine that a presentation was done in Keynote (Apple's presentation software) are if it contains tons of eye candy, or it is being played from an MOV file, or if I see the presenter using a Mac. Besides Beamer, there are several other ways to produce presentations in LaTeX (including FoilTeX and Powerdot), and I don't know how to tell the end products of those apart. So my classification systems was Beamer, PowerPoint, Keynote or "Other" (where "Other" could include any misclassified presentations).&lt;br /&gt;&lt;br /&gt;As it turns out, I did not see any presentations that I could detect were done in Keynote. (I think Tim Hopper might have used it for his portion of our panel session on social media, but I had my back to the screen when he was presenting.) My final count was 24 Beamer files, 9 PowerPoint files and 8 "Other" files.&lt;br /&gt;&lt;br /&gt;I came away with two conclusions. The first is that PowerPoint may be losing market share among the INFORMS crowd, since a few years ago my informal survey had an even split between Beamer and PowerPoint. Then again, this may reflect a decrease in the number of US presenters at INFORMS, since LaTeX (and Beamer) seem to be more popular among European and possibly Asian users than among Americans. PowerPoint was pretty ubiquitous at the DSI meeting (which is populated mainly with business school faculty and doctoral students). The second conclusion is that either PowerPoint has gotten better or people have gotten better at using it: there were no missing formulas in any of the papers I saw presented.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-5028055687849936837?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/5028055687849936837/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/11/back-to-back-conferences.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/5028055687849936837'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/5028055687849936837'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/11/back-to-back-conferences.html' title='Back to Back Conferences'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-5951907373052528351</id><published>2011-11-11T17:00:00.001-05:00</published><updated>2011-11-25T09:27:03.895-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='INFORMS'/><title type='text'>Blogging at INFORMS 2011</title><content type='html'>&lt;div&gt;I volunteered to be a guest blogger at the 2011 INFORMS national meeting in Charlotte, NC. I haven't even hopped a plane yet, and I've already spammed the blog (er, &lt;i&gt;posted&lt;/i&gt;) once. You can find the post, if you're curious, at&amp;nbsp;&lt;a href="http://meetings2.informs.org/charlotte2011/blog/?p=145" target="_blank"&gt;http://meetings2.informs.org/charlotte2011/blog/?p=145&lt;/a&gt;.&amp;nbsp;&amp;nbsp;There is quite a cast of bloggers for the meeting, so if you are attending (or just interested), I recommend subscribing to the RSS feed.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-5951907373052528351?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/5951907373052528351/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/11/blogging-at-informs-2011.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/5951907373052528351'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/5951907373052528351'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/11/blogging-at-informs-2011.html' title='Blogging at INFORMS 2011'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-2894184904010306612</id><published>2011-11-07T14:55:00.000-05:00</published><updated>2011-11-07T14:55:31.899-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Mint'/><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><category scheme='http://www.blogger.com/atom/ns#' term='Ubuntu'/><title type='text'>Mint/Ubuntu Update Broke Printing</title><content type='html'>Today I was suddenly unable to use my home HP ink jet printer with Linux Mint, despite the fact that this morning it was printing fine from Windows (my system is dual-boot).&amp;nbsp; The error message informed me that &lt;span style="font-family: &amp;quot;Trebuchet MS&amp;quot;,sans-serif;"&gt;/usr/lib/cups/backend/hp&lt;/span&gt; had failed for unspecified reasons.&amp;nbsp; Toggling the printer off and back on did not help, nor did rebooting the system, nor did switching the driver.&lt;br /&gt;&lt;br /&gt;A quick web search, however, revealed the fact that some unspecified update had screwed up permissions on the &lt;span style="font-family: &amp;quot;Trebuchet MS&amp;quot;,sans-serif;"&gt;/usr/lib/cups/backend&lt;/span&gt; directory (restricting it to root only).&amp;nbsp; Most of the executables in that directory looked okay, but the permissions for &lt;span style="font-family: &amp;quot;Trebuchet MS&amp;quot;,sans-serif;"&gt;cups-pdf&lt;/span&gt; were also root only, so I'm guessing that it was an update to &lt;span style="font-family: &amp;quot;Trebuchet MS&amp;quot;,sans-serif;"&gt;cups-pdf&lt;/span&gt; that blew things up.&lt;br /&gt;&lt;br /&gt;The solution: &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;sudo chmod -R 755 /usr/lib/cups/backend&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;I thought Microsoft had a patent on destructive updates.&amp;nbsp; Guess not.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-2894184904010306612?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/2894184904010306612/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/11/mintubuntu-update-broke-printing.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/2894184904010306612'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/2894184904010306612'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/11/mintubuntu-update-broke-printing.html' title='Mint/Ubuntu Update Broke Printing'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-2116087013317588765</id><published>2011-10-29T17:50:00.001-04:00</published><updated>2011-10-29T17:52:57.615-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Blogger'/><category scheme='http://www.blogger.com/atom/ns#' term='LaTeX'/><title type='text'>Scalable Images in Blogger</title><content type='html'>Questions about a &lt;a href="http://orinanobworld.blogspot.com/2011/10/benders-decomposition-then-and-now.html" target="_blank"&gt;recent post&lt;/a&gt; containing a couple of flow charts made me regret the fact that &lt;a href="http://www.google.com/url?sa=t&amp;amp;rct=j&amp;amp;q=&amp;amp;esrc=s&amp;amp;source=web&amp;amp;cd=1&amp;amp;ved=0CDMQFjAA&amp;amp;url=http%3A%2F%2Fwww.blogger.com%2F&amp;amp;ei=KHOsTuTkI8mFsgKe6vDXDg&amp;amp;usg=AFQjCNGb2S_ihucIn-YF2o0ZlC3KCh92Aw" target="_blank"&gt;Blogger&lt;/a&gt; does not support SVG graphics.&amp;nbsp; Although I made the charts using the excellent &lt;a href="http://www.ctan.org/pkg/pgf" target="_blank"&gt;TiKZ&lt;/a&gt; LaTeX package (which produces vector output in the form of a PDF file), I had to convert the PDF output to PNG for Blogger, and the images are a tad fuzzy (and do not scale well when zoomed), which may have led to some confusion. So I was on a mission today to find a workaround.&lt;br /&gt;&lt;br /&gt;The first thing I discovered that SVG is not nirvana.&amp;nbsp; I generated the images as separate PDF files from the TiKZ source.&amp;nbsp; (Hint to people doing this: use the LaTeX &lt;a href="http://www.ctan.org/pkg/standalone" target="_blank"&gt;standalone&lt;/a&gt; document class and the output file will automatically be cropped to the smallest rectangle containing the image.)&amp;nbsp; I then used &lt;a href="http://www.google.com/url?sa=t&amp;amp;rct=j&amp;amp;q=&amp;amp;esrc=s&amp;amp;source=web&amp;amp;cd=1&amp;amp;ved=0CCcQFjAA&amp;amp;url=http%3A%2F%2Fwww.imagemagick.org%2F&amp;amp;ei=cXKsTu-rJvKMsALYx4jtDg&amp;amp;usg=AFQjCNEj86ZXrN6Iqx9rZ73Ad4L4ypmDtQ" target="_blank"&gt;ImageMagick&lt;/a&gt; to convert the PDF files to SVG files ... which blew them up from around 54 KB to about 8+ MB. Each. Oops!&amp;nbsp; I tried a tool I found to convert the SVG files to "canvas" files, which got me another 5x or so increase in size.&amp;nbsp; So back to PDF files.&amp;nbsp; Blogger does not consider PDFs to be images, to the plan now is to use a PNG file as the image and link it to the corresponding PDF, allowing readers to click on the image and at least get a scalable version in a new window or tab.&lt;br /&gt;&lt;br /&gt;Blogger does not allow you to upload arbitrary files, only images in formats it recognizes (which are actually stored in &lt;a href="http://www.google.com/url?sa=t&amp;amp;rct=j&amp;amp;q=&amp;amp;esrc=s&amp;amp;source=web&amp;amp;cd=1&amp;amp;ved=0CDkQFjAA&amp;amp;url=http%3A%2F%2Fpicasa.google.com%2F&amp;amp;ei=Q3OsTrPeGI32sQLBgonhAg&amp;amp;usg=AFQjCNHHrKCEwrKaKrze1K3hvtv5sDtBsw" target="_blank"&gt;Picassa&lt;/a&gt;, another Google product/service). I thought about putting the PDFs on a personal server somewhere, but I worry about moving things (including them) to a new server at some future date and not remembering to update the links.&amp;nbsp; Enter &lt;a href="http://www.google.com/url?sa=t&amp;amp;rct=j&amp;amp;q=&amp;amp;esrc=s&amp;amp;source=web&amp;amp;cd=1&amp;amp;ved=0CDsQFjAA&amp;amp;url=http%3A%2F%2Fdocs.google.com%2F&amp;amp;ei=oXWsTq3qBYiasgK7g6TnDg&amp;amp;usg=AFQjCNHj75Au5kt8svXmuNkhBD_DjnPhNQ" target="_blank"&gt;Google Documents&lt;/a&gt;.&amp;nbsp; I just have to upload the PDFs to Google Docs, make them public, grab the URLs and set the links on the PNGs (which by default point to the PNG files in Picassa) to point to the PDFs in Google Docs instead.&lt;br /&gt;&lt;br /&gt;I did this with the aforementioned post, and I think it's working. The one question mark for me is whether everyone can see them.&amp;nbsp; I can, but Google knows I'm the owner.&amp;nbsp; If either of my loyal readers runs into problems, or wants me to convert images from earlier posts, please drop a comment here.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-2116087013317588765?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/2116087013317588765/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/10/scalable-images-in-blogger.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/2116087013317588765'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/2116087013317588765'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/10/scalable-images-in-blogger.html' title='Scalable Images in Blogger'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-8747788750490736877</id><published>2011-10-21T17:03:00.001-04:00</published><updated>2011-10-21T17:03:42.487-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='statistics'/><category scheme='http://www.blogger.com/atom/ns#' term='whimsy'/><category scheme='http://www.blogger.com/atom/ns#' term='current events'/><title type='text'>Time Series, Causality and Renting a Congressman</title><content type='html'>This morning I was reading an article, in a national (US) news magazine, that discussed energy policy decisions. It mentioned executives of companies in various energy-related industries contributing to the coffers of various congressmen (from both parties), and it mentioned their votes on key policy issues. The implication was clear: the votes were being bought, or at least influenced, by interested parties.&lt;br /&gt;&lt;br /&gt;I understand why writers do this: it spices up the articles (a hint of corruption) without making any explicit charges that cannot be backed up with hard evidence; and it appeals to voters looking for confirmation of their prior belief that congressmen are crooks. I tend to view our elected representatives as by and large venal to some extent myself. The last part of the title of this post is motivated by a &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/Simon_Cameron#Quotes"&gt;quote from Simon Cameron&lt;/a&gt; (Abraham Lincoln's first Secretary of War): "An honest politician is one who, when he is bought, will stay bought." As you can tell from the title, I am not sanguine about finding honest politicians.&lt;br /&gt;&lt;br /&gt;As an OR professional, though, I understand the flaw in the argument (if we can characterize what is really innuendo as an "argument"). It relates in part to confusing correlation with causation and in part with confusing the direction of causation. Let's say that our fearless reporter accurately reports that Representative A votes for subsidies for domestic production of buggy whips, and Ms. B, CEO of a large manufacturer of buggy whips, donates regularly and/or generously to Rep. A's election campaigns. With minimal effort choosing words, our reporter can make this sound as if A voted for subsidies &lt;i&gt;because&lt;/i&gt; B (and perhaps others of a similar mind) paid him off. That is indeed one possibility.&lt;br /&gt;&lt;br /&gt;Another possibility is that A voted for subsidies first and then B donated, recognizing A (from his vote) as a friend of the buggy whip industry. There's causation, but in the opposite direction from what the reporter implied, and nothing venal. The nature of political contributions is that you usually contribute to candidates with whom you agree. (I say &lt;i&gt;usually&lt;/i&gt; because lobbyists sometimes contribute to both sides, hoping the winner will remember their contribution to her and not to her opponent.)&lt;br /&gt;&lt;br /&gt;Yet another possibility is that B contributed to A first, either anticipating a pro-buggy whip platform or for reasons unrelated to industrial policy, and A favors subsidizing domestic production for sincerely held (if possibly misguided) reasons. This is a case of trying to infer causation from what may be mere correlation.&lt;br /&gt;&lt;br /&gt;How can we tell whether A's vote is in fact being purchased? Anyone who has done much with statistics recognizes how hard it is to establish causality, especially in the absence of a designed experiment with an appropriate control group. We could try tracking A's votes over time, matching them with B's contributions (or the contributions of B and other pro-subsidy individuals or groups), and look for a positive cross-correlation with lag 1 or higher (so that swings in donations lead swings in votes). A positive cross-correlation would still not be solid proof of vote-buying, though, and might also lack "power" as a test of vote-buying:&amp;nbsp; if A fits Cameron's definition of an honest politician, and consistently votes pro-buggy whip because he is taking graft, there will be no variance in his votes and therefore no cross-correlation.&lt;br /&gt;&lt;br /&gt;This leaves me in the unsatisfying position of not knowing whether or not A is a crook. There have been enough US congressmen convicted of malfeasance to convince me that the proportion of occupants of Capitol Hill who are crooks is not zero.&amp;nbsp; Still, there is also a well known aphorism (of &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/Hanlon%27s_razor"&gt;uncertain provenance&lt;/a&gt;) that might apply: "Never ascribe to malice that which is adequately explained by incompetence." We have ample evidence that incompetence is not in short supply on the Hill.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-8747788750490736877?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/8747788750490736877/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/10/time-series-causality-and-renting.html#comment-form' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/8747788750490736877'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/8747788750490736877'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/10/time-series-causality-and-renting.html' title='Time Series, Causality and Renting a Congressman'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-5807499689428688704</id><published>2011-10-09T12:09:00.001-04:00</published><updated>2011-12-06T16:00:52.386-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='math programming'/><category scheme='http://www.blogger.com/atom/ns#' term='operations research'/><title type='text'>Benders Decomposition Then and Now</title><content type='html'>&lt;script type="text/x-mathjax-config"&gt;MathJax.Hub.Config({  tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}});&lt;/script&gt;&lt;script src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML" type="text/javascript"&gt;&lt;/script&gt;A couple of years ago, a coauthor and I had a paper under review at a prestigious journal that shall remain nameless. In the paper we solved a mixed integer linear program (MILP) using &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/Benders%27_decomposition"&gt;Benders decomposition&lt;/a&gt;, with &lt;a href="https://www-01.ibm.com/software/integration/optimization/cplex-optimizer/"&gt;CPLEX&lt;/a&gt; link as the solver, and we employed &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/Callback_%28computer_programming%29"&gt;callbacks&lt;/a&gt; to check each potential solution to the master problem as it occurred. One of the reviewers asked me to justify the use of callbacks. My first inclination was a variation on “because it's standard practice”, but since I have not actually surveyed practitioners to confirm that it is standard (and because, as an academic, I'm naturally loquacious), I gave a longer explanation. What brought this to mind is a recent email exchange in which someone else asked me why I used callbacks with Benders decomposition. It occurred to me that, assuming I'm correct about it being the current norm, this may be a case of textbooks not having caught up to practice. So here is a quick (?) explanation.&lt;br /&gt;&lt;br /&gt;If I recall correctly, the original paper by Jack Benders [1] dealt with continuous nonlinear optimization, not discrete linear optimization, and I do not know who first made the connection to MILP models. The application I have in mind here deals with problems that, without loss of generality, can be modeled as follows:&lt;br /&gt;\[\begin{array}{lrclcc}\textrm{minimize} &amp;amp; c_{1}'x &amp;amp; + &amp;amp; c_{2}'y\\\textrm{subject to} &amp;amp; Ax &amp;amp;  &amp;amp;  &amp;amp; \ge &amp;amp; a\\ &amp;amp;  &amp;amp;  &amp;amp; By &amp;amp; \ge &amp;amp; b\\ &amp;amp; Dx &amp;amp; + &amp;amp; Ey &amp;amp; \ge &amp;amp; d\\ &amp;amp; x &amp;amp; \in &amp;amp; \mathbb{Z}^{m}\\ &amp;amp; y &amp;amp; \in &amp;amp; \mathbb{R}^{n}\end{array}\]&amp;nbsp; &lt;br /&gt;Benders decomposition splits this into a master problem and a subproblem. The subproblem must be a linear program (LP), so all the discrete variables have to go into the master problem (a MILP). You can optionally keep some of the continuous variables in the master, but I will not do so here. You can also optionally create multiple subproblems (with disjoint subsets of $y$), but again I will not do so here. Finally, in the spirit of keeping things simple (and because unbounded models are usually a sign of a lazy modeler), I'll assume that the original problem is bounded (if feasible), which implies that both the master and subproblem will be bounded (if feasible).&lt;br /&gt;&lt;br /&gt;The master problem is as follows:&lt;br /&gt;\[\begin{array}{lrclccc}\textrm{minimize} &amp;amp; c_{1}'x &amp;amp; + &amp;amp; z\\\textrm{subject to} &amp;amp; Ax &amp;amp;  &amp;amp;  &amp;amp; \ge &amp;amp; a\\ &amp;amp; g'x &amp;amp; + &amp;amp; z &amp;amp; \ge &amp;amp; f &amp;amp; \forall (g,f)\in\mathcal{O}\\ &amp;amp; g'x &amp;amp;  &amp;amp;  &amp;amp; \ge &amp;amp; f &amp;amp; \forall (g,f)\in\mathcal{F}\\ &amp;amp; x &amp;amp; \in &amp;amp; \mathbb{Z}^{m}\\ &amp;amp; z &amp;amp; \in &amp;amp; \mathbb{R}\end{array}.\]Variable $z$&amp;nbsp; acts as a surrogate for the objective contribution $c_{2}'y$ of the continuous variables. Set $\mathcal{O}$ contains what are sometimes known as “optimality cuts”: cuts that correct underestimation of $c_{2}'y$ by $z$. $\mathcal{F}$ contains what are sometimes known as “feasibility cuts”: cuts that eliminate solutions $x$ for which the subproblem is infeasible. Initially $\mathcal{O}=\emptyset=\mathcal{F}$. The subproblem, for a given $x$ feasible in the master problem, is:\[\begin{array}{lrcl}\textrm{minimize} &amp;amp; c_{2}'y\\\textrm{subject to} &amp;amp; By &amp;amp; \ge &amp;amp; b\\ &amp;amp; Ey &amp;amp; \ge &amp;amp; d-Dx\\ &amp;amp; y &amp;amp; \in &amp;amp; \mathbb{R}^{n}\end{array}\]Optimality cuts are generated using the dual solution to a feasible subproblem; feasibility cuts are generated using an extreme ray of the dual of an infeasible subproblem. The precise details are unnecessary for this post.&lt;br /&gt;&lt;br /&gt;Back in the '60s ('70s, '80s), solvers were essentially closed boxes: you inserted a problem, set some parameters, started them and went off to read the collected works of Jane Austen. Intervening in the algorithms was not an option. Thus the original flowchart for Benders decomposition looked like the following.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://docs.google.com/open?id=0B-BSG5eMtXyJZTc1Y2JmZmMtNzIzOS00YmJiLWI3NTUtNDkxZDQxOWFkZmIz" imageanchor="1" style="margin-left: 1em; margin-right: 1em;" target="_blank"&gt;&lt;img border="0" height="320" src="http://3.bp.blogspot.com/-TIL4dfStWh8/TpHFMLeCJOI/AAAAAAAAAFo/LJw7SmjFznc/s320/benders1.png" width="286" /&gt;&lt;/a&gt;&lt;/div&gt;The modern approach, using callbacks, looks like this:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://docs.google.com/open?id=0B-BSG5eMtXyJZjc3NGY0MTUtMDBlYS00MjUzLWE5ODctOWQ2MzE2MDJmZjE3" imageanchor="1" style="margin-left: 1em; margin-right: 1em;" target="_blank"&gt;&lt;img border="0" height="320" src="http://2.bp.blogspot.com/-XTf1hcmA1Aw/TpHFMV5LpYI/AAAAAAAAAFs/UT7LMYPx-2I/s320/benders2.png" width="316" /&gt;&lt;/a&gt;&lt;/div&gt;Obviously the modern approach can only be implemented if you are using a solver that supports callbacks, and requires more advanced programming than the classical approach. Other than that, what are the advantages and disadvantages?&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The main advantage of the callback approach is that it is likely to avoid considerable rework. In the original approach, each time you add a cut to the master problem, you have to solve it anew. Although the new cuts may change the structure of the solution tree (by changing the solver's branching decisions), you are probably going to spend time revisiting candidate solutions that you had already eliminated earlier. Moreover, you may actually encounter the optimal solution to the original problem and then discard it, because a superoptimal solution that is either infeasible in the original problem or has an artificially superior value of $z$ causes the true optimum to appear suboptimal. With the callback approach, you use a single search tree, never revisit a node, and never overlook a truly superior solution.&lt;br /&gt;&lt;br /&gt;The potential disadvantage of the callback approach is that you potentially generate a cut each time a new incumbent is found, and some of those cuts quite possibly would have been avoided if you followed the classical approach (and added a cut only when an “optimal” solution was found). Modern solvers are good at carrying “lazy” constraints in a pool, rather than adding the cuts to the active constraint set, but there is still a chance that the modern approach will take longer than the classical approach. I believe (but have no data to support my belief) that the modern approach will typically prove the faster of the two. &lt;br /&gt;&lt;br /&gt;[1] Benders, J. F., &lt;i&gt;Partitioning Procedures for Solving Mixed-Variables Programming Problems&lt;/i&gt;, &lt;b&gt;Numerische Mathematik&lt;/b&gt; 4 (1962), 238--252.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-5807499689428688704?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/5807499689428688704/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/10/benders-decomposition-then-and-now.html#comment-form' title='12 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/5807499689428688704'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/5807499689428688704'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/10/benders-decomposition-then-and-now.html' title='Benders Decomposition Then and Now'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-TIL4dfStWh8/TpHFMLeCJOI/AAAAAAAAAFo/LJw7SmjFznc/s72-c/benders1.png' height='72' width='72'/><thr:total>12</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-3350449212112046974</id><published>2011-09-30T17:09:00.001-04:00</published><updated>2011-09-30T19:36:25.440-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='INFORMS blog challenge'/><category scheme='http://www.blogger.com/atom/ns#' term='operations research'/><title type='text'>OR, the Environment, and the Law of Unintended Consequences</title><content type='html'>&lt;div&gt;The topic of the &lt;a href="http://www.informs.org/About-INFORMS/News-Room/INFORMS-Blog/July-Blog-Challenge-Results-O.R.-and-Social-Networking-September-s-Blog-Challenge-O.R.-and-the-Environment"&gt;INFORMS blog challenge&lt;/a&gt; for September is "OR and the Environment", and I'm slipping this in just under the wire.&amp;nbsp; My guess is that most if not all of the other challenge entries will extol some way in which the use of OR helps the environment.&amp;nbsp; I shall be (slightly) contrarian here.&lt;br /&gt;&lt;br /&gt;***** &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Problem&lt;/b&gt;: Reduce the cost of shipping raw materials and manufactured goods by sea.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Solution&lt;/b&gt;: Companies use OR techniques to pack vessels more efficiently (reducing the number of loads), route vessels more efficiently (reducing transit times and, hopefully, total travel distances), etc.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Short-term Environmental Impact&lt;/b&gt;: Fewer ships covering less distance means less consumption of fossil fuels, so less air (and water) pollution.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Long-term Environmental Impact&lt;/b&gt;: Lower shipping costs make it more cost effective for manufacturers in Europe and the US to purchase materials and components from distant countries such as India and China, shifting the manufacturing operations from regions with relatively stringent environmental reg (medium environmental regulation) ulations to regions with more lax regulations. The increased volume being shipped by ocean more than offsets the reduction in distance per shipment and results in an increase in ocean traffic.&lt;br /&gt;&lt;br /&gt;***** &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Problem&lt;/b&gt;: Make alternative fuel sources for automobiles more cost-effective.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Solution&lt;/b&gt;: Employ OR techniques to improve the manufacture and distribution of &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/Alcohol_fuel#Alcohol_in_the_United_States"&gt;gasohol&lt;/a&gt; (gasoline/alcohol mixtures), reducing the pump price and therefore expanding the consumption of gasohol.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Short-term Environmental Impact&lt;/b&gt;: Some of the demand for a non-renewable source (fossil fuels) with a relatively high pollutant output is shifted to a renewable source (crops such as corn) with a lower pollutant content.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Long-term Environmental Impact&lt;/b&gt;: Crops previously grown as animal feed or for human consumption are diverted to the more profitable biofuel production, causing shortages or price increases in food. In some countries, this causes farmers to &lt;a href="http://www.guardian.co.uk/world/2007/may/09/foodanddrink.renewableenergy"&gt;clear forest areas for replanting with food crops&lt;/a&gt;. Forests capture carbon more efficiently than food crops do, and clearing a forest by burning it releases significant amounts of carbon. (There are also arguments in both directions as to whether biofuels actually &lt;a href="http://www.news.cornell.edu/releases/aug01/corn-basedethanol.hrs.html"&gt;produce a net gain in energy&lt;/a&gt; or reduce net pollution when the activities involved in growing the crops are factored in.)&lt;br /&gt;&lt;br /&gt;***** &lt;br /&gt;&lt;br /&gt;Does this mean that I think OR is bad for the environment?&amp;nbsp; Not at all; but it's not automatically good for the environment either.&amp;nbsp; What OR brings to the table that might be most important, in the context of environmental impact, is a systems perspective.&amp;nbsp; Hopefully OR practitioners can help decision-makers view problems in sufficient breadth, and yet with sufficient (model-aided?) clarity, to recognize the secondary and tertiary effects of their choices. That still leaves the issue of getting environmental impact on the table as a criterion for evaluating choices -- which is a political, not mathematical problem.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-3350449212112046974?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/3350449212112046974/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/09/or-environment-and-law-of-unintended.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/3350449212112046974'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/3350449212112046974'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/09/or-environment-and-law-of-unintended.html' title='OR, the Environment, and the Law of Unintended Consequences'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-5879493892201393497</id><published>2011-09-25T18:01:00.001-04:00</published><updated>2011-09-25T18:01:49.989-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Beamer'/><category scheme='http://www.blogger.com/atom/ns#' term='LyX'/><category scheme='http://www.blogger.com/atom/ns#' term='LaTeX'/><title type='text'>Fixing TiKZ/PGF to Work with Gnuplot</title><content type='html'>While working on a new presentation today (in &lt;a href="http://latex-beamer.sourceforge.net/"&gt;Beamer&lt;/a&gt;), I grabbed a slide from a previous presentation (one I reuse annually). The slide contains &lt;a href="http://sourceforge.net/projects/pgf/"&gt;PGF&lt;/a&gt; code that uses &lt;a href="http://www.gnuplot.info/"&gt;Gnuplot&lt;/a&gt; to plot functions (which I then annotate using PGF commands). Small problem: the transplanted slide didn't work (no curves on the plot) ... which led me to attempt to recompile the original presentation and discover that it, too, no longer worked. Grrr!&lt;br /&gt;&lt;br /&gt;Poking in the files in the /tmp directory showed me that Gnuplot was crabbing about a command (&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;set terminal table&lt;/span&gt;) that PGF uses to tell it to create a text file with the points to be plotted. A bit of searching led me to a &lt;a href="http://itlab.dbit.dk/%7Etoine/?p=557"&gt;blog post&lt;/a&gt; by &lt;br /&gt;Toine Bogers containing the fix. Instructions for Linux follow (I haven't tried it on Windows yet):&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Open a terminal and run '&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;kpsewhich&amp;nbsp;pgfmoduleplot.code.tex&lt;/span&gt;' to locate the file you need to edit. (The location varies with the LaTeX distribution you use; this takes the work out of finding it.)&lt;/li&gt;&lt;li&gt;Issue '&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;sudo gedit &amp;lt;path&amp;gt;/pgfmoduleplot.code.tex'&lt;/span&gt; (where &amp;lt;path&amp;gt; is the path you found in the previous step) and give your password when prompted. (Feel free to use a different editor if &lt;span style="font-family: &amp;quot;Trebuchet MS&amp;quot;,sans-serif;"&gt;gedit&lt;/span&gt; is not your cup of tea.)&lt;/li&gt;&lt;li&gt;Find the line containing '&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;set terminal table&lt;/span&gt;' and delete the word 'terminal', so that it becomes '&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;set table&lt;/span&gt;' (the rest of the line staying unchanged).&lt;/li&gt;&lt;li&gt;Save the modified file, and you should be good to go&lt;/li&gt;&lt;/ol&gt;In &lt;a href="http://www.lyx.org/"&gt;LyX&lt;/a&gt;, you also have to go to &lt;span style="font-family: &amp;quot;Trebuchet MS&amp;quot;,sans-serif;"&gt;Tools &amp;gt; Preferences... &amp;gt; File Handling &amp;gt; Converters&lt;/span&gt;, locate the converter for &lt;span style="font-family: &amp;quot;Trebuchet MS&amp;quot;,sans-serif;"&gt;LaTeX (pdflatex) -&amp;gt; PDF (pdflatex)&lt;/span&gt;, and tweak the &lt;span style="font-family: &amp;quot;Trebuchet MS&amp;quot;,sans-serif;"&gt;Converter:&lt;/span&gt; entry to read '&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;pdflatex -shell-escape $$i&lt;/span&gt;'. Then click &lt;span style="font-family: &amp;quot;Trebuchet MS&amp;quot;,sans-serif;"&gt;Modify&lt;/span&gt; and &lt;span style="font-family: &amp;quot;Trebuchet MS&amp;quot;,sans-serif;"&gt;Save&lt;/span&gt;. If you use other formats besides&lt;span style="font-family: &amp;quot;Trebuchet MS&amp;quot;,sans-serif;"&gt; PDF (pdflatex)&lt;/span&gt; to view/export Beamer presentations, you may have to add the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;-shell-escape&lt;/span&gt; flag (or something similar) to them as well. The flag allows pdflatex to run an external program (in this case gnuplot) in a shell.&amp;nbsp; Users of other other LaTeX editing software will likely need a similar tweak.&lt;br /&gt;&lt;br /&gt;I love open source software, but one of the challenges of using lots of separate pieces of software is that developers will change something in the latest version of one program or library, and that change will break some interaction with another program/library from an entirely separate developer. To modify a saying from my misspent youth: "You pays your money [or, in this case, you don't] and you takes your chances."&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-5879493892201393497?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/5879493892201393497/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/09/fixing-tikzpgf-to-work-with-gnuplot.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/5879493892201393497'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/5879493892201393497'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/09/fixing-tikzpgf-to-work-with-gnuplot.html' title='Fixing TiKZ/PGF to Work with Gnuplot'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-6738033893082033399</id><published>2011-09-24T15:40:00.000-04:00</published><updated>2011-09-24T15:40:39.421-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Mint'/><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><category scheme='http://www.blogger.com/atom/ns#' term='Ubuntu'/><title type='text'>Fixing CUPS-PDF</title><content type='html'>Not that I needed to find another bug in Mint 11 Katya/Ubuntu 11 Natty, but I just discovered that the "Print to PDF" printer (cups-pdf) was writing a 2.1 KB PDF file containing a single blank page, regardless of what I printed.&amp;nbsp; A quick web search turned up multiple reports of this.&amp;nbsp; I used Synaptic to reinstall the cups-pdf package, to no avail.&amp;nbsp; The solution (which I found on a bug report web page) was to go into &lt;span style="font-family: &amp;quot;Trebuchet MS&amp;quot;,sans-serif;"&gt;Control Center &amp;gt; Printing&lt;/span&gt;, delete the "Print to PDF" printer entirely, then use &lt;span style="font-family: &amp;quot;Trebuchet MS&amp;quot;,sans-serif;"&gt;Server &amp;gt; New Printer&lt;/span&gt; to reinstall it.&amp;nbsp; It seems to be working now.&amp;nbsp; I wonder what the interarrival time for the next gremlin is.&amp;nbsp; :-(&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-6738033893082033399?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/6738033893082033399/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/09/fixing-cups-pdf.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/6738033893082033399'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/6738033893082033399'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/09/fixing-cups-pdf.html' title='Fixing CUPS-PDF'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-144432817450649545</id><published>2011-09-15T09:33:00.000-04:00</published><updated>2011-09-15T22:05:02.367-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rant'/><title type='text'>Comment Spam</title><content type='html'>In the interest of free and open discussion (and because I've been known to make mistakes, which I hope someone will correct), I leave this blog open to comments from anyone, with no registration requirement.&amp;nbsp; To date I've gotten very little comment spam.&amp;nbsp; (If you're not sure what "comment spam" is, it's some self-promoting poster child for rectal problems leaving a comment that has nothing to do with the actual blog entry and everything to do with drawing attention to a website they own.)&amp;nbsp; On the rare occasions when I do get comment spam, Blogger is fairly good about moving it to the spam file on its own.&lt;br /&gt;&lt;br /&gt;That raises a point I should make for actual readers (and you both know who you are): if you write a comment and shortly thereafter it seems to have disappeared, don't worry.&amp;nbsp; Blogger has moved it to the spam file for some reason, but I still get an email ping that the comment was posted.&amp;nbsp; I always check comments to be sure they ended up in the right place, and if your comment was mistakenly classified as spam (this has happened at least once and at most twice in the history of the blog), I will restore it to its rightful place in the sunshine.&lt;br /&gt;&lt;br /&gt;In the past couple of days, I've gotten the same comment spam message twice.&amp;nbsp; Curiously, Blogger correctly identified it as spam the first time but not the second time.&amp;nbsp; It's a link to "&lt;a href="http://www.potentiamed.com/" rel="nofollow"&gt;Team PotentiaMED&lt;/a&gt;" web site.&amp;nbsp; The information blurb on their site is long on meaningless buzz phrases and a bit short on specifics, but I think they are some sort of consulting operation.&amp;nbsp; I'll let you judge their merits for yourself, if you're curious.&amp;nbsp; Personally, I automatically assume that any business relying on spam to get customers probably lacks solid reasons to patronize them (the sort of reasons that would make for an effective conventional marketing campaign).&amp;nbsp; I also don't trust anyone who spams.&lt;br /&gt;&lt;br /&gt;By way of contrast, the proprietors of &lt;a href="http://www.onlineengineeringdegree.org/about-us"&gt;Online Engineering Degree&lt;/a&gt; contacted me by email to ask permission to post a comment pointing to one of their pages, a list of Q&amp;amp;A sites.&amp;nbsp; Instead, I devoted a short post to providing the link, since (a) I thought it might be relevant to readers with an interest in industrial engineering and (b) it was not really relevant as a comment to any particular existing post.&amp;nbsp; A writer from &lt;a href="http://www.mastersinengineering.org/"&gt;Masters in Engineering&lt;/a&gt; wrote to me asking if I would like to mention a page listing forums and boards for engineers. The sites listed were potentially useful to engineers in general but did not seem very useful to IEs, so I declined.&amp;nbsp; I want to give both of them credit for doing things the right way.&lt;br /&gt;&lt;br /&gt;Now if I can just find a way to report comment spammers to Blogger ...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-144432817450649545?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/144432817450649545/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/09/comment-spam.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/144432817450649545'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/144432817450649545'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/09/comment-spam.html' title='Comment Spam'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-2828231225469513929</id><published>2011-08-21T15:57:00.000-04:00</published><updated>2012-01-18T18:22:29.051-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='math programming'/><category scheme='http://www.blogger.com/atom/ns#' term='operations research'/><title type='text'>Piecewise-linear Functions Redux</title><content type='html'>&lt;script type="text/x-mathjax-config"&gt;MathJax.Hub.Config({  tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}});&lt;/script&gt;&lt;script src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML" type="text/javascript"&gt;&lt;/script&gt;A &lt;a href="http://www.or-exchange.com/questions/3515/cplex-whats-a-good-way-to-model-step-staircase-functions"&gt;recent question&lt;/a&gt; on OR-Exchange about step functions in mathematical programs made me decide to update an earlier post about piecewise-linear functions.&lt;br /&gt;&lt;br /&gt;In the &lt;a href="http://orinanobworld.blogspot.com/2010/10/piecewise-linear-functions-in-math.html"&gt;prior post&lt;/a&gt; I dealt with continuous piecewise-linear functions (of a single variable) in mathematical programs. As a quick recap, if the function represents a diseconomy of scale (convex in the objective of a minimization problem or concave in the objective of a maximization problem), as in the first plot below, it can be modeled strictly with linear inequality constraints (no binary variables needed). Note that convexity implies continuity everywhere except possibly the endpoints (where you can have a jump discontinuity and still be convex or concave). The method I previously described requires continuity at the endpoints as well.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-ku-2R7mb4VM/TlFeeqIvStI/AAAAAAAAAFU/I5jqWQmOxXM/s1600/pwlinear_convex.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="231" src="http://3.bp.blogspot.com/-ku-2R7mb4VM/TlFeeqIvStI/AAAAAAAAAFU/I5jqWQmOxXM/s320/pwlinear_convex.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;If the function is continuous but lacks the appropriate convexity/concavity, as in the next plot (which is neither convex nor concave), the all-inequality trick fails. It may also fail for convex or concave functions that appear in constraints, either because the convexity of the function does not match the direction of the inequality (you have $f(x)\ge b$ where $f()$ is convex or $f(x)\le b$ where $f()$ is concave), or because $f()$ is tied to other variables in the constraints in such a way that there is a diseconomy of scale to the direct contribution of $f()$ to the objective value but an economy of scale overall (overestimating the value of convex $f()$ or underestimating the value of concave $f()$ allows the other variables to take values that should be infeasible given the value of $x$). If $f()$ appears in any constraints and you are not &lt;i&gt;absolutely certain&lt;/i&gt; that it matches the directions of the constraints in which it appears and represents an &lt;i&gt;overall&lt;/i&gt; diseconomy of scale, treat it as an arbitrary continuous piecewise-linear function, as discussed next.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-LhbsPhVU1Ro/TlFefUdfoQI/AAAAAAAAAFY/VhQUWKgJ3sk/s1600/pwlinear_nonconvex.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="231" src="http://4.bp.blogspot.com/-LhbsPhVU1Ro/TlFefUdfoQI/AAAAAAAAAFY/VhQUWKgJ3sk/s320/pwlinear_nonconvex.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;Again recapping the previous post, for an arbitrary continuous piecewise linear function $f(x)$ with break points $a_{1}\lt a_{2}\lt\cdots\lt a_{n+1}$ and values $f_{i}=f(a_{i})$ at the break points, we introduce continuous variables $\lambda_{1},\dots,\lambda_{n+1}$, add the constraint $\lambda_{1}+\cdots+\lambda_{n+1}=1$, and tell the solver that the $\lambda$ variables form an &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/Special_ordered_set"&gt;SOS2&lt;/a&gt; set. We then add the constraint $x=a_{1}\lambda_{1}+\cdots+a_{n+1}\lambda_{n+1}$ and replace $y=f(x)$ with $y=f_{1}\lambda_{1}+\cdots+f_{n+1}\lambda_{n+1}$. If the solver does not understand SOS2 sets, it is necessary to introduce binary variables (as described in the previous post).&lt;br /&gt;&lt;br /&gt;Step functions, such as the one plotted below, are not continuous, so nothing from the earlier post applies to them. Suppose we have break points $a_{i}$ as above, with $f(x)=f_{i}$ when $a_{i}\le x\lt a_{i+1}$. The first problem we confront is that mathematical programs abhor strict inequalities. To a mathematical programming solver, there is no difference between $x\lt a_{i+1}$ and $x\le a_{i+1}$ unless $x$ is a &lt;i&gt;discrete&lt;/i&gt; variable (i.e., there is a largest possible value for $x$ strictly less than $a_{i+1}$. That will not be the case here, so we will simply have to deal with the fact that if the solver decides it wants $x=a_{i+1}$, it will set $f(x)$ arbitrarily to whichever of $f_{i}$ and $f_{i+1}$ makes for the better objectiveresult.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-0m4f_cNC9mw/TlFef8BHgHI/AAAAAAAAAFc/o2D37gtJoMg/s1600/step.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="231" src="http://1.bp.blogspot.com/-0m4f_cNC9mw/TlFef8BHgHI/AAAAAAAAAFc/o2D37gtJoMg/s320/step.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;To model a step function, we use an SOS1 rather than SOS2 set. Add binary variables $u_{1},\dots,u_{n}$ constrained by $u_{1}+\cdots+u_{n}=1$, declare them to be an SOS1 set, and include the constraints \begin{eqnarray*} \sum_{i=1}^{n}a_{i}u_{i} &amp;amp;\le &amp;amp; x &amp;amp;\le &amp;amp;\sum_{i=1}^{n}a_{i+1}u_{i}\\ y &amp;amp; &amp;amp;= &amp;amp;&amp;amp; \sum_{i=1}^{n}f_{i}u_{i}. \end{eqnarray*} (Explicit declaration of the SOS1 set may not be necessary; some solvers recognize SOS1 sets automatically, and some may not exploit the useful properties of an SOS1 set even if the set is identified for them by the modeler.)&lt;br /&gt;&lt;br /&gt;One last point: both the SOS1 and SOS2 methods require that $x$ have a finite upper bound ($a_{n+1}$). That upper bound will show up as a coefficient in the constraint matrix. The larger it is, the more likely the model is to be &lt;a href="http://orinanobworld.blogspot.com/2011/07/perils-of-big-m.html"&gt;numerically unstable&lt;/a&gt;.  So avoid the temptation to set $a_{n+1}$ equal to the largest floating point value your compiler can handle. Infinity is not your friend here.&lt;br /&gt;&lt;br /&gt;Hmm. This is all a bit dry.&amp;nbsp; Maybe a soundtrack would help?&amp;nbsp; &lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;object class="BLOGGER-youtube-video" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" data-thumbnail-src="http://0.gvt0.com/vi/cvChjHcABPA/0.jpg" height="266" width="320"&gt;&lt;param name="movie" value="http://www.youtube.com/v/cvChjHcABPA&amp;fs=1&amp;source=uds" /&gt;&lt;param name="bgcolor" value="#FFFFFF" /&gt;&lt;embed width="320" height="266"  src="http://www.youtube.com/v/cvChjHcABPA&amp;fs=1&amp;source=uds" type="application/x-shockwave-flash"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-2828231225469513929?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/2828231225469513929/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/08/piecewise-linear-functions-redux.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/2828231225469513929'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/2828231225469513929'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/08/piecewise-linear-functions-redux.html' title='Piecewise-linear Functions Redux'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-ku-2R7mb4VM/TlFeeqIvStI/AAAAAAAAAFU/I5jqWQmOxXM/s72-c/pwlinear_convex.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-4481595998983605471</id><published>2011-08-20T14:36:00.000-04:00</published><updated>2011-08-21T16:53:36.817-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='whimsy'/><title type='text'>The Heisenberg Budget Principle</title><content type='html'>Watching Congress turn sirloin into (bad) hamburger during the recent borrowing limit debate/debacle, I realized that the &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/Uncertainty_principle"&gt;Heisenberg Uncertainty Principle&lt;/a&gt; translates somewhat cleanly from particle physics to political economics:&lt;br /&gt;&lt;blockquote&gt;The difference of two numbers can simultaneously have both positive and negative sign, depending on the position of the viewer (left or right side of the aisle).&lt;/blockquote&gt;I don't think this actually works in the real universe, but in the &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/Bubble_universe_theory"&gt;bubble universe&lt;/a&gt; of Washington D.C. it appears to hold.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Edit&lt;/b&gt;: I confess that I suck at physics. This probably is a manifestation of &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/Special_relativity"&gt;Einstein's special relativity&lt;/a&gt; rather than Heisenberg's uncertainty principle. First, it's not the &lt;i&gt;act&lt;/i&gt; of observing the difference from a particular vantage point that makes it positive or negative; it's the location of the observer (and/or the observer's velocity toward the extreme of his/her party's ideology). Second, there is no uncertainty involved: one party is absolute, irrefutably certain the difference is positive; and the other party is equally certain the difference is negative. To admit a grain of doubt is to cause your party's bubble universe to collapse noisily and, worse still, to concede the possibility the other guys are right (this once).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-4481595998983605471?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/4481595998983605471/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/08/heisenberg-budget-principle.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/4481595998983605471'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/4481595998983605471'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/08/heisenberg-budget-principle.html' title='The Heisenberg Budget Principle'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-9170476827787445266</id><published>2011-08-16T15:02:00.002-04:00</published><updated>2011-08-21T17:05:58.985-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Mint'/><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><category scheme='http://www.blogger.com/atom/ns#' term='Ubuntu'/><title type='text'>Spontaneous Reboots</title><content type='html'>&lt;a href="http://www.linuxmint.com/"&gt;Mint&lt;/a&gt; Katya (a derivative of &lt;a href="http://www.ubuntu.com/"&gt;Ubuntu&lt;/a&gt; Natty Narwhal) on my AMD-64 system has suddenly developed a penchant for spontaneously rebooting.&amp;nbsp; So far, it has only happened while I'm typing. I think it has happened twice when I was typing messages in &lt;a href="http://www.mozilla.org/thunderbird/"&gt;Thunderbird&lt;/a&gt; and once or perhaps twice when I was typing in the &lt;a href="http://yoono.com/"&gt;Yoono&lt;/a&gt; plug-in for &lt;a href="https://www.mozilla.org/"&gt;Firefox&lt;/a&gt;. I don't recall any recent updates to T-bird, Firefox or Yoono, nor have I changed my keyboard (in case this is related to n-key rollover -- my fingers sometimes get ahead of my brain when I'm typing). The mosquitoes have gotten quite aggressive (and numerous) around my house; maybe they drove some gremlins indoors?&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Update #1&lt;/b&gt;: I was sloppy above. It's not Mint that is rebooting; it's the X server. This is apparently a &lt;a href="https://bugs.launchpad.net/ubuntu/+source/xorg-server/+bug/778490"&gt;common problem&lt;/a&gt;,although the variety of symptoms posted there suggest that this is in fact multiple distinct bugs with a common end result (X crashing). Things I have discovered:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Unlike several of those reports, I have not experienced any crashes as a result of clicking. Only typing triggers a crash.&lt;/li&gt;&lt;li&gt;Unlike the reports from laptop users, power management is not the culprit (the machine that crashes for me is a desktop).&lt;/li&gt;&lt;li&gt;Someone pointed the finger at running the AMD-64 version of Natty on an Intel CPU. My copy of Mint is in fact based on the AMD-64 Natty, but my box has an AMD-64 CPU.&lt;/li&gt;&lt;li&gt;Turning the proprietary NVIDIA driver off and then on did not help. (I have a GPU from NVIDIA.)&lt;/li&gt;&lt;li&gt;Installing xserver-xorg-video-nv did not help.&lt;/li&gt;&lt;/ul&gt;&lt;b&gt;Update #2&lt;/b&gt;: I used the wizardous &lt;a href="http://smxi.org/"&gt;sgfxi script&lt;/a&gt; to update my NVIDIA drivers a few days ago. Since then I have had no spontaneous X crashes. I hesitated to claim victory lest it be premature, but today I wrote a moderately lengthy blog post (touch-typing at my usual subsonic speed) with nary a glitch. So hopefully the driver reload cured this problem. Thanks to Harald Hope for a handy script!&lt;br /&gt;&lt;ul&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-9170476827787445266?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/9170476827787445266/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/08/spontaneous-reboots.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/9170476827787445266'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/9170476827787445266'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/08/spontaneous-reboots.html' title='Spontaneous Reboots'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-5761941978086114782</id><published>2011-08-12T09:16:00.000-04:00</published><updated>2011-08-12T09:16:27.444-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='industrial engineering'/><title type='text'>Q&amp;A Sites for Engineers</title><content type='html'>One of the authors at &lt;a href="http://www.onlineengineeringdegree.org/about-us"&gt;Online Engineering Degree&lt;/a&gt; asked me to mention an article there: &lt;a href="http://www.onlineengineeringdegree.org/25-qa-sites-for-engineers"&gt;25 Q&amp;amp;A Sites for Engineers&lt;/a&gt;.&amp;nbsp; It's a compendium of links to exactly what the title describes.&amp;nbsp; I'm not sure anyone reading this blog will be interested (industrial engineering does not seem to get much play among the sites listed), but I'm happy to pass the link along.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-5761941978086114782?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/5761941978086114782/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/08/q-sites-for-engineers.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/5761941978086114782'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/5761941978086114782'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/08/q-sites-for-engineers.html' title='Q&amp;A Sites for Engineers'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-1877293325696007801</id><published>2011-08-06T11:23:00.001-04:00</published><updated>2011-08-06T11:23:55.910-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Mint'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><category scheme='http://www.blogger.com/atom/ns#' term='Ubuntu'/><title type='text'>Tab Completion Bug in Mint 11</title><content type='html'>This is really a tab completion bug in Ubuntu 11.04 - and may actually be a pair of bugs (I'm not sure), one not the fault of Ubuntu.&amp;nbsp; Details can be found in this &lt;a href="https://bugs.launchpad.net/ubuntu/+source/bash-completion/+bug/769866"&gt;bug report&lt;/a&gt;. The short form is that command line tab completion (where you start typing a path and hit &lt;span style="font-family: &amp;quot;Trebuchet MS&amp;quot;,sans-serif;"&gt;TAB&lt;/span&gt; to complete it) started breaking down on one of my Mint machines. Hitting &lt;span style="font-family: &amp;quot;Trebuchet MS&amp;quot;,sans-serif;"&gt;TAB&lt;/span&gt; would add an unwanted space at the end of the path (forcing me to backspace if I were not yet done) and also failed to escape spaces.&amp;nbsp; In fact, if I typed the portion of the path containing the space and escaped it, then hit &lt;span style="font-family: &amp;quot;Trebuchet MS&amp;quot;,sans-serif;"&gt;TAB&lt;/span&gt;, the escape character (backslash) would be removed.&lt;br /&gt;&lt;br /&gt;The bug report contains two possible fixes. As it happens, I had started out with Acrobat Reader 9 installed from the repository on this machine, then replaced it with the version downloaded from Adobe's web site.&amp;nbsp; This is my 64 bit box, and there's an issue with Acrobat Reader looking for 32 bit versions of libraries (which I have installed), finding the 64 bit versions instead, and tripping over them.&amp;nbsp; I thought maybe using the Adobe version would fix the problem.&amp;nbsp; (It did not.)&lt;br /&gt;&lt;br /&gt;At any rate, I tried one of the two suggestions in the bug report: deleting &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;/etc/bash_&lt;/span&gt;&lt;br /&gt;&lt;wbr style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;/wbr&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;completion.&lt;/span&gt;&lt;wbr style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;/wbr&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;d/acroread.&lt;/span&gt;&lt;wbr style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;/wbr&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;sh&lt;/span&gt; (which is a symlink to a script that comes with the Adobe version of Reader). That seems to have fixed the tab completion bug (knock on virtual wood). It does not seem to have done any harm to Reader, either.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-1877293325696007801?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/1877293325696007801/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/08/tab-completion-bug-in-mint-11.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/1877293325696007801'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/1877293325696007801'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/08/tab-completion-bug-in-mint-11.html' title='Tab Completion Bug in Mint 11'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-8497380298497807725</id><published>2011-08-04T15:33:00.000-04:00</published><updated>2011-08-04T15:33:15.333-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Mint'/><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><category scheme='http://www.blogger.com/atom/ns#' term='Ubuntu'/><title type='text'>A GNOME Panel Hack</title><content type='html'>Linux Mint 11 (Katya), built on Ubuntu 11.04 (Natty Narwhal), continues to act goofy at times, notably with intermittent boot failures on both my home PC (AMD 64 bit quad-core) and my laptop (Intel 32 bit dual-core).&amp;nbsp; On the desktop, when a boot fails I get a set of messages that stop abruptly; the failure point is a bit random (sometimes it stops after the battery check, sometimes it goes deeper).&amp;nbsp; On the laptop, the screen stays blank; two of the LED indicators (either numeric lock and caps lock or caps lock and scroll lock; I forget which pair) blink in unison.&amp;nbsp; On both machines, rebooting eventually succeeds.&lt;br /&gt;&lt;br /&gt;Another intermittent problem has to do with the GNOME panel. Again on both machines, I sometimes get a message that one of the panel components failed to load (sometimes the indicator applet, sometimes the clock applet, this morning the Mint Menu button).&amp;nbsp; I'm asked if I want to delete it, to which I always reply in the negative.&lt;br /&gt;&lt;br /&gt;Killing the GNOME panel will cause it to spontaneously regenerate, and usually it regenerates correctly.&amp;nbsp; (Occasionally it needs to be killed a second, or even third, time.)&amp;nbsp; So I cobbled together a menu entry to do this.&amp;nbsp; I put a file named &lt;span style="font-family: &amp;quot;Trebuchet MS&amp;quot;,sans-serif;"&gt;Fix\ Panel.desktop&lt;/span&gt; into &lt;span style="font-family: &amp;quot;Trebuchet MS&amp;quot;,sans-serif;"&gt;~/.local/share/applications&lt;/span&gt;.&amp;nbsp; The contents of the file are listed below.&amp;nbsp; Now all I have to do is click the Menu button, find "Fix Panel" and click it to (hopefully) repair the panel.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;#!/usr/bin/env xdg-open&lt;br /&gt;&lt;br /&gt;[Desktop Entry]&lt;br /&gt;Version=1.0&lt;br /&gt;Type=Application&lt;br /&gt;Terminal=false&lt;br /&gt;Icon[en_US]=gnome-panel-launcher&lt;br /&gt;Name[en_US]=Fix Panel&lt;br /&gt;Exec=killall gnome-panel&lt;br /&gt;Comment[en_US]=Restarts GNOME panel if it's glitched&lt;br /&gt;Name=Fix Panel&lt;br /&gt;Comment=Restarts GNOME panel if it's glitched&lt;br /&gt;Icon=gnome-panel-launcher&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-8497380298497807725?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/8497380298497807725/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/08/gnome-panel-hack.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/8497380298497807725'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/8497380298497807725'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/08/gnome-panel-hack.html' title='A GNOME Panel Hack'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-3208514944966636234</id><published>2011-07-31T17:46:00.001-04:00</published><updated>2011-08-01T16:34:33.368-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='whimsy'/><title type='text'>The Curse of Basic Numeracy (or Why I Keep Gaining Weight)</title><content type='html'>Like all O.R. people (I hope!), and perhaps 2% of political officeholders in the U.S. (fewer if you restrict the count to Congress), I am functionally &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/Numeracy"&gt;numerate&lt;/a&gt;. In particular, when ordering food at restaurants or high-calorie beverages (like the one I'm slurping as I type this) at coffee shops, I recognize when multiple sizes of the same order are priced so as to give the consumer an economy of scale.&amp;nbsp; For instance, the price of the frozen mocha in front of me comes from the following table:&lt;br /&gt;&lt;br /&gt;&lt;style&gt;		&lt;!-- 		BODY,DIV,TABLE,THEAD,TBODY,TFOOT,TR,TH,TD,P { font-family:"Arial" }		 --&gt;	&lt;/style&gt; 	  &lt;br /&gt;&lt;table border="0" cellspacing="0" cols="3" frame="VOID" rules="NONE"&gt;	&lt;colgroup&gt;&lt;col width="86"&gt;&lt;/col&gt;&lt;col width="86"&gt;&lt;/col&gt;&lt;col width="86"&gt;&lt;/col&gt;&lt;col width="86"&gt;&lt;/col&gt;&lt;/colgroup&gt; 	 &lt;thead&gt;&lt;tr&gt; 			&lt;td align="RIGHT" height="17" width="86"&gt;&lt;br /&gt;Size&lt;br /&gt;(oz.)&lt;/td&gt; 			&lt;td align="RIGHT" width="86"&gt;&lt;br /&gt;Price&lt;br /&gt;(USD)&lt;/td&gt; 			&lt;td align="RIGHT" width="86"&gt;Marginal Cost&lt;br /&gt;(USD/oz.)&lt;/td&gt;&lt;td align="RIGHT" width="86"&gt;Average Cost&lt;br /&gt;(USD/oz.)&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt; &lt;tbody&gt;&lt;tr&gt; 			&lt;td align="RIGHT" height="17"&gt;10&lt;/td&gt; 			&lt;td align="RIGHT"&gt;3.75&lt;/td&gt; 			&lt;td align="RIGHT"&gt;0.375&lt;/td&gt; 		&lt;td align="RIGHT"&gt;0.3750&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt; 			&lt;td align="RIGHT" height="17"&gt;16&lt;/td&gt; 			&lt;td align="RIGHT"&gt;4.35&lt;/td&gt; 			&lt;td align="RIGHT"&gt;0.100&lt;/td&gt; 		&lt;td align="RIGHT"&gt;0.2719&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt; 			&lt;td align="RIGHT" height="17"&gt;20&lt;/td&gt; 			&lt;td align="RIGHT"&gt;4.65&lt;/td&gt; 			&lt;td align="RIGHT"&gt;0.075&lt;/td&gt; 		&lt;td align="RIGHT"&gt;0.2325&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt; 			&lt;td align="RIGHT" height="17"&gt;24&lt;/td&gt; 			&lt;td align="RIGHT"&gt;5.05&lt;/td&gt; 			&lt;td align="RIGHT"&gt;0.100&lt;/td&gt; 		&lt;td align="RIGHT"&gt;0.2104&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt; &lt;/table&gt;&lt;br /&gt;There is a modest diseconomy of scale in marginal cost going from the 20 oz. size to the 24 oz. size, the reason for which eludes me. That in turn bothers me at one level (I teach in a business school, so I feel that I should understand pricing models) and not at another (I occasionally fly on commercial airlines, whose ticket pricing algorithms appear to be the first "practical" application of &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/Chaos_theory"&gt;chaos theory&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;Obviously, being an O.R. person (and a business prof at that), I was compelled to order either the 20 oz. size (best marginal cost) or the 24 oz. size (best average cost). Thus do I, being perfectly rational, give the locker room scale one more reason to shudder when I walk in the door. I did order a reduced-calorie version, which is somewhat like playing &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/Stick_ball"&gt;stickball&lt;/a&gt; on a busy one-way street as opposed to a busy two-way street.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Update&lt;/b&gt;: I'm now sitting in another coffee shop, where I buy beans. They have a pretty sweet deal: buy a pound of beans (slightly more expensive bargain brands at the local supermarket, but not much more) and get a free drink, any type, any size.&amp;nbsp; I'm not sure exactly how many ounces in this drink, but the fact that it has its own lifeguard on duty is not a good sign. I truly do not want to think about how many calories it contains.&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-3208514944966636234?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/3208514944966636234/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/07/curse-of-basic-numeracy-or-why-i-keep.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/3208514944966636234'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/3208514944966636234'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/07/curse-of-basic-numeracy-or-why-i-keep.html' title='The Curse of Basic Numeracy (or Why I Keep Gaining Weight)'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-7739454994684350381</id><published>2011-07-26T15:55:00.001-04:00</published><updated>2011-07-26T15:55:41.526-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='operations research'/><category scheme='http://www.blogger.com/atom/ns#' term='job market'/><title type='text'>Princeton Consultants Is Hiring</title><content type='html'>This is a first for me.&amp;nbsp; I received an email this morning for someone at Princeton Consultants, asking if it would appropriate to list some job openings on the blog. Given the current unemployment rate in the U.S., who am I to say no -- especially since their name is "Princeton Consultants" and that they are headquartered in Princeton, NJ (although as far as I know are unaffiliated with Princeton University).&lt;br /&gt;&lt;br /&gt;Quoting the message I got:&lt;br /&gt;&lt;blockquote&gt;Our firm, Princeton Consultants, does IT and Management Consulting (optimization, systems integration, business process improvement, etc.) for a variety of Fortune 500 companies.  We are currently looking for 10-15 new employees to start immediately as an Associate, Senior Associate or Analyst. &lt;/blockquote&gt;These are apparently all full-time positions. Interested readers can learn more about the company from their &lt;a href="http://www.princeton.com/join/"&gt;careers&lt;/a&gt; page, and can find a brief &lt;a href="http://www.princeton.com/join/assessment/"&gt;application form&lt;/a&gt; on their site. If you know any OR types in the job market, please pass the word to them.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-7739454994684350381?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/7739454994684350381/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/07/princeton-consultants-is-hiring.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/7739454994684350381'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/7739454994684350381'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/07/princeton-consultants-is-hiring.html' title='Princeton Consultants Is Hiring'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-5299646808834849011</id><published>2011-07-25T18:57:00.001-04:00</published><updated>2011-07-25T18:57:35.055-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='INFORMS blog challenge'/><category scheme='http://www.blogger.com/atom/ns#' term='whimsy'/><title type='text'>USENET: A Remembrance</title><content type='html'>Although I've already submitted a post to the July &lt;a href="http://www.informs.org//About-INFORMS/News-Room/INFORMS-Blog/Enter-July-Blog-Challenge-O.R.-and-Social-Networking-Review-June-Entries-on-O.R.-and-Muggles."&gt;INFORMS blog challenge&lt;/a&gt; ("O.R. and Social Networking"), I cannot let the topic go by without a (an?) homage to &lt;a href="https://groups.google.com/forum/#%21forum/sci.op-research"&gt;sci.op-research&lt;/a&gt;. It is probably premature (albeit barely) to write an epitaph for &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/Usenet"&gt;USENET&lt;/a&gt;: in fact, its traffic apparently continues to grow, and where once you needed access to a USENET server, now much of it is accessible via &lt;a href="https://groups.google.com/forum/#%21overview"&gt;Google Groups&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://upload.wikimedia.org/wikipedia/commons/7/7e/Usenet_traffic_per_day_%28en%29.svg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="205" src="http://upload.wikimedia.org/wikipedia/commons/7/7e/Usenet_traffic_per_day_%28en%29.svg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-size: x-small;"&gt;(image source: Wikipedia)&lt;/span&gt;&lt;/div&gt;I suspect, though, that the traffic growth is more a tribute to our insatiable appetite for naughty pictures, bootleg videos and software, and passionate debates about atonal musicians than a testimonial to continued use of USENET as a social network for professionals.&lt;br /&gt;&lt;br /&gt;I'm sure a lot of younger people think "social networks" started with MySpace and Facebook. For those of use who predate the Internet (yes, kids, a few of us remain), social networks were once both virtual and analog (cf. "&lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/Old_boys_network"&gt;Old Boy Network&lt;/a&gt;"). After the introduction of the Internet, but before the advent of the World Wide Web (second note to the kiddies: yes, the two are distinct, and came into being several years apart), we began to enjoy a new way of connecting with people outside our sphere of physical contact: &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/Bulletin_board_system"&gt;bulletin boards systems&lt;/a&gt; (BBSes). These tended to be text only and slightly cumbersome, but they were for many of us the first medium for broadcast communication, where your message is not directed at a specific individual, unlike letters, telephone calls etc. (For me they were the second such medium; I was an amateur radio operator briefly in my teens.)&lt;br /&gt;&lt;br /&gt;Then came the mother of all BBSes, USENET.&amp;nbsp; I think it caught on first with system operators, programmers and other "computer geeks", then with a smattering of other technical types. (Bear in mind that, in the early days of the Internet, access was somewhat limited, largely to universities and the military here in the U.S.)&amp;nbsp; Then came the flood of, um, less technical stuff (alt.animals.otters? alt.amazon-women.admirers??).&amp;nbsp; Circa 1993, Mohan Sodhi came up with the idea for a USENET group for operations researchers, and sci.op-research was born.&lt;br /&gt;&lt;br /&gt;For a while, at least, sci.op-research was a way for individuals in the O.R. community to ask and answer questions, and for the occasional non-O.R. person to get help.&amp;nbsp; By 2009, Mike Trick was ready to pronounce it, and the rest of USENET, &lt;a href="http://mat.tepper.cmu.edu/blog/?p=630"&gt;irrelevant&lt;/a&gt;. Today, sadly, it has little non-spam activity. (Mike gets the self-fulfilling prophecy award for creating &lt;a href="http://www.or-exchange.com/"&gt;OR-Exchange&lt;/a&gt;, which likely is the nail in sci.op-research's coffin.) Someone with a quick O.R. question or thought today may think Twitter first; for a longer question, they likely will look to a web forum (such as OR-Exchange). Google+ may yet become another viable alternative for communications with and among O.R. people.&lt;br /&gt;&lt;br /&gt;Still, in its heyday sci.op-research (and at least portions of USENET) served a useful purpose ... and not just to let O.R. professionals network with each other. One time I answered a question from a practitioner (MS in some engineering discipline, no formal O.R. training that I recall) that led to an exchange of emails as we pinned down the answer to his question.&amp;nbsp; A year later he contacted me again, offering co-authorship in a paper (which landed in a respectable journal). To this day I've never met my co-author. Neither the collaboration nor the paper would have happened without USENET.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-5299646808834849011?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/5299646808834849011/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/07/usenet-remembrance.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/5299646808834849011'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/5299646808834849011'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/07/usenet-remembrance.html' title='USENET: A Remembrance'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-2206203218657281406</id><published>2011-07-24T14:31:00.001-04:00</published><updated>2011-07-24T14:32:10.193-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='INFORMS blog challenge'/><category scheme='http://www.blogger.com/atom/ns#' term='operations research'/><category scheme='http://www.blogger.com/atom/ns#' term='analytics'/><title type='text'>Social Networks at Work</title><content type='html'>The theme for the &lt;a href="http://www.informs.org//About-INFORMS/News-Room/INFORMS-Blog/Enter-July-Blog-Challenge-O.R.-and-Social-Networking-Review-June-Entries-on-O.R.-and-Muggles."&gt;INFORMS Blog Challenge for July&lt;/a&gt; is "O.R. and Social Networking". I suspect that most posts will deal either with how O.R. tools can be applied to social networks (algorithms that recommend new "friends", managing network traffic, ...) or how social networks can benefit O.R. people. I hope to take a slightly different tack here. Operations research, management science and analytics propose to help people make better decisions and help systems operate more smoothly, and I think we have something to offer in better understanding and managing the role of social networks in the workplace.&lt;br /&gt;&lt;br /&gt;Let me start by disclaiming any originality of the following ideas. Researchers in organizational behavior have already taken note of social networks in and between organizations. The central notion is that individual workers and groups of workers gain productivity by leveraging contacts in other units of the same organization or in other, separate organizations. Often those are direct contacts, but sometimes not. (To be concrete, if we picture a social network as a graph with actors or groups of actors as nodes and relationships as edges, direct contacts are nodes adjacent to a given node. Indirect contacts are nodes connected to a given node by a path of length greater than one.) There are various reasons why an organization might be concerned about social networks within it and between it and other organizations:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;If workers become more productive by exploiting links, the organization might benefit from fostering the development of such links.&lt;/li&gt;&lt;li&gt;A social network within an organization may improve intra-organizational communication.&lt;/li&gt;&lt;li&gt;Conversely, a social network within an organization might contribute to the development of cliques and cause a rise in "political" behaviors.&lt;/li&gt;&lt;li&gt;Contacts with members of allied organizations might improve the relationship between the organizations (for instance, helping coordinate a supply chain).&lt;/li&gt;&lt;li&gt;Contacts with members of competing organizations might foster cooperation on some issues, but also might lead to leakage of proprietary information.&lt;/li&gt;&lt;li&gt;Individuals with many valuable connections (nodes with high degree, either weighted or unweighted) may be of particular value to the organization, warranting extra effort to retain and reward them. &lt;/li&gt;&lt;li&gt;Unmanaged development of social networks, both within the organization and leading to the outside, might result in the workforce being divided into "ins" (highly connected individuals) and "outs" (nodes with low degree). To the extent that the social network improves performance, the "outs" may be at a disadvantage in career development. This can undermine mentoring and retention efforts, and may be a particular concern for minorities and non-domestic workers.&lt;/li&gt;&lt;/ul&gt;To manage social networks, organizations need to be able to quantify them. This means:&lt;br /&gt;&lt;ul&gt;&lt;li&gt; defining what constitutes a network;&lt;/li&gt;&lt;li&gt;mapping the network;&lt;/li&gt;&lt;li&gt;finding a way to quantify things such as influence level and value to productivity (which may not be symmetric, meaning the network is directional);&lt;/li&gt;&lt;li&gt;identifying options for creating or manipulating networks (decision variables);&lt;/li&gt;&lt;li&gt;estimating the cost and potential impact of each option;&lt;/li&gt;&lt;li&gt;assessing risks of various options (including allowing networks to grow unmanaged); and&lt;/li&gt;&lt;li&gt;finding an optimal program of network construction/management.&lt;/li&gt;&lt;/ul&gt;(Being an optimization guy, I had to squeeze that last item in.) The measurement aspects, including mining existing data (emails, phone records, reports) to help identify existing networks, sound like analytics; the mapping, analysis of costs and impacts, and prescriptive recommendations sound like operations research. So I think we have something to contribute here.&lt;br /&gt;&lt;br /&gt;And the great thing about being a blog author is that I'm not required to come up with any solutions (or even brilliant insights). :-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-2206203218657281406?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/2206203218657281406/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/07/social-networks-at-work.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/2206203218657281406'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/2206203218657281406'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/07/social-networks-at-work.html' title='Social Networks at Work'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-1370385766082574483</id><published>2011-07-23T16:45:00.001-04:00</published><updated>2012-01-13T09:12:52.382-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='math programming'/><category scheme='http://www.blogger.com/atom/ns#' term='CPLEX'/><title type='text'>Farkas Certificates in CPLEX</title><content type='html'>&lt;script type="text/x-mathjax-config"&gt;MathJax.Hub.Config({  tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}});&lt;/script&gt; &lt;script src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML" type="text/javascript"&gt;&lt;/script&gt;&lt;br /&gt;This is a post about linear programs, specifically &lt;i&gt;infeasible &lt;/i&gt;linear programs, and how to deal with them in CPLEX. In response to a question on a CPLEX forum, I played around a bit with Farkas certificates as implemented in CPLEX 12.2. I've never really worked with them, as I have a tendency to produce feasible models. The posted question, though, aroused my curiosity. It asked how to extend a Farkas certificate to a ray for the (unbounded) dual when the primal problem contains bounds on variables.&lt;br /&gt;&lt;br /&gt;A &lt;i&gt;Farkas certificate&lt;/i&gt; is a vector of constraint multipliers that proves a primal linear program to be infeasible. The name comes from &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/Farkas_lemma"&gt;Farkas's Lemma&lt;/a&gt;. Assume, without loss of generality, that we have a linear program of the form\[&lt;br /&gt;\textrm{(P) }\begin{array}{lrcl}&lt;br /&gt;\textrm{minimize} &amp;amp; 0\\&lt;br /&gt;\textrm{subject to} &amp;amp; Ax &amp;amp; \ge &amp;amp; b\\&lt;br /&gt;&amp;amp; x &amp;amp; \ge &amp;amp; l\\&lt;br /&gt;&amp;amp; x &amp;amp; \le &amp;amp; u&lt;br /&gt;\end{array}.&lt;br /&gt;\]We are interested here only in the feasibility of (P), so we may as well assume the objective function (irrelevant to feasibility) is zero. Vectors $l$ and $u$ are lower and upper bounds for the variables $x$. To simplify the discussion, we will assume that $l$ and $u$ are finite (but not necessarily nonnegative). What will transpire extends easily to infinite bounds.&lt;br /&gt;&lt;br /&gt;Assume that the lower and upper bounds are entered as bounds, rather than as constraints (so that the solver sees $Ax\ge b$ as the only set of constraints). A Farkas certificate for (P) will be a vector $y\ge0$ with the following property. Set $q'=y'A$ and define a vector $z$ of the same dimension as $x$ as follows:\[&lt;br /&gt;z_{j}=\begin{cases}&lt;br /&gt;l_{j} &amp;amp; \textrm{if }q_{j}&amp;lt;0\\&lt;br /&gt;u_{j} &amp;amp; \textrm{if }q_{j}\ge0&lt;br /&gt;\end{cases}.&lt;br /&gt;\](Actually,the definition of $z_{j}$ is arbitrary and irrelevant if $q_{j}=0$; I chose $u_{j}$ just for concreteness.) The key property of the Farkas certificate is that it will satisfy\[&lt;br /&gt;q'z=y'Az &amp;lt; y'b.&lt;br /&gt;\]Now suppose that $x$ is any feasible solution, so that in particular $l\le x\le u$.&amp;nbsp; Then \[&lt;br /&gt;q_{j}\ge0\implies z_{j}=u_{j}\ge x_{j}\implies q_{j}z_{j}\ge q_{j}x_{j}&lt;br /&gt;\]and&lt;br /&gt;\[&lt;br /&gt;q_{j}&amp;lt;0\implies z_{j}=l_{j}\le x_{j}\implies q_{j}z_{j}\ge q_{j}x_{j}.&lt;br /&gt;\]So $q'x\le q'z&amp;lt;y'b$. If $x$ is feasible in (P), though, we have $Ax\ge b$; given that $y\ge0$, it must follow that $q'x=y'Ax\ge y'b$, a contradiction. Thus the existence of a Farkas certificate for (P) tells us that there cannot be any feasible solutions $x$ to (P).&lt;br /&gt;&lt;br /&gt;Now let's tie this to the dual (D) of (P), which is\[&lt;br /&gt;\textrm{(D) }\begin{array}{lrcl}&lt;br /&gt;\textrm{maximize} &amp;amp; y'b+v'l-w'u\\&lt;br /&gt;\textrm{subject to} &amp;amp; y'A+v'-w' &amp;amp; = &amp;amp; 0\\&lt;br /&gt;&amp;amp; y,v,w &amp;amp; \ge &amp;amp; 0&lt;br /&gt;\end{array}&lt;br /&gt;\]if we now include the bounds on $x$ as constraints (and treat $x$ as unrestricted in sign). The feasible region of (D) is a cone with vertex at the origin. Denoting by $h^{+}$ and $h^{-}$ the positive and negative parts respectively of a vector $h$ (i.e., $h_{j}^{+}=\max(h_{j,}0)$ and $h_{j}^{-}=-\min(h_{j},0)$), let $y$ be a Farkas certificate for (P), let $q'=y'A$ as before, and let $v=q^{-}$ and $w=q^{+}$. Then $(y',v',w')\ge0$ and $(y'A+v'-w')'=q+v-w=q+q^{-}-q^{+}=0$;&lt;br /&gt;so $(y',v',w')$ is a feasible solution to (D). Moreover, based on our definition of $z$ above, $q'z=-(q^{-})'l+(q^{+})'u=-v'l+w'u$, and so $y'b+v'l-w'u=y'b-q'z&amp;gt;0$. By extending the Farkas certificate $y$ with $v=q^{-}$ and $w=q^{+}$, we obtain a feasible solution to the dual with a positive dual objective value. Since the dual is a cone, $(y',v',w')$ is a recession direction along which the dual objective is unbounded.&lt;br /&gt;&lt;br /&gt;Let's go in the other direction. Suppose that (D) is unbounded (making (P) infeasible), and let $(y',v',w')$ be a feasible dual solution with objective value $y'b+v'l-w'u&amp;gt;0$. Let $q'=y'A=w'-v'$ and define $z$ as before. Then $l\le z\le u$, so\[&lt;br /&gt;q'z=w'z-v'z\le w'u-v'l&amp;lt;y'b&lt;br /&gt;\](the last step since the dual objective is positive at $(y',v',w')$); thus $y$ must be a Farkas certificate for (P).&lt;br /&gt;&lt;br /&gt;To answer the original question (finally!), suppose we are solving an infeasible primal problem in CPLEX. CPLEX provides a mechanism (the IloCplex.dualFarkas method in the Java API) to retrieve a Farkas certificate $y$. To extend that to the corresponding dual multipliers $v$, $w$ for the lower and upper bounds respectively, compute $y'A$ and assign the positive parts to $w$ and the negative parts to $v$. It would be nice if there were a more direct method (one that would avoid the multiplication $y'A$), but I do not know of one.&lt;br /&gt;&lt;br /&gt;One last note: the point of extending the Farkas certificate to a full dual solution is usually to obtain an extreme ray of the dual. As shown above, any solution to (D) with positive objective value provides a Farkas certificate, not just extreme rays. So we rely on the mechanism by which the solver generates the certificate to pick one corresponding to an extreme ray.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-1370385766082574483?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/1370385766082574483/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/07/farkas-certificates-in-cplex.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/1370385766082574483'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/1370385766082574483'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/07/farkas-certificates-in-cplex.html' title='Farkas Certificates in CPLEX'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-6257750304825342866</id><published>2011-07-18T11:49:00.003-04:00</published><updated>2011-08-09T10:23:48.467-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Mint'/><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>The Continuing Adventure of Mint 11</title><content type='html'>I should have left "well enough" alone.&amp;nbsp; Mint 11 Katya (AMD 64 bit version) was running well on my Acer Inspire home PC, other than one little annoyance: when I booted, before and after the grub menu, my monitor would nag about a suboptimal resolution (and tell me that 1440x900 at 60Hz was optimal).&amp;nbsp; So I decided to change the screen resolution used by the boot loader (&lt;span style="font-family: &amp;quot;Trebuchet MS&amp;quot;,sans-serif;"&gt;Control &amp;amp;gt; Startup-Manager&lt;/span&gt;).&amp;nbsp; Now I can't swear that was the cause (cf. "&lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/Post_hoc_ergo_propter_hoc"&gt;post hoc ergo propter hoc&lt;/a&gt; fallacy"), but ever since then normal boots freeze, sometimes after the battery state is reported as OK and sometimes before.&amp;nbsp; I'm still able to get Linux up and running, but by one of a couple of circuitous routes:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;booting into recovery mode, starting in the failsafe X mode, then rebooting normally seems to work;&lt;/li&gt;&lt;li&gt;booting into recovery mode, then using the option to reboot with a file system check routinely works, even though the file system check appears to find no problems.&lt;/li&gt;&lt;/ul&gt;I also tried the dpkg repair option after booting into recovery mode.&amp;nbsp; It found no packages but did give me the option to upgrade the system core (which I did -- another slow process).&amp;nbsp; That proved to be no help either.&lt;br /&gt;&lt;br /&gt;Channeling my inner &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/Sherlock_Holmes"&gt;Sherlock Holmes&lt;/a&gt;, I review the facts: a change to display parameters immediately preceded the problems; booting in failsafe X mode appears to help bypass the problem.&amp;nbsp; So perhaps something in the display subsystem&amp;nbsp; is the culprit (although that does not explain why a mandated disk check gets the machine to boot properly).&lt;br /&gt;&lt;br /&gt;A search of the Internet shows that I'm not alone in experience the boot problem, although it is unclear that what's going splat on my system is the same as what's going splat on other systems.&amp;nbsp; The author of &lt;a href="http://www.walkingrandomly.com/?p=3563"&gt;this post&lt;/a&gt;, for instance, appears to have encountered multiple maladies, sufficient that he abandoned the attempt to use Mint. Someone experiencing the &lt;a href="http://forums.linuxmint.com/viewtopic.php?f=46&amp;amp;t=66667"&gt;same symptoms&lt;/a&gt; with an earlier release had some success hiding the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;xorg.conf&lt;/span&gt; file.&amp;nbsp; I tried moving it (and eventually deleted it), but to no avail. &lt;a href="http://forums.linuxmint.com/viewtopic.php?f=90&amp;amp;t=75048"&gt;Another user&lt;/a&gt; found success by deleting and reinstalling the NVidia driver.&amp;nbsp; I tried that (strangely slow to uninstall, &lt;i&gt;very&lt;/i&gt; slow to download and reinstall!), but no joy for me.&amp;nbsp; At least I think not.&amp;nbsp; My first reboot after reinstalling the NVidia driver failed to make it even as far as the battery check.&amp;nbsp; So I rebooted, again in normal mode, and the system started properly.&amp;nbsp; Previously, rebooting repeatedly in normal mode failed (every boot attempt got stuck in the same place).&amp;nbsp; Is this progress? Will the beast boot normally from now on?&amp;nbsp; Only time will tell.&amp;nbsp; Meanwhile, I have to go back to doing actual work.&amp;nbsp; If anything changes or I find new information, I'll update this post.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Update #1&lt;/b&gt;: The day after I reloaded the NVidia driver, the machine booted normally.&amp;nbsp; So I was cautiously optimistic that maybe the reload had fixed the problem, and the hang immediately after the reload (previous paragraph) was just a last gasp of the bug.&amp;nbsp; No such luck.&amp;nbsp; The first boot this morning hung somewhere around the line saying that flushing the log to disk had stopped. I did a plain reboot, and the second attempt made it to the battery status ok line.&amp;nbsp; I did a third plain boot, and lo and behold it booted properly.&amp;nbsp; So the bug is still there, but either unsuccessful boots make some sort of progress now (write something to disk?) or else it's just stochastic (race condition?).&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Update #2&lt;/b&gt;: Thinking that perhaps I'd messed up something in grub, I reinstalled grub and reverted something (a config file? a script?) to the package maintainer's version when asked. The next couple of boots went fine, but the bug then reappeared. So no joy there. However, after a few days of win some/lose some boots, my AMD box has gone on a tear of 30 straight successful boots. I can't think of anything I did that could account for this, and none of the updates pushed down to the machine &lt;i&gt;appear&lt;/i&gt; to be related to booting.&amp;nbsp; So maybe Loki just remembered he had business elsewhere. My laptop, however, continues to occasionally conk out during a boot, which is probably an entirely different bug.&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-6257750304825342866?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/6257750304825342866/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/07/continuing-adventure-of-mint-11.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/6257750304825342866'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/6257750304825342866'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/07/continuing-adventure-of-mint-11.html' title='The Continuing Adventure of Mint 11'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-2821769359339985616</id><published>2011-07-16T22:36:00.000-04:00</published><updated>2011-07-16T22:36:58.071-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='INFORMS'/><category scheme='http://www.blogger.com/atom/ns#' term='mathematics'/><category scheme='http://www.blogger.com/atom/ns#' term='science'/><category scheme='http://www.blogger.com/atom/ns#' term='current events'/><title type='text'>Facts, Beliefs ... and Budgets</title><content type='html'>Melissa Moore (@mooremm), Executive Director of &lt;a href="http://www.informs.org/"&gt;INFORMS&lt;/a&gt;, recently tweeted the following question: "What &lt;a class="  twitter-hashtag" href="http://twitter.com/#%21/search?q=%23ORMS" rel="nofollow" title="#ORMS"&gt;&lt;span class="hash"&gt;#&lt;/span&gt;&lt;span class="hash-text"&gt;ORMS&lt;/span&gt;&lt;/a&gt; or &lt;a class="  twitter-hashtag" href="http://twitter.com/#%21/search?q=%23Analytics" rel="nofollow" title="#Analytics"&gt;&lt;span class="hash"&gt;#&lt;/span&gt;&lt;span class="hash-text"&gt;Analytics&lt;/span&gt;&lt;/a&gt; tools would you use if you were asked to help solve the US Federal &lt;a class="  twitter-hashtag" href="http://twitter.com/#%21/search?q=%23budget" rel="nofollow" title="#budget"&gt;&lt;span class="hash"&gt;#&lt;/span&gt;&lt;span class="hash-text"&gt;budget&lt;/span&gt;&lt;/a&gt;/#debt impass?"&amp;nbsp; My initial reaction (after verifying that a &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/Flammenwerfer_35"&gt;flammenwerfer&lt;/a&gt; is not considered an OR tool) was that OR and analytics would be of no use in the budget debate (debacle?).&amp;nbsp; OR and analytics rely on facts and logic; it is unclear that either side of the debate is interested in facts or willing to be constrained by logic.&lt;br /&gt;&lt;br /&gt;The question did set me to thinking about the difference between facts and beliefs.&amp;nbsp; I have a hard time sorting out when demagogues, whether politicians or media bloviators, are espousing positions they actually believe and when they are simply pandering for ratings/votes.&amp;nbsp; (My cynicism is hard won: I grew up in New York, went to school in New Jersey, and cast my first vote to reelect Richard M. Nixon.&amp;nbsp; It's been downhill from there.)&amp;nbsp; For the sake of argument, let's stipulate that both sides are acting on beliefs they truly hold.&amp;nbsp; When I was younger it seemed to me that, however venal either side's motives might be, both the left and the right were capable of negotiating based on some common understanding of governance and the political, social and economic realities of the country they governed.&amp;nbsp; It's hard to trade horses, though, when one side can't tell a horse from a zebra and the other can't tell a horse from a camel. Today, one party thinks that the answer to any question that does not contain the phrase "gay marriage" is "cut taxes".&amp;nbsp; The other side thinks that the answer to any question that does not contain the phrase "gay marriage" is "tax the rich".&amp;nbsp; That the proposed solution might not work is simply inconceivable (as is the possibility that the other side's solution might work).&lt;br /&gt;&lt;br /&gt;The somewhat unnerving truth, however, is that everything we think we know as a fact (raw data aside) is ultimately a belief.&amp;nbsp; My training is in mathematics. Casual users of mathematics, and even forgetful mathematicians, tend to think that what has been "proved" (i.e., a theorem) is definitively true. In reality, theorems are merely statements that must follow logically from a set of axioms (beliefs). The system of logic we accept is itself a matter of belief, but in the interest of avoiding a painful flashback to an undergraduate formal logic course I'll drop that line of thought right now. As in mathematics, so too in the physical sciences: theory arises from a mix of assumptions and empirical evidence; when new evidences clashes with the theory, modifications are made; and when the modifications become untenable, some assumption is altered or deleted and the theory is rebuilt.&amp;nbsp; (Remember when the speed of light was a constant?)&lt;br /&gt;&lt;br /&gt;So if mathematics and physical sciences are built on leaps of faith, we really cannot fault elected representatives (and economists) from doing the same.&amp;nbsp; What we perhaps can demand, though, is that these beliefs at least be acknowledged as beliefs (not "proven facts"), and that decision makers attempt to examine the likely impact of any of those beliefs turning out false. As a parallel (pun deliberate), consider Euclid's &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/Euclid%27s_Elements"&gt;Elements&lt;/a&gt;, written ca. 300BC, in which Euclid developed many theorems of what we now refer to as "Euclidean" geometry based on five postulates.&amp;nbsp; The postulates appear self-evident, and mathematicians over the centuries tried unsuccessfully to derive one from the others (turning the derived one into a theorem). In the 19th century, &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/Nikolai_Ivanovich_Lobachevsky"&gt;Nikolai Lobachevsky&lt;/a&gt; famously replaced Euclid's fifth postulate with a negation of it, perhaps hoping to prove the fifth postulate from the others by contradiction. Rather than finding a contradiction, he invented &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/Hyperbolic_geometry"&gt;hyperbolic geometry&lt;/a&gt;, which is not only consistent as a mathematical system but has actually found use (those bleeping physicists again).&lt;br /&gt;&lt;br /&gt;So, back to the original question: can OR bring any useful tools to bear on the budget debate? With enough time and effort, and exploiting the systems perspective that underlies OR, perhaps we could diagram out the interplay of all the assumptions being made (consciously or unconsciously) by each side; and perhaps, using simulation models based on those assumptions and calibrated to historical data, we could explore the consequences of each side's preferred solution (or, for that matter, any compromise solution) should any specific assumption not hold up. It would be a massive undertaking, and I am not confident it would be productive in the end. Zealously held beliefs will not yield easily to "what if" analyses.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-2821769359339985616?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/2821769359339985616/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/07/facts-beliefs-and-budgets.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/2821769359339985616'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/2821769359339985616'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/07/facts-beliefs-and-budgets.html' title='Facts, Beliefs ... and Budgets'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-9041494209135674580</id><published>2011-07-11T19:39:00.000-04:00</published><updated>2011-07-11T19:39:50.921-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='math programming'/><category scheme='http://www.blogger.com/atom/ns#' term='computing'/><title type='text'>Perils of "Big M"</title><content type='html'>&lt;style type="text/css"&gt;&lt;!--body.hl	{ background-color:#ffffff; }pre.hl	{ color:#000000; background-color:#ffffff; font-size:10pt; font-family:'Courier New';}.hl.num { color:#2928ff; }.hl.esc { color:#ff00ff; }.hl.str { color:#ff0000; }.hl.dstr { color:#818100; }.hl.slc { color:#838183; font-style:italic; }.hl.com { color:#838183; font-style:italic; }.hl.dir { color:#008200; }.hl.sym { color:#000000; }.hl.line { color:#555555; }.hl.mark	{ background-color:#ffffbb;}.hl.kwa { color:#000000; font-weight:bold; }.hl.kwb { color:#830000; }.hl.kwc { color:#000000; font-weight:bold; }.hl.kwd { color:#010181; }//--&gt;&lt;/style&gt;&lt;script type="text/x-mathjax-config"&gt;MathJax.Hub.Config({  tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}});&lt;/script&gt; &lt;script src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML" type="text/javascript"&gt;&lt;/script&gt;A somewhat recent Twitter exchange with Bo Jensen, which I believe was triggered by a post on an optimization forum (details of which are fading rapidly from my memory), motivated this entry. It deals with optimization models (specifically linear or integer linear ones) that are constructed using what is sometimes referred to as the "big M" method.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;  Terminology&lt;/h2&gt;First, I need to clarify terminology.&amp;nbsp; Any reference to "big M" means the incorporation into a model of coefficients (usually represented by $M$) that are in a sense surrogates for $\infty$. The phrase "big M method" is frequently used to cover two somewhat different modeling techniques.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://glossary.computing.society.informs.org/index.php?page=B.html#Big-M_method"&gt;One&lt;/a&gt; eliminates the &lt;a href="http://glossary.computing.society.informs.org/second.php?page=P.html#Phase_I"&gt;first phase&lt;/a&gt; (finding a feasible solution) of the two-phase simplex method by merging the phase I and phase II objective functions into a single function, penalizing the artificial variables with very large coefficients ($M$). It's an example of using a &lt;a href="http://glossary.computing.society.informs.org/index.php?page=P.html#Penalty_function"&gt;penalty function&lt;/a&gt;, and requires a sufficiently large value of $M$ to ensure that violating a constraint is never optimal.&lt;/li&gt;&lt;li&gt;The other provides a way for binary variables to turn constraints on or off. Consider, for example, a &lt;a href="http://glossary.computing.society.informs.org/index.php?page=L.html#Lockbox_problem"&gt;lockbox problem&lt;/a&gt; in which the number $x_{ij}$ of checks from customer $i$ assigned to lockbox location $j$ cannot exceed some capacity limit $M$ if the location is used (binary variable $y_j=1$), but should be zero if the location is not used ($y_j=0$). This is formulated as $$x_{ij}-My_j\le 0.$$&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;h2&gt;  Rounding error&lt;/h2&gt;My first course in graduate school was in numerical analysis, and it came as a bit of a shock to my system. We covered &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/Numerical_analysis#The_generation_and_propagation_of_errors"&gt;rounding, truncation and representation errors&lt;/a&gt; rather extensively -- very disconcerting stuff to a pure mathematician. One would like to think that computers do arithmetic accurately. One would like to believe that politicians are honest and competent. One is destined to be disappointed both times.&lt;br /&gt;&lt;br /&gt;I won't go into a lengthy introduction to the aforementioned types of error (which I'll somewhat cavalierly lump together under the name "rounding error"). Let me instead give a small example. The code is in Python (which represents all &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/Floating_point"&gt;floating point&lt;/a&gt; numbers in &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/Double_precision"&gt;double precision&lt;/a&gt;), but it could be any language.&lt;br /&gt;&lt;pre class="hl"&gt;x &lt;span class="hl sym"&gt;=&lt;/span&gt; &lt;span class="hl num"&gt;1.0&lt;/span&gt;e10&lt;br /&gt;y &lt;span class="hl sym"&gt;=&lt;/span&gt; &lt;span class="hl num"&gt;1.0e-9&lt;/span&gt;&lt;br /&gt;z &lt;span class="hl sym"&gt;=&lt;/span&gt; x &lt;span class="hl sym"&gt;-&lt;/span&gt; y&lt;br /&gt;w &lt;span class="hl sym"&gt;=&lt;/span&gt; z &lt;span class="hl sym"&gt;-&lt;/span&gt; x&lt;br /&gt;&lt;span class="hl kwa"&gt;print&lt;/span&gt; x&lt;span class="hl sym"&gt;,&lt;/span&gt; y&lt;span class="hl sym"&gt;,&lt;/span&gt; z&lt;span class="hl sym"&gt;,&lt;/span&gt; w&lt;br /&gt;&lt;span class="hl kwa"&gt;print&lt;/span&gt; &lt;span class="hl sym"&gt;(&lt;/span&gt;z &lt;span class="hl sym"&gt;==&lt;/span&gt; x&lt;span class="hl sym"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;print&lt;/span&gt; &lt;span class="hl sym"&gt;(&lt;/span&gt;w &lt;span class="hl sym"&gt;== -&lt;/span&gt;y&lt;span class="hl sym"&gt;), (&lt;/span&gt;w &lt;span class="hl sym"&gt;==&lt;/span&gt; &lt;span class="hl num"&gt;0&lt;/span&gt;&lt;span class="hl sym"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;The output of the first print line is:&amp;nbsp; &lt;br /&gt;&lt;pre&gt;1.00000000000000e10 1.00000000000000e-9 1.00000000000000e10&lt;br /&gt; 0.000000000000000&lt;/pre&gt;&amp;nbsp;Note that &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;z&lt;/span&gt; looks suspiciously like &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;x&lt;/span&gt; (it should be strictly smaller), and &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;w&lt;/span&gt; (which should be &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;-y&lt;/span&gt;) is zero. That could just be limited precision in the output. The next three prints, however, tell the tale. The first (&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;z==x&lt;/span&gt;) and third (&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;w==0&lt;/span&gt;) should be false, while the second (&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;w==-y&lt;/span&gt;) should be true. What we actually get: &lt;br /&gt;&lt;pre&gt;True&lt;br /&gt;False True&lt;/pre&gt;Whoops!&lt;br /&gt;&lt;br /&gt;This leads me to a few truisms from that long-ago numerical analysis course:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Addition or subtraction of numbers introduce rounding errors, and addition or subtraction of numbers with substantially different magnitudes introduce rounding headaches. (Multiplication and division can also introduce small errors, but addition and subtraction tend to be the killers. The biggest problem with multiplication or division is probably &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/Overflow_error"&gt;overflow&lt;/a&gt; or &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/Arithmetic_underflow"&gt;underflow&lt;/a&gt;.)&lt;/li&gt;&lt;li&gt;Comparisons are closet subtractions. It's generally unsafe to test $x=y$ when $x$ and $y$ are floating point numbers. Instead, test $|x-y|\lt \epsilon$ for a suitably small (but not too small) $\epsilon \gt 0$.&lt;/li&gt;&lt;li&gt;In particular, things that should be zero often come out not quite zero (commonly referred to as "decimal dust"). More than once I've seen someone ask why some solver gave an optimal solution to his problem that had a binary variable equal to 1.0e-9 (throw in a few more junk digits if you like). It should be either 0 or 1!&amp;nbsp; Well, yes; but if the solver held out for exactly 0 or exactly 1, you'd get a lot of wrong answers due to decimal dust. So the solver accepts that "darned near 0" is 0 and "darned near 1" is 1.&amp;nbsp;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;ul&gt;&lt;/ul&gt;&lt;h2&gt;  $M$ in the objective or RHS&lt;/h2&gt;Having $M$ in the objective function (as in the first definition of "big M" above, eliminating phase I of the simplex method) or having it as the right hand side of a constraint introduces rounding error (per my first bullet above). Specifically, $M$ in the objective can cause rounding errors in reduced costs, which may confuse the solver about which columns are candidates for entry to the basis. $M$ in the right hand side can introduce rounding errors in the right hand sides of subsequent tableaus, which may cause problems selecting the variable to leave the basis. As far as I know, those issues are generally survivable, and I've not seen any crash landings caused by it. Perhaps someone who has will comment with an example of a bad outcome from $M$ on the perimeter of the model.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;  $M$ in the constraints &lt;/h2&gt;The lockbox formulation illustrates the situation where $M$ shows up as a coefficient in the constraint matrix. This is where serious misadventures can occur. If $M$ creeps into the basis matrix $\textbf{B}$ (or a column that is a candidate for entry into the basis matrix), the ensuing rounding errors can cause $\textbf{B}$ to look singular (or can cause a column that should be ineligible for entry to the basis, because it would make $\textbf{B}$ singular, look eligible). The rounding errors can also cause severe loss of precision in the computation of $\textbf{B}^{-1}$. In technical terms, $M$ (or $1/M$) appearing in $\textbf{B}$ can make $\textbf{B}$ &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/Condition_number#Matrices"&gt;&lt;i&gt;ill-conditioned&lt;/i&gt;&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Suppose that, in a formulation with $M$ in constraints, we bump into the following candidate for a basis matrix$$\textbf{B}=\left[\begin{array}{ccc} 1 &amp;amp; 0 &amp;amp; \frac{1}{M} \\ M &amp;amp; 0 &amp;amp; 1 \\ 1 &amp;amp; M &amp;amp; 0\end{array}\right].$$Since $$\textbf{B}\ \left[\begin{array}{c}1 \\ \frac{-1}{M} \\ -M\end{array}\right]=\left[\begin{array}{c}0\\0\\0\end{array}\right]$$it is obvious that $\textbf{B}$ is singular. Right? Well, let's check the determinant of $\textbf{B}$. I did the calculations using &lt;a href="http://www.sagemath.org/"&gt;Sage&lt;/a&gt; 4.7, but I have no reason to think other packages would do any better (although pathologies might well vary).&lt;br /&gt;&lt;br /&gt;Here is the Sage code I used to compute the determinants:&lt;br /&gt;&lt;pre class="hl"&gt;B &lt;span class="hl sym"&gt;=&lt;/span&gt; &lt;span class="hl kwd"&gt;matrix&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl num"&gt;3&lt;/span&gt;&lt;span class="hl sym"&gt;,&lt;/span&gt;&lt;span class="hl num"&gt;3&lt;/span&gt;&lt;span class="hl sym"&gt;,[&lt;/span&gt;&lt;span class="hl num"&gt;1.0&lt;/span&gt;&lt;span class="hl sym"&gt;,&lt;/span&gt;&lt;span class="hl num"&gt;0.0&lt;/span&gt;&lt;span class="hl sym"&gt;,&lt;/span&gt;&lt;span class="hl num"&gt;1.0&lt;/span&gt;&lt;span class="hl sym"&gt;/&lt;/span&gt;M&lt;span class="hl sym"&gt;,&lt;/span&gt;M&lt;span class="hl sym"&gt;,&lt;/span&gt;&lt;span class="hl num"&gt;0.0&lt;/span&gt;&lt;span class="hl sym"&gt;,&lt;/span&gt;&lt;span class="hl num"&gt;1.0&lt;/span&gt;&lt;span class="hl sym"&gt;,&lt;/span&gt;&lt;span class="hl num"&gt;1.0&lt;/span&gt;&lt;span class="hl sym"&gt;,&lt;/span&gt;M&lt;span class="hl sym"&gt;,&lt;/span&gt;&lt;span class="hl num"&gt;0.0&lt;/span&gt;&lt;span class="hl sym"&gt;]);&lt;/span&gt;&lt;br /&gt;&lt;span class="hl sym"&gt;[&lt;/span&gt;&lt;span class="hl kwd"&gt;det&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;B&lt;span class="hl sym"&gt;.&lt;/span&gt;&lt;span class="hl kwd"&gt;substitute&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;M&lt;span class="hl sym"&gt;=&lt;/span&gt;&lt;span class="hl num"&gt;10&lt;/span&gt;&lt;span class="hl sym"&gt;.&lt;/span&gt;^k&lt;span class="hl sym"&gt;))&lt;/span&gt; &lt;span class="hl kwa"&gt;for&lt;/span&gt; k &lt;span class="hl kwa"&gt;in&lt;/span&gt; &lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl num"&gt;28&lt;/span&gt;&lt;span class="hl sym"&gt;,&lt;/span&gt; &lt;span class="hl num"&gt;29&lt;/span&gt;&lt;span class="hl sym"&gt;,&lt;/span&gt; &lt;span class="hl num"&gt;30&lt;/span&gt;&lt;span class="hl sym"&gt;,&lt;/span&gt; &lt;span class="hl num"&gt;31&lt;/span&gt;&lt;span class="hl sym"&gt;)];&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;Here is a table of the results:$$\begin{array}{rccc}M &amp;amp; 10^{28} &amp;amp; 10^{29} \\ \det(\textbf{B}) &amp;amp; 0.000000000000000 &amp;amp; 0.000000000000000 \\&amp;nbsp; \\&lt;br /&gt;M &amp;amp; 10^{30} &amp;amp; 10^{31} \\  \det(\textbf{B}) &amp;amp; -1.40737488355328e14 &amp;amp; 0.000000000000000\end{array}$$&lt;br /&gt;So something inexplicable (but bad) happened when $M=10^{30}$, presumably due to loss of precision in some key computation.&lt;br /&gt;&lt;br /&gt;You won't see exactly this glitch in&amp;nbsp; a typical "big M" model, but if you play with enough "big M" formulations, sooner or later (probably sooner) you will trip over numerical instability attributable to mixing disgustingly large coefficients with considerably smaller ones.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;  $M$ in MIP models&lt;/h2&gt;As I mentioned above, one common use of "big M" formulations (illustrated by the lockbox example) is to allow a binary variable to turn a constraint on or off. Even if ill-conditioned basis matrices do not occur, large values of $M$ can cause branch-and-bound solvers to make slow progress solving the mixed-integer programming model (MIP). Consider our simple lockbox constraint: $x_{ij}-My_j\le 0$. There will be an associated penalty cost (say, $c_j y_j$) in the objective function for using location $j$. Now suppose that, at some point, the solver is considering a node where $x_{1j}=2$, $x_{2j}=5$ and $x_{ij}=0$ for other values of $i$. Logically, we know this requires $y_j=1$ and incurs cost $c_j$; but in the LP-relaxation of the node problem, $y_j=5/M$ is sufficient, incurring a cost of just $5c_j/M$. For large values of $M$, this substantially underestimates the true cost, leading to loose node bounds.&amp;nbsp; Loose bounds at nodes in turn make it hard for the solver to prune nodes based on objective value, and so more nodes need to be examined, slowing the solution process.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt; $M$ and (dubious) pedagogy&lt;/h2&gt;I can't write a post this long without at least one rant. Let me stipulate up front that neither text book authors nor instructors can be expected to cover every exigency. That said, many instructors and authors introduce students to "big M" formulations in the abstract, because they are mathematically neat and easy to explain, and then move on to the next topic without regard to the grubby implementation details. I confess to having done this myself when I was young and foolish.&lt;br /&gt;&lt;br /&gt;At least one thing, though, is simply notational laziness. That $M$ in my lockbox example? It should be $M_j$. There is no reason why a single value should be used for all instances of $M$ in a model, and very good reasons why the values should differ. I don't recall seeing $M$ subscripted very often, if ever. (Are text book authors charged for each subscript they use?) In certain examples, including lockbox problems, there is a natural and obvious value for $M$ (typically a capacity limit), and in those cases you see individualized values being used. More often, though, there is just this undifferentiated symbol $M$ floating throughout the model. I think that influences users to actually use a single, very large value everywhere. (I recently saw a model on a CPLEX support forum that was clearly a "big M" model with a single large value of $M$ in about half the constraints.)&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Concluding thoughts...&lt;/h2&gt;... and if you're still with me, you're &lt;i&gt;very&lt;/i&gt; ready for this post to conclude.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;If you are going to use a "big M" formulation, look for the smallest values of $M$ that work in the context of the model. (I once wrote a paper in which I analytically derived a sufficiently large but not horribly inflated value for $M$. There are tricks for doing so.)&lt;/li&gt;&lt;li&gt; $M$ does not need to be one size fits all.&lt;/li&gt;&lt;li&gt;Particularly if $M$ will show up as the coefficient of a variable in a constraint, be prepared for numerical instability. Learn how to detect numerical problems and what levers your solver has for coping with instability.&lt;/li&gt;&lt;li&gt;Consider alternatives to a "big M" approach (two phase simplex, Benders decomposition, ...) if you have stability or accuracy problems you cannot resolve.&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-9041494209135674580?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/9041494209135674580/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/07/perils-of-big-m.html#comment-form' title='17 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/9041494209135674580'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/9041494209135674580'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/07/perils-of-big-m.html' title='Perils of &quot;Big M&quot;'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>17</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-8972968850672010997</id><published>2011-06-19T18:10:00.001-04:00</published><updated>2011-06-19T18:10:38.019-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='INFORMS blog challenge'/><category scheme='http://www.blogger.com/atom/ns#' term='operations research'/><category scheme='http://www.blogger.com/atom/ns#' term='analytics'/><title type='text'>Hitting the Muggles from All Sides</title><content type='html'>The theme of the &lt;a href="http://www.informs.org/About-INFORMS/News-Room/INFORMS-Blog/May-Blog-Challenge-Results-O.R.-and-Analytics-Junes-s-Blog-Challenge-O.R.-for-Muggles"&gt;June INFORMS Blog Challenge&lt;/a&gt; is "O.R. for Muggles". I mention that at the outset because I do not want to be accused of using the word "&lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/Muggle"&gt;Muggles&lt;/a&gt;" to drive search engine traffic to my blog. (For that I use references to naughty videos featuring &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/Dumbledore"&gt;Dumbledore&lt;/a&gt;.) The rationale for the theme is articulated as follows:&lt;br /&gt;&lt;blockquote&gt;[T]hese conversations tend to reach an already involved audience. We’d love to spread the word about OR/MS and analytics to a wider audience.&lt;/blockquote&gt;&amp;nbsp;So we shall assume here that "Muggles" are people who are not part of the O.R. community (and not students likely to join the O.R. community).&lt;br /&gt;&lt;br /&gt;If our goal is to spread the word about the value of O.R. and analytics, and particularly if the ultimate aim is to generate work for O.R. experts and to raise its prestige (and priority) in academic institutions, we might want to adopt a three-pronged strategy.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Top Down&lt;/h3&gt;&lt;br /&gt;This approach targets C-level executives (or at least executives as high in the corporate food chain as we can reach) along with their governmental counterparts. The key is to convince them that they can achieve competitive advantage using O.R. and analytical modeling (or that they will suffer a competitive disadvantage if they fail to do so). Hopefully they will then give marching orders to subordinates to seek out opportunities to exploit this wonderful new (?) type of magic.&lt;br /&gt;&lt;br /&gt;Business honchos are famous both for being very busy and for having short attention spans. Discussing mathematical or statistical details would be the kiss of death here. What might work would be to present them with &lt;i&gt;short&lt;/i&gt;, &lt;i&gt;non-technical&lt;/i&gt; but &lt;i&gt;compelling&lt;/i&gt; stories of organizations that have benefited significantly from O.R. or analytics. Benefiting from O.R. models hard-coded into "canned" software is &lt;i&gt;not&lt;/i&gt; what I have in mind; the stories need to involve customer-specific analysis by human (or plausibly human) experts.&lt;br /&gt;&lt;br /&gt;I'm pretty sure consultants have been doing this for years, and I think INFORMS is doing a decent job as well. Publicizing the Edelman awards is a step in the right direction, although my impression is that the Edelman videos are way too long to engage a C-level executive. We should probably be doing more along this line, though, perhaps including more focus on non-profits and government organizations. How you get to these people is a question above my rather modest pay grade. Articles in key publications (&lt;i&gt;Forbes&lt;/i&gt;? &lt;i&gt;Business Week&lt;/i&gt;? &lt;i&gt;Harvard Business Review&lt;/i&gt;?) may be part of the answer. Guest speakers at business round tables may be another component.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Bottom Up&lt;/h3&gt;&lt;br /&gt;Here we try to plant seeds in the minds of students about to enter the working world. I don't mean students majoring in O.R., industrial engineering, management science and augury (oops, make that "analytics"). We need to target generic business students (especially MBA candidates) and try to convince them that there is an arsenal of really useful tools that may avail them down the road (provided they acquire artisans capable of using those tools).&lt;br /&gt;&lt;br /&gt;I'm inclined to grade our performance here as at best a C. When I began my academic career (about the same time transistors -- not integrated circuits -- were pushing vacuum tubes out of the computing business), it was fairly common for both undergraduate and graduate business curricula to include mandatory "quantitative methods" courses. Unfortunately, we tended to shoot ourselves in the foot (repeatedly) by putting way too much emphasis on theory and hand computation, too little emphasis on the business consequences of the solutions to the models ("you will save $XXX") ("and earn a quick promotion"), and way too little emphasis on problem identification and classification (where you will actually see this problem in the "real world", how your problem might be amenable to a "transportation model" even though it has nothing to do with transportation, why your actual mess will not be nearly as neatly structured as a textbook problem, etc.). This was exacerbated by a lack of user-friendly software, or perhaps any software at all.&lt;br /&gt;&lt;br /&gt;The result was that we produced, at least in the U.S., generations of business graduates who's main take-away from their quant methods course was that they hated it and never wanted to deal with that stuff again. Their lack of enthusiasm when giving feedback to administrators paved the way for other disciplines to push aside quant methods courses and grab their space in the curriculum.&amp;nbsp; Quant methods is still required at many schools, and is very popular at some, but its "footprint" in the curriculum is often diminished, and it is all too frequently no longer required at all (excluding perhaps a basic statistics course).&lt;br /&gt;&lt;br /&gt;Software and hardware are ubiquitous now, and the software quality is quite good. Based on recent market-leading textbooks, though, I believe we are still focusing general quant methods courses heavily on application of specific O.R. tools (linear programming, simulation, decision trees). Some skill building is fine, but it is hard to say whether planting graduates with good skills at small-scale modeling in supply chain, marketing or finance positions will lead organizations to attack larger and more complex problems (where O.R. analysts are needed), or will diminish the need for workers with O.R. training (because the generic business graduate can do enough of the analysis on his or her own). Perhaps more critically, it is not clear to me that a non-O.R. graduate with decent modeling skills for the scope and scale taught in a classroom will necessarily be able to identify larger opportunities that would justify bringing in consultants or creating an internal O.R. group.&lt;br /&gt;&lt;br /&gt;The key here may be to dial back a little on teaching specific models and algorithms, and put more emphasis on general modeling and problem-solving skills (including recognizing the actual problem and delineating its scope).&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Sideways&lt;/h3&gt;&lt;br /&gt;This is the direction that I think is most often overlooked. Small to medium businesses (SMBs), small non-profits and small governmental institutions (think your local school district) are probably underserved by the operations research community, particularly as they may tend not to be lucrative potential clients for consultancies. The key decision makers are often not business school graduates, and may have no idea that O.R. and analytics even exist (unless they know "analytics" in the sense of parsing web server logs). Presentations at local Chamber of Commerce meetings, participation in local business forums (do your local businesses have a &lt;a href="http://www.linkedin.com/"&gt;LinkedIn&lt;/a&gt; group?), and even pro-bono consulting will help show people both what O.R. is about and how it can pay off. My guess is that this group is particularly ripe for word-of-mouth marketing.&lt;br /&gt;&lt;br /&gt;As I said, this segment is probably not particularly lucrative monetarily. Every once in a while, though, one of those SMBs will take off and become a large company; hopefully they will remember the role O.R. played in their growth. Organizations in this category that benefit from O.R. help may also have the ear of politicians and university administrators, which may foster some growth in O.R. curricula. Finally, press reports of success stories at this level may catch the eyes of executives in larger firms.&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-8972968850672010997?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/8972968850672010997/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/06/hitting-muggles-from-all-sides.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/8972968850672010997'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/8972968850672010997'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/06/hitting-muggles-from-all-sides.html' title='Hitting the Muggles from All Sides'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-6848187203659163279</id><published>2011-06-15T18:01:00.065-04:00</published><updated>2011-06-15T18:27:33.732-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Mint'/><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>Do Gremlins Find Mint Tasty?</title><content type='html'>In my two most recent posts I mentioned &lt;a href="http://orinanobworld.blogspot.com/2011/06/upgrading-linux-mint.html"&gt;upgrading&lt;/a&gt; &lt;a href="http://www.linuxmint.com/"&gt;Linux Mint&lt;/a&gt; (to "Katya", version 11) and then &lt;a href="http://orinanobworld.blogspot.com/2011/06/tweaking-mint-settings.html"&gt;tweaking&lt;/a&gt; it. The upgrade created one or two adventures, notably a loss of the ability to reorder the application buttons in the GNOME panel by dragging them. Editing GNOME panel properties such as its size, or whether it automatically expands, would restore the drag option, but no fix that I found survived the end of a session.&lt;br /&gt;&lt;br /&gt;That changed on my office PC, for reasons unknown to me, after a routine application of updates.&amp;nbsp; I'm not sure which update did what, but suddenly the ability to drag buttons is back. The fix came at a bit of a cost, though.&amp;nbsp; The first time I logged in at the console after the upgrade (which I did remotely), I found that buttons dragged (good news) and windows minimized and maximized (not news), but that I could neither resize nor move windows (bad news!).&amp;nbsp; Neither could I switch to any of the other workspaces I have set up. (Workspace Switcher is set for four workspaces.)&lt;br /&gt;&lt;br /&gt;A little desperate Googling failed to find any report of the same problem but did lead me, indirectly, to the fix.&amp;nbsp; In &lt;span style="color: #38761d; font-family: &amp;quot;Trebuchet MS&amp;quot;,sans-serif;"&gt;Control Center &amp;gt; CompizConfig Settings Manager &amp;gt; Window Management&lt;/span&gt;, &lt;span style="color: #38761d; font-family: &amp;quot;Trebuchet MS&amp;quot;,sans-serif;"&gt;Move Window&lt;/span&gt; and &lt;span style="color: #38761d; font-family: &amp;quot;Trebuchet MS&amp;quot;,sans-serif;"&gt;Resize Window&lt;/span&gt; had somehow become deselected and needed to be turned back on.&amp;nbsp; Similarly, under &lt;span style="color: #38761d; font-family: &amp;quot;Trebuchet MS&amp;quot;,sans-serif;"&gt;Desktop&lt;/span&gt; the &lt;span style="color: #38761d; font-family: &amp;quot;Trebuchet MS&amp;quot;,sans-serif;"&gt;Desktop Wall&lt;/span&gt; control had to be turned on.&amp;nbsp; I have no idea what turned them off -- moving, resizing and switching workspaces all worked the last time I was in the office -- but I assume it was something in the update.&amp;nbsp; At least the fix was easy.&lt;br /&gt;&lt;br /&gt;Meanwhile, I got a new machine at home and configured it to dual-boot Windows 7 (which came preinstalled) and Mint 11.&amp;nbsp; This time I used the 64-bit version of Mint (my laptop and office PC run the 32-bit version).&amp;nbsp; Whether due to my choice of the 64-bit version or because it was a clean install (not inheriting any settings from an earlier installation), button dragging worked from the outset on the home machine (once I made a change I will discuss momentarily), and so far there have been no sudden behavioral changes regarding windows.&lt;br /&gt;&lt;br /&gt;That one change I made is&amp;nbsp; rather important, though.&amp;nbsp; When first installed, the 64-bit version did not create buttons for windows.&amp;nbsp; If you minimized a window, it simply disappeared (though the app was still running), with no obvious way to recover it.&amp;nbsp; Dragging buttons was not an issue, since there were no buttons.&amp;nbsp; I can't picture working in an environment where minimized windows can be reopened.&amp;nbsp; With a little digging, I discovered that the &lt;span style="color: #38761d; font-family: &amp;quot;Trebuchet MS&amp;quot;,sans-serif;"&gt;Window List&lt;/span&gt; (the container for the buttons) was not installed on the GNOME panel.&amp;nbsp; It was easy to install it (right-click the panel, select "Add to Panel..." and then choose it from the menu).&amp;nbsp; Positioning it was a bit trickier.&amp;nbsp; You position it the same way you position any applet on the panel: right-click, choose "Move", slide it where you want it and then right-click again and choose "Lock to Panel".&amp;nbsp; The problem is that the Window List itself is invisible, with neither drawn boundaries nor a distinct background color; so you have to grope for it (right-click where you think it might be and see what context menu you get).&amp;nbsp; At least that's fixed now (unless another update brings a new &lt;a href="http://en.wikipedia.org/wiki/Gremlin"&gt;gremlin&lt;/a&gt; with it).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-6848187203659163279?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/6848187203659163279/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/06/do-gremlins-find-mint-tasty.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/6848187203659163279'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/6848187203659163279'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/06/do-gremlins-find-mint-tasty.html' title='Do Gremlins Find Mint Tasty?'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-5672449704837046550</id><published>2011-06-08T17:37:00.000-04:00</published><updated>2011-06-08T17:37:50.946-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Mint'/><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>Tweaking Mint Settings</title><content type='html'>I got myself into a bit of an adventure with my office PC, recently upgraded to Mint 11 (Katya), and I'd better take some notes before I forget and have to relive the adventure.&lt;br /&gt;&lt;br /&gt;As installed, &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Alt-Tab&lt;/span&gt; popped up a panel with thumbnails of all open windows, and let me cycle among them in a rather static way.&amp;nbsp; (Choice of the word "static" relates to what follows.)&amp;nbsp; In past versions, I've had Mint set up to task-switch with a bit more flair: displaying a rotating list of snapshots of the app windows in a horizontal bar, three at a time, with the center one brought to the foreground behind the switcher, and cycling through the list (ring) each time I hit &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Tab&lt;/span&gt; while holding down &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Alt&lt;/span&gt;.&amp;nbsp; Bear with me if I don't use the official terminology for this effect, because part of today's adventure was learning some terminology that I do not find entirely intuitive.&amp;nbsp; All I remembered going in was that (a) &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Alt-Tab&lt;/span&gt; was the key combination to make it happen (the same one used for "cool tabbing" in Windows, and thus easy to remember), (b) it required Compiz (installed by default with Mint), and (c) it was not a default behavior and thus needed to be set.&lt;br /&gt;&lt;br /&gt;So I went to the &lt;span style="color: #274e13; font-family: &amp;quot;Trebuchet MS&amp;quot;,sans-serif;"&gt;Control Center&lt;/span&gt;, thence to &lt;span style="color: #274e13; font-family: &amp;quot;Trebuchet MS&amp;quot;,sans-serif;"&gt;CompizConfig Settings Manager&lt;/span&gt;, and stared at a multitude of choices, not many of which are self-explanatory.&amp;nbsp; In tweaking settings, I managed to cause the maximize/minimize/close buttons on all windows to disappear (not desired -- I really use those a lot).&amp;nbsp; I also found a setting labeled "Compiz Fusion Icon" (in &lt;span style="color: #274e13; font-family: &amp;quot;Trebuchet MS&amp;quot;,sans-serif;"&gt;Control Center &amp;gt; Hardware&lt;/span&gt;).&amp;nbsp; It seemed odd that there would be a setting for an icon (doing what? choosing which version of the icon to display?), so I clicked it a couple of times but observed no results (because I'm unobservant ... more about this in a second).&amp;nbsp; Finally, somewhere in the process of mucking with settings and dealing with messages about conflicts over certain key-combinations (most notably &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Alt-Tab&lt;/span&gt; and &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Shift-Alt-Tab&lt;/span&gt;) I managed to disable &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Alt-Tab&lt;/span&gt; entirely.&lt;br /&gt;&lt;br /&gt;So I'll note here the key information necessary to resolve all this, since I'm sure I'll forget it by tomorrow.&amp;nbsp; First, the "Compiz Fusion Icon" button in &lt;span style="color: #274e13; font-family: &amp;quot;Trebuchet MS&amp;quot;,sans-serif;"&gt;Control Center &amp;gt; Hardware&lt;/span&gt; actually did something: it added a "Compiz Fusion" icon to the GNOME panel (in fact, one per click, so I ended up with two side by side).&amp;nbsp; Right-clicking the icon lets you switch between Compiz and Metacity, and gives easy access to the Compiz settings in the &lt;span style="color: #274e13; font-family: &amp;quot;Trebuchet MS&amp;quot;,sans-serif;"&gt;Control Center&lt;/span&gt;.&amp;nbsp; I suppose the icon is handy if you plan to switch between Compiz and Metacity regularly; I don't, so I banished the icon again.&lt;br /&gt;&lt;br /&gt;Second, to get the desired &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Alt-Tab&lt;/span&gt; variant, I needed to deselect "Static Application Switcher" in &lt;span style="color: #274e13; font-family: &amp;quot;Trebuchet MS&amp;quot;,sans-serif;"&gt;CompizConfig &amp;gt; Window Management&lt;/span&gt; and select "Application Switcher" instead, then modify key combinations as desired.&amp;nbsp; (In point of fact, I ended up opting for the fanciest switcher, the "Shift Switcher", once I read about the &lt;a href="http://wiki.compiz.org/Plugins/Switcher"&gt;choices&lt;/a&gt;.)&amp;nbsp; Having &lt;i&gt;very&lt;/i&gt; limited memory, I decided to change the keys for "Shift Switcher" so that &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Alt-Tab&lt;/span&gt; and &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Shift-Alt-Tab&lt;/span&gt; rotate forward/backward among windows in the current workspace, and &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Super-Tab&lt;/span&gt; and &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Shift-Super-Tab&lt;/span&gt; do the same in all workspaces.&amp;nbsp; (Now if I can just remember that second part ...)&lt;br /&gt;&lt;br /&gt;Third, the missing maximize/minimize/close controls for the windows were the result of the "Window Decoration" option under &lt;span style="color: #274e13; font-family: &amp;quot;Trebuchet MS&amp;quot;,sans-serif;"&gt;CompizConfig &amp;gt; Effects&lt;/span&gt; being deselected.&amp;nbsp; (I don't think I did that, but it's possible an errant click was the culprit.&amp;nbsp; I've seen one or two forum messages suggesting that it might be the action of a gremlin.)&amp;nbsp; Here's a prime example of what I mean by unintuitive terminology.&amp;nbsp; To me, calling those controls a decoration is like calling a door know a decoration.&amp;nbsp; They're controls!&amp;nbsp; I think of "decorations" as being not particularly functional, which those controls are.&amp;nbsp; For that matter, I don't find them all that decorative.&amp;nbsp; Anyway, turning "Window Decoration" back on restored the controls to their normal positions (and my blood pressure to its normal level).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-5672449704837046550?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/5672449704837046550/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/06/tweaking-mint-settings.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/5672449704837046550'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/5672449704837046550'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/06/tweaking-mint-settings.html' title='Tweaking Mint Settings'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-4690781403873656651</id><published>2011-06-02T17:02:00.000-04:00</published><updated>2011-06-02T17:02:54.873-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Mint'/><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>Upgrading Linux Mint</title><content type='html'>I believe that the &lt;a href="http://www.linuxmint.com/"&gt;Mint&lt;/a&gt; distribution of Linux, which I use, has a six month release cycle. Something I learned from watching cowboy shows on TV as a kid was that you don't change horses in the middle of a river, so I skip the upgrades that occur during the school year and just do the ones that occur late spring/early summer. As a result, I only get the odd numbered versions, which is fine. I've been champing at the bit to install Mint 11 (Katya), because I want to upgrade to &lt;a href="http://www.lyx.org/"&gt;LyX&lt;/a&gt; 2.0. I've already done so on my Windows box, but the dependencies for the Linux version would have created issues with Mint 9 (Isadora). Somewhat to my surprise (I've come to expect servers and mirrors to be slammed any time a major software distribution drops), I was able to download Katya within a few days of its release. I &lt;i&gt;think&lt;/i&gt; the upgrade on my office machine is done (subject to the inevitable tweaking here and there), and I decided to jot down my notes on the process.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Problems:&lt;/b&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The upgrade installs a new version of &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;/etc/apt/sources.list.d/local-repository.list&lt;/span&gt;. Unfortunately, the sole line of text in it is buggered.&amp;nbsp; It should end with "binary/" but instead ends with "katya". The result is that attempts to update packages after the installation fail. Fortunately, editing the file is an easy fix. I found the information fairly quickly after a Google search, but I'm surprised it's not listed among the "Known Issues", nor prominently posted on the Mint blog, nor posted in the vicinity of the download instructions.&lt;/li&gt;&lt;li&gt;Once I'd fixed the aforementioned bug and started updating packages, I got a lot of error messages about repositories. It turns out that the installation added to Synaptic's repository list a bunch of URLs for ubuntu.com and canonical.com that used "Katya" as the distribution name. The problem is that "Katya" is a Mint name, not an Ubuntu name. (I believe the corresponding Ubuntu distribution is "Natty", and in fact similar URLs containing "Natty" are also present.) So I weeded out the offending repository entries, and after that updates worked just fine.&lt;/li&gt;&lt;li&gt;For some reason, I cannot reload the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;r-cran-vr&lt;/span&gt; package. First it complained that several other &lt;a href="http://www.r-project.org/"&gt;R&lt;/a&gt; packages were unfilled dependencies. Then, after I updated those packages to current versions, it said I would have to revert to earlier versions of them. Perhaps the VR package is for an earlier version of R. In any case, I don't really need it, so I'll leave it uninstalled.&lt;/li&gt;&lt;li&gt;While attempting to reinstall software from a backup list of all installed packages, I kept getting an error message saying "fix broken packages first" -- even though Synaptic said there were no broken packages. This might have been related to the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;r-cran-vr&lt;/span&gt; problem. I skipped installing a bunch of packages, including &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;r-cran-vr&lt;/span&gt;, and that got rid of the message. &lt;/li&gt;&lt;/ul&gt;&lt;b&gt;Smooth bits:&lt;/b&gt; &lt;br /&gt;&lt;ul&gt;&lt;li&gt;Once again, having &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;/home&lt;/span&gt; in a separate partition paid dividends. I told the installer to remount that partition as &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;/home&lt;/span&gt; with the same file system it already had (ext3), and without reformatting. Voila, all personal stuff (including pretty much all software settings) was preserved. The only problem with this approach is that eventually Linux will be using the ext9287 file system, and my home partition will still be ext3.&lt;/li&gt;&lt;li&gt;Usually I have the installer reformat everything else to the latest file system, but my other main partition (&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;/&lt;/span&gt;) was already ext4, so I told the installer to remount it there but not format it. Most of it gets overwritten anyway, but &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;/opt&lt;/span&gt; came through intact, so a couple of (large) software packages I'd installed there survived the upgrade without needing to be reinstalled.&lt;/li&gt;&lt;li&gt;I used mintBackup to create a list of installed packages. After fixing the aforementioned problems with Synaptic and doing a couple of updates of the new installation (I'm not sure why two updates were required, but no big deal), I started reloading packages from this list (again via mintBackup). Although it's possible to select all the packages on the list from known repositories and reload in one gulp, I found it more useful to upload in groups. First, it meant that if a problem were going to occur, I didn't have to wait through eight petabytes of downloads to find out. Second, it's a nice way to do a little housecleaning. In particular, I did not select any of the lib* packages. My guess is that quite a few of them were vestigial, and any that were needed would presumably be installed automatically as dependencies of the package(s) that needed them.&lt;/li&gt;&lt;li&gt;The few apps I installed under Wine survived the upgrade (since they live in the home partition).&lt;/li&gt;&lt;/ul&gt;&lt;b&gt;Minor Pains in the Posterior:&lt;/b&gt; &lt;br /&gt;&lt;ul&gt;&lt;li&gt;I have OpenSSH and the free version of &lt;a href="http://www.nomachine.com/"&gt;NoMachine&lt;/a&gt;'s NX server installed on my office machine, so that I can remote desktop to it. With every upgrade, I have to remember to: install new keys for OpenSSh; convince client machines to accept the new keys (not a big deal); install new keys for the NX server; distribute the public NX key to every machine running the client; and install the new key into each client session. Life would be easier if someone came up with a script to preserve all public/private key pairs during OS upgrades.&lt;/li&gt;&lt;li&gt;I use &lt;a href="http://getpopfile.org/"&gt;POPFile&lt;/a&gt; to filter spam (it runs continuously on my office PC and filters at the IMAP server, so my laptop and home machines get the benefit of the filtering). Sadly, the corpus (database) for POPFile seems to live somewhere in &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;/usr&lt;/span&gt;, which means it gets clobbered by the upgrade, and so I have to retrain POPFile from scratch. Maybe next time I'll remember to track it down and back it up.&lt;/li&gt;&lt;li&gt;Apparently printer definitions are not housed in the home partition. I'm having to reselect them, and it took a couple of tries to get the right driver for our networked printer. &lt;/li&gt;&lt;li&gt;After the reload, I found I could not reorder application icons (for maximized and windowed applications, not applets) in the GNOME panel. Usually that is just a matter of grabbing the "button" for an application and dragging it laterally. (The corresponding functionality in Windows XP requires a third party application.) A Google search turned up similar reports on a support forum, but nothing very helpful by way of a solution. So I fooled around a bit, and at one point turned the "expand" property of the GNOME panel off (which causes it to size itself just big enough to hold its contents) and then back on (the default, which stretches it to the full width of the screen). I'm not sure if that fixed the problem (could be the &lt;i&gt;post hoc ergo propter hoc &lt;/i&gt;&lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/Post_hoc_ergo_propter_hoc"&gt;fallacy&lt;/a&gt;), but after I did that, icon reordering returned.&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-4690781403873656651?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/4690781403873656651/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/06/upgrading-linux-mint.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/4690781403873656651'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/4690781403873656651'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/06/upgrading-linux-mint.html' title='Upgrading Linux Mint'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-3696058543734600280</id><published>2011-05-29T17:33:00.000-04:00</published><updated>2011-05-29T17:33:19.605-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='AMPL'/><category scheme='http://www.blogger.com/atom/ns#' term='math programming'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>Peeking Inside the Black Box</title><content type='html'>&lt;script type="text/x-mathjax-config"&gt;MathJax.Hub.Config({  tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}});&lt;/script&gt;&lt;script src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML" type="text/javascript"&gt;&lt;/script&gt;From the perspective of an analyst, rather than a developer of algorithms, the computational side of operations research might be described in terms of a black box: insert model and data; turn crank; make sense of the results. When it comes to the question of how much the analyst needs to know about what goes on inside the box, I find myself walking a somewhat narrow line between &lt;a href="http://www.powdo.com/soobahk/flag.html"&gt;the Um and the Yang&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;When teaching statistics to end users, I resist the exhortations of some of my colleagues that students must do computations by hand to “really learn” about statistics. For instance, said colleagues will argue that in order for a student to grasp the concept of correlation, they must take a set of observations of a pair of variables and (manually) center the variables, compute squares and cross-products, total the squares and cross-products, and use the totals to compute standard deviations and the Pearson correlation coefficient. To me, that is just gratuitous grunt work. Students need to know the domain of the correlation coefficient (-1 to +1), when to use it (looking for linear relationships) or not (looking for nonlinear relationships), and its interpretation (including the dangers of making a leap from correlation to causation). The actual computation can safely be left to software.&lt;br /&gt;&lt;br /&gt;On the other hand, the widespread availability of modeling software and powerful solvers has changed the practice of optimization in a very fundamental way. Once the exclusive province of people who had taken extensive coursework in the mathematical theory behind the pertinent algorithms (not to mention formal training in numerical analysis), optimization is now increasingly being undertaken by people who apparently have minimal formal training, and who may understand the contextual domain of the problem they are trying to solve but perhaps do not understand the mathematical underpinnings of the methods being used. I've seen evidence of this in a number of forums recently. One of the symptoms is a failure to understand issues relating to rounding error and numerical stability, ranging from the subtle (poor scaling leading to incorrect answers or solver failures) to the blatant (“My binary variable came out 0.99999999999 -- what went wrong??”).&lt;br /&gt;&lt;br /&gt;A few recent posts suggested that some users either do not understand the difference between local and global optima or do not understand the role of convexity in optimization models. In particular, I cringe whenever I see nonlinear equality constraints in a model, whereas they don't seem to bother the model authors very much. (I'm not saying that nonlinear equality constraints are fundamentally wrong; I'm just saying that I'd really like not to have any in my model.) A very simple example will illustrate why.&lt;br /&gt;&lt;br /&gt;Consider the following trivial optimization problems:\[\begin{array}{clccclc}\textrm{(D)} &amp;amp; \min &amp;amp; x &amp;amp; \,\,\, &amp;amp; \textrm{(C)} &amp;amp; \min &amp;amp; x\\ &amp;amp; \textrm{s.t.} &amp;amp; x^{2}+y^{2}\le1 &amp;amp;  &amp;amp;  &amp;amp; \textrm{s.t.} &amp;amp; x^{2}+y^{2}=1\\ &amp;amp;  &amp;amp; -2\le x\le2 &amp;amp;  &amp;amp;  &amp;amp;  &amp;amp; -2\le x\le2\\ &amp;amp;  &amp;amp; -2\le y\le2 &amp;amp;  &amp;amp;  &amp;amp;  &amp;amp; -2\le y\le2\end{array}\]The (convex) feasible region of problem (D) is a disk, while the (nonconvex) feasible region of problem (C) is a circle. The solution to both problems is clearly $(x,y)=(-1,0)$.&lt;br /&gt;&lt;br /&gt;Let's perform a little experiment (using &lt;a href="http://www.ampl.com/"&gt;AMPL&lt;/a&gt; to model the problems and &lt;a href="http://www.sbsi-sol-optimize.com/asp/sol_products_minos_desc.htm"&gt;MINOS&lt;/a&gt; 5.51 to solve them). We will solve both (D) and (C) with initial values $(x,y)=(cos(\theta),sin(\theta))$ where $\theta$ is an integer multiple of $\frac{\pi}{4}$. The AMPL code is as follows:&lt;br /&gt;&lt;style type="text/css"&gt;pre.hl { color:#000000; background-color:#ffffff; font-size:10pt; font-family:'Courier New';}.hl.num { color:#2928ff; }.hl.esc { color:#ff00ff; }.hl.str { color:#ff0000; }.hl.dstr { color:#818100; }.hl.slc { color:#838183; font-style:italic; }.hl.com { color:#838183; font-style:italic; }.hl.dir { color:#008200; }.hl.sym { color:#000000; }.hl.line { color:#555555; }.hl.mark { background-color:#ffffbb;}.hl.kwa { color:#000000; font-weight:bold; }.hl.kwb { color:#830000; }.hl.kwc { color:#000000; font-weight:bold; }.hl.kwd { color:#010181; }&lt;/style&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;span class="hl slc"&gt;# problem definitions&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;var&lt;/span&gt; x &lt;span class="hl sym"&gt;&amp;gt;= -&lt;/span&gt;&lt;span class="hl num"&gt;2&lt;/span&gt; &lt;span class="hl sym"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="hl num"&gt;2&lt;/span&gt;&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;var&lt;/span&gt; y &lt;span class="hl sym"&gt;&amp;gt;= -&lt;/span&gt;&lt;span class="hl num"&gt;2&lt;/span&gt; &lt;span class="hl sym"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="hl num"&gt;2&lt;/span&gt;&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;minimize&lt;/span&gt; Obj&lt;span class="hl sym"&gt;:&lt;/span&gt; x&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;s.t. Disk&lt;span class="hl sym"&gt;:&lt;/span&gt; x^&lt;span class="hl num"&gt;2&lt;/span&gt; &lt;span class="hl sym"&gt;+&lt;/span&gt; y^&lt;span class="hl num"&gt;2&lt;/span&gt; &lt;span class="hl sym"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="hl num"&gt;1&lt;/span&gt;&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;s.t. Circle&lt;span class="hl sym"&gt;:&lt;/span&gt; x^&lt;span class="hl num"&gt;2&lt;/span&gt; &lt;span class="hl sym"&gt;+&lt;/span&gt; y^&lt;span class="hl num"&gt;2&lt;/span&gt; &lt;span class="hl sym"&gt;==&lt;/span&gt; &lt;span class="hl num"&gt;1&lt;/span&gt;&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;problem D&lt;span class="hl sym"&gt;:&lt;/span&gt; x&lt;span class="hl sym"&gt;,&lt;/span&gt; y&lt;span class="hl sym"&gt;,&lt;/span&gt; Obj&lt;span class="hl sym"&gt;,&lt;/span&gt; Disk&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;problem C&lt;span class="hl sym"&gt;:&lt;/span&gt; x&lt;span class="hl sym"&gt;,&lt;/span&gt; y&lt;span class="hl sym"&gt;,&lt;/span&gt; Obj&lt;span class="hl sym"&gt;,&lt;/span&gt; Circle&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="hl slc"&gt;# bit used to define starting locations&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;param&lt;/span&gt; pi4 &lt;span class="hl sym"&gt;:=&lt;/span&gt; &lt;span class="hl kwb"&gt;atan&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl num"&gt;1&lt;/span&gt;&lt;span class="hl sym"&gt;);&lt;/span&gt; &lt;span class="hl slc"&gt;# pi/4&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;set&lt;/span&gt; ANGLE &lt;span class="hl sym"&gt;:=&lt;/span&gt; &lt;span class="hl num"&gt;0&lt;/span&gt;.&lt;span class="hl num"&gt;.7&lt;/span&gt;&lt;span class="hl sym"&gt;;&lt;/span&gt; &lt;span class="hl slc"&gt;# from 0 to 7/4*pi&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="hl slc"&gt;# storage for optimal solutions&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;param&lt;/span&gt; dsol &lt;span class="hl sym"&gt;{&lt;/span&gt;ANGLE&lt;span class="hl sym"&gt;};&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;param&lt;/span&gt; csol &lt;span class="hl sym"&gt;{&lt;/span&gt;ANGLE&lt;span class="hl sym"&gt;};&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="hl slc"&gt;# solve disk problem from all starting angles&lt;/span&gt;&lt;br /&gt;problem D&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;for &lt;span class="hl sym"&gt;{&lt;/span&gt;t &lt;span class="hl kwa"&gt;in&lt;/span&gt; ANGLE&lt;span class="hl sym"&gt;} {&lt;/span&gt;&lt;br /&gt;  &lt;span class="hl kwa"&gt;let&lt;/span&gt; x &lt;span class="hl sym"&gt;:=&lt;/span&gt; &lt;span class="hl kwb"&gt;cos&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;t&lt;span class="hl sym"&gt;*&lt;/span&gt;pi4&lt;span class="hl sym"&gt;);&lt;/span&gt;&lt;br /&gt;  &lt;span class="hl kwa"&gt;let&lt;/span&gt; y &lt;span class="hl sym"&gt;:=&lt;/span&gt; &lt;span class="hl kwb"&gt;sin&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;t&lt;span class="hl sym"&gt;*&lt;/span&gt;pi4&lt;span class="hl sym"&gt;);&lt;/span&gt;&lt;br /&gt;  solve&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class="hl kwa"&gt;let&lt;/span&gt; dsol&lt;span class="hl sym"&gt;[&lt;/span&gt;t&lt;span class="hl sym"&gt;] :=&lt;/span&gt; x&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class="hl sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="hl slc"&gt;# solve circle problem from all starting angles&lt;/span&gt;&lt;br /&gt;problem C&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;for &lt;span class="hl sym"&gt;{&lt;/span&gt;t &lt;span class="hl kwa"&gt;in&lt;/span&gt; ANGLE&lt;span class="hl sym"&gt;} {&lt;/span&gt;&lt;br /&gt;  &lt;span class="hl kwa"&gt;let&lt;/span&gt; x &lt;span class="hl sym"&gt;:=&lt;/span&gt; &lt;span class="hl kwb"&gt;cos&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;t&lt;span class="hl sym"&gt;*&lt;/span&gt;pi4&lt;span class="hl sym"&gt;);&lt;/span&gt;&lt;br /&gt;  &lt;span class="hl kwa"&gt;let&lt;/span&gt; y &lt;span class="hl sym"&gt;:=&lt;/span&gt; &lt;span class="hl kwb"&gt;sin&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;t&lt;span class="hl sym"&gt;*&lt;/span&gt;pi4&lt;span class="hl sym"&gt;);&lt;/span&gt;&lt;br /&gt;  solve&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class="hl kwa"&gt;let&lt;/span&gt; csol&lt;span class="hl sym"&gt;[&lt;/span&gt;t&lt;span class="hl sym"&gt;] :=&lt;/span&gt; x&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class="hl sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;display&lt;/span&gt; dsol&lt;span class="hl sym"&gt;,&lt;/span&gt; csol&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;The results? For all starting angles, MINOS determines that $(x,y)=(-1,0)$ is the optimal solution to (D). That also applies for (C), with one glaring exception: when $\theta=0$, MINOS decides that the initial value $(x,y)=(1,0)$ is the optimal solution.&lt;br /&gt;&lt;br /&gt;The figure below tells the tale. MINOS uses a reduced gradient method, which is a souped-up form of steepest descent. If allowed to, it will move in the direction pointed to by the gradient of the objective function at the current point when maximizing, and in the opposite direction when minimizing. (In this example, the gradient is a constant $(1,0)$.) When movement in that direction is infeasible, it will project the positive or negative gradient onto the hyperplane tangent to the feasible region at the current point, and search in that direction. &lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-9d9iitRBlqI/TeKvSuhfqXI/AAAAAAAAADA/ekms0c1FSAQ/s1600/black_box.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;br /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-05nmbHVMEbs/TeK0zzj0cAI/AAAAAAAAADc/i49lovXzGls/s1600/black_box.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="624" src="http://4.bp.blogspot.com/-05nmbHVMEbs/TeK0zzj0cAI/AAAAAAAAADc/i49lovXzGls/s640/black_box.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;The red arrows indicate the (constant) negative gradient direction; the blue arrows are the projections of the gradient onto the unit circle. Having a hard time seeing the blue arrows anchored at $(\pm1,0)$? That's because they have length zero. So for any starting point other than $(\pm1,0)$ in problem (D), MINOS moves right to left across the unit disk until it reaches the boundary (the unit circle), then wends its way around the circle until it reaches the optimum at&amp;nbsp; $(-1,0)$. If it starts from $(+1,0)$, it cuts straight across the $x$-axis and arrives directly at the optimum. For problem (C), cutting across the disk is not an option. Given any start other than &amp;nbsp; $(\pm1,0)$, MINOS winds around the circle. Started at $(+1,0)$, however, MINOS sees a zero projection of the gradient, declares victory, stages a photo op and goes home.&lt;br /&gt;&lt;br /&gt;The behavior of MINOS on problem (C) is correct given what's inside the black box. MINOS only guarantees local optima, and even that can only be delivered if the problem is moderately well behaved and/or the starting point is chosen well. &lt;a href="http://www.coin-or.org/projects/Ipopt.xml"&gt;Ipopt&lt;/a&gt;, another popular nonlinear solver, has similar limitations. From some recent posts that I've seen, though, I have the impression that some users are creating highly nonconvex models and expecting optimal solutions they are not destined to get. Compounding this, of course, is the fact that the solver will generally not know it has arrived at a suboptimal solution, and therefore will not alert the user that the solution is suboptimal.&lt;br /&gt;&lt;br /&gt;Perhaps modeling languages and solvers should ship with a “warning label” stating that use of the software without first reading a book or taking a course in linear/nonlinear/integer programming is inadvisable.&lt;br /&gt;&lt;br /&gt;Speaking of books, I can recommend David Luenberger's "Linear and Nonlinear Programming" (an &lt;a href="http://www.amazon.com/Nonlinear-Programming-International-Operations-Management/dp/1441945040/ref=sr_1_2?ie=UTF8&amp;amp;s=books&amp;amp;qid=1306703933&amp;amp;sr=8-2"&gt;updated version&lt;/a&gt; of which has apparently been published with coauthor Yinyu Ye).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-3696058543734600280?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/3696058543734600280/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/05/peeking-inside-black-box.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/3696058543734600280'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/3696058543734600280'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/05/peeking-inside-black-box.html' title='Peeking Inside the Black Box'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-05nmbHVMEbs/TeK0zzj0cAI/AAAAAAAAADc/i49lovXzGls/s72-c/black_box.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-1642158982138321960</id><published>2011-05-23T17:37:00.000-04:00</published><updated>2011-05-23T17:37:49.267-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='statistics'/><category scheme='http://www.blogger.com/atom/ns#' term='R'/><title type='text'>Stepwise Regression in R: Part II</title><content type='html'>&lt;script type="text/x-mathjax-config"&gt;MathJax.Hub.Config({  tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}});&lt;/script&gt;&lt;script src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML" type="text/javascript"&gt;&lt;/script&gt;Someone requested a demonstration of how to use the R stepwise function I &lt;a href="http://orinanobworld.blogspot.com/2011/02/stepwise-regression-in-r.html"&gt;previously posted&lt;/a&gt;, so here goes.&amp;nbsp; I'll use the "swiss" data set that comes with R (in the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;datasets&lt;/span&gt; package).&amp;nbsp; There are six variables in the data set; I will use &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Fertility&lt;/span&gt; as the dependent variable (mainly because that is what the example code in the help file for &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;regsubsets&lt;/span&gt; does). The code below assumes that my function is saved in a file named &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;stepwise.R&lt;/span&gt;, and that the working directory is set to the folder containing that file.&lt;br /&gt;&lt;br /&gt;Decisions to add or delete a variable in my function are based on an F-test comparing the model with and without the variable.&amp;nbsp; In both cases, the null hypothesis is that the variable's true coefficient is zero, so a variable is deleted if we fail to reject the null hypothesis and added if we succeed in rejecting the null hypothesis.&amp;nbsp; For demonstration purposes, I will use significance levels $\alpha=0.05$ for deletions and $\alpha=0.10$ for additions.&lt;br /&gt;&lt;br /&gt;Here is the code:&lt;br /&gt;&lt;div style="overflow: auto;"&gt;&lt;div class="geshifilter"&gt;&lt;pre class="r geshifilter-R" style="font-family: monospace;"&gt;&lt;a href="http://inside-r.org/r-doc/base/source"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;source&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;span style="color: blue;"&gt;'./stepwise.R'&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt; &lt;span style="color: #666666; font-style: italic;"&gt;# load the stepwise function&lt;/span&gt;&lt;br /&gt;&lt;a href="http://inside-r.org/r-doc/utils/data"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;data&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;a href="http://inside-r.org/r-doc/datasets/swiss"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;swiss&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt; &lt;span style="color: #666666; font-style: italic;"&gt;# 47 observations of 6 variables, from dataset package&lt;/span&gt;&lt;br /&gt;&lt;a href="http://inside-r.org/r-doc/base/attach"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;attach&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;&lt;a href="http://inside-r.org/r-doc/datasets/swiss"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;swiss&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt; &lt;span style="color: #666666; font-style: italic;"&gt;# so we don't have to prefix every variable&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #666666; font-style: italic;"&gt;# we will (arbitrarily) use alpha = 0.05 to add a variable and alpha = 0.10 to remove one&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #666666; font-style: italic;"&gt;# the first run will start with just a constant term&lt;/span&gt;&lt;br /&gt;&lt;a href="http://inside-r.org/packages/cran/stepwise"&gt;stepwise&lt;/a&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;Fertility ~ &lt;span style="color: #cc66cc;"&gt;1&lt;/span&gt; + Agriculture + Examination + Education + Catholic + Infant.Mortality&lt;span style="color: #339933;"&gt;,&lt;/span&gt; Fertility ~ &lt;span style="color: #cc66cc;"&gt;1&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt; &lt;span style="color: #cc66cc;"&gt;0.05&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt; &lt;span style="color: #cc66cc;"&gt;0.10&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #666666; font-style: italic;"&gt;# the second run starts with the complete model and initially winnows it&lt;/span&gt;&lt;br /&gt;&lt;a href="http://inside-r.org/packages/cran/stepwise"&gt;stepwise&lt;/a&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;Fertility ~ &lt;span style="color: #cc66cc;"&gt;1&lt;/span&gt; + Agriculture + Examination + Education + Catholic + Infant.Mortality&lt;span style="color: #339933;"&gt;,&lt;/span&gt; Fertility ~ &lt;span style="color: #cc66cc;"&gt;1&lt;/span&gt; + Agriculture + Examination + Education + Catholic + Infant.Mortality&lt;span style="color: #339933;"&gt;,&lt;/span&gt; &lt;span style="color: #cc66cc;"&gt;0.05&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt; &lt;span style="color: #cc66cc;"&gt;0.10&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;a href="http://www.inside-r.org/pretty-r" title="Created by Pretty R at inside-R.org"&gt;Created by Pretty R at inside-R.org&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The output for the first call (which starts with just a constant term, and builds from there) is as follows:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;            Estimate Std. Error  t value     Pr(&amp;gt;|t|)&lt;br /&gt;(Intercept) 70.14255   1.822101 38.49542 1.212895e-36&lt;br /&gt;&lt;br /&gt;S = 12.491697, R-sq = 0.000000, R-sq(adj) = 0.000000, C-p = 94.805296&lt;br /&gt;=====&lt;br /&gt;+++ Adding Education &lt;br /&gt;&lt;br /&gt;              Estimate Std. Error   t value     Pr(&amp;gt;|t|)&lt;br /&gt;(Intercept) 79.6100585  2.1040971 37.835734 9.302464e-36&lt;br /&gt;Education   -0.8623503  0.1448447 -5.953619 3.658617e-07&lt;br /&gt;&lt;br /&gt;S = 9.446029, R-sq = 0.440616, R-sq(adj) = 0.428185, C-p = 35.204895&lt;br /&gt;=====&lt;br /&gt;+++ Adding Catholic &lt;br /&gt;&lt;br /&gt;              Estimate Std. Error   t value     Pr(&amp;gt;|t|)&lt;br /&gt;(Intercept) 74.2336892 2.35197061 31.562337 7.349828e-32&lt;br /&gt;Education   -0.7883293 0.12929324 -6.097219 2.428340e-07&lt;br /&gt;Catholic     0.1109210 0.02980965  3.720974 5.598332e-04&lt;br /&gt;&lt;br /&gt;S = 8.331442, R-sq = 0.574507, R-sq(adj) = 0.555167, C-p = 18.486158&lt;br /&gt;=====&lt;br /&gt;+++ Adding Infant.Mortality &lt;br /&gt;&lt;br /&gt;                    Estimate Std. Error   t value     Pr(&amp;gt;|t|)&lt;br /&gt;(Intercept)      48.67707330 7.91908348  6.146806 2.235983e-07&lt;br /&gt;Education        -0.75924577 0.11679763 -6.500524 6.833658e-08&lt;br /&gt;Catholic          0.09606607 0.02721795  3.529511 1.006201e-03&lt;br /&gt;Infant.Mortality  1.29614813 0.38698777  3.349326 1.693753e-03&lt;br /&gt;&lt;br /&gt;S = 7.505417, R-sq = 0.662544, R-sq(adj) = 0.639000, C-p = 8.178162&lt;br /&gt;=====&lt;br /&gt;+++ Adding Agriculture &lt;br /&gt;&lt;br /&gt;                   Estimate Std. Error   t value     Pr(&amp;gt;|t|)&lt;br /&gt;(Intercept)      62.1013116 9.60488611  6.465596 8.491981e-08&lt;br /&gt;Education        -0.9802638 0.14813668 -6.617293 5.139985e-08&lt;br /&gt;Catholic          0.1246664 0.02889350  4.314686 9.503030e-05&lt;br /&gt;Infant.Mortality  1.0784422 0.38186621  2.824136 7.220378e-03&lt;br /&gt;Agriculture      -0.1546175 0.06818992 -2.267454 2.856968e-02&lt;br /&gt;&lt;br /&gt;S = 7.168166, R-sq = 0.699348, R-sq(adj) = 0.670714, C-p = 5.032800&lt;br /&gt;=====&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;So all the predictors other than &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Examination&lt;/span&gt; are added. Now here is the output from the second call:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;                   Estimate  Std. Error   t value     Pr(&amp;gt;|t|)&lt;br /&gt;(Intercept)      66.9151817 10.70603759  6.250229 1.906051e-07&lt;br /&gt;Agriculture      -0.1721140  0.07030392 -2.448142 1.872715e-02&lt;br /&gt;Examination      -0.2580082  0.25387820 -1.016268 3.154617e-01&lt;br /&gt;Education        -0.8709401  0.18302860 -4.758492 2.430605e-05&lt;br /&gt;Catholic          0.1041153  0.03525785  2.952969 5.190079e-03&lt;br /&gt;Infant.Mortality  1.0770481  0.38171965  2.821568 7.335715e-03&lt;br /&gt;&lt;br /&gt;S = 7.165369, R-sq = 0.706735, R-sq(adj) = 0.670971, C-p = 6.000000&lt;br /&gt;=====&lt;br /&gt;--- Dropping Examination &lt;br /&gt;&lt;br /&gt;                   Estimate Std. Error   t value     Pr(&amp;gt;|t|)&lt;br /&gt;(Intercept)      62.1013116 9.60488611  6.465596 8.491981e-08&lt;br /&gt;Agriculture      -0.1546175 0.06818992 -2.267454 2.856968e-02&lt;br /&gt;Education        -0.9802638 0.14813668 -6.617293 5.139985e-08&lt;br /&gt;Catholic          0.1246664 0.02889350  4.314686 9.503030e-05&lt;br /&gt;Infant.Mortality  1.0784422 0.38186621  2.824136 7.220378e-03&lt;br /&gt;&lt;br /&gt;S = 7.168166, R-sq = 0.699348, R-sq(adj) = 0.670714, C-p = 5.032800&lt;br /&gt;=====&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;We start with the full model, delete &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Examination&lt;/span&gt;, and stop there.&lt;br /&gt;&lt;br /&gt;Not content to leave well enough alone, let's see what happens if we start&amp;nbsp; with the "E" variables (&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Education&lt;/span&gt; and &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Examination&lt;/span&gt;) and go from there.&amp;nbsp; The code for the function call is&lt;br /&gt;&lt;br /&gt;&lt;div style="overflow: auto;"&gt;&lt;div class="geshifilter"&gt;&lt;pre class="r geshifilter-R" style="font-family: monospace;"&gt;&lt;a href="http://inside-r.org/packages/cran/stepwise"&gt;stepwise&lt;/a&gt;&lt;span style="color: #009900;"&gt;(&lt;/span&gt;Fertility ~ &lt;span style="color: #cc66cc;"&gt;1&lt;/span&gt; + Agriculture + Examination + Education + Catholic + Infant.Mortality&lt;span style="color: #339933;"&gt;,&lt;/span&gt; Fertility ~ Examination + Education&lt;span style="color: #339933;"&gt;,&lt;/span&gt; &lt;span style="color: #cc66cc;"&gt;0.05&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt; &lt;span style="color: #cc66cc;"&gt;0.10&lt;/span&gt;&lt;span style="color: #009900;"&gt;)&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;a href="http://www.inside-r.org/pretty-r" title="Created by Pretty R at inside-R.org"&gt;Created by Pretty R at inside-R.org&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;and the output is&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;              Estimate Std. Error   t value     Pr(&amp;gt;|t|)&lt;br /&gt;(Intercept) 85.2532753  3.0854981 27.630312 1.945244e-29&lt;br /&gt;Examination -0.5572183  0.2319374 -2.402451 2.057160e-02&lt;br /&gt;Education   -0.5394570  0.1924380 -2.803277 7.497224e-03&lt;br /&gt;&lt;br /&gt;S = 8.981812, R-sq = 0.505485, R-sq(adj) = 0.483007, C-p = 28.135883&lt;br /&gt;=====&lt;br /&gt;+++ Adding Infant.Mortality &lt;br /&gt;&lt;br /&gt;                   Estimate Std. Error   t value     Pr(&amp;gt;|t|)&lt;br /&gt;(Intercept)      55.2746618  8.8077340  6.275696 1.451652e-07&lt;br /&gt;Examination      -0.5108888  0.2063175 -2.476226 1.729132e-02&lt;br /&gt;Education        -0.5225093  0.1709099 -3.057221 3.832793e-03&lt;br /&gt;Infant.Mortality  1.4556114  0.4064507  3.581274 8.644778e-04&lt;br /&gt;&lt;br /&gt;S = 7.973957, R-sq = 0.619096, R-sq(adj) = 0.592521, C-p = 14.252399&lt;br /&gt;=====&lt;br /&gt;+++ Adding Catholic &lt;br /&gt;&lt;br /&gt;                    Estimate Std. Error    t value     Pr(&amp;gt;|t|)&lt;br /&gt;(Intercept)      50.02820666 8.66076269  5.7764204 8.325568e-07&lt;br /&gt;Examination      -0.10580461 0.26036962 -0.4063631 6.865390e-01&lt;br /&gt;Education        -0.70415772 0.17969218 -3.9186887 3.221868e-04&lt;br /&gt;Infant.Mortality  1.30567908 0.39150335  3.3350393 1.790664e-03&lt;br /&gt;Catholic          0.08631125 0.03649293  2.3651501 2.271709e-02&lt;br /&gt;&lt;br /&gt;S = 7.579356, R-sq = 0.663865, R-sq(adj) = 0.631853, C-p = 9.993398&lt;br /&gt;=====&lt;br /&gt;--- Dropping Examination &lt;br /&gt;&lt;br /&gt;                    Estimate Std. Error   t value     Pr(&amp;gt;|t|)&lt;br /&gt;(Intercept)      48.67707330 7.91908348  6.146806 2.235983e-07&lt;br /&gt;Education        -0.75924577 0.11679763 -6.500524 6.833658e-08&lt;br /&gt;Infant.Mortality  1.29614813 0.38698777  3.349326 1.693753e-03&lt;br /&gt;Catholic          0.09606607 0.02721795  3.529511 1.006201e-03&lt;br /&gt;&lt;br /&gt;S = 7.505417, R-sq = 0.662544, R-sq(adj) = 0.639000, C-p = 8.178162&lt;br /&gt;=====&lt;br /&gt;+++ Adding Agriculture &lt;br /&gt;&lt;br /&gt;                   Estimate Std. Error   t value     Pr(&amp;gt;|t|)&lt;br /&gt;(Intercept)      62.1013116 9.60488611  6.465596 8.491981e-08&lt;br /&gt;Education        -0.9802638 0.14813668 -6.617293 5.139985e-08&lt;br /&gt;Infant.Mortality  1.0784422 0.38186621  2.824136 7.220378e-03&lt;br /&gt;Catholic          0.1246664 0.02889350  4.314686 9.503030e-05&lt;br /&gt;Agriculture      -0.1546175 0.06818992 -2.267454 2.856968e-02&lt;br /&gt;&lt;br /&gt;S = 7.168166, R-sq = 0.699348, R-sq(adj) = 0.670714, C-p = 5.032800&lt;br /&gt;=====&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;All roads seem to lead to the same model. Also note that the constant term was not explicitly stated in the third call (no "&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;1+&lt;/span&gt;" in the formulas). As usual with R, a constant term is assumed unless explicitly omitted (using "&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;0 +&lt;/span&gt;").&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-1642158982138321960?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/1642158982138321960/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/05/stepwise-regression-in-r-part-ii.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/1642158982138321960'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/1642158982138321960'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/05/stepwise-regression-in-r-part-ii.html' title='Stepwise Regression in R: Part II'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-1265404192740834290</id><published>2011-05-21T19:43:00.000-04:00</published><updated>2011-05-21T19:43:47.069-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='education'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>A Shoutout to Anki</title><content type='html'>I'd like to point out &lt;a href="http://ankisrs.net/"&gt;Anki&lt;/a&gt;, an open source (GPL 3) virtual flashcard program I've been using. Anki runs on all major PC platforms (and an impressive array of mobile devices), and is feature-rich. It has a plug-in architecture. Cards can contain not just text but also images and audio files. Anki supports LaTeX, so it should be easy to put mathematical formulas on cards. Use of card decks is very flexible (including an easy way to have cards representing difficult concepts repeat sooner than cards representing easy concepts). It is easy to create or import card decks, and you can share card decks (and plug-ins) with other people through their &lt;a href="http://ankiweb.net/account/login"&gt;AnkiWeb&lt;/a&gt; site. (Disclaimer: I have not looked at the available shared decks, nor have I looked at any plug-ins. The basic download fills my needs.)&lt;br /&gt;&lt;br /&gt;My use for Anki has been to learn my students names. At the outset of each semester, I acquire a class list with student photos, strip out the photos, and turn them into an Anki deck. During idle moments at coffee shops, I play the decks and learn to associate names with faces. (Addressing students by name on the first day of class freaks them out; I think they tend to be more docile thereafter.)&lt;br /&gt;&lt;br /&gt;I'm not a big fan of rote memorization in education, but I suppose it has its place.&amp;nbsp; I could see using Anki to learn formulas from queuing theory (for instance, "M/M/1 steady-state queue length" on the front, the corresponding formula on the back) or perhaps some terminology from linear programming (graph of a feasible region and an objective hyperplane tangent along an edge on the front, "multiple optima" on the back). As there are more things in heaven and earth than are dreamt of in my philosophy, I suppose there are more ways Anki could be used in the teaching of operations research.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-1265404192740834290?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/1265404192740834290/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/05/shoutout-to-anki.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/1265404192740834290'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/1265404192740834290'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/05/shoutout-to-anki.html' title='A Shoutout to Anki'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-7503506476117070688</id><published>2011-05-17T11:27:00.000-04:00</published><updated>2011-05-17T11:27:42.940-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='math programming'/><category scheme='http://www.blogger.com/atom/ns#' term='CPLEX'/><title type='text'>My Infinity Is Bigger Than Your Infinity</title><content type='html'>&lt;script type="text/x-mathjax-config"&gt;MathJax.Hub.Config({  tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}});&lt;/script&gt;&lt;script src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML" type="text/javascript"&gt;&lt;/script&gt;Mathematicians are used to the concept that some infinities (e.g., &lt;a href="http://en.wikipedia.org/wiki/Aleph_null#Aleph-naught"&gt;$\aleph_0$&lt;/a&gt;) are bigger than other infinities (e.g., &lt;a href="http://en.wikipedia.org/wiki/Aleph_null#Aleph-one"&gt;$\aleph_1$&lt;/a&gt;). In mathematical programming, though, "infinity" is really just a placeholder for "I know there is a finite limit but I don't know what it is" (or "I know there is a finite limit but I'm too lazy to look for it"). The only place you'll see $\infty$ in a mathematical program is as an omitted bound on a variable.&lt;br /&gt;&lt;br /&gt;There are two other truisms, related to this post, that are well known to anyone with a reasonable amount of experience solving mathematical programs via user-written code (including APIs to solver libraries). The first is that solvers run on double-precision floating point arithmetic, and $\infty$ is not a d-p number. So it is reasonable to treat any d-p number larger than some specified limit $M$ as a surrogate for $\infty$. In the CPLEX APIs, $M=1e+20$. (In the Java version of the Concert API, the static constants &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Double.MAX_VALUE&lt;/span&gt; and &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Double.POSITIVE_INFINITY&lt;/span&gt; work well for $\infty$, while &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;-Double.MAX_VALUE&lt;/span&gt; and &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Double.NEGATIVE_INFINITY&lt;/span&gt; work for $-\infty$; but you can just as easily use $\pm 1e20$.) The second truism is that mixing very large coefficients with not-so-large&amp;nbsp; coefficients in constraints is an invitation to numerical instability.&lt;br /&gt;&lt;br /&gt;This brings me to something I tripped over accidentally a day or so ago. Consider the following trivial linear programming problem: $$\begin{array}{lc}\mathrm{maximize} &amp;amp; x \\ \mathrm{s.t.} &amp;amp; x\le M\end{array}$$ where $M&amp;gt;0$ is a large (but finite) number. The problem has an obvious (and trivial) optimal solution ($x=M$) ... unless you are using a solver, and $M$ is large enough to look like $\infty$. Indeed, for $M\ge 1e+20$, CPLEX (using any of the APIs) will (and should) declare the problem unbounded.&lt;br /&gt;&lt;br /&gt;The following table shows the results of a little experiment I did (with CPLEX 12.2.0.2, but the results are not version-dependent):&lt;br /&gt;&lt;br /&gt;&lt;table align="center" width="80%" frame="border"&gt;&lt;thead&gt;&lt;tr align="center"&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;Presolve&lt;/th&gt;&lt;th&gt;No Presolve&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr align="center"&gt;&lt;td&gt;$M\lt 1e+10$&lt;/td&gt;&lt;td&gt;Optimal ($x=M$)&lt;/td&gt;&lt;td&gt;Optimal ($x=M$)&lt;/td&gt;&lt;/tr&gt;&lt;tr align="center"&gt;&lt;td&gt;$M= 1e+10$&lt;/td&gt;&lt;td&gt;Unbounded&lt;/td&gt;&lt;td&gt;Optimal ($x=M$)&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Note the result in the lower left corner: the CPLEX presolver asserts that the problem is unbounded. An e-mail exchange with Dr. Ed Klotz of IBM sorted this out for me, and the rationale does in fact make sense. Suppose that the presolver encounters a variable $x$ that it can fix at a large bound $M$. As it eliminates the variable from the model, any instance of $x$ in the model (say, $a_i x$ in the $i^{\mathrm{th}}$ constraint) is replaced by a potentially large number ($a_i M$), which may introduce numerical instability (see second truism above). So CPLEX is somewhat conservative during presolve about how large is too large. In effect, $\infty=1e+20$ in the solver but $\infty=1e+10$ in the presolver.&lt;br /&gt;&lt;br /&gt;I discovered this purely by accident, because I'm a firm believer that no model should have coefficients (including bounds) that require me to type two digit exponent fields in scientific notation. If there are values that large, it's time to rescale. It just caught me by surprise that the surrogate for $\infty$ in the presolver was not the same one used in the APIs.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-7503506476117070688?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/7503506476117070688/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/05/my-infinity-is-bigger-than-your.html#comment-form' title='18 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/7503506476117070688'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/7503506476117070688'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/05/my-infinity-is-bigger-than-your.html' title='My Infinity Is Bigger Than Your Infinity'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>18</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-2568052333919767411</id><published>2011-05-15T07:29:00.000-04:00</published><updated>2011-05-15T07:29:54.147-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='R'/><title type='text'>Rejiggering an R Data Frame</title><content type='html'>This is a new experience for me.&amp;nbsp; Mark Allen (author of the &lt;a href="http://openresearch.wordpress.com/"&gt;Open Source Research&lt;/a&gt; blog) tweeted a question about rearranging a data frame in R.&amp;nbsp; The question being longer than 140 characters, he used &lt;a href="http://www.tweetdeck.com/deckly"&gt;Deck.ly&lt;/a&gt; to post an &lt;a href="http://www.tweetdeck.com/twitter/siah/%7E5Cxz9"&gt;extended tweet&lt;/a&gt;.&amp;nbsp; So I learned something new about the Twitterverse.&amp;nbsp; I don't have a &lt;a href="http://www.tweetdeck.com/"&gt;TweetDeck&lt;/a&gt; account, though, so my best option to post a response is to put it here.&lt;br /&gt;&lt;br /&gt;Mark has a data frame with one row for each response to any of a set of questions, and three columns: respondent ID; question number; response. Here's a chunk of R code to create a small demo data frame along those lines:&lt;br /&gt;&lt;div style="overflow:auto;"&gt;&lt;div class="geshifilter"&gt;&lt;pre class="r geshifilter-R" style="font-family:monospace;"&gt;&lt;span style="color: #666666; font-style: italic;"&gt;# create some data&lt;/span&gt;&lt;br /&gt;m &lt;span style=""&gt;&amp;lt;-&lt;/span&gt; &lt;a href="http://inside-r.org/r-doc/base/matrix"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;matrix&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;a href="http://inside-r.org/r-doc/base/c"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;c&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;1&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;1&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;11&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;2&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;3&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;23&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;1&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;2&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;12&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;2&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;1&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;21&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;2&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;2&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;22&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;1&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;3&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;13&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt; &lt;a href="http://inside-r.org/r-doc/base/nrow"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;nrow&lt;/span&gt;&lt;/a&gt;=&lt;span style="color: #cc66cc;"&gt;6&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt; &lt;a href="http://inside-r.org/r-doc/base/ncol"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;ncol&lt;/span&gt;&lt;/a&gt;=&lt;span style="color: #cc66cc;"&gt;3&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt; byrow=&lt;span style="color: #000000; font-weight: bold;"&gt;TRUE&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;d &lt;span style=""&gt;&amp;lt;-&lt;/span&gt; &lt;a href="http://inside-r.org/r-doc/base/data.frame"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;data.frame&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;m&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;&lt;a href="http://inside-r.org/r-doc/base/names"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;names&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;d&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style=""&gt;&amp;lt;-&lt;/span&gt; &lt;a href="http://inside-r.org/r-doc/base/c"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;c&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;quot;ID&amp;quot;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;quot;Question&amp;quot;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;quot;Answer&amp;quot;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;&lt;a href="http://inside-r.org/r-doc/base/print"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;print&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;d&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;a href="http://www.inside-r.org/pretty-r" title="Created by Pretty R at inside-R.org"&gt;Created by Pretty R at inside-R.org&lt;/a&gt;&lt;/p&gt;&lt;p&gt;The output is:&lt;/p&gt;&lt;pre&gt;&lt;br /&gt;  ID Question Answer&lt;br /&gt;1  1        1     11&lt;br /&gt;2  2        3     23&lt;br /&gt;3  1        2     12&lt;br /&gt;4  2        1     21&lt;br /&gt;5  2        2     22&lt;br /&gt;6  1        3     13&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;Here is code to rearrange it:&lt;/p&gt;&lt;div style="overflow:auto;"&gt;&lt;div class="geshifilter"&gt;&lt;pre class="r geshifilter-R" style="font-family:monospace;"&gt;&lt;span style="color: #666666; font-style: italic;"&gt;# sort the data by ID, then by Question&lt;/span&gt;&lt;br /&gt;d &lt;span style=""&gt;&amp;lt;-&lt;/span&gt; d&lt;span style="color: #009900;"&gt;&amp;#91;&lt;/span&gt;&lt;a href="http://inside-r.org/r-doc/base/do.call"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;do.call&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;a href="http://inside-r.org/r-doc/base/order"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;order&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;d&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#93;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #666666; font-style: italic;"&gt;# extract a list of unique IDs and Question numbers&lt;/span&gt;&lt;br /&gt;id &lt;span style=""&gt;&amp;lt;-&lt;/span&gt; &lt;a href="http://inside-r.org/r-doc/base/unique"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;unique&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;d&lt;span style="color: #009900;"&gt;&amp;#91;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;quot;ID&amp;quot;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#93;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;&lt;a href="http://inside-r.org/r-doc/base/q"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;q&lt;/span&gt;&lt;/a&gt; &lt;span style=""&gt;&amp;lt;-&lt;/span&gt; &lt;a href="http://inside-r.org/r-doc/base/unique"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;unique&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;d&lt;span style="color: #009900;"&gt;&amp;#91;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;quot;Question&amp;quot;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#93;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #666666; font-style: italic;"&gt;# rearrange the answers into the desired matrix layout&lt;/span&gt;&lt;br /&gt;m &lt;span style=""&gt;&amp;lt;-&lt;/span&gt; &lt;a href="http://inside-r.org/r-doc/base/matrix"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;matrix&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;d&lt;span style="color: #009900;"&gt;&amp;#91;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;quot;Answer&amp;quot;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#93;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt; &lt;a href="http://inside-r.org/r-doc/base/nrow"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;nrow&lt;/span&gt;&lt;/a&gt;=&lt;a href="http://inside-r.org/r-doc/base/length"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;length&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;id&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt; &lt;a href="http://inside-r.org/r-doc/base/ncol"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;ncol&lt;/span&gt;&lt;/a&gt;=&lt;a href="http://inside-r.org/r-doc/base/length"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;length&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;a href="http://inside-r.org/r-doc/base/q"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;q&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt; byrow=&lt;span style="color: #000000; font-weight: bold;"&gt;TRUE&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #666666; font-style: italic;"&gt;# add the ids and make a new data frame&lt;/span&gt;&lt;br /&gt;m &lt;span style=""&gt;&amp;lt;-&lt;/span&gt; &lt;a href="http://inside-r.org/r-doc/base/cbind"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;cbind&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;id&lt;span style="color: #339933;"&gt;,&lt;/span&gt; m&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;dd &lt;span style=""&gt;&amp;lt;-&lt;/span&gt; &lt;a href="http://inside-r.org/r-doc/base/data.frame"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;data.frame&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;m&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;&lt;a href="http://inside-r.org/r-doc/base/names"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;names&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;dd&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style=""&gt;&amp;lt;-&lt;/span&gt; &lt;a href="http://inside-r.org/r-doc/base/c"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;c&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;quot;ID&amp;quot;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt; &lt;a href="http://inside-r.org/r-doc/base/paste"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;paste&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;quot;Q&amp;quot;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt; &lt;a href="http://inside-r.org/r-doc/base/q"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;q&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt; sep=&lt;span style="color: #0000ff;"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;br /&gt;&lt;a href="http://inside-r.org/r-doc/base/print"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;print&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;dd&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;a href="http://www.inside-r.org/pretty-r" title="Created by Pretty R at inside-R.org"&gt;Created by Pretty R at inside-R.org&lt;/a&gt;&lt;/p&gt;&lt;p&gt;The output of the last line (the rejiggered data frame) is:&lt;/p&gt;&lt;pre&gt;  ID Q1 Q2 Q3&lt;br /&gt;1  1 11 12 13&lt;br /&gt;2  2 21 22 23&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-2568052333919767411?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/2568052333919767411/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/05/rejiggering-r-data-frame.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/2568052333919767411'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/2568052333919767411'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/05/rejiggering-r-data-frame.html' title='Rejiggering an R Data Frame'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-1511370476755263067</id><published>2011-05-13T20:06:00.000-04:00</published><updated>2011-05-13T20:06:23.524-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='INFORMS blog challenge'/><category scheme='http://www.blogger.com/atom/ns#' term='operations research'/><category scheme='http://www.blogger.com/atom/ns#' term='analytics'/><title type='text'>Will Analytics Drag O.R. Back to Its Roots?</title><content type='html'>The &lt;a href="http://www.informs.org/About-INFORMS/News-Room/INFORMS-Blog/April-Blog-Challenge-Results-O.R.-and-Healthcare-May-s-Blog-Challenge-O.R.-and-Analytics"&gt;INFORMS blog challenge for May&lt;/a&gt; is "O.R. and Analytics", so here goes ...&lt;br /&gt;&lt;br /&gt;There are about as many definitions of "analytics" as there are explanations for the recent global economic crash. My take on "analytics" has been that, at least until now, what it meant to business executives was "take this huge pile of data and make sense of it". Operations research models in the real world have always relied on some level of data analysis, because models contain parameters and parameters must be estimated. (Outside the real world -- which is to say in academe and government service -- modelers get to make up whatever parameter values they like.) That said, I've never really associated heavy duty data analysis with O.R. Statisticians analyze data and data miners try to read sheep entrails (according to the statisticians); O.R. analysts build and use models.&lt;br /&gt;&lt;br /&gt;As the term "analytics" grabs mind share among executives, though, O.R. societies and O.R. practitioners are trying, to borrow a phrase from Microsoft, to "embrace and extend" it. The societies see this as a way to boost membership and conference attendance, and both the societies and practitioners see it as a way to enhance the visibility of O.R. to the people who will (hopefully) employ O.R. analysts, directly or as consultants. I would not be surprised if the data analysis crowd see this as O.R. people trying to share the spotlight uninvited. Fortunately, since their forte is recognizing patterns as opposed to prescribing solutions, they'll see us coming but probably won't be able to keep us out.&lt;br /&gt;&lt;br /&gt;Extending the O.R. brand will require more than just saying "operations research ... including data analysis" or "operations research is analytics ... plus so much more". If we're serious about this, we'll need to reconsider what we mean by "operations research", and perhaps how we go about its practice. Therein lies an opportunity to return to O.R.'s roots.&lt;br /&gt;&lt;br /&gt;The history of O.R. traces back to World War II, and the stories from that era have a common thread. Someone has a problem. The problem appears somewhat quantitative in nature (or at least amenable to measurement and quantification). We want to model it, and see what the model suggests might solve the problem. Absent from this description is any pigeon-holing of the problem as a linear program, or a queueing problem, or a discrete event simulation. One of the classic examples was finding ways to move men and materiel from the U.S. to the U.K. more safely during the Battle of the Atlantic. The answer involved determining the optimal shape of a convey (which was &lt;i&gt;not&lt;/i&gt; a mathematical programming problem, the word "optimal" notwithstanding), recognizing that small convoys of fast ships (small possibly meaning a single ship) might not need an escort (they were too fast for the U-boats to pick on), and so forth.&lt;br /&gt;&lt;br /&gt;As O.R. bloomed after the war, we developed more and better tools (theory, algorithms, software) ... and along the way, we became more specialized. So now we have experts in optimization and experts in simulation and so on, and we tend to adhere to the maxim (which I will shamelessly bastardize) that if you're really good with a screwdriver, everything looks like a screw. At a recent INFORMS conference, I attended a session about teaching modeling to MBAs. Given the topic, I suspect most of the attendees were fellow academics, so I apologize if I offend any practitioners by tarring them with the same brush. At one point in the session, the presenters posed a scenario to us (the Red Cross is thinking about paying for blood donations, and wants some consulting on it), and, with not much more detail than what I just gave, turned us loose on it. The optimizers started writing optimization models. The simulators started sketching out simulation models. If there were any decision analysts in the room, I'm sure they were drawing decision trees. In other words, most of us framed the problem in terms of our favorite tools, rather than fleshing out the problem (which was quite vague) and then looking for tools (possibly mathematically unsophisticated tools) that would match it.&lt;br /&gt;&lt;br /&gt;As we try to figure out how data mining and "business intelligence" (note that I'm skipping all oxymoron jokes here, a severe exercise in restraint) fit with O.R., perhaps we can seize the opportunity to starting conceptualizing (and teaching) O.R. as first and foremost sorting out and describing what the problem actually is. My very limited understanding of data mining suggests that it leans more toward letting the data tell you what it wants to tell you than to making the data fit a preconceived model; extend that to the overall problem, rather than just the data, and we're back to something I think the progenitors of O.R. would recognize.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-1511370476755263067?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/1511370476755263067/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/05/will-analytics-drag-or-back-to-its.html#comment-form' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/1511370476755263067'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/1511370476755263067'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/05/will-analytics-drag-or-back-to-its.html' title='Will Analytics Drag O.R. Back to Its Roots?'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-1589708718341805959</id><published>2011-04-30T22:54:00.000-04:00</published><updated>2011-04-30T22:54:15.134-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='operations research'/><category scheme='http://www.blogger.com/atom/ns#' term='applications'/><title type='text'>An Unbalanced Round Robin Bridge Schedule</title><content type='html'>Ages ago, while studying (sort of) for my doctorate in mathematics, I played a significant amount of duplicate bridge, frequently with my grad school buddies Bluto and Dawn and my now-long-lost love (She Who Will Not Be Named).&amp;nbsp; Bluto and Dawn (who are married) are now retired, and not too long ago I got an e-mail from Bluto.&amp;nbsp; He and Dawn continue to play bridge with a group of friends, and they have a sort of league set up.&amp;nbsp; Since he and Dawn both studied math, the duty of constructing a schedule for the league naturally fell to them.&lt;br /&gt;&lt;br /&gt;The way their league functions is as follows.&amp;nbsp; Once a month, couples get together at various houses, with four couples at each house (that being the most people couples are willing to host). Their league has 12 couples, so there are three venues operating simultaneously.&amp;nbsp; At each house, each of the four couples plays against each of the other couples (so three games per venue per date).&amp;nbsp; The objectives in forming the schedule are to minimize the variation in how often any pair of couples faces each other, and simultaneously to minimize the variation in how often a couple is called upon to host a game.&amp;nbsp; The planning horizon is eight dates.&lt;br /&gt;&lt;br /&gt;Dawn (the brighter of the two) was apparently able to construct a balanced schedule for 16 couples, four venues per date and an unspecified horizon (which I'm sure was divisible by five), despite being hampered by a degree in abstract algebra.&amp;nbsp; Neither of them could find a schedule for 12 couples/eight dates, in part because it cannot be balanced: each couple plays three games per date, so 24 games total, which means they cannot play the other 11 couples an equal number of times.&amp;nbsp; Bluto asked me if this was an operations research problem, which it most definitely is.&lt;br /&gt;&lt;br /&gt;It can be attacked in a variety of ways (mixed integer program, constraint program, metaheuristic); I chose to try a MIP model first, since that's the type of software with which I'm most familiar.&amp;nbsp; As with many MIP problems, the model was easy but the solution was a bit time-consuming, even after tweaking the model to eliminate some of the symmetry that plagues the problem.&lt;br /&gt;I won't bore anyone with the model details, but I thought I'd post the best schedule I found, in case anyone else happens to be trying to schedule 12 team round-robins (although I suspect the parameters of this particular problem are rather unusual).&amp;nbsp; In the tables below, couples are identified with the letters 'a' through 'l'; hosts are capitalized.&lt;br /&gt;&lt;br /&gt;&lt;theading&gt;&lt;/theading&gt;&lt;br /&gt;&lt;table align="center" border="1"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;Date&lt;/th&gt;&lt;th&gt;Game 1&lt;/th&gt;&lt;th&gt;Game 2&lt;/th&gt;&lt;th&gt;Game 3&lt;/th&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;tbody&gt;&lt;tr align="center"&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;abcD&lt;/td&gt;&lt;td&gt;efgH&lt;/td&gt;&lt;td&gt;iJkl&lt;/td&gt;&lt;/tr&gt;&lt;tr align="center"&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;aeFj&lt;/td&gt;&lt;td&gt;Bdhl&lt;/td&gt;&lt;td&gt;cgIk&lt;/td&gt;&lt;/tr&gt;&lt;tr align="center"&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;agHj&lt;/td&gt;&lt;td&gt;Bfkl&lt;/td&gt;&lt;td&gt;cdeI&lt;/td&gt;&lt;/tr&gt;&lt;tr align="center"&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;Abek&lt;/td&gt;&lt;td&gt;Cghl&lt;/td&gt;&lt;td&gt;dFij&lt;/td&gt;&lt;/tr&gt;&lt;tr align="center"&gt;&lt;td&gt;5&lt;/td&gt;&lt;td&gt;ahiK&lt;/td&gt;&lt;td&gt;bcfG&lt;/td&gt;&lt;td&gt;dejL&lt;/td&gt;&lt;/tr&gt;&lt;tr align="center"&gt;&lt;td&gt;6&lt;/td&gt;&lt;td&gt;acEl&lt;/td&gt;&lt;td&gt;bGij&lt;/td&gt;&lt;td&gt;dfhK&lt;/td&gt;&lt;/tr&gt;&lt;tr align="center"&gt;&lt;td&gt;7&lt;/td&gt;&lt;td&gt;adgL&lt;/td&gt;&lt;td&gt;bEhi&lt;/td&gt;&lt;td&gt;Cfjk&lt;/td&gt;&lt;/tr&gt;&lt;tr align="center"&gt;&lt;td&gt;8&lt;/td&gt;&lt;td&gt;Afil&lt;/td&gt;&lt;td&gt;bchJ&lt;/td&gt;&lt;td&gt;Degk&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Charitably assuming I transcribed that correctly, each team plays every other team either two or three times. (With 12 teams playing three games on each of eight dates, for 24 games total per team, you would expect to play nine of the other 11 teams twice and the other two three times each, so this tracks.)&amp;nbsp; Everyone hosts exactly twice.&amp;nbsp; In terms of meeting Bluto's stated criteria, it does pretty well; but looking at it, I wonder if I should have added a penalty for couples hosting on consecutive dates, or tried to maximize the minimum elapsed time between hosting assignments for any couple?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-1589708718341805959?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/1589708718341805959/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/04/unbalanced-round-robin-bridge-schedule.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/1589708718341805959'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/1589708718341805959'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/04/unbalanced-round-robin-bridge-schedule.html' title='An Unbalanced Round Robin Bridge Schedule'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-3928965069048591450</id><published>2011-04-17T18:32:00.000-04:00</published><updated>2011-04-17T18:32:12.615-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='INFORMS blog challenge'/><category scheme='http://www.blogger.com/atom/ns#' term='operations research'/><category scheme='http://www.blogger.com/atom/ns#' term='healthcare'/><title type='text'>Data Mining and Pharmaceutical Bar Tending</title><content type='html'>In a &lt;a href="http://www.informs.org/ORMS-Today/Public-Articles/February-Volume-38-Number-1/The-ongoing-battle-over-health-care-reform" linkindex="177"&gt;recent article&lt;/a&gt; in &lt;a href="http://www.informs.org/ORMS-Today/" linkindex="178"&gt;OR/MS Today&lt;/a&gt; (a sequel to his excellent &lt;a href="http://viewer.zmags.com/publication/0dfc3a66#/0dfc3a66/28" linkindex="179"&gt;article&lt;/a&gt; in &lt;a href="http://www.analytics-magazine.com/" linkindex="180"&gt;Analytics&lt;/a&gt;), Douglas Samuelson writes about various OR opportunities as the health care industry in the U.S. reacts to the Mother of All Health Care Bills.&amp;nbsp; OR in health care also happens to be the theme of this month's &lt;a href="http://www.informs.org/About-INFORMS/News-Room/INFORMS-Blog/March-Blog-Challenge-Results-O.R.-and-Sports-April-s-Blog-Challenge-O.R.-and-Healthcare" linkindex="181"&gt;INFORMS blog challenge&lt;/a&gt; (for which today's post is my entry).&amp;nbsp;&lt;br /&gt;&lt;br /&gt;Let me focus on one particular statement in Samuelson's latest article:&lt;br /&gt;&lt;blockquote&gt;Another aspect of uncoordinated care is polypharmacy, the use of multiple prescription medications in combination, with too little attention to possible interactions. According to the medical examiner’s official report, polypharmacy killed high-profile celebrities Anna Nicole Smith and Michael Jackson, both of whom used multiple doctors and multiple pharmacies. Safety testing is usually done one medication at a time, so interactions can take quite some time to become identified and publicized. This is a growing problem, and information technology offers a promising answer.&lt;/blockquote&gt;I've seen statistics asserting that accidental drug interactions cause a staggering number of "adverse results" (dying being counted as an adverse result).&amp;nbsp; Those events include not only prescriptions of multiple drugs whose interactions are unknown, but prescriptions of combinations with known interactions where the prescriptions may be issued by multiple doctors and/or filled at multiple pharmacies.&amp;nbsp; My physician's office asks patients to bring all their meds with them on visits (but of course I don't).&amp;nbsp; My guess is that many patients never think to mention some medications they are taking (or incorrectly remember names, which is fairly easy given the choice between an unpronounceable generic name and a brand name devoid of mnemonic value).&amp;nbsp; There are also patients who partially self-medicate (borrowing unprescribed medications from friends or relatives, taking left over pills from long-expired prescriptions, or ordering cheap drugs over the Internet, from suppliers who couldn't spell "prescription", let alone recognize one).&lt;br /&gt;&lt;br /&gt;Since drug manufacturers cannot possibly test all possible combinations of medications, to a large extent risky interactions have to be identified the hard way.&amp;nbsp; As Samuelson states in the quote above, information technology (combined with data analysis) offers some hope there.&amp;nbsp; If changes to the health care system lead to more thorough (and more accurate) record keeping, there is an opportunity for data analysis to ferret out potential problems, which can then be tested in laboratories.&amp;nbsp; Better use of electronic record keeping will also help pharmacists detect when a customer is purchasing drugs that may interact in unfortunate ways, even if the purchases are being made at multiple pharmacies.&lt;br /&gt;&lt;br /&gt;I think there is one more opportunity for "predictive analytics", though, and that is in identifying patients likely to be at greatest risk of an adverse interaction.&amp;nbsp; Just as considerable effort is going into profiling likely terrorists, so that time and energy screening travelers or inspecting cargo can be focused where it will do the most good, we can think about profiling patients.&amp;nbsp; If analytics allows us to identify patients at greatest risk, whether it be due to their errors or to errors by doctors or pharmacists, then perhaps either government or insurers can intervene (assign a case manager, warn pharmacists to ask extra questions, use a cell phone application to nag the patient, ...) and reduce the danger.&amp;nbsp; Making intelligent, data-driven decisions to achieve the best possible outcome:&amp;nbsp; sounds like OR to me.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-3928965069048591450?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/3928965069048591450/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/04/data-mining-and-pharmaceutical-bar.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/3928965069048591450'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/3928965069048591450'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/04/data-mining-and-pharmaceutical-bar.html' title='Data Mining and Pharmaceutical Bar Tending'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-6772583520831926848</id><published>2011-03-27T17:13:00.000-04:00</published><updated>2011-03-27T17:13:53.913-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='LaTeX'/><title type='text'>Mixed Case Titles</title><content type='html'>Writing pointless academic papers requires citing other pointless academic papers.&amp;nbsp; Thus do academicians, in a symbiotic process eerily similar to those of lawyers and nuclear weapons manufacturers, keep each other in business.&amp;nbsp; Since I write in &lt;a href="http://www.lyx.org/"&gt;LyX&lt;/a&gt; and generate the documents with &lt;a href="http://www.ctan.org/"&gt;LaTeX&lt;/a&gt;, it is unsurprising that I process bibliographies using &lt;a href="http://www.bibtex.org/"&gt;BibTeX&lt;/a&gt;.&amp;nbsp; My preferred tool for maintaining BibTeX databases is &lt;a href="http://jabref.sourceforge.net/"&gt;JabRef&lt;/a&gt;, which is cross-platform, has a decent feature set, and just plain works.&lt;br /&gt;&lt;br /&gt;When I add references to by BibTeX databases, I'm careful to capitalize most of the words in the title.&amp;nbsp; Anyone who has had the misfortune to deal with journals&amp;nbsp; knows that every journal publisher employs at least one or two people with obsessive/compulsive disorder, who are tasked with ensuring that this journal formats various things (possibly tables or figure captions, but &lt;i&gt;always&lt;/i&gt;, &lt;b&gt;always&lt;/b&gt; references) in a way that visually distinguishes it from every other journal in the galaxy. Thus I have to find (or cobble together) a BibTeX style file specific to whatever journal makes the mistake of accepting of my paper.&amp;nbsp; BibTeX style files can "downshift" titles to lower case, but as far as I know they do not "upshift" to what I'll call "title" case (nouns, verbs, adjectives, adverbs and initial articles capitalized, other articles and conjunctions not).&amp;nbsp; So it behooves me to insert the reference into the database in "title" case.&lt;br /&gt;&lt;br /&gt;On the other hand, I'm a firm believer in copying and pasting to avoid retyping.&amp;nbsp; So I frequently copy article information from a web page or PDF file and paste it into JabRef.&amp;nbsp; Small problem: as far as I know, JabRef does not have an editing feature to adjust cases.&amp;nbsp; That led me to some searching, which in turn led me to discover that &lt;a href="http://projects.gnome.org/gedit/"&gt;gedit&lt;/a&gt; (my primary editor on Linux) comes with a preinstalled plug-in to shift cases.&amp;nbsp; Said plug-in can shift to lower, upper or (drumroll) "title" case. On Windows, &lt;a href="http://www.notetab.com/"&gt;NoteTab&lt;/a&gt; (including the free "Light" version) has a similar feature.&amp;nbsp; If I recall correctly, NoteTab's converter is available with no configuration.&amp;nbsp; In gedit, though, it needs to be turned on (Edit &amp;gt; Preferences &amp;gt; Plugins &amp;gt; Change Case), a revelation to which I have recently (and belatedly) come.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-6772583520831926848?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/6772583520831926848/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/03/mixed-case-titles.html#comment-form' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/6772583520831926848'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/6772583520831926848'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/03/mixed-case-titles.html' title='Mixed Case Titles'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-5608852419371594924</id><published>2011-03-20T14:36:00.001-04:00</published><updated>2011-03-30T11:24:37.363-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='AMPL'/><category scheme='http://www.blogger.com/atom/ns#' term='math programming'/><category scheme='http://www.blogger.com/atom/ns#' term='CPLEX'/><title type='text'>Semicontinuous Variables</title><content type='html'>&lt;script type="text/x-mathjax-config"&gt;MathJax.Hub.Config({  tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}});&lt;/script&gt;&lt;script type="text/javascript"  src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"&gt;&lt;/script&gt;This question pops up from time to time on various forums.&amp;nbsp; In a math programming model, how does one handle a variable that can either be zero or in some range not containing zero?&amp;nbsp; The mathematical description of the variable would be something like $$x\in {0} \cup [a,b]$$where $a&amp;gt;0$.&amp;nbsp; A couple of common applications in supply chain models include quantity discounts (a vendor offers a discounted price if you buy in bulk; $x$ is the amount purchased at the discounted price and $a$ is the minimum amount to qualify for the discount) and minimum lot sizes (where $x$ is the amount of a custom-made product obtained from a vendor who requires a minimum order of $a$ to justify the setup cost of the order).&lt;br /&gt;&lt;br /&gt;The variable $x$ is known in math programming jargon as &lt;i&gt;semicontinuous&lt;/i&gt;.&amp;nbsp; For whatever reason, the term is not well publicized; I taught a graduate course on integer programming for years without coming across it.&amp;nbsp; Some solvers can model these variables directly.&amp;nbsp; For instance, the C++ and Java APIs for CPLEX contain a class named IloSemiContVar.&amp;nbsp; I'm not sure which other solvers directly support semicontinuous variables. For solvers that do not recognize semicontinuous variables, there is a generic formulation.&amp;nbsp; You introduce a binary variable $y$ that will be 1 if $x$ is nonzero and 0 if $x$ is zero, and you add the contraints $x\ge ay$ and $x\le by$.&lt;br /&gt;&lt;br /&gt;AMPL allows you to define a semicontinuous variable without explicitly adding constraints. Our example could be written in AMPL as&lt;style type="text/css"&gt;&lt;!--pre.hl { color:#000000; background-color:#ffffff; font-size:10pt; font-family:'Courier New';}.hl.num { color:#2928ff; }.hl.esc { color:#ff00ff; }.hl.str { color:#ff0000; }.hl.dstr { color:#818100; }.hl.slc { color:#838183; font-style:italic; }.hl.com { color:#838183; font-style:italic; }.hl.dir { color:#008200; }.hl.sym { color:#000000; }.hl.line { color:#555555; }.hl.mark { background-color:#ffffbb;}.hl.kwa { color:#000000; font-weight:bold; }.hl.kwb { color:#830000; }.hl.kwc { color:#000000; font-weight:bold; }.hl.kwd { color:#010181; }//--&gt;&lt;/style&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;span class="hl kwa"&gt;param&lt;/span&gt; a &lt;span class="hl sym"&gt;&amp;gt;&lt;/span&gt; &lt;span class="hl num"&gt;0&lt;/span&gt;&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;param&lt;/span&gt; b &lt;span class="hl sym"&gt;&amp;gt;&lt;/span&gt; a&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;var&lt;/span&gt; x &lt;span class="hl kwa"&gt;in&lt;/span&gt; &lt;span class="hl sym"&gt;{&lt;/span&gt;&lt;span class="hl num"&gt;0&lt;/span&gt;&lt;span class="hl sym"&gt;}&lt;/span&gt; &lt;span class="hl kwa"&gt;union interval&lt;/span&gt;&lt;span class="hl sym"&gt;[&lt;/span&gt;a&lt;span class="hl sym"&gt;,&lt;/span&gt; b&lt;span class="hl sym"&gt;];&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;Currently, AMPL converts that into the pair of constraints mentioned above, even if the chosen solver is CPLEX.&amp;nbsp; Whether that will change in the future I do not know.&lt;br /&gt;&lt;br /&gt;One potential virtue of directly modelling semicontinuous variables is that it may lead to a more parsimonious formulation.&amp;nbsp; If the solver understands semicontinuous variables, it can modify the branching logic to separate nodes based on $x=0$ versus $x\ge a$ without having to add the binary variable $y$ and the extra constraints.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-5608852419371594924?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/5608852419371594924/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/03/semicontinuous-variables.html#comment-form' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/5608852419371594924'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/5608852419371594924'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/03/semicontinuous-variables.html' title='Semicontinuous Variables'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-725099312486895386</id><published>2011-03-16T20:00:00.000-04:00</published><updated>2011-03-16T20:00:20.141-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='math programming'/><category scheme='http://www.blogger.com/atom/ns#' term='operations research'/><category scheme='http://www.blogger.com/atom/ns#' term='applications'/><title type='text'>Forming Competitive Teams</title><content type='html'>This post is motivated by the March INFORMS blog challenge: &lt;a href="http://www.informs.org/About-INFORMS/News-Room/INFORMS-Blog/Feb-Blog-Challenge-Results-O.R.-and-Love-March-s-Blog-Challenge-O.R.-and-Sports" linkindex="164"&gt;O.R. and Sports&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;A couple or so years ago, someone contacted me about a model to assign children to sports teams.&amp;nbsp; My correspondent volunteered for a youth recreation league in his home town.&amp;nbsp; Two things are significant in that sentence.&amp;nbsp; The first is "volunteered", which comes from the Latin phrase meaning "budget = zero".&amp;nbsp; So whatever solution we came up with had to be cost-free.&amp;nbsp; The second is "youth".&amp;nbsp; In recreational sports leagues (at least for the youngest competitors), the tendency is for the parents to enroll their children in a league, rather than a specific team.&amp;nbsp; The league then has to form rosters, and the goal is not to produce winners (which would imply losers as well), but to form teams that are as close to competitive parity as possible.&lt;br /&gt;&lt;br /&gt;The approach taken by this league was to try to get the average (mean) value of various attributes as close to constant across teams as possible, subject to some constraints (minimum and maximum team sizes, for instance).&amp;nbsp; For qualitative attributes, such as gender, we can treat this as averaging indicator variables (1=girl, 0=boy or 1=experienced, 0=inexperienced).&amp;nbsp; So far, this looks like a modified version of the Hitchcock (transportation) problem, with kids as unit-supply "sources" and teams as "sinks".&amp;nbsp; The modifications include some additional constraints (a utilized "sink" has to contain at least enough players to field a full team) and a rather funky (and, as it turns out, nonlinear) objective function.&amp;nbsp; The nonlinearity occurs because attribute averages involve dividing by team size, which is not constant.&lt;br /&gt;&lt;br /&gt;Anyone who has designed a model for a real-world (not textbook) problem is probably painfully aware that the problem you are initially asked to model winds up not being the problem you actually have to model.&amp;nbsp; Sure enough, additional wrinkles creep in.&amp;nbsp; Parents with twins want/need to have the kids on the same team (to avoid car-pool nightmares).&amp;nbsp; Some kids may need to be separated (to avoid fights).&amp;nbsp; Some kids have parents who volunteer (that word again) to be assistant coaches, but only for the team their kid is on; there are not enough assistant coaches to go around, so we really don't want two on the same team, which means separating the kids with volunteer parents.&amp;nbsp; And so on.&lt;br /&gt;&lt;br /&gt;I won't go into mind-numbing details (I'll save that for students that can't outrun me :-)), but the code I ended up writing (called &lt;a href="http://paritybuilder.sourceforge.net/" linkindex="165"&gt;Parity Builder&lt;/a&gt;) is available open-source.&amp;nbsp; All it requires for infrastructure is Sun Java (1.6 or higher), and it comes with a tutorial.&lt;br /&gt;&lt;br /&gt;One last point, which I find interesting.&amp;nbsp; One of my colleagues in organizational behaviour (the "OB world" in the blog title) pointed me to some literature alleging that competitive performance may depend more on the within-team variance of certain attributes than the mean.&amp;nbsp; If true (and if it applies to any of the attributes used by the recreational league), perhaps the approach we took does not really optimize balance.&amp;nbsp; On the other hand, it almost surely optimizes the &lt;i&gt;appearance&lt;/i&gt; of balance, and the true objective function was probably "minimize parental bitching".&amp;nbsp; So maybe we're good after all.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-725099312486895386?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/725099312486895386/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/03/forming-competitive-teams.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/725099312486895386'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/725099312486895386'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/03/forming-competitive-teams.html' title='Forming Competitive Teams'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-4020138184666292079</id><published>2011-03-13T18:15:00.000-04:00</published><updated>2011-03-13T18:15:49.974-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='AMPL'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>Random Sampling in AMPL</title><content type='html'>This came up on the AMPL user group; I figured I'd "double dip" and post an edited version of my solution here.&amp;nbsp; The question was how to randomly sample without replacement in AMPL.&amp;nbsp; The code below shows one way.&lt;br /&gt;&lt;style type="text/css"&gt;&lt;!--body.hl { background-color:#ffffff; }pre.hl { color:#000000; background-color:#ffffff; font-size:10pt; font-family:'Courier New';}.hl.num { color:#2928ff; }.hl.esc { color:#ff00ff; }.hl.str { color:#ff0000; }.hl.dstr { color:#818100; }.hl.slc { color:#838183; font-style:italic; }.hl.com { color:#838183; font-style:italic; }.hl.dir { color:#008200; }.hl.sym { color:#000000; }.hl.line { color:#555555; }.hl.mark { background-color:#ffffbb;}.hl.kwa { color:#000000; font-weight:bold; }.hl.kwb { color:#830000; }.hl.kwc { color:#000000; font-weight:bold; }.hl.kwd { color:#010181; }//--&gt;&lt;/style&gt;&lt;br /&gt;&lt;pre class="hl"&gt;&lt;span class="hl slc"&gt;#&lt;/span&gt;&lt;br /&gt;&lt;span class="hl slc"&gt;# randomly sample items from a set, with or without replacement&lt;/span&gt;&lt;br /&gt;&lt;span class="hl slc"&gt;#&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;set&lt;/span&gt; UNIVERSE &lt;span class="hl kwa"&gt;ordered&lt;/span&gt;&lt;span class="hl sym"&gt;;&lt;/span&gt;  &lt;span class="hl slc"&gt;# set of items to sample -- must be ordered&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;param&lt;/span&gt; ssize &lt;span class="hl kwa"&gt;integer&lt;/span&gt; &lt;span class="hl sym"&gt;&amp;gt;&lt;/span&gt; &lt;span class="hl num"&gt;0&lt;/span&gt;&lt;span class="hl sym"&gt;;&lt;/span&gt;  &lt;span class="hl slc"&gt;# sample size desired&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;param&lt;/span&gt; sample &lt;span class="hl sym"&gt;{&lt;/span&gt;&lt;span class="hl num"&gt;1&lt;/span&gt;..ssize&lt;span class="hl sym"&gt;}&lt;/span&gt; &lt;span class="hl kwa"&gt;symbolic&lt;/span&gt;&lt;span class="hl sym"&gt;;&lt;/span&gt;  &lt;span class="hl slc"&gt;# will hold generated sample&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;data&lt;/span&gt;&lt;span class="hl sym"&gt;;&lt;/span&gt; &lt;span class="hl slc"&gt;# data below is just for demonstration purposes&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;set&lt;/span&gt; UNIVERSE &lt;span class="hl sym"&gt;:=&lt;/span&gt; &lt;span class="hl str"&gt;'cat'&lt;/span&gt;&lt;span class="hl sym"&gt;,&lt;/span&gt; &lt;span class="hl str"&gt;'dog'&lt;/span&gt;&lt;span class="hl sym"&gt;,&lt;/span&gt; &lt;span class="hl str"&gt;'bird'&lt;/span&gt;&lt;span class="hl sym"&gt;,&lt;/span&gt; &lt;span class="hl str"&gt;'fish'&lt;/span&gt;&lt;span class="hl sym"&gt;,&lt;/span&gt; &lt;span class="hl str"&gt;'turtle'&lt;/span&gt;&lt;span class="hl sym"&gt;,&lt;/span&gt; &lt;span class="hl str"&gt;'snake'&lt;/span&gt;&lt;span class="hl sym"&gt;,&lt;/span&gt; &lt;span class="hl str"&gt;'frog'&lt;/span&gt;&lt;span class="hl sym"&gt;,&lt;/span&gt; &lt;span class="hl str"&gt;'rock'&lt;/span&gt;&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;param&lt;/span&gt; ssize &lt;span class="hl sym"&gt;:=&lt;/span&gt; &lt;span class="hl num"&gt;4&lt;/span&gt;&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;model&lt;/span&gt;&lt;span class="hl sym"&gt;;&lt;/span&gt;  &lt;span class="hl slc"&gt;# back to the code&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;let&lt;/span&gt; ssize &lt;span class="hl sym"&gt;:=&lt;/span&gt; &lt;span class="hl kwa"&gt;min&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;ssize&lt;span class="hl sym"&gt;,&lt;/span&gt; &lt;span class="hl kwb"&gt;card&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;UNIVERSE&lt;span class="hl sym"&gt;));&lt;/span&gt;  &lt;span class="hl slc"&gt;# omit if sampling with replacement&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;param&lt;/span&gt; item &lt;span class="hl kwa"&gt;symbolic&lt;/span&gt;&lt;span class="hl sym"&gt;;&lt;/span&gt;  &lt;span class="hl slc"&gt;# dummy parameter to hold each selection&lt;/span&gt;&lt;br /&gt;for &lt;span class="hl sym"&gt;{&lt;/span&gt;i &lt;span class="hl kwa"&gt;in&lt;/span&gt; &lt;span class="hl num"&gt;1&lt;/span&gt;..ssize&lt;span class="hl sym"&gt;} {&lt;/span&gt;&lt;br /&gt;  &lt;span class="hl kwa"&gt;let&lt;/span&gt; item &lt;span class="hl sym"&gt;:=&lt;/span&gt; &lt;span class="hl kwb"&gt;member&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwb"&gt;ceil&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl kwb"&gt;Uniform&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;&lt;span class="hl num"&gt;0&lt;/span&gt;&lt;span class="hl sym"&gt;,&lt;/span&gt; &lt;span class="hl kwb"&gt;card&lt;/span&gt;&lt;span class="hl sym"&gt;(&lt;/span&gt;UNIVERSE&lt;span class="hl sym"&gt;))),&lt;/span&gt; UNIVERSE&lt;span class="hl sym"&gt;);&lt;/span&gt;&lt;br /&gt;  &lt;span class="hl kwa"&gt;let&lt;/span&gt; sample&lt;span class="hl sym"&gt;[&lt;/span&gt;i&lt;span class="hl sym"&gt;] :=&lt;/span&gt; item&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class="hl kwa"&gt;let&lt;/span&gt; UNIVERSE &lt;span class="hl sym"&gt;:=&lt;/span&gt; UNIVERSE &lt;span class="hl kwa"&gt;diff&lt;/span&gt; &lt;span class="hl sym"&gt;{&lt;/span&gt;item&lt;span class="hl sym"&gt;};&lt;/span&gt;  &lt;span class="hl slc"&gt;# omit if sampling with replacement&lt;/span&gt;&lt;br /&gt;&lt;span class="hl sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;display&lt;/span&gt; sample&lt;span class="hl sym"&gt;;&lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&lt;br /&gt;I might mention a few things about the code:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;I used symbolic data in the example. If you are sampling from a set of numbers, you can omit the two instances of the keyword &lt;b&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;symbolic&lt;/span&gt;&lt;/b&gt;.&lt;/li&gt;&lt;li&gt;If you want to sample with replacement, there are two lines (marked by comments) that you need to omit.&lt;/li&gt;&lt;li&gt;The code puts the sample in a (vector) parameter.&amp;nbsp; If you are sampling without replacement, an alternative is to put the code into a set.&amp;nbsp; Define the set with a default value of &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;{}&lt;/span&gt;, and use the &lt;b&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;union&lt;/span&gt;&lt;/b&gt; operator with second argument &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;{item}&lt;/span&gt; to add the item to the sample set inside the loop.&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-4020138184666292079?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/4020138184666292079/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/03/random-sampling-in-ampl.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/4020138184666292079'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/4020138184666292079'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/03/random-sampling-in-ampl.html' title='Random Sampling in AMPL'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-6689107536049841987</id><published>2011-03-10T12:23:00.000-05:00</published><updated>2011-03-10T12:23:38.722-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><category scheme='http://www.blogger.com/atom/ns#' term='R'/><title type='text'>Configuring R for Java</title><content type='html'>I have two &lt;a href="http://www.r-project.org/" linkindex="164"&gt;R&lt;/a&gt; packages that have consistently refused to be updated: rgl (which I believe is used for 3D visualization) and rJava (an API for accessing Java from R).&amp;nbsp; I probably don't really need either one, but at least one R GUI (&lt;a href="http://www.rforge.net/JGR/" linkindex="165"&gt;JGR&lt;/a&gt;), needs rJava.&amp;nbsp; I must have figured out (and then forgotten) the configuration magic that allows rJava to update, because the update.packages() command on my office PC (Linux Mint) has not problem with it ... but update.packages() on my laptop (also Linux Mint) kept running into an error.&lt;br /&gt;&lt;br /&gt;So here is the solution (which I found &lt;a href="http://ubuntuforums.org/showthread.php?t=1504920" linkindex="166"&gt;here&lt;/a&gt;), just in case I need it again.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Run &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;sudo update-alternatives --config java&lt;/span&gt; (in a terminal) and pick Sun Java as the default. (I thought I'd already done that, but apparently not.)&lt;/li&gt;&lt;li&gt;Add &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;export JAVA_HOME=/usr/lib/jvm/java-6-openjdk/jre&lt;/span&gt; to .bashrc (again, thought I'd done that but hadn't).&lt;/li&gt;&lt;li&gt;Run &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;sudo R CMD javareconf&lt;/span&gt; in a terminal.&amp;nbsp; (That I had done -- multiple times, with no error messages -- but apparently with the wrong configuration in place.)&lt;/li&gt;&lt;li&gt;Run R as root and update the package.&lt;/li&gt;&lt;/ul&gt;I hope that, the next time this comes up, I at least remember I put the necessary steps here. &lt;br /&gt;&lt;ul&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-6689107536049841987?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/6689107536049841987/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/03/configuring-r-for-java.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/6689107536049841987'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/6689107536049841987'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/03/configuring-r-for-java.html' title='Configuring R for Java'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-2618027847349854185</id><published>2011-03-09T16:12:00.000-05:00</published><updated>2011-03-09T16:12:32.844-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WIndows'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>Honey, I Shrank the Registry!</title><content type='html'>I have one rather superannuated PC running Windows XP, which I refuse to upgrade to Win 7 for various reasons (not least being that I suspect it would run at the speed of glacial drift, if at all).  Lately, it's been complaining at boot that the system registry is too large, and that future requests for registry space will be denied (and the offending programs no doubt will be executed).&lt;br /&gt;&lt;br /&gt;So I did a little searching and found a pair of free programs by a programmer in Germany named Lars Hederer: &lt;a href="http://www.larshederer.homepage.t-online.de/erunt/" linkindex="158"&gt;ERUNT and NTREGOPT&lt;/a&gt;.&amp;nbsp; The former backs up and restores the registry (not a bad idea when you plan to perform surgery on it), while the latter compresses it.&amp;nbsp; In my case, NTREGOPT reduced the registry size by &lt;i&gt;75% &lt;/i&gt;(!!), from around a quarter GB to something in the 70 MB range.&lt;br /&gt;&lt;br /&gt;Hmm ... wonder if it could reduce &lt;i&gt;my&lt;/i&gt; size (weight please; advancing age is already attacking my height) (and preferably not 75%).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-2618027847349854185?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/2618027847349854185/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/03/honey-i-shrank-registry.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/2618027847349854185'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/2618027847349854185'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/03/honey-i-shrank-registry.html' title='Honey, I Shrank the Registry!'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-2603134788671483010</id><published>2011-03-08T18:17:00.000-05:00</published><updated>2011-03-08T18:17:09.582-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='statistics'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><category scheme='http://www.blogger.com/atom/ns#' term='R'/><title type='text'>A Vote for VIFs</title><content type='html'>Shown below is output from a linear multiple regression model run in &lt;a href="http://www.minitab.com/" linkindex="163"&gt;Minitab&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;Predictor   Coef SE Coef     T     P&lt;br /&gt;Constant  2.4765  0.7055  3.51 0.001&lt;br /&gt;DIAMETER -0.7880  0.1826 -4.31 0.000&lt;br /&gt;WEIGHT   0.44314 0.03633 12.20 0.000&amp;nbsp;&lt;/pre&gt;&lt;br /&gt;Other statistics programs I've used, or whose output I've seen, may format things differently, but they generally stick to the same fundamental ingredients: the estimated coefficient value; the standard error of that coefficient; the T-ratio; and the p-value of that ratio.&amp;nbsp; Note that there is a certain redundancy here.&amp;nbsp; If I know any two of the first three items, I can figure out the third rather easily.&amp;nbsp; If I know the T-ratio (and the degrees of freedom), I can&amp;nbsp;get the p-value.&amp;nbsp; (Going the other direction is subject to accuracy problems, since small p-values tend to be truncated).&lt;br /&gt;&lt;br /&gt;Redundancy is not really the issue, though.&amp;nbsp; What do we care about in that output?&amp;nbsp; Certainly we want the coefficient, and quite possibly we want the standard error (if we are going to hand compute confidence intervals, for instance).&amp;nbsp; If we care about statistical significance (and we generally should), we want to see the p-value.&amp;nbsp; Since the sole reason for computing the T-ratio is to get to the p-value, I consider it a waste of space.&amp;nbsp; I suspect it is a holdover from bygone days when software did not compute p-values, and users had to look up the T-ratio in tables.&lt;br /&gt;&lt;br /&gt;Meanwhile, there is something missing from the standard output that I think really should be there:&amp;nbsp; the &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/Variance_inflation_factor" linkindex="164"&gt;variance inflation factors&lt;/a&gt; (VIFs).&amp;nbsp; VIFs give you a quick diagnostic check of whether you need be concerned about multicollinearity.&amp;nbsp; In a doctoral seminar on regression that I've taught in recent years, we read papers from the business and social science literature in which regression models are presented (and used to test hypotheses).&amp;nbsp; The vast majority of these papers contain no indication that the authors checked for multicollinearity.&amp;nbsp; In a few cases, the authors state that because the correlation matrix of the predictors exhibits no large pairwise correlations, multicollinearity is not a concern.&amp;nbsp; This sense of security is entirely unfounded when there are more than two predictors, as multicollinearity can occur without any large pairwise correlations.&lt;br /&gt;&lt;br /&gt;Perhaps if we saw VIFs every time we ran a multiple regression, we would get in the habit of spot-checking for multicollinearity.&amp;nbsp; Most software will produce VIFs, but you may have to dig to find out how to get them.&amp;nbsp; (In &lt;a href="http://www.r-project.org/" linkindex="165"&gt;R&lt;/a&gt;, for instance, I have to load the "car" library to find a VIF function.)&amp;nbsp; If software vendors are concerned about real estate on the screen/page, I nominate the T-ratio column as something we can sacrifice to make room for VIFs.&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-2603134788671483010?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/2603134788671483010/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/03/vote-for-vifs.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/2603134788671483010'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/2603134788671483010'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/03/vote-for-vifs.html' title='A Vote for VIFs'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-3767969452652830783</id><published>2011-03-06T16:56:00.003-05:00</published><updated>2011-03-30T11:18:35.210-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>Syntax Highlighting</title><content type='html'>I just burned about an hour of my life going back and retrofitting syntax highlighting to some of my old posts.  The fault lies entirely with Bo Jensen, who first suggested it.&amp;nbsp; Some of the code to be highlighted (including what triggered the suggestion) is in R, some in Java, a bit in Bash.&amp;nbsp; (Thank goodness I got over &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/APL_%28programming_language%29" linkindex="19"&gt;APL&lt;/a&gt; decades ago; that would be a font nightmare.)&amp;nbsp; Obviously, for blogging purposes, I need a highlighter that generates HTML, not just a syntax highlighting code editor.&amp;nbsp; Given my rather modest output rate, an online highlighter would be just fine (no need to install it locally).&amp;nbsp; Finally, and this turns out to disqualify several of the available R highlighters, I like having function names highlighted, not just keywords.&lt;br /&gt;&lt;br /&gt;So I scrounged around the 'Net a bit and found two very useful sites:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://quickhighlighter.com/" linkindex="20"&gt;Quick Highlighter&lt;/a&gt;, which handles most of my needs other than R; and&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.inside-r.org/pretty-r/tool" linkindex="21"&gt;Pretty R&lt;/a&gt;, which does a great job highlighting R code.&lt;/li&gt;&lt;/ul&gt;Thanks to both sites for making my life easier. &lt;br /&gt;&lt;br /&gt;One side note:&amp;nbsp; This morning, by sheer coincidence, I received a couple of tweets from &lt;a href="http://twitter.com/hakankj" linkindex="22"&gt;Hakan Kjellerstrand&lt;/a&gt; indicating that he was experimenting with a GPL version of the &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/J_programming_language" linkindex="23"&gt;J programming language&lt;/a&gt;.&amp;nbsp; Curious, I took a look at some code samples on the &lt;a href="http://www.jsoftware.com/index.html" linkindex="24"&gt;Jsoftware&lt;/a&gt; site and started having flashbacks to APL.&amp;nbsp; While perusing the Wikipedia page for APL (linked above), I discovered that the flashback was not just random:&amp;nbsp; Kenneth Iverson, the designer of APL, was also a designer of J.&lt;br /&gt;&lt;br /&gt;I need to stare at some FORTRAN for a while to clear my head.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Update&lt;/b&gt; (9 March 2011):&amp;nbsp; It's official -- I'm stupid. On my Windows box, I've been using &lt;a href="http://notepad-plus-plus.org/" linkindex="25"&gt;Notepad++&lt;/a&gt; for some time now (not so much for programming as for general editing of text files).&amp;nbsp; As it turns out, Notepad++ does syntax highlighting for a variety of languages, including both R and Java, and can export to an HTML file.&lt;br /&gt;&lt;br /&gt;Fine, but I do most of work on Linux Mint these days, and Notepad++ is a Windows-only program.&amp;nbsp; It's based on &lt;a href="http://www.scintilla.org/" linkindex="26"&gt;Scintilla&lt;/a&gt;, though, as is &lt;a href="http://www.scintilla.org/SciTE.html" linkindex="27"&gt;SciTE&lt;/a&gt;, which I use for similar purposes on my Mint PC and laptop.&amp;nbsp; (SciTE is also available for Windows, but I'm already using NP++ and, as we say here, if it ain't broke, don't fix it.)&amp;nbsp; SciTE does Java highlighting out of the box, and with a small tweak, it does R syntax highlighting.&amp;nbsp; It also exports to HTML.&amp;nbsp; (The tweak: run SciTE via sudo, open the global options file, scroll down near the bottom and uncomment "import r", then save.)&lt;br /&gt;&lt;br /&gt;So I'm set for highlighting with tools I'm already using.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Update&lt;/b&gt; (13 March 2011):&amp;nbsp; I discovered a Linux command line utility named (shockingly) &lt;a href="http://linux.die.net/man/1/highlight" linkindex="28"&gt;highlight&lt;/a&gt;.&amp;nbsp; It converts code files in a variety of languages (including AMPL, which I needed today, but sadly not including R) to a variety of output formats (notably HTML, but also LaTeX). The utility is available from the Ubuntu universe repository, so you can load it via Synaptic without having to add a new source.&lt;br /&gt;&lt;br /&gt;Of course, life can't be quite that simple.&amp;nbsp; The executable is installed as &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;/usr/bin/highlight&lt;/span&gt;.&amp;nbsp; I already have a program of the same name at &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;/usr/local/bin/highlight&lt;/span&gt;.&amp;nbsp; I don't know where it came from or what it does, but it seems to expect input from &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;stdin&lt;/span&gt; regardless of any command line switches.&amp;nbsp; Since it's in the local bin directory, it loads ahead of the one I want (grrr).&amp;nbsp; Not knowing whether it's part of a larger package, I'm reluctant to nuke it.&amp;nbsp; So I've added &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;alias highlight=/usr/bin/highlight&lt;/span&gt; to my &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;.bashrc&lt;/span&gt; file, which gives me a safe (I think) workaround.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-3767969452652830783?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/3767969452652830783/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/03/syntax-highlighting.html#comment-form' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/3767969452652830783'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/3767969452652830783'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/03/syntax-highlighting.html' title='Syntax Highlighting'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-7604724627984078885</id><published>2011-03-01T13:32:00.000-05:00</published><updated>2011-03-01T13:32:49.567-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mathematics'/><category scheme='http://www.blogger.com/atom/ns#' term='science'/><title type='text'>Math and Science Can Be Sexy</title><content type='html'>I just tripped over the following facts (one of which I already knew):&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Hedy_Lamarr" linkindex="317"&gt;Hedy Lamarr&lt;/a&gt;, vintage Hollywood hottie, co-invented &lt;a href="http://en.wikipedia.org/wiki/Frequency_hopping" linkindex="318"&gt;frequency hopping&lt;/a&gt;, used by cell phones today.&lt;/li&gt;&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Danica_mckellar" linkindex="319"&gt;Danica McKellar&lt;/a&gt;, teen age TV star (and successful actress since), is co-author of the Chayes–McKellar–Winn theorem (as an &lt;i&gt;undergraduate&lt;/i&gt; math major).&amp;nbsp; (This one I knew.)&lt;/li&gt;&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Mayim_Bialik" linkindex="320"&gt;Mayim Bialik&lt;/a&gt;, who as a teen had the title role in the TV series "Blossom" and now plays a neurobiologist on "The Big Bang Theory", actually has a Ph.D. in neurobiology.&lt;/li&gt;&lt;/ul&gt;Now we just need some sexy male mathematicians and scientists (besides me, that is) to balance the list. &lt;br /&gt;&lt;ul&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-7604724627984078885?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/7604724627984078885/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/03/math-and-science-can-be-sexy.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/7604724627984078885'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/7604724627984078885'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/03/math-and-science-can-be-sexy.html' title='Math and Science Can Be Sexy'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-1226301386863181368</id><published>2011-02-27T19:06:00.003-05:00</published><updated>2011-03-06T14:37:48.279-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='statistics'/><category scheme='http://www.blogger.com/atom/ns#' term='R'/><title type='text'>Stepwise Regression in R</title><content type='html'>Let me start with a disclaimer:&amp;nbsp; I am not an advocate of stepwise regression.&amp;nbsp; I teach it in a doctoral seminar (because it's in the book, and because the students may encounter it reading papers), but I try to point out to them some of its limitations.&amp;nbsp; If you want to read some interesting discussions on the issues with stepwise, search the USENET group &lt;a href="https://groups.google.com/forum/#%21forum/sci.stat.math" linkindex="83"&gt;sci.stat.math&lt;/a&gt; for references to stepwise.&amp;nbsp; (If you are a proponent of stepwise, I suggest that you don flame retardant underwear first.)&lt;br /&gt;&lt;br /&gt;Since I teach stepwise in my seminar, I would like to demonstrate it in R (not to mention some of my students are learning R while doing their homework, which includes a stepwise problem).&amp;nbsp; The catch is that R seems to lack any library routines to do stepwise as it is normally taught.&amp;nbsp; There is a function (leaps::regsubsets) that does both best subsets regression and a form of stepwise regression, but it uses AIC or BIC to select models.&amp;nbsp; That's fine for best subsets, but stepwise (at least as I've seen it in every book or paper where I've encountered it) uses nested model F tests to make decisions.&amp;nbsp; Again, if you search around, you can find some (fairly old) posts on help forums by people searching (fruitlessly, it appears) for a stepwise implementation in R.&lt;br /&gt;&lt;br /&gt;So I finally forced myself to write a stepwise function for R.&amp;nbsp; My knowledge of R coding is very, very limited, so I made no attempt to tack on very many bells and whistles, let alone make it a library package.&amp;nbsp; Unlike most R routines, it does not create an object; it just merrily writes to the standard output stream.&amp;nbsp; There are a number of limitations (expressed in the comments), and I've only tested it on a few data sets.&amp;nbsp; All that said, I'm going to post it below, in case someone else is desperate to do conventional stepwise regression in R.&lt;br /&gt;&lt;br /&gt;=== code follows ===&lt;br /&gt;&lt;div style="overflow:auto;"&gt;&lt;div class="geshifilter"&gt;&lt;pre class="r geshifilter-R" style="font-family:monospace;"&gt;    &lt;span style="color: #666666; font-style: italic;"&gt;#&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #666666; font-style: italic;"&gt;# This is an R function to perform stepwise regression based on a &amp;quot;nested model&amp;quot; F test for inclusion/exclusion&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #666666; font-style: italic;"&gt;# of a predictor.  To keep it simple, I made no provision for forcing certain variables to be included in&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #666666; font-style: italic;"&gt;# all models, did not allow for specification of a data frame, and skipped some consistency checks (such as whether&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #666666; font-style: italic;"&gt;# the initial model is a subset of the full model).&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #666666; font-style: italic;"&gt;#&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #666666; font-style: italic;"&gt;# One other note: since the code uses R's drop1 and add1 functions, it respects hierarchy in models. That is,&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #666666; font-style: italic;"&gt;# regardless of p values, it will not attempt to drop a term while retaining a higher order interaction&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #666666; font-style: italic;"&gt;# involving that term, nor will it add an interaction term if the lower order components are not all present.&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #666666; font-style: italic;"&gt;# (You can of course defeat this by putting interactions into new variables and feeding it what looks like&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #666666; font-style: italic;"&gt;# a first-order model.)&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #666666; font-style: italic;"&gt;#&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #666666; font-style: italic;"&gt;# Consider this to be &amp;quot;beta&amp;quot; code (and feel free to improve it).  I've done very limited testing on it.&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #666666; font-style: italic;"&gt;#&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #666666; font-style: italic;"&gt;# Author: Paul A. Rubin (rubin@msu.edu)&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #666666; font-style: italic;"&gt;#&lt;/span&gt;&lt;br /&gt;    &lt;a href="http://inside-r.org/packages/cran/stepwise"&gt;&lt;span style=""&gt;stepwise&lt;/span&gt;&lt;/a&gt; &lt;span style=""&gt;&amp;lt;-&lt;/span&gt; &lt;a href="http://inside-r.org/r-doc/base/function"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;function&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;full.model&lt;span style="color: #339933;"&gt;,&lt;/span&gt; initial.model&lt;span style="color: #339933;"&gt;,&lt;/span&gt; alpha.to.enter&lt;span style="color: #339933;"&gt;,&lt;/span&gt; alpha.to.leave&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;      &lt;span style="color: #666666; font-style: italic;"&gt;# full.model is the model containing all possible terms&lt;/span&gt;&lt;br /&gt;      &lt;span style="color: #666666; font-style: italic;"&gt;# initial.model is the first model to consider&lt;/span&gt;&lt;br /&gt;      &lt;span style="color: #666666; font-style: italic;"&gt;# alpha.to.enter is the significance level above which a variable may enter the model&lt;/span&gt;&lt;br /&gt;      &lt;span style="color: #666666; font-style: italic;"&gt;# alpha.to.leave is the significance level below which a variable may be deleted from the model&lt;/span&gt;&lt;br /&gt;      &lt;span style="color: #666666; font-style: italic;"&gt;# (Useful things for someone to add: specification of a data frame; a list of variables that must be included)&lt;/span&gt;&lt;br /&gt;      full &lt;span style=""&gt;&amp;lt;-&lt;/span&gt; &lt;a href="http://inside-r.org/r-doc/stats/lm"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;lm&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;full.model&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;  &lt;span style="color: #666666; font-style: italic;"&gt;# fit the full model&lt;/span&gt;&lt;br /&gt;      msef &lt;span style=""&gt;&amp;lt;-&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;a href="http://inside-r.org/r-doc/base/summary"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;summary&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;full&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style=""&gt;$&lt;/span&gt;sigma&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style=""&gt;^&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;2&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;  &lt;span style="color: #666666; font-style: italic;"&gt;# MSE of full model&lt;/span&gt;&lt;br /&gt;      n &lt;span style=""&gt;&amp;lt;-&lt;/span&gt; &lt;a href="http://inside-r.org/r-doc/base/length"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;length&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;full&lt;span style=""&gt;$&lt;/span&gt;residuals&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;  &lt;span style="color: #666666; font-style: italic;"&gt;# sample size&lt;/span&gt;&lt;br /&gt;      allvars &lt;span style=""&gt;&amp;lt;-&lt;/span&gt; &lt;a href="http://inside-r.org/r-doc/base/attr"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;attr&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;full&lt;span style=""&gt;$&lt;/span&gt;terms&lt;span style="color: #339933;"&gt;,&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;&amp;quot;predvars&amp;quot;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;  &lt;span style="color: #666666; font-style: italic;"&gt;# this gets a list of all predictor variables&lt;/span&gt;&lt;br /&gt;      current &lt;span style=""&gt;&amp;lt;-&lt;/span&gt; &lt;a href="http://inside-r.org/r-doc/stats/lm"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;lm&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;initial.model&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;  &lt;span style="color: #666666; font-style: italic;"&gt;# this is the current model&lt;/span&gt;&lt;br /&gt;      &lt;span style="color: #000000; font-weight: bold;"&gt;while&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;TRUE&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;  &lt;span style="color: #666666; font-style: italic;"&gt;# process each model until we break out of the loop&lt;/span&gt;&lt;br /&gt;        temp &lt;span style=""&gt;&amp;lt;-&lt;/span&gt; &lt;a href="http://inside-r.org/r-doc/base/summary"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;summary&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;current&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;  &lt;span style="color: #666666; font-style: italic;"&gt;# summary output for the current model&lt;/span&gt;&lt;br /&gt;        rnames &lt;span style=""&gt;&amp;lt;-&lt;/span&gt; &lt;a href="http://inside-r.org/r-doc/base/rownames"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;rownames&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;temp&lt;span style=""&gt;$&lt;/span&gt;coefficients&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;  &lt;span style="color: #666666; font-style: italic;"&gt;# list of terms in the current model&lt;/span&gt;&lt;br /&gt;        &lt;a href="http://inside-r.org/r-doc/base/print"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;print&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;temp&lt;span style=""&gt;$&lt;/span&gt;coefficients&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;  &lt;span style="color: #666666; font-style: italic;"&gt;# write the model description&lt;/span&gt;&lt;br /&gt;        p &lt;span style=""&gt;&amp;lt;-&lt;/span&gt; &lt;a href="http://inside-r.org/r-doc/base/dim"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;dim&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;temp&lt;span style=""&gt;$&lt;/span&gt;coefficients&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#91;&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;1&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#93;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;  &lt;span style="color: #666666; font-style: italic;"&gt;# current model's size&lt;/span&gt;&lt;br /&gt;        mse &lt;span style=""&gt;&amp;lt;-&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;temp&lt;span style=""&gt;$&lt;/span&gt;sigma&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style=""&gt;^&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;2&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;  &lt;span style="color: #666666; font-style: italic;"&gt;# MSE for current model&lt;/span&gt;&lt;br /&gt;        cp &lt;span style=""&gt;&amp;lt;-&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;n&lt;span style=""&gt;-&lt;/span&gt;p&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style=""&gt;*&lt;/span&gt;mse&lt;span style=""&gt;/&lt;/span&gt;msef &lt;span style=""&gt;-&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;n&lt;span style=""&gt;-&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;2&lt;/span&gt;&lt;span style=""&gt;*&lt;/span&gt;p&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;  &lt;span style="color: #666666; font-style: italic;"&gt;# Mallow's cp&lt;/span&gt;&lt;br /&gt;        fit &lt;span style=""&gt;&amp;lt;-&lt;/span&gt; &lt;a href="http://inside-r.org/r-doc/base/sprintf"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;sprintf&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;quot;&lt;span style="color: #000099; font-weight: bold;"&gt;\n&lt;/span&gt;S = %f, R-sq = %f, R-sq(adj) = %f, C-p = %f&amp;quot;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;&lt;br /&gt;                       temp&lt;span style=""&gt;$&lt;/span&gt;sigma&lt;span style="color: #339933;"&gt;,&lt;/span&gt; temp&lt;span style=""&gt;$&lt;/span&gt;r.squared&lt;span style="color: #339933;"&gt;,&lt;/span&gt; temp&lt;span style=""&gt;$&lt;/span&gt;adj.r.squared&lt;span style="color: #339933;"&gt;,&lt;/span&gt; cp&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;&lt;br /&gt;        &lt;a href="http://inside-r.org/r-doc/base/write"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;write&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;fit&lt;span style="color: #339933;"&gt;,&lt;/span&gt; &lt;a href="http://inside-r.org/r-doc/base/file"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;file&lt;/span&gt;&lt;/a&gt;=&lt;span style="color: #0000ff;"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;  &lt;span style="color: #666666; font-style: italic;"&gt;# show the fit&lt;/span&gt;&lt;br /&gt;        &lt;a href="http://inside-r.org/r-doc/base/write"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;write&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;quot;=====&amp;quot;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt; &lt;a href="http://inside-r.org/r-doc/base/file"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;file&lt;/span&gt;&lt;/a&gt;=&lt;span style="color: #0000ff;"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;  &lt;span style="color: #666666; font-style: italic;"&gt;# print a separator&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;p &lt;span style=""&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #cc66cc;"&gt;1&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;  &lt;span style="color: #666666; font-style: italic;"&gt;# don't try to drop a term if only one is left&lt;/span&gt;&lt;br /&gt;          d &lt;span style=""&gt;&amp;lt;-&lt;/span&gt; &lt;a href="http://inside-r.org/r-doc/stats/drop1"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;drop1&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;current&lt;span style="color: #339933;"&gt;,&lt;/span&gt; test=&lt;span style="color: #0000ff;"&gt;&amp;quot;F&amp;quot;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;  &lt;span style="color: #666666; font-style: italic;"&gt;# looks for significance of terms based on F tests&lt;/span&gt;&lt;br /&gt;          &lt;a href="http://inside-r.org/r-doc/base/pmax"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;pmax&lt;/span&gt;&lt;/a&gt; &lt;span style=""&gt;&amp;lt;-&lt;/span&gt; &lt;a href="http://inside-r.org/r-doc/base/max"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;max&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;d&lt;span style="color: #009900;"&gt;&amp;#91;&lt;/span&gt;&lt;span style=""&gt;-&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;1&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;6&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#93;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;  &lt;span style="color: #666666; font-style: italic;"&gt;# maximum p-value of any term (have to skip the intercept to avoid an NA value)&lt;/span&gt;&lt;br /&gt;          &lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;a href="http://inside-r.org/r-doc/base/pmax"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;pmax&lt;/span&gt;&lt;/a&gt; &lt;span style=""&gt;&amp;gt;&lt;/span&gt; alpha.to.leave&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #666666; font-style: italic;"&gt;# we have a candidate for deletion&lt;/span&gt;&lt;br /&gt;            &lt;a href="http://inside-r.org/r-doc/stats/var"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;var&lt;/span&gt;&lt;/a&gt; &lt;span style=""&gt;&amp;lt;-&lt;/span&gt; &lt;a href="http://inside-r.org/r-doc/base/rownames"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;rownames&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;d&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#91;&lt;/span&gt;d&lt;span style="color: #009900;"&gt;&amp;#91;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;6&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#93;&lt;/span&gt; &lt;span style=""&gt;==&lt;/span&gt; &lt;a href="http://inside-r.org/r-doc/base/pmax"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;pmax&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#93;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;  &lt;span style="color: #666666; font-style: italic;"&gt;# name of variable to delete&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;a href="http://inside-r.org/r-doc/base/length"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;length&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;a href="http://inside-r.org/r-doc/stats/var"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;var&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style=""&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #cc66cc;"&gt;1&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;              &lt;span style="color: #666666; font-style: italic;"&gt;# if an intercept is present, it will be the first name in the list&lt;/span&gt;&lt;br /&gt;              &lt;span style="color: #666666; font-style: italic;"&gt;# there also could be ties for worst p-value&lt;/span&gt;&lt;br /&gt;              &lt;span style="color: #666666; font-style: italic;"&gt;# taking the second entry if there is more than one is a safe solution to both issues&lt;/span&gt;&lt;br /&gt;              &lt;a href="http://inside-r.org/r-doc/stats/var"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;var&lt;/span&gt;&lt;/a&gt; &lt;span style=""&gt;&amp;lt;-&lt;/span&gt; &lt;a href="http://inside-r.org/r-doc/stats/var"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;var&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#91;&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;2&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#93;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;            &lt;a href="http://inside-r.org/r-doc/base/write"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;write&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;a href="http://inside-r.org/r-doc/base/paste"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;paste&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;quot;--- Dropping&amp;quot;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt; &lt;a href="http://inside-r.org/r-doc/stats/var"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;var&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;&amp;quot;&lt;span style="color: #000099; font-weight: bold;"&gt;\n&lt;/span&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt; &lt;a href="http://inside-r.org/r-doc/base/file"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;file&lt;/span&gt;&lt;/a&gt;=&lt;span style="color: #0000ff;"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;  &lt;span style="color: #666666; font-style: italic;"&gt;# print out the variable to be dropped&lt;/span&gt;&lt;br /&gt;            f &lt;span style=""&gt;&amp;lt;-&lt;/span&gt; &lt;a href="http://inside-r.org/r-doc/stats/formula"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;formula&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;current&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;  &lt;span style="color: #666666; font-style: italic;"&gt;# current formula&lt;/span&gt;&lt;br /&gt;            f &lt;span style=""&gt;&amp;lt;-&lt;/span&gt; &lt;a href="http://inside-r.org/r-doc/stats/as.formula"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;as.formula&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;a href="http://inside-r.org/r-doc/base/paste"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;paste&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;f&lt;span style="color: #009900;"&gt;&amp;#91;&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;2&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#93;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;&amp;quot;~&amp;quot;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt; &lt;a href="http://inside-r.org/r-doc/base/paste"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;paste&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;f&lt;span style="color: #009900;"&gt;&amp;#91;&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;3&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#93;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt; &lt;a href="http://inside-r.org/r-doc/stats/var"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;var&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt; sep=&lt;span style="color: #0000ff;"&gt;&amp;quot; - &amp;quot;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;  &lt;span style="color: #666666; font-style: italic;"&gt;# modify the formula to drop the chosen variable (by subtracting it)&lt;/span&gt;&lt;br /&gt;            current &lt;span style=""&gt;&amp;lt;-&lt;/span&gt; &lt;a href="http://inside-r.org/r-doc/stats/lm"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;lm&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;f&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;  &lt;span style="color: #666666; font-style: italic;"&gt;# fit the modified model&lt;/span&gt;&lt;br /&gt;            next&lt;span style="color: #339933;"&gt;;&lt;/span&gt;  &lt;span style="color: #666666; font-style: italic;"&gt;# return to the top of the loop&lt;/span&gt;&lt;br /&gt;          &lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #666666; font-style: italic;"&gt;# if we get here, we failed to drop a term; try adding one&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #666666; font-style: italic;"&gt;# note: add1 throws an error if nothing can be added (current == full), which we trap with tryCatch&lt;/span&gt;&lt;br /&gt;        a &lt;span style=""&gt;&amp;lt;-&lt;/span&gt; &lt;a href="http://inside-r.org/r-doc/base/tryCatch"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;tryCatch&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;a href="http://inside-r.org/r-doc/stats/add1"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;add1&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;current&lt;span style="color: #339933;"&gt;,&lt;/span&gt; &lt;a href="http://inside-r.org/packages/cran/scope"&gt;&lt;span style=""&gt;scope&lt;/span&gt;&lt;/a&gt;=full&lt;span style="color: #339933;"&gt;,&lt;/span&gt; test=&lt;span style="color: #0000ff;"&gt;&amp;quot;F&amp;quot;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt; error=&lt;a href="http://inside-r.org/r-doc/base/function"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;function&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;e&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;NULL&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;  &lt;span style="color: #666666; font-style: italic;"&gt;# looks for significance of possible additions based on F tests&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;a href="http://inside-r.org/r-doc/base/is.null"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;is.null&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;a&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;          break&lt;span style="color: #339933;"&gt;;&lt;/span&gt;  &lt;span style="color: #666666; font-style: italic;"&gt;# there are no unused variables (or something went splat), so we bail out&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;        &lt;a href="http://inside-r.org/r-doc/base/pmin"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;pmin&lt;/span&gt;&lt;/a&gt; &lt;span style=""&gt;&amp;lt;-&lt;/span&gt; &lt;a href="http://inside-r.org/r-doc/base/min"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;min&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;a&lt;span style="color: #009900;"&gt;&amp;#91;&lt;/span&gt;&lt;span style=""&gt;-&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;1&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;6&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#93;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;  &lt;span style="color: #666666; font-style: italic;"&gt;# minimum p-value of any term (skipping the intercept again)&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;a href="http://inside-r.org/r-doc/base/pmin"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;pmin&lt;/span&gt;&lt;/a&gt; &lt;span style=""&gt;&amp;lt;&lt;/span&gt; alpha.to.enter&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;          &lt;span style="color: #666666; font-style: italic;"&gt;# we have a candidate for addition to the model&lt;/span&gt;&lt;br /&gt;          &lt;a href="http://inside-r.org/r-doc/stats/var"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;var&lt;/span&gt;&lt;/a&gt; &lt;span style=""&gt;&amp;lt;-&lt;/span&gt; &lt;a href="http://inside-r.org/r-doc/base/rownames"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;rownames&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;a&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#91;&lt;/span&gt;a&lt;span style="color: #009900;"&gt;&amp;#91;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;6&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#93;&lt;/span&gt; &lt;span style=""&gt;==&lt;/span&gt; &lt;a href="http://inside-r.org/r-doc/base/pmin"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;pmin&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#93;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;  &lt;span style="color: #666666; font-style: italic;"&gt;# name of variable to add&lt;/span&gt;&lt;br /&gt;          &lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;a href="http://inside-r.org/r-doc/base/length"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;length&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;a href="http://inside-r.org/r-doc/stats/var"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;var&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style=""&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #cc66cc;"&gt;1&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #666666; font-style: italic;"&gt;# same issue with ties, intercept as above&lt;/span&gt;&lt;br /&gt;            &lt;a href="http://inside-r.org/r-doc/stats/var"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;var&lt;/span&gt;&lt;/a&gt; &lt;span style=""&gt;&amp;lt;-&lt;/span&gt; &lt;a href="http://inside-r.org/r-doc/stats/var"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;var&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#91;&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;2&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#93;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;&lt;br /&gt;          &lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;          &lt;a href="http://inside-r.org/r-doc/base/write"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;write&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;a href="http://inside-r.org/r-doc/base/paste"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;paste&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;quot;+++ Adding&amp;quot;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt; &lt;a href="http://inside-r.org/r-doc/stats/var"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;var&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;&amp;quot;&lt;span style="color: #000099; font-weight: bold;"&gt;\n&lt;/span&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt; &lt;a href="http://inside-r.org/r-doc/base/file"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;file&lt;/span&gt;&lt;/a&gt;=&lt;span style="color: #0000ff;"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;  &lt;span style="color: #666666; font-style: italic;"&gt;# print the variable being added&lt;/span&gt;&lt;br /&gt;          f &lt;span style=""&gt;&amp;lt;-&lt;/span&gt; &lt;a href="http://inside-r.org/r-doc/stats/formula"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;formula&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;current&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;  &lt;span style="color: #666666; font-style: italic;"&gt;# current formula&lt;/span&gt;&lt;br /&gt;          f &lt;span style=""&gt;&amp;lt;-&lt;/span&gt; &lt;a href="http://inside-r.org/r-doc/stats/as.formula"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;as.formula&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;a href="http://inside-r.org/r-doc/base/paste"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;paste&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;f&lt;span style="color: #009900;"&gt;&amp;#91;&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;2&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#93;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;&amp;quot;~&amp;quot;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt; &lt;a href="http://inside-r.org/r-doc/base/paste"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;paste&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;f&lt;span style="color: #009900;"&gt;&amp;#91;&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;3&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#93;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt; &lt;a href="http://inside-r.org/r-doc/stats/var"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;var&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt; sep=&lt;span style="color: #0000ff;"&gt;&amp;quot; + &amp;quot;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;  &lt;span style="color: #666666; font-style: italic;"&gt;# modify the formula to add the chosen variable&lt;/span&gt;&lt;br /&gt;          current &lt;span style=""&gt;&amp;lt;-&lt;/span&gt; &lt;a href="http://inside-r.org/r-doc/stats/lm"&gt;&lt;span style="color: #003399; font-weight: bold;"&gt;lm&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;f&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;  &lt;span style="color: #666666; font-style: italic;"&gt;# fit the modified model&lt;/span&gt;&lt;br /&gt;          next&lt;span style="color: #339933;"&gt;;&lt;/span&gt;  &lt;span style="color: #666666; font-style: italic;"&gt;# return to the top of the loop&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #666666; font-style: italic;"&gt;# if we get here, we failed to make any changes to the model; time to punt&lt;/span&gt;&lt;br /&gt;        break&lt;span style="color: #339933;"&gt;;&lt;/span&gt;&lt;br /&gt;      &lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt; &lt;br /&gt;    &lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;a href="http://www.inside-r.org/pretty-r" title="Created by Pretty R at inside-R.org"&gt;Created by Pretty R at inside-R.org&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-1226301386863181368?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/1226301386863181368/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/02/stepwise-regression-in-r.html#comment-form' title='11 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/1226301386863181368'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/1226301386863181368'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/02/stepwise-regression-in-r.html' title='Stepwise Regression in R'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>11</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-7542421121476866778</id><published>2011-02-26T12:46:00.001-05:00</published><updated>2011-03-30T11:48:39.090-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='AMPL'/><category scheme='http://www.blogger.com/atom/ns#' term='math programming'/><title type='text'>Finding Multiple Solutions in a Binary MIP</title><content type='html'>&lt;script type="text/x-mathjax-config"&gt;MathJax.Hub.Config({  tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}});&lt;/script&gt;&lt;script type="text/javascript"  src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"&gt;&lt;/script&gt;I'm going to post some &lt;a href="http://www.ampl.com/" linkindex="154"&gt;AMPL&lt;/a&gt; code here that illustrates how to find more than one solution to a mixed integer program in which all integer variables are binary.&amp;nbsp; The problem I'll use is a multiple knapsack where the supply of each item is one.&amp;nbsp; The AMPL code should be pretty self-explanatory, with the possible exception of the exclusion constraints.&amp;nbsp; The notion for those is as follows.&amp;nbsp; Suppose that my binary variables are $x\in \{0,1\}^d$.&amp;nbsp; I solve the original model and obtain a solution with $x=\tilde{x}$.&amp;nbsp; I now add the following constraint:$$\sum_{i : \tilde{x}_i = 0} x_i + \sum_{i : \tilde{x}_i =1}(1-x_i)\ge 1.$$Note that this constraint forces at least one of the binary variables to change its value. (Exclusion constraints for general integer variables are harder to come by.&amp;nbsp; The only way I know off-hand involves binary expansions of the general integer variables.)&lt;br /&gt;&lt;br /&gt;The AMPL code solves the model in a loop, recording each solution and adding an exclusion constraint.&amp;nbsp; The small example I created happens by chance to have multiple optimal solutions, enough so that the five solutions generated by the code are all optimal (but distinct).&amp;nbsp; More generally, you could get a sequence of increasingly suboptimal solutions.&lt;br /&gt;&lt;br /&gt;Three things are perhaps noteworthy in the code.&amp;nbsp; The first is the check for infeasibility:&amp;nbsp; if you've already enumerated all possible solutions (and excluded them), the model will become infeasible.&amp;nbsp; The second is that I gave default values for the exclusion constraint coefficients (and right hand sides).&amp;nbsp; AMPL otherwise solved the base model (with no exclusion constraints) but then nagged me when I tried to record the result, because the first exclusion constraint used undefined coefficients.&amp;nbsp; Apparently recording the result (or even trying to display it) triggered a reevaluation of the model.&amp;nbsp; I think I could have ducked that by waiting to update nfound, but default values were an easy fix.&amp;nbsp; Third, note that I did not check whether a binary variable equaled 0 or 1; that might bump into rounding issues.&amp;nbsp; Saying that anything above (below) 0.5 is a 1 (0) is a very safe test.&amp;nbsp; (If your rounding error is that bad, you need to clean the beads on your abacus.)&lt;br /&gt;&lt;br /&gt;One last comment is that this is not the most efficient way to find multiple solutions, in that it requires the (expanded) model to be solved &lt;i&gt;ab initio&lt;/i&gt; each time.&amp;nbsp; If the solver supports callbacks, a more efficient approach is to use callbacks to record incumbents, reject them, and add exclusion constraints on the fly.&amp;nbsp; CPLEX has a "solution pool" feature that lets you track multiple solutions (and if CPLEX has it, my guess is that other commercial solvers do or soon will).&amp;nbsp; Using that is probably even&amp;nbsp; more efficient than using callbacks.&amp;nbsp; If the model is easy enough to solve, though, or if your solver lacks those features, the method demonstrated below may be a good choice.&lt;br /&gt;&lt;br /&gt;Here is the code:&lt;br /&gt;&lt;style type="text/css"&gt;&lt;!--body.hl { background-color:#ffffff; }pre.hl { color:#000000; background-color:#ffffff; font-size:10pt; font-family:'Courier New';}.hl.num { color:#2928ff; }.hl.esc { color:#ff00ff; }.hl.str { color:#ff0000; }.hl.dstr { color:#818100; }.hl.slc { color:#838183; font-style:italic; }.hl.com { color:#838183; font-style:italic; }.hl.dir { color:#008200; }.hl.sym { color:#000000; }.hl.line { color:#555555; }.hl.mark { background-color:#ffffbb;}.hl.kwa { color:#000000; font-weight:bold; }.hl.kwb { color:#830000; }.hl.kwc { color:#000000; font-weight:bold; }.hl.kwd { color:#010181; }//--&gt;&lt;/style&gt;&lt;pre class="hl"&gt;&lt;span class="hl slc"&gt;# Example of how to generate and record multiple solutions to a binary MIP.&lt;/span&gt;&lt;br /&gt;&lt;span class="hl slc"&gt;#&lt;/span&gt;&lt;br /&gt;&lt;span class="hl slc"&gt;# The sample problem is a 0-1 multiple knapsack.&lt;/span&gt;&lt;br /&gt;&lt;span class="hl slc"&gt;#&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;set&lt;/span&gt; ITEMS&lt;span class="hl sym"&gt;;&lt;/span&gt;  &lt;span class="hl slc"&gt;# items available for the knapsacks&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;set&lt;/span&gt; KNAPSACKS&lt;span class="hl sym"&gt;;&lt;/span&gt;  &lt;span class="hl slc"&gt;# available knapsacks&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;param&lt;/span&gt; value &lt;span class="hl sym"&gt;{&lt;/span&gt;ITEMS&lt;span class="hl sym"&gt;} &amp;gt;&lt;/span&gt; &lt;span class="hl num"&gt;0&lt;/span&gt;&lt;span class="hl sym"&gt;;&lt;/span&gt;  &lt;span class="hl slc"&gt;# item values&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;param&lt;/span&gt; size &lt;span class="hl sym"&gt;{&lt;/span&gt;ITEMS&lt;span class="hl sym"&gt;} &amp;gt;&lt;/span&gt; &lt;span class="hl num"&gt;0&lt;/span&gt;&lt;span class="hl sym"&gt;;&lt;/span&gt;  &lt;span class="hl slc"&gt;# item sizes&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;param&lt;/span&gt; capacity &lt;span class="hl sym"&gt;{&lt;/span&gt;KNAPSACKS&lt;span class="hl sym"&gt;} &amp;gt;&lt;/span&gt; &lt;span class="hl num"&gt;0&lt;/span&gt;&lt;span class="hl sym"&gt;;&lt;/span&gt;  &lt;span class="hl slc"&gt;# knapsack capacities&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;var&lt;/span&gt; Pack &lt;span class="hl sym"&gt;{&lt;/span&gt;ITEMS&lt;span class="hl sym"&gt;,&lt;/span&gt; KNAPSACKS&lt;span class="hl sym"&gt;}&lt;/span&gt; &lt;span class="hl kwa"&gt;binary&lt;/span&gt;&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class="hl slc"&gt;# Pack[i,k] = 1 iff item i is packed in knapsack k&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;maximize&lt;/span&gt; LoadValue&lt;span class="hl sym"&gt;:&lt;/span&gt; &lt;span class="hl kwa"&gt;sum&lt;/span&gt; &lt;span class="hl sym"&gt;{&lt;/span&gt;i &lt;span class="hl kwa"&gt;in&lt;/span&gt; ITEMS&lt;span class="hl sym"&gt;,&lt;/span&gt; k &lt;span class="hl kwa"&gt;in&lt;/span&gt; KNAPSACKS&lt;span class="hl sym"&gt;}&lt;/span&gt; value&lt;span class="hl sym"&gt;[&lt;/span&gt;i&lt;span class="hl sym"&gt;]*&lt;/span&gt;Pack&lt;span class="hl sym"&gt;[&lt;/span&gt;i&lt;span class="hl sym"&gt;,&lt;/span&gt;k&lt;span class="hl sym"&gt;];&lt;/span&gt;&lt;br /&gt;  &lt;span class="hl slc"&gt;# maximize value of load&lt;/span&gt;&lt;br /&gt;s.t. Capacity &lt;span class="hl sym"&gt;{&lt;/span&gt;k &lt;span class="hl kwa"&gt;in&lt;/span&gt; KNAPSACKS&lt;span class="hl sym"&gt;}:&lt;/span&gt;&lt;br /&gt;  &lt;span class="hl kwa"&gt;sum&lt;/span&gt; &lt;span class="hl sym"&gt;{&lt;/span&gt;i &lt;span class="hl kwa"&gt;in&lt;/span&gt; ITEMS&lt;span class="hl sym"&gt;}&lt;/span&gt; size&lt;span class="hl sym"&gt;[&lt;/span&gt;i&lt;span class="hl sym"&gt;]*&lt;/span&gt;Pack&lt;span class="hl sym"&gt;[&lt;/span&gt;i&lt;span class="hl sym"&gt;,&lt;/span&gt;k&lt;span class="hl sym"&gt;]  &amp;lt;=&lt;/span&gt; capacity&lt;span class="hl sym"&gt;[&lt;/span&gt;k&lt;span class="hl sym"&gt;];&lt;/span&gt;  &lt;span class="hl slc"&gt;# capacity limits&lt;/span&gt;&lt;br /&gt;s.t. Supply &lt;span class="hl sym"&gt;{&lt;/span&gt;i &lt;span class="hl kwa"&gt;in&lt;/span&gt; ITEMS&lt;span class="hl sym"&gt;}:&lt;/span&gt;&lt;br /&gt;  &lt;span class="hl kwa"&gt;sum&lt;/span&gt; &lt;span class="hl sym"&gt;{&lt;/span&gt;k &lt;span class="hl kwa"&gt;in&lt;/span&gt; KNAPSACKS&lt;span class="hl sym"&gt;}&lt;/span&gt; Pack&lt;span class="hl sym"&gt;[&lt;/span&gt;i&lt;span class="hl sym"&gt;,&lt;/span&gt;k&lt;span class="hl sym"&gt;]  &amp;lt;=&lt;/span&gt; &lt;span class="hl num"&gt;1&lt;/span&gt;&lt;span class="hl sym"&gt;;&lt;/span&gt;  &lt;span class="hl slc"&gt;# only one of each item available&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;option&lt;/span&gt; solver cplexamp&lt;span class="hl sym"&gt;;&lt;/span&gt;  &lt;span class="hl slc"&gt;# to use CPLEX as the solver&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;data&lt;/span&gt;&lt;span class="hl sym"&gt;;&lt;/span&gt;  &lt;span class="hl slc"&gt;# ordinarily I'd use a separate file for the data&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;set&lt;/span&gt; ITEMS &lt;span class="hl sym"&gt;:=&lt;/span&gt; &lt;span class="hl num"&gt;1 2 3 4 5 6 7 8 9&lt;/span&gt;&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;set&lt;/span&gt; KNAPSACKS &lt;span class="hl sym"&gt;:=&lt;/span&gt; &lt;span class="hl num"&gt;1 2&lt;/span&gt;&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;param&lt;/span&gt; capacity &lt;span class="hl sym"&gt;:=&lt;/span&gt; &lt;span class="hl num"&gt;1 6 2 4&lt;/span&gt;&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;param&lt;/span&gt;&lt;span class="hl sym"&gt;:&lt;/span&gt;  value  size  &lt;span class="hl sym"&gt;:=&lt;/span&gt;&lt;br /&gt;   &lt;span class="hl num"&gt;1       6     3&lt;/span&gt;&lt;br /&gt;   &lt;span class="hl num"&gt;2       5     2&lt;/span&gt;&lt;br /&gt;   &lt;span class="hl num"&gt;3       4     4&lt;/span&gt;&lt;br /&gt;   &lt;span class="hl num"&gt;4       3     1&lt;/span&gt;&lt;br /&gt;   &lt;span class="hl num"&gt;5       2     1&lt;/span&gt;&lt;br /&gt;   &lt;span class="hl num"&gt;6       4     5&lt;/span&gt;&lt;br /&gt;   &lt;span class="hl num"&gt;7       7     6&lt;/span&gt;&lt;br /&gt;   &lt;span class="hl num"&gt;8       2     3&lt;/span&gt;&lt;br /&gt;   &lt;span class="hl num"&gt;9       1     1&lt;/span&gt;  &lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;model&lt;/span&gt;&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="hl slc"&gt;# we now create some structure to record multiple solutions&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;param&lt;/span&gt; want &lt;span class="hl sym"&gt;:=&lt;/span&gt; &lt;span class="hl num"&gt;5&lt;/span&gt;&lt;span class="hl sym"&gt;;&lt;/span&gt;  &lt;span class="hl slc"&gt;# number of solutions we want&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;set&lt;/span&gt; SOLUTIONS &lt;span class="hl sym"&gt;:=&lt;/span&gt; &lt;span class="hl num"&gt;1&lt;/span&gt;..want&lt;span class="hl sym"&gt;;&lt;/span&gt;  &lt;span class="hl slc"&gt;# index set for solutions&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;param&lt;/span&gt; packed &lt;span class="hl sym"&gt;{&lt;/span&gt;ITEMS&lt;span class="hl sym"&gt;,&lt;/span&gt; KNAPSACKS&lt;span class="hl sym"&gt;,&lt;/span&gt; SOLUTIONS&lt;span class="hl sym"&gt;};&lt;/span&gt;&lt;br /&gt;  &lt;span class="hl slc"&gt;# packed[i,k,s] will be 1 if solution s packed item i in knapsack k&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;param&lt;/span&gt; payoff &lt;span class="hl sym"&gt;{&lt;/span&gt;SOLUTIONS&lt;span class="hl sym"&gt;};&lt;/span&gt;  &lt;span class="hl slc"&gt;# objective values of recorded solutions&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;param coef&lt;/span&gt; &lt;span class="hl sym"&gt;{&lt;/span&gt;ITEMS&lt;span class="hl sym"&gt;,&lt;/span&gt; KNAPSACKS&lt;span class="hl sym"&gt;,&lt;/span&gt; SOLUTIONS&lt;span class="hl sym"&gt;}&lt;/span&gt; &lt;span class="hl kwa"&gt;default&lt;/span&gt; &lt;span class="hl num"&gt;0&lt;/span&gt;&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class="hl slc"&gt;# coefficients of solution exclusion constraints&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;param&lt;/span&gt; rhs &lt;span class="hl sym"&gt;{&lt;/span&gt;SOLUTIONS&lt;span class="hl sym"&gt;}&lt;/span&gt; &lt;span class="hl kwa"&gt;default&lt;/span&gt; &lt;span class="hl num"&gt;0&lt;/span&gt;&lt;span class="hl sym"&gt;;&lt;/span&gt;  &lt;span class="hl slc"&gt;# right hand sides of exclusion constraints&lt;/span&gt;&lt;br /&gt;&lt;span class="hl kwa"&gt;param&lt;/span&gt; nfound &lt;span class="hl kwa"&gt;default&lt;/span&gt; &lt;span class="hl num"&gt;0&lt;/span&gt;&lt;span class="hl sym"&gt;;&lt;/span&gt;  &lt;span class="hl slc"&gt;# number of solutions found&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="hl slc"&gt;# we add constraints to the previous model to exclude&lt;/span&gt;&lt;br /&gt;&lt;span class="hl slc"&gt;# solutions we've already seen&lt;/span&gt;&lt;br /&gt;s.t. Exclude &lt;span class="hl sym"&gt;{&lt;/span&gt;s &lt;span class="hl kwa"&gt;in&lt;/span&gt; &lt;span class="hl num"&gt;1&lt;/span&gt;..nfound&lt;span class="hl sym"&gt;}:&lt;/span&gt;&lt;br /&gt;  &lt;span class="hl kwa"&gt;sum&lt;/span&gt; &lt;span class="hl sym"&gt;{&lt;/span&gt;i &lt;span class="hl kwa"&gt;in&lt;/span&gt; ITEMS&lt;span class="hl sym"&gt;,&lt;/span&gt; k &lt;span class="hl kwa"&gt;in&lt;/span&gt; KNAPSACKS&lt;span class="hl sym"&gt;}&lt;/span&gt; &lt;span class="hl kwa"&gt;coef&lt;/span&gt;&lt;span class="hl sym"&gt;[&lt;/span&gt;i&lt;span class="hl sym"&gt;,&lt;/span&gt;k&lt;span class="hl sym"&gt;,&lt;/span&gt;s&lt;span class="hl sym"&gt;]*&lt;/span&gt;Pack&lt;span class="hl sym"&gt;[&lt;/span&gt;i&lt;span class="hl sym"&gt;,&lt;/span&gt;k&lt;span class="hl sym"&gt;] &amp;gt;=&lt;/span&gt; rhs&lt;span class="hl sym"&gt;[&lt;/span&gt;s&lt;span class="hl sym"&gt;];&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="hl slc"&gt;# solve until either the problem becomes infeasible or&lt;/span&gt;&lt;br /&gt;&lt;span class="hl slc"&gt;# the right number of solutions has been found&lt;/span&gt;&lt;br /&gt;for &lt;span class="hl sym"&gt;{&lt;/span&gt;s &lt;span class="hl kwa"&gt;in&lt;/span&gt; SOLUTIONS&lt;span class="hl sym"&gt;} {&lt;/span&gt;&lt;br /&gt;  solve&lt;span class="hl sym"&gt;;&lt;/span&gt;  &lt;span class="hl slc"&gt;# solve the model&lt;/span&gt;&lt;br /&gt;  &lt;span class="hl kwa"&gt;if&lt;/span&gt; solve_result &lt;span class="hl sym"&gt;=&lt;/span&gt; &lt;span class="hl str"&gt;'infeasible'&lt;/span&gt; &lt;span class="hl kwa"&gt;then&lt;/span&gt; break&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class="hl slc"&gt;# if the model has become infeasible, give up&lt;/span&gt;&lt;br /&gt;  &lt;span class="hl kwa"&gt;let&lt;/span&gt; nfound &lt;span class="hl sym"&gt;:=&lt;/span&gt; s&lt;span class="hl sym"&gt;;&lt;/span&gt;  &lt;span class="hl slc"&gt;# bump the counter for solutions found&lt;/span&gt;&lt;br /&gt;  &lt;span class="hl kwa"&gt;let&lt;/span&gt; payoff&lt;span class="hl sym"&gt;[&lt;/span&gt;s&lt;span class="hl sym"&gt;] :=&lt;/span&gt; LoadValue.val&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class="hl kwa"&gt;let&lt;/span&gt; rhs&lt;span class="hl sym"&gt;[&lt;/span&gt;s&lt;span class="hl sym"&gt;] :=&lt;/span&gt; &lt;span class="hl num"&gt;1&lt;/span&gt;&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class="hl slc"&gt;# create an exclusion constraint that forces at least&lt;/span&gt;&lt;br /&gt;  &lt;span class="hl slc"&gt;# one binary variable to change value&lt;/span&gt;&lt;br /&gt;  for &lt;span class="hl sym"&gt;{&lt;/span&gt;i &lt;span class="hl kwa"&gt;in&lt;/span&gt; ITEMS&lt;span class="hl sym"&gt;,&lt;/span&gt; k &lt;span class="hl kwa"&gt;in&lt;/span&gt; KNAPSACKS&lt;span class="hl sym"&gt;} {&lt;/span&gt;&lt;br /&gt;    &lt;span class="hl kwa"&gt;if&lt;/span&gt; Pack&lt;span class="hl sym"&gt;[&lt;/span&gt;i&lt;span class="hl sym"&gt;,&lt;/span&gt;k&lt;span class="hl sym"&gt;] &amp;gt;&lt;/span&gt; &lt;span class="hl num"&gt;0.5&lt;/span&gt; &lt;span class="hl kwa"&gt;then&lt;/span&gt; &lt;span class="hl sym"&gt;{&lt;/span&gt;&lt;br /&gt;      &lt;span class="hl slc"&gt;# treat this as a 1&lt;/span&gt;&lt;br /&gt;      &lt;span class="hl kwa"&gt;let&lt;/span&gt; packed&lt;span class="hl sym"&gt;[&lt;/span&gt;i&lt;span class="hl sym"&gt;,&lt;/span&gt;k&lt;span class="hl sym"&gt;,&lt;/span&gt;s&lt;span class="hl sym"&gt;] :=&lt;/span&gt; &lt;span class="hl num"&gt;1&lt;/span&gt;&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;      &lt;span class="hl kwa"&gt;let coef&lt;/span&gt;&lt;span class="hl sym"&gt;[&lt;/span&gt;i&lt;span class="hl sym"&gt;,&lt;/span&gt;k&lt;span class="hl sym"&gt;,&lt;/span&gt;s&lt;span class="hl sym"&gt;] := -&lt;/span&gt;&lt;span class="hl num"&gt;1&lt;/span&gt;&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;      &lt;span class="hl kwa"&gt;let&lt;/span&gt; rhs&lt;span class="hl sym"&gt;[&lt;/span&gt;s&lt;span class="hl sym"&gt;] :=&lt;/span&gt; rhs&lt;span class="hl sym"&gt;[&lt;/span&gt;s&lt;span class="hl sym"&gt;] -&lt;/span&gt; &lt;span class="hl num"&gt;1&lt;/span&gt;&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class="hl sym"&gt;}&lt;/span&gt;&lt;br /&gt;    &lt;span class="hl kwa"&gt;else&lt;/span&gt; &lt;span class="hl sym"&gt;{&lt;/span&gt;&lt;br /&gt;      &lt;span class="hl slc"&gt;# treat this as a 0&lt;/span&gt;&lt;br /&gt;      &lt;span class="hl kwa"&gt;let&lt;/span&gt; packed&lt;span class="hl sym"&gt;[&lt;/span&gt;i&lt;span class="hl sym"&gt;,&lt;/span&gt;k&lt;span class="hl sym"&gt;,&lt;/span&gt;s&lt;span class="hl sym"&gt;] :=&lt;/span&gt; &lt;span class="hl num"&gt;0&lt;/span&gt;&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;      &lt;span class="hl kwa"&gt;let coef&lt;/span&gt;&lt;span class="hl sym"&gt;[&lt;/span&gt;i&lt;span class="hl sym"&gt;,&lt;/span&gt;k&lt;span class="hl sym"&gt;,&lt;/span&gt;s&lt;span class="hl sym"&gt;] :=&lt;/span&gt; &lt;span class="hl num"&gt;1&lt;/span&gt;&lt;span class="hl sym"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class="hl sym"&gt;}&lt;/span&gt;&lt;br /&gt;  &lt;span class="hl sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="hl sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-7542421121476866778?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/7542421121476866778/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/02/finding-multiple-solutions-in-binary.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/7542421121476866778'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/7542421121476866778'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/02/finding-multiple-solutions-in-binary.html' title='Finding Multiple Solutions in a Binary MIP'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-5925099595645386439</id><published>2011-02-15T11:04:00.000-05:00</published><updated>2011-02-15T11:04:53.515-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='statistics'/><category scheme='http://www.blogger.com/atom/ns#' term='R'/><title type='text'>An R Resource</title><content type='html'>Catching up on some backlogged blog reading, I came across several interesting posts about R on John D. Cook's blog (&lt;a href="http://www.johndcook.com/blog/" linkindex="508"&gt;The Endeavor&lt;/a&gt;).&amp;nbsp; Happily, there is an index of all &lt;a href="http://www.johndcook.com/blog/tag/r/" linkindex="509"&gt;R-related posts&lt;/a&gt; there, so I can record one link here (where I'm unlikely to lose it) and catch any new posts with it.&amp;nbsp; There's a ton of information to &lt;strike&gt;mined&lt;/strike&gt; acquired from those posts.&amp;nbsp; (I didn't want to get the data-mining crowd whipped into a frenzy, hence the edit).&amp;nbsp; Among other things, I learned why S (and R by inheritance) has the convention of using a dot to create compound variable names (apparently underscore is an assignment operator in S).&amp;nbsp; That's one less itch to scratch.&lt;br /&gt;&lt;br /&gt;On the same blog, there is also an interesting (and interactive) diagram of the &lt;a href="http://www.johndcook.com/distribution_chart.html" linkindex="510"&gt;relationships among various distributions&lt;/a&gt;.&amp;nbsp; This could be quite useful in a probability and statistics course.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-5925099595645386439?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/5925099595645386439/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/02/r-resource.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/5925099595645386439'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/5925099595645386439'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/02/r-resource.html' title='An R Resource'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-8444169840014333620</id><published>2011-02-08T11:41:00.001-05:00</published><updated>2011-03-30T11:56:51.454-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='math programming'/><title type='text'>Bounding Dual Variables</title><content type='html'>&lt;script type="text/x-mathjax-config"&gt;MathJax.Hub.Config({  tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}});&lt;/script&gt;&lt;script type="text/javascript"  src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"&gt;&lt;/script&gt;An interesting question came up on &lt;a href="http://groups.google.com/forum/#%21forum/sci.op-research" linkindex="17"&gt;sci.op-research&lt;/a&gt; today: can we (easily) determine bounds for the variables in the dual of an linear program?&amp;nbsp; If the goal is &lt;i&gt;tight&lt;/i&gt; bounds, I don't see any easy solution; but it turns out that, at least in some problems, there may be finite (reasonable?) bounds to be had cheaply.&lt;br /&gt;&lt;br /&gt;Let's start with a primal problem in canonical form (alternative forms are left to the reader as an exercise):\[\begin{array}{lrclr}\textrm{minimize} &amp;amp; c'x\\\textrm{s.t.} &amp;amp; Ax &amp;amp; \ge &amp;amp; b &amp;amp; \textrm{(P)}\\ &amp;amp; x &amp;amp; \ge &amp;amp; 0\end{array}\] with dual\[\begin{array}{lrclr}\textrm{maximize} &amp;amp; b'y\\\textrm{s.t.} &amp;amp; A'y &amp;amp; \le &amp;amp; c &amp;amp; \textrm{(D)}\\ &amp;amp; y &amp;amp; \ge &amp;amp; 0\end{array}.\]To get an upper bound on dual variable $y_j$, we could solve a modified form of the dual problem:\[\begin{array}{lrclr}\textrm{maximize} &amp;amp; y_j\\\textrm{s.t.} &amp;amp; A'y &amp;amp; \le &amp;amp; c &amp;amp; \textrm{(D*)}\\ &amp;amp; y &amp;amp; \ge &amp;amp; 0\end{array}.\]This looks for the largest value of $y_j$ (which we hope is finite) consistent with the dual constraints. The dual to this problem is:\[\begin{array}{lrclr}\textrm{minimize} &amp;amp; c'x\\\textrm{s.t.} &amp;amp; Ax &amp;amp; \ge &amp;amp; e_j &amp;amp; \textrm{(P*)}\\ &amp;amp; x &amp;amp; \ge &amp;amp; 0\end{array}\]where $e_j$ is a vector whose $j$-th component is 1 and whose other components are all 0.&lt;br /&gt;&lt;br /&gt;Now suppose we know a primal vector $\tilde{x}\ge 0$ for (P) such that $A\tilde{x}=h\gg 0$, where $h\gg 0$ means that $h$ is strictly positive in every component. Let $x^*=(1/h_j)\tilde{x}$. Then $x^*$ is feasible in (P*), which means $c'x^*$ is an upper bound for the optimal value of (P*), and therefore also an upper bound for the optimal value of (D*). So we can safely assert $y_j\le c'x^*$ in (D).&lt;br /&gt;&lt;br /&gt;If $b\gg 0$, then any feasible solution to (P) is a candidate value of $\tilde{x}$, and the closer $\tilde{x}$ is to optimal, the tighter the bound on $y_j$. Also note that a single $\tilde{x}$ provides bounds for all of the dual variables $y_j$. So the trick is to know a vector $x\ge 0$ for which $Ax\gg 0$.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-8444169840014333620?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/8444169840014333620/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/02/bounding-dual-variables.html#comment-form' title='38 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/8444169840014333620'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/8444169840014333620'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/02/bounding-dual-variables.html' title='Bounding Dual Variables'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>38</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-4047988638477052504</id><published>2011-02-05T14:50:00.001-05:00</published><updated>2011-02-05T14:54:07.693-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software'/><category scheme='http://www.blogger.com/atom/ns#' term='Firefox'/><title type='text'>Twitter and Firefox</title><content type='html'>In the beginning, I completely ignored &lt;a href="https://twitter.com/" linkindex="1066"&gt;Twitter&lt;/a&gt;.&amp;nbsp; Recently, I started following a few Twitter feeds (from OR people) in &lt;a href="http://www.google.com/reader/" linkindex="1067"&gt;Google Reader&lt;/a&gt;, mainly because they tended to post links to things I actually found interesting (i.e., not what the tweeter had for lunch, nor where said lunch occurred).&amp;nbsp; Finally, I bit the bullet and opened a Twitter account, largely so that I could respond to the occasional provocative tweet.&amp;nbsp; (I think I'm up to three tweets so far, which should hold me for a while.)&lt;br /&gt;&lt;br /&gt;The next step was to look for an extension to either &lt;a href="https://www.mozillamessaging.com/en-US/thunderbird/" linkindex="1068"&gt;Thunderbird&lt;/a&gt; or &lt;a href="https://www.mozilla.com/en-US/firefox/" linkindex="1069"&gt;Firefox&lt;/a&gt; (both of which I keep open when being abused by a computer), so that I could tweet, retweet or ___ (is there a term for responding to a tweet?&amp;nbsp; tweeply?) easily.&amp;nbsp; Of course, I could just open Twitter in a Firefox tab, but that would be too low tech, right?&amp;nbsp; I found one Tbird extension, but it was an alpha version.&amp;nbsp; I found several promising looking Firefox extensions, of which the most complete and polished seemed to be &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/echofon-for-twitter/" linkindex="1070"&gt;Echofon&lt;/a&gt;.&amp;nbsp; So yesterday I installed in on my office PC (Linux Mint Isadora), where it worked well, and this morning I installed it on my home PC (Win XP), where it also worked well.&lt;br /&gt;&lt;br /&gt;Unfortunately, in between I installed it on my laptop (also Mint Isadora), where it proceeded to spew authentication errors in an alarmingly &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/Ocd" linkindex="1071"&gt;OCD&lt;/a&gt; way.&amp;nbsp; In fact, short of killing Firefox from a terminal, the only way I could stop the error messages (which popped up an average of about two seconds apart) was to turn off my WiFi connection.&amp;nbsp; (I couldn't log out of Twitter, nor exit Firefox gracefully, because the incessant error dialogs were modal.)&lt;br /&gt;&lt;br /&gt;Fortunately, I could diff my settings between the laptop and the (working) office PC.&amp;nbsp; It turns out there was a conflict with another Firefox extension, the Electronic Frontier Foundation's &lt;a href="https://www.eff.org/https-everywhere" linkindex="1072"&gt;HTTPS-Everywhere&lt;/a&gt;.&amp;nbsp; This extension automatically converts insecure HTTP connections to many sites to secure HTTPS connections.&amp;nbsp; I installed it on my laptop (which likes to go out for a cup of coffee pretty often) but not my office PC (which hides behind a firewall) (although I may eventually install it there as well).&amp;nbsp; It works fine with Twitter when I surf to my Twitter account, but apparently it does not get along at all well with Echofon.&amp;nbsp; Fortunately, HTTPS-Everywhere allows you to configure which sites it will try to seduce into secure connections; by deselecting Twitter.com, I got Echofon to work properly (if perhaps not entirely securely).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-4047988638477052504?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/4047988638477052504/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/02/twitter-and-firefox.html#comment-form' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/4047988638477052504'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/4047988638477052504'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/02/twitter-and-firefox.html' title='Twitter and Firefox'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-1897820918180407338</id><published>2011-02-05T11:59:00.001-05:00</published><updated>2011-02-14T17:21:43.803-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='presentations'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>More Presentation Software</title><content type='html'>I previously wrote about the tools I use to &lt;a href="http://orinanobworld.blogspot.com/2010/03/presentation-software.html" linkindex="30"&gt;create presentations&lt;/a&gt;. Lately, I've been looking for tools that allow an instructor to:&lt;br /&gt;&lt;ul&gt;&lt;li&gt; annotate files being projected (from a PC or laptop, through a digital projector);&lt;/li&gt;&lt;li&gt;turn the display into a whiteboard and draw on it;&lt;/li&gt;&lt;li&gt;share the screen between slides and a whiteboard (some of my colleagues like to work homework problems by hand while simultaneously displaying either the problem statement or the relevant formulas); and&lt;/li&gt;&lt;li&gt;save some of the better doodling as an image (to be uploaded to our course management system).&lt;/li&gt;&lt;/ul&gt;The motivation for this is largely that we grown our classroom technology incrementally, adding features on top of features in rooms that were not designed for them. A particular recurring theme is rooms with wall-mounted whiteboards that are largely obscured by screens for the digital projectors (leaving a small margin on either side accessible to the instructor).&lt;br /&gt;&lt;br /&gt;I've come across several useful programs that I thought I'd list here.&amp;nbsp; (I'm still working on the other piece of the puzzle, which is finding appropriate and reliable input methods.&amp;nbsp; My attempts to write with a mouse cause MDs to giggle uncontrollably.)&amp;nbsp; I should mention that I'm looking for tools for multiple platforms:&amp;nbsp; our classroom PCs are predominantly Windows-based, and most of my colleagues run Windows on their laptops, but I run Linux on mine and there are at least a few Mac users to be considered.&amp;nbsp; Also, I'm looking exclusively at free (preferably but not necessarily open source) software, and I'm not looking at "smart board" technology (we may get into that, but most classrooms will continue to have stupid boards, if I may be un-PC). What I've found so far:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://technet.microsoft.com/en-us/sysinternals/bb897434" linkindex="31"&gt;ZoomIt&lt;/a&gt; (Windows only, any version): This is a &lt;i&gt;very&lt;/i&gt; lightweight program (267KB download; no installation, no writing to the registry) that does what it does very well.&amp;nbsp; It requires keyboard use to control but handles pen input for the actual writing.&amp;nbsp; You freeze whatever is currently on the screen (optionally zooming in on it), then draw in one of six colors (red, blue, orange, green, yellow, pink -- no black).&amp;nbsp; The width of the pen stroke can be varied.&amp;nbsp; You can draw rectangles, ellipses and straight lines by holding a key down as you go.&amp;nbsp; There's blanket erase (with one keystroke) and&amp;nbsp; incremental undo, but no redo.&amp;nbsp; With one keystroke, you can turn the entire display into a whiteboard or blackboard.&amp;nbsp; You can copy the screen (to be pasted into an appropriate program) or save it to disk (as an image).&amp;nbsp; Three caveats: if you switch among screen annotation, whiteboard and blackboard you lose your annotations; there is no way to return to presentation mode, then come back and retain your annotations; and the image capture is always the full screen (so you may need to crop in another program before uploading it to its final home).&amp;nbsp; Image manipulations can be done in a variety of programs (I recommend &lt;a href="http://www.irfanview.com/" linkindex="32"&gt;IrfanView&lt;/a&gt;).&lt;/li&gt;&lt;li&gt;&lt;a href="http://code.google.com/p/ardesia/" linkindex="33"&gt;Ardesia&lt;/a&gt; (Linux, Windows Vista/7): Ordinarily I find it easier to find free/open-source applications for Linux than for Windows, but it took me a couple of hours of searching to find a screen annotation program I liked. &lt;a href="http://www.home.unix-ag.org/simon/gromit/" linkindex="34"&gt;Gromit&lt;/a&gt; works pretty well, but it has limited flexibility and requires you to tweak a configuration file to change pen color, etc. Ardesia seems to do almost everything I'd want.&amp;nbsp; Documentation is a bit lacking, so you need to read the tool tips and do some experimenting, but it works very well.&amp;nbsp; You can draw in any color, using one of three or four stroke widths, in one of three modes (totally freehand, or with automatic conversion of some strokes to either lines or splines).&amp;nbsp; You can also type text. If you draw an enclosed region, you can fill it (something I'm not sure I'd use much).&amp;nbsp; You can add arrow heads, erase portions of the screen (or the whole screen with one click), undo and redo, and save your screen (PDF or PNG).&amp;nbsp; There's even a recording feature (which I've not figured out yet).&amp;nbsp; Once it's running, everything is controlled from a toolbar docked on the perimeter of the screen, which is helpful when you're using a convertible laptop and the screen/tablet is covering the keyboard.&amp;nbsp; There are a few "eye-candy" options I have not mentioned (and have not installed ... yet). Ardesia is available as a .deb package for Ubuntu, and allegedly compiles on other Linux/BSD systems.&amp;nbsp; It requires a composite manager.&amp;nbsp; I have not tested the Win 7 version (yet), but it might end up replacing ZoomIt for me.&amp;nbsp; The only real drawback (other than documentation) from my perspective is that there are no ellipse and rectangle tools.&amp;nbsp; (Hypothetically I can draw polygons and ellipses in the straight line or spline mode, but so far that has proved to be purely hypothetical.)&lt;/li&gt;&lt;li&gt;&lt;a href="http://whyteboard.org/" linkindex="35"&gt;Whyteboard&lt;/a&gt; (Windows, Linux, Mac): If you want to turn your display into a whiteboard (either full screen or windowed), rather than writing on top of some other image, I doubt you'll do better than this. You get a tabbed interface (so that you can have multiple screens of writing, and switch among them at will) with a full palette of drawing tools (text, arrows, lines, basic shapes), with multiple colors and an eraser.&amp;nbsp; You can save and reopen tabs, and you can attach notes to them. Unlike the screen drawing programs, you can grab any shape and move or resize it, and change its color.&amp;nbsp; A history of your drawings is kept and can be replayed.&amp;nbsp; Audio and video players can be dropped onto the whiteboard. If &lt;a href="http://www.imagemagick.org/" linkindex="36"&gt;ImageMagick&lt;/a&gt; is installed, you can suck in a PDF and draw over it.&amp;nbsp; Windows 7 (or XP tablet version) users can do some of this in Windows Journal, but having tried both I'm going with Whyteboard (plus it's cross-platform, which is useful to me). &lt;strike&gt;The biggest drawback I've found so far is that, while you can save your drawings in a program-specific format, there does not seem to be an image export feature.&lt;/strike&gt;&amp;nbsp; [Editor's note:&amp;nbsp; Author is apparently blind.&amp;nbsp; Program does export images.&amp;nbsp; See comment below.] You can, however, select a portion of a tab and copy it to the clipboard, so you can paste it into a program (such as IrfanView, which incidentally runs fine on Linux under Wine) and then crop, rotate, fiddle and export.&lt;/li&gt;&lt;/ul&gt;Now if I could just like that illegible screen writing problem ...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-1897820918180407338?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/1897820918180407338/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/02/more-presentation-software.html#comment-form' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/1897820918180407338'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/1897820918180407338'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/02/more-presentation-software.html' title='More Presentation Software'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-7467121385389432688</id><published>2011-02-01T18:19:00.001-05:00</published><updated>2011-03-30T11:57:49.486-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='math programming'/><title type='text'>Binary Exclusive Or</title><content type='html'>&lt;script type="text/x-mathjax-config"&gt;MathJax.Hub.Config({  tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}});&lt;/script&gt;&lt;script type="text/javascript"  src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"&gt;&lt;/script&gt;Lately I've been playing with a mixed integer programming model that involves &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/Hamming_distance" linkindex="155"&gt;Hamming distances&lt;/a&gt; between binary vectors.&amp;nbsp; This involves what amounts to computing the exclusive or between two binary variables.&amp;nbsp; In a &lt;a href="http://orinanobworld.blogspot.com/2010/07/inclusive-or-in-mathematical-programs.html" linkindex="156"&gt;previous post&lt;/a&gt; I made a comment about exclusive or being somewhat tricky to implement, but that was in reference to general linear constraints -- requiring that exactly one of two possible linear equalities/inequalities be satisfied.&amp;nbsp; Fortunately, an &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/Exclusive_or" linkindex="157"&gt;exclusive or&lt;/a&gt; between to binary variables is easy.&lt;br /&gt;&lt;br /&gt;Let $x$ and $y$ be two binary variables, and let $z=x\oplus y$&amp;nbsp; be the exclusive disjunction of $x$ and $y$, also declared as a binary variable. The truth table is as follows:&lt;br /&gt;&lt;table align="center" cellspacing="20"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;$x$&lt;/th&gt;&lt;th&gt;$y$&lt;/th&gt;&lt;th nowrap&gt;$z=x\oplus y$&lt;/th&gt;&lt;/tr&gt;&lt;tr align="center"&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;/tr&gt;&lt;tr align="center"&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;/tr&gt;&lt;tr align="center"&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;/tr&gt;&lt;tr align="center"&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;We accomplish this with the following inequalities:\begin{eqnarray*}z\le x + y\\z\le 2 - x - y\\ z\ge x - y\\z \ge y-x.\end{eqnarray*} Verification that this works is left to the reader as an exercise.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-7467121385389432688?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/7467121385389432688/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/02/binary-exclusive-or.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/7467121385389432688'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/7467121385389432688'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/02/binary-exclusive-or.html' title='Binary Exclusive Or'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-3663221265655777345</id><published>2011-01-30T11:15:00.000-05:00</published><updated>2011-01-30T11:15:07.046-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='INFORMS blog challenge'/><category scheme='http://www.blogger.com/atom/ns#' term='whimsy'/><title type='text'>The Diogenes Problem</title><content type='html'>Shiva Subramanian's post yesterday about "&lt;a href="http://dualnoise.blogspot.com/2011/01/honest-politician-and-other-rare-events.html" linkindex="485"&gt;The honest politician and other rare events&lt;/a&gt;", his contribution to the January &lt;a href="http://www.informs.org/About-INFORMS/News-Room/INFORMS-Blog/INFORMS-first-Blog-Challenge-Results" linkindex="486"&gt;INFORMS blog challenge&lt;/a&gt;, got me thinking about the following OR problem.&amp;nbsp; Suppose that, in &lt;a href="http://en.wikipedia.org/wiki/Philip_Jos%C3%A9_Farmer" linkindex="487"&gt;Philip José Farmer&lt;/a&gt;'s &lt;a href="http://en.wikipedia.org/wiki/Riverworld" linkindex="488"&gt;Riverworld&lt;/a&gt; (of recent &lt;a href="http://en.wikipedia.org/wiki/Riverworld_%282010_Film%29" linkindex="489"&gt;TV movie&lt;/a&gt; fame), we are able to take all the politicians that ever were (excluding those still living) and pack them into a finite rectangular enclosure.&amp;nbsp; Suppose further that we are able to assign a probability to each of them being honest (and that the probability function is not identically zero, which may be the hardest assumption to swallow in this &lt;a href="http://en.wikipedia.org/wiki/Gedankenexperiment" linkindex="490"&gt;Gedankenexperiment&lt;/a&gt;).&amp;nbsp; Now let's say we are able to map out a path for &lt;a href="http://en.wikipedia.org/wiki/Diogenes_of_Sinope" linkindex="491"&gt;Diogenes&lt;/a&gt; that minimizes the expected time until his first encounter with an honest person (I'm assuming both male and female politicians are present) in the room.&amp;nbsp; Would that path be a space-filling curve?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-3663221265655777345?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/3663221265655777345/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/01/diogenes-problem.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/3663221265655777345'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/3663221265655777345'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/01/diogenes-problem.html' title='The Diogenes Problem'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-8750636089436026206</id><published>2011-01-22T17:59:00.001-05:00</published><updated>2011-01-22T18:02:48.066-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rant'/><category scheme='http://www.blogger.com/atom/ns#' term='INFORMS blog challenge'/><title type='text'>OR v. CYA</title><content type='html'>People who work in operations research tend to believe that governments (and everyone else, but especially governments) would benefit from making more and better use of it.  At the heart of operations research is logical, dispassionate analysis of how a system works, and how it can work better, quantifying options and possible outcomes using hard data where possible.&lt;br /&gt;&lt;br /&gt;One of the most challenging areas in operations research is risk analysis.  The challenges are many, and frequently the most difficult aspects are not algorithmic but rather in assessing probabilities using scant or messy data (how likely is a nuclear power plant to release radiation? we happily lack a large sample of incidents) and in attaching values to outcomes.  Particularly problematic is assigning a value to a human life.  It is done all the time, by &lt;a href="http://www.time.com/time/health/article/0,8599,1808049,00.html" linkindex="24"&gt;insurers&lt;/a&gt;, by juries and, consciously or not, by government agencies.  Adding to the difficulty is that mathematical analysis may produce results we as people find uncomfortable.&lt;br /&gt;&lt;br /&gt;An example I've heard more than once (for which I have no citation) is whether government (here the Federal Aviation Administration) should require that infants on airline flights be parked in some version of a car seat.  I imagine most people, at least before hearing the arguments, would say yes.  The picture of an infant turning into a projectile during turbulence or a hard landing is very discomfiting.  Against that, the analyst weighs the facts that (a) requiring the infant to be in a conveyor most likely imposes on the parents the requirement to buy another ticket, (b) the cost of an extra ticket will, at the margin, impel some number of families to drive rather than to fly and (c) on a per-mile basis, commercial flight is safer than driving.  So requiring a safety seat for infants on flights might, paradoxically, lead to more injuries or deaths to infants during long trips, rather than fewer.  (I'm restraining myself from saying something about "throwing the baby out with the bathwater".)  (Apparently, I was not successful.)&lt;br /&gt;&lt;br /&gt;Enter your friendly federal, state or local government representatives. They are locked into a perpetual (re)election cycle, so making decisions that would at first blush seem insensitive or uncaring is bad for business.  When it comes to national security, the worst thing they can do is appear to do nothing.  The guiding principle seems to be that good theater trumps good analysis.&lt;br /&gt;&lt;br /&gt;Thus, after the attacks on the World Trade Center and Pentagon in 2001, the federal government instituted a variety of security procedures at airports that many fliers view as cosmetic at best.  Some of the perpetrators were in the U.S. on expired student visas, so the federal government made student visas harder to get (and, in the process, scared off a significant number of international students, costing U.S. universities a fair bit of money.)  In the aftermath of an attempt to &lt;a href="http://articles.cnn.com/2010-10-29/us/security.concern_1_suspicious-packages-petn-explosive-material?_s=PM:US" linkindex="25"&gt;smuggle explosive devices&lt;/a&gt; into the U.S. on cargo flights, the Transportation Safety Administration has moved up its target date for &lt;a href="http://www.tsa.gov/what_we_do/layers/aircargo/index.shtm" linkindex="26"&gt;screening of 100% of air cargo&lt;/a&gt;, a move that was already in the works. What is unclear is the extent to which any rigorous analysis of costs and benefits went into any of these decisions.  At least some of the new policies likely have helped avert additional attacks.  Some may have created new jobs.  Some assuredly imposed new costs on businesses, and some make air travel (already less than a thrilling prospect for those of us in sardine class) even less comfortable.&lt;br /&gt;&lt;br /&gt;Whenever another event triggers a panicky reaction (and I'm waiting to see what the &lt;a href="http://news.blogs.cnn.com/2011/01/08/several-people-shot-at-arizona-store-police-official-says/" linkindex="27"&gt;Tucson shootings&lt;/a&gt; yield), I think back to what my English relatives lived through during the Blitz, and the "&lt;a href="http://video.google.com/videoplay?docid=-1528313029232126903#"&gt;duck-and-cover&lt;/a&gt;" drills of my childhood.  (I lived about midway between New York City and &lt;a href="http://www.bnl.gov/world/" linkindex="28"&gt;Brookhaven National Laboratory&lt;/a&gt;, so I figured no matter which way the wind blew I was going to be in the radiation's path.)  Back then people seemed a bit more accepting of risk, and the fact that Bad Things Happen and sometimes they just cannot be prevented, and elected officials were less concerned about theatrics.&lt;br /&gt;&lt;br /&gt;In there era of sound-bite politics and tweet-length policy discussions, though, I'm afraid that OR is trumped by the political credo &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/Cover_your_ass" linkindex="29"&gt;CYA&lt;/a&gt;.  Better to be seen doing something pointless than to be perceived as doing nothing.&lt;br /&gt;&lt;br /&gt;(The preceding rant was motivated by the &lt;a href="https://twitter.com/INFORMS/statuses/22679944563793920" linkindex="30"&gt;INFORM blog challenge for January&lt;/a&gt;: O.R. and Politics.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-8750636089436026206?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/8750636089436026206/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/01/or-v-cya.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/8750636089436026206'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/8750636089436026206'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/01/or-v-cya.html' title='OR v. CYA'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-4079240981934482280</id><published>2011-01-19T21:18:00.000-05:00</published><updated>2011-01-19T21:18:34.825-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='analytics'/><title type='text'>Home Field Advantage</title><content type='html'>The January 17, 2011 issue of &lt;i&gt;Sports Illustrated&lt;/i&gt; contains an interesting article, "What's &lt;i&gt;Really&lt;/i&gt; Behind Home Field Advantage?" by Tobias J. Moskowitz and L. Jon Wertheim.&amp;nbsp; It's an excerpt from the book "SCORECASTING: The Hidden Influences Behind How Sports Are Played and Games Are Won" by the same two authors.&amp;nbsp; The premises of the article are that&lt;br /&gt;&lt;ul&gt;&lt;li&gt;home field advantage is real (in most if not all sports);&lt;/li&gt;&lt;li&gt;its primary (sole?) cause is biased officiating (the bias likely being unconscious); and&lt;/li&gt;&lt;li&gt;the magnitude of the advantage is an increasing function of crowd size.&lt;/li&gt;&lt;/ul&gt;The article is something of a "meta-analysis".&amp;nbsp; The authors do no statistical research themselves, but rather cite a number of studies that consistently support those premises.&lt;br /&gt;&lt;br /&gt;As a (non-rabid) sports fan, and having done a bit of low-level officiating myself, I found the conclusions interesting; but I mention it here because the studies it cites illustrate nicely how to do solid, persuasive statistical analysis using observational data.&amp;nbsp; It's a good example of what some of us are now calling "descriptive analytics" done right.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-4079240981934482280?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/4079240981934482280/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/01/home-field-advantage.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/4079240981934482280'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/4079240981934482280'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/01/home-field-advantage.html' title='Home Field Advantage'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-243185446199584894</id><published>2011-01-13T10:44:00.000-05:00</published><updated>2011-01-13T10:44:00.828-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='constraint programming'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>Numberjack</title><content type='html'>A response over at &lt;a href="http://www.or-exchange.com/" linkindex="152"&gt;OR-Exchange&lt;/a&gt; led me to discover &lt;a href="http://4c110.ucc.ie/numberjack/" linkindex="153"&gt;Numberjack&lt;/a&gt;, an open-source (LPGL) constraint programming platform written in Python.&amp;nbsp; I haven't had time to look at it carefully, and won't for a while (among other things, I need to learn more Python first), but I had to give them a shout-out just for the slogan on their home page (superimposed on a photograph of a forest): "Cuts your exponential search tree into logs."&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-243185446199584894?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/243185446199584894/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/01/numberjack.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/243185446199584894'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/243185446199584894'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/01/numberjack.html' title='Numberjack'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-3081989616844775993</id><published>2011-01-09T17:40:00.000-05:00</published><updated>2011-01-09T17:40:10.357-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='education'/><category scheme='http://www.blogger.com/atom/ns#' term='mathematics'/><category scheme='http://www.blogger.com/atom/ns#' term='science'/><title type='text'>Physiology and Mathematics Education</title><content type='html'>As a math lifer, I'm concerned about what more and more people are calling a &lt;a href="http://www.eschoolnews.com/2009/11/13/how-to-fix-the-stem-education-crisis/" linkindex="18"&gt;crisis&lt;/a&gt; in STEM (Science, Technology, Engineering and Mathematics) education in the United States. It seems as if every few days we read about the U. S. lagging behind other countries in &lt;a href="http://online.wsj.com/article/SB10001424052748703471904576003842497574526.html" linkindex="19"&gt;math or science test scores&lt;/a&gt;. We continue to &lt;a href="http://www.inc.com/news/briefs/200703/0312patents.html" linkindex="20"&gt;lead the world in innovation&lt;/a&gt; &lt;i&gt;for the moment&lt;/i&gt;, but it's hard to picture how we can sustain that lead without producing (or importing) more scientists and engineers (and, dare I say, mathematicians).&amp;nbsp; Equally importantly, in the age of the "information economy", if average U. S. citizens (not the ones in the right tail on math scores) come up short in STEM ability, where are they going to find jobs that pay respectable salaries?&amp;nbsp; (This is very important to me:&amp;nbsp; I'm on the cusp of retirement, and I'm counting on them both to pay down the burgeoning national debt and to sustain my lifestyle once my paychecks stop.)&lt;br /&gt;&lt;br /&gt;The press (and, thus, the populace) are gradually waking up to the looming crisis, as evidenced by &lt;a href="http://www.nsf.gov/news/news_summ.jsp?cntn_id=107123" linkindex="21"&gt;government panels&lt;/a&gt;, &lt;a href="http://www.whitehouse.gov/blog/2011/01/06/america-competes-act-keeps-americas-leadership-target" linkindex="22"&gt;legislation&lt;/a&gt;, academic workshops and periodic episodes of public hand-wringing.&amp;nbsp; Naturally, this spawns a wave of finger-pointing as we seek (a) one single explanation for what is undoubtedly a phenomenon with multiple roots and (b) someone (other than ourselves) whom we can blame.&amp;nbsp; A &lt;a href="http://www.heritage.org/research/reports/2009/04/a-new-approach-to-improving-science-technology-engineering-and-math-education" linkindex="23"&gt;backgrounder from the Heritage Foundation&lt;/a&gt; aptly points out that if the K-12 pipeline does not produce students well grounded in science and math, colleges and universities will be hard-pressed to find students willing and able to major in those subjects (and, by extension, graduate program enrollments will also suffer).&lt;br /&gt;&lt;br /&gt;Now please indulge me in an apparent digression that will actually tie back (I hope).&amp;nbsp; I recently found myself engaged in a conversation about math education, math ability and its connection (if any) to gender.&amp;nbsp; In this conversation, I recalled a colleague (a professor of economics) complaining to me that his daughter had essentially been told outright by a high school teacher that, being female, she should have diminished expectations for learning upper level mathematics (I suspect this meant calculus, but the conversation was long ago and the details elude me).&amp;nbsp; My colleague was justifiably apoplectic.&lt;br /&gt;&lt;br /&gt;I also recalled some misadventures from my graduate student days, when I taught a math class for elementary education majors.&amp;nbsp; On paper, the course dealt with how to teach math to K-6 students.&amp;nbsp; In practice, it meant (gulp) teaching K-6 math to college students majoring in elementary education.&amp;nbsp; Lest you think I exaggerate, let me share an anecdote.&amp;nbsp; My then girlfriend also taught the course, in the summer, when the students were elementary school teachers returning to pick up additional credits.&amp;nbsp; One student asked if she could bring her eight year old son to class to avoid daycare hassles, which request my girlfriend was happy to accommodate.&amp;nbsp; On the day of the first exam, she saw him sitting with nothing to occupy him, so she game him a spare copy of the exam, figuring he could color on the back.&amp;nbsp; Instead, he flipped it over, did the exam -- and received the highest score in the class!&lt;br /&gt;&lt;br /&gt;So, on the one hand, we have people telling children that they are doomed to be weak at math (and science?) because they lack a Y chromosome.&amp;nbsp; I suspect similar comments are made based on race or other factors.&amp;nbsp; On the other hand, we have teachers (at least in elementary school) who themselves are weak in math (and science?) and are inclined to pass their fear of the subject on to their students.&amp;nbsp; (If the teacher finds something difficult, he or she is likely to communicate to the pupil that the pupil should not worry about finding it challenging.)&amp;nbsp; &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/The_Gripping_Hand" linkindex="24"&gt;On the gripping hand&lt;/a&gt; (and this is purely my conjecture), I suspect we also discourage students of all levels from taking STEM courses by rewarding them for weak work in non-STEM courses.&amp;nbsp; I think it's harder to give inflated grades in STEM subjects because they tend to have definitive correct and incorrect answers.&amp;nbsp; (At least it's harder for me to give them.)&amp;nbsp; At the same time, it's easy for a student to be discouraged at having to work hard for medium grades in STEM subjects when they can get better grades with less effort in other classes.&lt;br /&gt;&lt;br /&gt;What ties this to the STEM crisis, for me, is a &lt;a href="http://www.newsweek.com/2011/01/03/can-you-build-a-better-brain.html" linkindex="25"&gt;recent article in Newsweek&lt;/a&gt; about physiological triggers for improvement (or degradation) in the human brain.&amp;nbsp; Specifically, according to author Sharon Begley,&lt;br /&gt;&lt;blockquote&gt;Finally, being told that you belong to a group that does very well on a test tends to let you do better than if you’re told you belong to a group that does poorly; the latter floods you with cortisol, while the former gives you the wherewithal and dopamine surge to keep plugging away.&lt;/blockquote&gt;So the effect of communicating diminished expectations to students may be more than psychological; it may trigger physiological changes that create a self-fulfilling prophecy ... and, in doing so, deepen the STEM crisis.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-3081989616844775993?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/3081989616844775993/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/01/physiology-and-mathematics-education.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/3081989616844775993'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/3081989616844775993'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/01/physiology-and-mathematics-education.html' title='Physiology and Mathematics Education'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-6400196042807432387</id><published>2011-01-07T18:57:00.001-05:00</published><updated>2011-03-30T11:29:26.997-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='math programming'/><title type='text'>Max and Min Functions in a MIP</title><content type='html'>&lt;script type="text/x-mathjax-config"&gt;MathJax.Hub.Config({  tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}});&lt;/script&gt;&lt;script type="text/javascript"  src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"&gt;&lt;/script&gt;&lt;a href="http://orinanobworld.blogspot.com/2010/12/lps-and-positive-part.html" linkindex="10"&gt;Previously&lt;/a&gt; I wrote about how to work the "positive part" function ($y^+=\max(y,0)$) into a mixed integer programming model. More general uses of the $\max$ and $\min$ functions are really just an extension of this, but the extension may not be entirely obvious. In this post I'll explain how to set $z=\max(x,y)$ in a MIP model, where $x$, $y$ and $z$ are all variables. If the model was in fact a linear program before introducing the $\max$ or $\min$ function, it may remain an LP, or it may become a MIP, depending on exactly what you are doing.&amp;nbsp; I'll use the $\max$ function for explanatory purposes; the necessary tweaks to deal with the $\min$ function are left to the reader as an exercise.&lt;br /&gt;&lt;br /&gt;Let's start with the obvious part: if $z=\max(x,y)$ then $$z\ge x$$ and $$z \ge y.$$In fact, adding those two constraints will be sufficient &lt;i&gt;if&lt;/i&gt; the nature of the model ensures that the smallest feasible value of $z$ will always be chosen&amp;nbsp; Typically this means that (a) $z$ has a positive coefficient in an objective function being minimized, or a negative coefficient in an objective function being maximized, and (b) $z$ does not connect to other variables, through constraints, in a way that might allow an inflated value of $z$ to cause other variables to change enough that their improved objective contribution would more than pay for the damage done by inflating $z$.&lt;br /&gt;&lt;br /&gt;There are also occasional cases where inflation of $z$ is not actually a concern: you need $z$ to be at least as big as both $x$ and $y$ (which the constraints ensure), but a larger than necessary value of $z$ will not affect the objective function or the values of other variables, and can be corrected manually once a solution is found.&lt;br /&gt;&lt;br /&gt;The (slightly) tricky case is when you cannot be sure that the "pressure" of the&amp;nbsp; objective function will prevent inflated values of $z$ from occurring, and you really do need the value of $z$ to be correct.&amp;nbsp; To handle this case, we will need finite bounds for $x$ and $y$, so from here on I will assume that $L_x \le x \le U_x$ and $L_y \le y \le U_y$.&amp;nbsp; We have to introduce a new binary variable $w$, which will switch values depending on whether $x$ or $y$ is the larger of the two. In addition to the two previous constraints, we add the following:$$z \le x + (U_y - L_x)w$$and$$z \le y + (U_x-L_y)(1-w).$$The combined effect of the constraints is that $w=0\implies z=x\ge y$ and $w=1\implies z=y\ge x$.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-6400196042807432387?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/6400196042807432387/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2011/01/max-and-min-functions-in-mip.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/6400196042807432387'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/6400196042807432387'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2011/01/max-and-min-functions-in-mip.html' title='Max and Min Functions in a MIP'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-490506901553603708</id><published>2010-12-26T10:59:00.000-05:00</published><updated>2010-12-26T10:59:35.581-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='math programming'/><category scheme='http://www.blogger.com/atom/ns#' term='operations research'/><title type='text'>Credit Card Rebates</title><content type='html'>Periodically I see questions or comments about how we use operations research in our personal lives.&amp;nbsp; The truth, of course, is that for the most part we don't.&amp;nbsp; We may use the systematic analysis and critical thinking inherent in OR, but generally we neither need nor bother with the mathematical models.&amp;nbsp; (As an example of the "critical thinking", consider the ads you see on TV for insurance companies, touting that "customers who switched to &amp;lt;insert company name&amp;gt; saved an average of &amp;lt;insert large positive amount&amp;gt; on their premiums".&amp;nbsp; A typical viewer may think "wow, they're pretty cheap".&amp;nbsp; An OR person thinks "no kidding -- people with negative savings didn't switch, so the data is censored".)&amp;nbsp; Recently, however, I actually found an application for an OR model in my personal life.&lt;br /&gt;&lt;br /&gt;In the aftermath of the "Financial Debacle of 2008" (or the "Great Recession", or whatever you prefer to call it), banks are scrambling to make money.&amp;nbsp; Thus, among other things, credit card rebate programs have become more byzantine.&amp;nbsp; Once upon a time, my Chase credit card earned rebates that were simply posted monthly, automatically and in the full amount I'd earned.&amp;nbsp; Couldn't have been simpler.&amp;nbsp; Didn't last.&lt;br /&gt;&lt;br /&gt;I now "enjoy" the benefits of the Chase &lt;a href="http://public.ultimaterewards.com/html/about_program.html" linkindex="6"&gt;Ultimate Rewards&lt;/a&gt; program. Rebates are no longer credited automatically; I have to log in each month and claim them.&amp;nbsp; There can be delays in how quickly they post. Rebate balances below $20 cannot be redeemed (they carry over to the following month).&amp;nbsp; I have options for claiming the rewards, including buying things I don't need through Chase (probably at higher than market prices) or asking them to cut me a check (then waiting for it to arrive, then depositing it somewhere).&amp;nbsp; The most convenient (or should I say least inconvenient?) way to redeem them may be what Chase calls the "pay yourself back" option, in which you apply the rebate to purchases made within the past 60 days.&amp;nbsp; The amount redeemed shows up as a credit on your next statement.&lt;br /&gt;&lt;br /&gt;Besides the delay in receiving the credit, there are other minor hassles with the "pay yourself back approach".&amp;nbsp; You cannot pay yourself back for part of a purchase; you must have sufficient rebate credit accumulated to pay back the entire amount.&amp;nbsp; The web form only allows you to pay back one purchase at a time, and the $20 minimum limit applies to each individual redemption, not to the combined set of redemptions.&amp;nbsp; Most of the time, this is a non-issue for me, since it usually takes me more than one billing cycle to accrue a rebate balance above $20, at which point I immediately repay myself for a recent $20+ purchase and drop the remaining balance back below $20, to sit for another cycle or two.&lt;br /&gt;&lt;br /&gt;Occasionally, however, some combination of unusual expenditures gets me a larger balance.&amp;nbsp; The trick then is to find a collection of purchases within the past 60 days, each $20 or more, whose combined total comes closest to my available rebate balance without exceeding it.&amp;nbsp; That's probably trial-and-error for most people, but readers of this blog may recognize the problem as a binary knapsack, where the value and "size" of an item are both the amount charged, the constraint limit is the available rebate balance, and only recent purchases of $20 or more make it into the model.&amp;nbsp; So I now have a spreadsheet containing just that model, which I'll probably need once or perhaps twice a year.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8781383461061929571-490506901553603708?l=orinanobworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://orinanobworld.blogspot.com/feeds/490506901553603708/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://orinanobworld.blogspot.com/2010/12/credit-card-rebates.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/490506901553603708'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8781383461061929571/posts/default/490506901553603708'/><link rel='alternate' type='text/html' href='http://orinanobworld.blogspot.com/2010/12/credit-card-rebates.html' title='Credit Card Rebates'/><author><name>Paul Rubin</name><uri>https://profiles.google.com/111303285497934501993</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-yJxR1ty0gA4/AAAAAAAAAAI/AAAAAAAAAE4/evnwSCx60oM/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8781383461061929571.post-3491220308225555411</id><published>2010-12-24T15:19:00.000-05:00</published><updated>2010-12-24T15:19:56.197-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='math programming'/><category scheme='http://www.blogger.com/atom/ns#' term='whimsy'/><title type='text'>A Seasonal TSP (Traveling Santa Problem)</title><content type='html'>You can tell when academics with blogs are between semesters by the increased frequency of their postings.&amp;nbsp; Yesterday Laura McLay &lt;a href="https://punkrockor.wordpress.com/2010/12/23/a-christmas-brain-teaser/" linkindex="147"&gt;posted a pointer&lt;/a&gt; to a 12-city &lt;a href="http://www.math-drills.com/christmas/santas_route.pdf" linkindex="148"&gt;traveling Santa problem&lt;/a&gt; (PDF file) at &lt;a href="http://math-drills.com/" linkindex="148"&gt;Math-Drills.Com&lt;/a&gt;.&amp;nbsp; Faced with a Christmas Eve choice of (a) paying bills, (b) performing some overdue data analysis for a paper-to-be or (c) playing with a TSP ... well, let's just say that I didn't need the &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/Analytic_hierarchy_process" linkindex="149"&gt;Analytic Hierarchy Process&lt;/a&gt; to sort that one out.&lt;br /&gt;&lt;br /&gt;Slightly (well, very slightly) more seriously, I was curious about the difficulty of the problem.&amp;nbsp; The TSP is one of the quintessential &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/Np-hard" linkindex="150"&gt;NP-hard&lt;/a&gt; problems, with all sorts of special purpose algorithms devised for it.&amp;nbsp; Sometimes, though, I think we confuse NP-hard with hard.&amp;nbsp; NP-hard refers to a &lt;i&gt;class&lt;/i&gt; of problems.&amp;nbsp; At the risk of starting a flame war with purists (which will at least drive up my site stats), all optimization problems get pretty darn hard when they're big enough; we tend to believe that NP-hard problems get pretty darn hard faster than NP-not-so-hard problems as their size grows.&amp;nbsp; What is sometimes overlooked, though, is that all this is a sort of asymptotic result; we can solve not horribly large problems pretty easily (I can do the three city TSP in my head, at least after a cup or two of coffee), and the dividing line between doable and not doable continually shifts with improvements in hardware and software.&lt;br /&gt;&lt;br /&gt;I wasn't really motivated enough to look up the latest and greatest algorithms for TSPs, so I started with an old, and I'm sure now "obsolete", method due I believe to Miller, Tucker and Zemlin ca. 1960.&amp;nbsp; It's a mixed integer linear programming formulation using binary variables to determine which links are included in the Hamiltonian circuit (route).&amp;nbsp; There are additional nonnegative variables that assign what we might call "potentials" to each node.&amp;nbsp; We require each node to be entered and exited once, and we require that any time a link is used, the potential of the destination city be at least one greater than the potential of the origin city, &lt;i&gt;unless&lt;/i&gt; the destination city is the starting point for the circuit (i.e., unless the link closes the loop).&amp;nbsp; The MTZ formulation is more compact than formulations built with subtour elimination constraints (of which exponentially many can occur), but I believe it tends to have weaker bounds (and I've seen some papers on tightening the bounds in the MTZ formulation, but can't recall any details).&lt;br /&gt;&lt;br /&gt;Anyway, driving back and forth between home and the YMCA (one of two loci of physical self-abuse for me), I mapped out a general strategy:&amp;nbsp; write a MILP model using the MTZ approach and see how long it takes to solve (using the Java API to CPLEX 12.2); see if identifying the single entry/single exit constraints as &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/Special_ordered_set" linkindex="151"&gt;SOS1&lt;/a&gt; sets (with "cleverly chosen" weights) helps; maybe try adding cuts on the fly to eliminate dominated segments of the tour (don't go A-B-C-D if A-C-B-D is shorter); maybe try depth-first search; etc., etc.&amp;nbsp; As always, to paraphrase someone (Napoleon?), the first casualty in every battle is the plan.&amp;nbsp; I wrote the basic MILP model with MTZ constraints pretty quickly (copying the data out of the PDF and into the Java editor, suitably reformatted, actually took longer than writing the 
