Sudoku Linear Optimization and the Ten Cent Diet

Originally posted on the Google Research blog. Cross posted on the Google Apps Developers blog

In 1945, future Nobel laureate George Stigler wrote an essay in the Journal of Farm Economics titled The Cost of Subsistence about a seemingly simple problem: how could a soldier be fed for as little money as possible?

The “Stigler Diet” became a classic problem in the then-new field of linear optimization, which is used today in many areas of science and engineering. Any time you have a set of linear constraints such as “at least 50 square meters of solar panels” or “the amount of paint should equal the amount of primer” along with a linear goal (e.g., “minimize cost” or “maximize customers served”), that’s a linear optimization problem.

At Google, our engineers work on plenty of optimization problems. One example is our YouTube video stabilization system, which uses linear optimization to eliminate the shakiness of handheld cameras. A more lighthearted example is in the Google Docs Sudoku add-on, which instantaneously generates and solves Sudoku puzzles inside a Google Sheet, using the SCIP mixed integer programming solver to compute the solution.
Today we’re proud to announce two new ways for everyone to solve linear optimization problems. First, you can now solve linear optimization problems in Google Sheets with the Linear Optimization add-on written by Google Software Engineer Mihai Amarandei-Stavila. The add-on uses Google Apps Script to send optimization problems to Google servers. The solutions are displayed inside the spreadsheet. For developers who want to create their own applications on top of Google Apps, we also provide an API to let you call our linear solver directly.
Second, we’re open-sourcing the linear solver underlying the add-on: Glop (the Google Linear Optimization Package), created by Bruno de Backer with other members of the Google Optimization team. It’s available as part of the or-tools suite and we provide a few examples to get you started. On that page, you’ll find the Glop solution to the Stigler diet problem. (A Google Sheets file that uses Glop and the Linear Optimization add-on to solve the Stigler diet problem is available here. You’ll need to install the add-on first.)

Stigler posed his problem as follows: given nine nutrients (calories, protein, Vitamin C, and so on) and 77 candidate foods, find the foods that could sustain soldiers at minimum cost.

The Simplex algorithm for linear optimization was two years away from being invented, so Stigler had to do his best, arriving at a diet that cost $39.93 per year (in 1939 dollars), or just over ten cents per day. Even that wasn’t the cheapest diet. In 1947, Jack Laderman used Simplex, nine calculator-wielding clerks, and 120 person-days to arrive at the optimal solution.

Glop’s Simplex implementation solves the problem in 300 milliseconds. Unfortunately, Stigler didn’t include taste as a constraint, and so the poor hypothetical soldiers will eat nothing but the following, ever:

  • Enriched wheat flour
  • Liver
  • Cabbage
  • Spinach
  • Navy beans

Is it possible to create an appealing dish out of these five ingredients? Google Chef Anthony Marco took it as a challenge, and we’re calling the result Foie Linéaire à la Stigler:
This optimal meal consists of seared calf liver dredged in flour, atop a navy bean purée with marinated cabbage and a spinach pesto.

Chef Marco reported that the most difficult constraint was making the dish tasty without butter or cream. That said, I had the opportunity to taste our linear optimization solution, and it was delicious.

Read More..

Linear layout

Linear layout is like a box that contains controls inside it. Controls are drawn one after each other either horizontally or vertically according to the Orientation of the layout.


When dealing with Linear layout there are five properties that we can deal with:
  1. Oientation.
  2. Fill model.
  3. Weight
  4. Gravity.
  5. padding.
Orientaition:
Orientation property determines whether the controls would be put in a horizontal way like in a row or in a vertical way like a column. The layout orientation is set by the property android:orientation


Vertical orientation:



<button
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:text="this is a button 1"
/>

<Button
android_layout_width="fill_parent"
android_layout_height="wrap_content"
android_text="this is a button 2"

/>




Horizontal Orientation


<Button
android_layout_width="fill_parent"
android_layout_height="wrap_content"
android_text="this is a button 1"

/>
<Button
android_layout_width="fill_parent"
android_layout_height="wrap_content"
android_text="this is a button 2"

/>




If you want to set the orientation programmatically you can use this code
android.widget.LinearLayout mainLayout=new LinearLayout(this);
mainLayout.setOrientation(LinearLayout.VERTICAL);
Fill Model:
The widgets inside linear layout have width and height properties. These properties can have three values:
  1. A numeric value in pixels or inches that gives the width or height properties an absolute value. 
  2. They can have the value wrap_content meaning the widget should occupy it’s natural size unless there is no space then android can use word wrap to make the widget fit.
  3. They can have the value fill_parent meaning the widget should occupy all the available space of the closing container.
To set the fill model programmitaclly use this code:
Button b=(Button)findViewById(R.id.btn);
b.setWidth(LayoutParams.WRAP_CONTENT);
b.setHeight(LayoutParams.FILL_PARENT);
This is an example to two buttons one with width set to fill_parent and the other set to wrap_content
Weight:
The weight property determines the ratio by which controls share free space. For example if we have two buttons and the weight of both is set to 1 (this is the default value) then the free space will be divided equally between them.
But if the value of the weight of one of them is 2 and the other is one, then the first button will occupy space half as that occupied by the second and so on.


<button
android:layout_height="fill_parent"
android:layout_weight="1"
android:layout_width="fill_parent"
android:text="weight set to 2"
/>
<button
android:id="@+id/btn"
android:layout_height="fill_parent"
android:layout_weight="1"
android:layout_width="fill_parent"
android:text="weight set to 1"
/>


To set the weight of a widget programmatically it’s a little bit different, we use this code:
Button b=(Button)findViewById(R.id.btn);
LayoutParams params=new android.widget.LinearLayout.LayoutParams(android.widget.LinearLayout.LayoutParams.FILL_PARENT,android.widget.LinearLayout.LayoutParams.FILL_PARENT,3);
b.setLayoutParams(params);

the widget does not have a method to set the weight directly, instead you define
LayoutParams params=new android.widget.LinearLayout.LayoutParams 
object and use the widget. setLayoutParams(params) method.
The LayoutParams class has many constructors including this one
public LinearLayout.LayoutParams (int width, int height, float weight)
Gravity:
By default widget are positioned in the top-left of the screen, but if you want to change this you can use the layout_gravity property


<button
android:layout_gravity="left"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="left">
/<button
android:layout_gravity="center"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="center"
/>
<button
android:layout_gravity="center_vertical" android_layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="center_vertical"
/>
<button
android:layout_gravity="center_horizontal" android_layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="center_horizontal"
/>
<button
android:layout_gravity="right"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="right"
/>

<button
android:layout_gravity="bottom"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="bottom"
/>




Or something like this


<button
android:layout_gravity="fill_vertical" android_layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="fill_vertical"
/>
<button
android:layout_gravity="fill_horizontal" android_layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="fill_horizontal"
/>
<button
android:gravity="right"
android:layout_gravity="clip_horizontal" android_layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="clip_horizontal"
/>
<button
android:gravity="top"
android:layout_gravity="clip_vertical" android_layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="clip_vertical"
/>



Notice that values clip_horizontal and clip_vertical are clear if only the android:gravity property is defined. If this property is not defined then the control will be clipped on both edges.

When using android:layout_gravity="clip_horizontal" with android:gravity="right" the control’s left edge will be clipped and if the android:gravity="left" the right edge will be clipped.

When using android:layout_gravity="clip_vertical" with android:gravity="top" the control’s bottom edge will be clipped and if the android:gravity="bottom" the top edge will be clipped.

So what is the difference between the android:layout_gravity and the android:gravity properties:

The android:layout_gravity sets the position of the view in the container, while android:gravity sets the position of the content of the view.


For example if the android:layout_gravity=”right” then the view would be placed in the right position in the container while if the view’s android:gravity=”right” then the text of the view would be placed at the right.


To set the android:gravity property programmatically you can use this code:

Button btn=(Button)findViewById(R.id.btn);
btn.setGravity(Gravity.RIGHT);

Padding:

The android:padding property sets the padding between widgets. if you specify the padding property to the container then the container with all of its widgets would be shifted by the value, if you specify it to a single widget then the contents of that widget would be shifted by the specified value.

If you use the android:padding property then this would apply the padding values to the four edges of the widget. If you need to be more specific you can use :
android:paddingTop or android:paddingLeft or android:paddingRight or android:paddingBottom


<button
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="button 1"
/>
<button
android:id="@+id/btn"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:paddingleft="40px"
android:text="button 2"
/>



Read More..

Blog Archive

Powered by Blogger.