इस सेक्शन में, हम स्टिगलर डाइट नाम की एक क्लासिक समस्या को हल करने का तरीका जानेंगे. इसका नाम अर्थशास्त्र के लिए रखा गया है. नोबेल पुरस्कार विजेता, जॉर्ज स्टिगलर ने एक तरह से सामान्य पोषण की ज़रूरत को पूरा करने के लिए एक सस्ता तरीका खोजा था. उन्होंने इसे खाने के सुझाव देने के बजाय, गणित से जुड़ी एक कसरत के तौर पर पेश किया. हालांकि, बेहतर पोषण की गणना की सोच हाल ही में चलकर शुरू हुई है.
Stigler डाइट के मुताबिक, इन ज़रूरी शर्तों को पूरा करना ज़रूरी है:
न्यूट्रिशन की सूची
न्यूट्रिशन | रोज़ाना सुझाई गई मात्रा |
---|---|
कैलोरी | 3,000 कैलोरी |
प्रोटीन | 70 ग्राम |
कैल्सियम | .8 ग्राम |
आयरन | 12 मिलीग्राम |
विटामिन ए | 5,000 आईयू |
थायमिन (विटामिन B1) | 1.8 मिलीग्राम |
राइबोफ़्लेविन (विटामिन B2) | 2.7 मिलीग्राम |
नायासिन | 18 मिलीग्राम |
ऐस्कोर्बिक ऐसिड (विटामिन सी) | 75 मिलीग्राम |
Stigler का आकलन करने वाले फ़ूड सेट में उस समय (1944) को दर्शाया गया है. नीचे दिया गया न्यूट्रिशनल डेटा, इकाई के हिसाब से नहीं, बल्कि डॉलर के हिसाब से दिया गया है. इसलिए, इसका मकसद यह तय करना है कि खाने की हर चीज़ पर कितने डॉलर खर्च करने हैं.
प्रॉडक्ट की सूची
कमोडिटी | इकाई | 1939 में कीमत (सेंट) | कैलोरी (kcal) | प्रोटीन (ग्राम) | कैल्सियम (ग्राम) | आयरन (मि॰ग्रा॰) | विटामिन ए (केआईयू) | थायमिन (मि॰ग्रा॰) | राइबोफ़्लेविन (मि॰ग्रा॰) | नायसिन (मि॰ग्रा॰) | ऐस्कोर्बिक ऐसिड (मि॰ग्रा॰) |
---|---|---|---|---|---|---|---|---|---|---|---|
गेहूं का आटा (बेहतर बनाया गया) | 10 पाउंड | 36 | 78 जीबी में से | 1411 | 2 | 365 | 0 | 55.4 | 33.3 | 441 | 0 |
सरसों | 1 पाउंड | 14.1 | 11.6 | 418 | 0.7 | 54 | 0 | 3.2 | यूरो | 68 | 0 |
गेहूं का अनाज (समृद्ध) | 28 आउंस | 24.2 | 11.8 | 377 | 14.4 | 175 | 0 | 14.4 | 8.8 | 114 | 0 |
कॉर्न फ़्लेक्स | 8 आउंस | 7.1 | 11.4 | 252 | 0.1 | 56 | 0 | 13.5 | 2.3 | 68 | 0 |
फोड़ा खाना | 1 पाउंड | 4.6 | 36.0 | 897 | 1.7 | 99 | 30.9 | 17.4 | 7.9 | 106 | 0 |
होमिनी ग्रिट्स | 24 आउंस | 8.5 | 28.6 | 680 | 0.8 | 80 | 0 | 10.6 | 1.6 | 110 | 0 |
चावल | 1 पाउंड | 7.5 | 21.2 | 460 | 0.6 | 41 | 0 | 2 | 78 जीबी में से | 60 | 0 |
रोल्ड ओट्स | 1 पाउंड | 7.1 | 78 जीबी में से | 907 | 5.1 | 341 | 0 | 37.1 | 8.9 | 64 | 0 |
व्हाइट ब्रेड (एनरिच्ड) | 1 पाउंड | 7.9 | 15.0 | 488 | 2.5 | 115 | 0 | 13.8 | 8.5 | 126 | 0 |
गेहूं की ब्रेड | 1 पाउंड | 9.1 | 12.2 | 484 | 2.7 | 125 | 0 | 13.9 | 6.4 | 160 | 0 |
राई ब्रेड | 1 पाउंड | 9.1 | 78 जीबी में से | 439 | 1.1 | 82 | 0 | 9.9 | 3 | 66 | 0 |
पाउंड केक | 1 पाउंड | 78 जीबी में से | 8.0 | 130 | 0.4 | 31 | यूरो | 2.8 | 3 | 17 | 0 |
सोडा क्रैकर्स | 1 पाउंड | 15.1 | 12.5 | 288 | 0.5 | 50 | 0 | 0 | 0 | 0 | 0 |
दूध | 1 क्वा. | 11 | 6.1 | 310 | 10.5 | 18 | 16.8 | 4 | 16 | 7 | 177 |
वाष्पीकरण वाला दूध (यह हो सकता है) | 14.5 आउंस | 6.7 | 8.4 | 422 | 15.1 | 9 | 26 | 3 | 23.5 | 11 | 60 |
मक्खन | 1 पाउंड | 30.8 | 10.8 | 9 | 0.2 | 3 | 44.2 | 0 | 0.2 | 2 | 0 |
ओलियोमार्जरिन | 1 पाउंड | 16.1 | 20.6 | 17 | 0.6 | 6 | 55.8 | 0.2 | 0 | 0 | 0 |
अंडे | 1 डोज़. | 32.6 | 2.9 | 238 | 1.0 | 52 | 18.6 | 2.8 | 6.5 | 1 | 0 |
चीज़ (चेडर) | 1 पाउंड | 24.2 | 7.4 | 448 | 16.4 | 19 | 28.1 | 0.8 | 10.3 | 4 | 0 |
क्रीम | 1/2 पॉइंट | 14.1 | 3.5 | 49 | 1.7 | 3 | यूरो | 0.6 | 2.5 | 0 | 17 |
पीनट बटर | 1 पाउंड | यूरो | 15.7 | 661 | 1.0 | 48 | 0 | 9.6 | 8.1 | 471 | 0 |
मायोनीज़ | 1/2 पॉइंट | 16.7 | 8.6 | 18 | 0.2 | 8 | 2.7 | 0.4 | 0.5 | 0 | 0 |
क्रिस्को | 1 पाउंड | 20.3 | 20.1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
लार्ड | 1 पाउंड | 9.8 | 41.7 | 0 | 0 | 0 | 0.2 | 0 | 0.5 | 5 | 0 |
सिरलॉइन स्टीक | 1 पाउंड | 39.6 | 2.9 | 166 | 0.1 | 34 | 0.2 | 2.1 | 2.9 | 69 | 0 |
राउंड स्टीक | 1 पाउंड | 36.4 | 2.2 | 214 | 0.1 | 32 | 0.4 | 2.5 | 2.4 | 87 | 0 |
रिब रोस्ट | 1 पाउंड | 29.2 | 3.4 | 213 | 0.1 | 33 | 0 | 0 | 2 | 0 | 0 |
चक रोस्ट | 1 पाउंड | 78 जीबी में से | 3.6 | 309 | 0.2 | 46 | 0.4 | 1 | 4 | 120 | 0 |
प्लेट | 1 पाउंड | 14.6 | 8.5 | 404 | 0.2 | 62 | 0 | 0.9 | 0 | 0 | 0 |
लिवर (बीफ़) | 1 पाउंड | 26.8 | 2.2 | 333 | 0.2 | 139 | 169.2 | 6.4 | 50.8 | 316 | 525 |
लेग ऑफ़ लैंब | 1 पाउंड | 27.6 | 3.1 | 245 | 0.1 | 20 | 0 | 2.8 | 3.9 | 86 | 0 |
लैंब चॉप (रिब) | 1 पाउंड | 78 जीबी में से | 3.3 | 140 | 0.1 | 15 | 0 | 1.7 | 2.7 | 54 | 0 |
पोर्क चॉप | 1 पाउंड | 78 जीबी में से | 3.5 | 196 | 0.2 | 30 | 0 | 17.4 | 2.7 | 60 | 0 |
पोर्क लोइन रोस्ट | 1 पाउंड | 24.2 | 78 जीबी में से | 249 | 0.3 | 37 | 0 | 18.2 | 3.6 | 79 | 0 |
बेकन | 1 पाउंड | 78 जीबी में से | 10.4 | 152 | 0.2 | 23 | 0 | 1.8 | 1.8 | 71 | 0 |
हैम, स्मोक किया गया | 1 पाउंड | 27.4 | 6.7 | 212 | 0.2 | 31 | 0 | 9.9 | 3.3 | 50 | 0 |
सॉल्ट पोर्क | 1 पाउंड | 16 | 78 जीबी में से | 164 | 0.1 | 26 | 0 | 1.4 | 1.8 | 0 | 0 |
भुनना मुर्गा | 1 पाउंड | 30.3 | 1.8 | 184 | 0.1 | 30 | 0.1 | 0.9 | 1.8 | 68 | 46 |
वील कटलेट | 1 पाउंड | 42.3 | 1.7 | 156 | 0.1 | 24 | 0 | 1.4 | 2.4 | 57 | 0 |
सैमन, गुलाबी (कर सकता है) | 16 आउंस | 13 | 5.8 | 705 | 6.8 | 45 | 3.5 | 1 | 4.9 | 209 | 0 |
सेब | 1 पाउंड | 78 जीबी में से | 5.8 | 27 | 0.5 | 36 | 7.3 | 3.6 | 2.7 | 5 | 544 |
केले | 1 पाउंड | 6.1 | 4.9 | 60 | 0.4 | 30 | 17.4 | 2.5 | 3.5 | 28 | 498 |
नींबू | 1 डोज़. | 26 | 1.0 | 21 | 0.5 | 14 | 0 | 0.5 | 0 | 4 | 952 |
संतरे | 1 डोज़. | 30.9 | 2.2 | 40 | 1.1 | 18 | 11.1 | 3.6 | 1.3 | 10 | 1998 |
ग्रीन बीन्स | 1 पाउंड | 7.1 | 2.4 | 138 | 3.7 | 80 | 69 | 4.3 | 5.8 | 37 | 862 |
गोभी | 1 पाउंड | 3.7 | 2.6 | 125 | 4.0 | 36 | 7.2 | 9 | 4.5 | 26 | 5369 |
गाजर | 1 बंडल | 4.7 | 2.7 | 73 | 2.8 | 43 | 188.5 | 6.1 | 4.3 | 89 | 608 |
सेलरी | 1 स्टॉक | 7.3 | 0.9 | 51 | 3.0 | 23 | 0.9 | 1.4 | 1.4 | 9 | 313 |
याहू! मैसेंजर | 1 सिर | 8.2 | 0.4 | 27 | 1.1 | 22 | 112.4 | 1.8 | 3.4 | 11 | 449 |
अनियन | 1 पाउंड | 3.6 | 5.8 | 166 | 78 जीबी में से | 59 | 16.6 | 4.7 | 5.9 | 21 | 1184 |
आलू | 15 पाउंड | 34 | 14.3 | 336 | 1.8 | 118 | 6.7 | 29.4 | 7.1 | 198 | 2522 |
पालक | 1 पाउंड | 8.1 | 1.1 | 106 | 0 | 138 | 918.4 | 5.7 | 13.8 | 33 | 2755 |
मीठे आलू | 1 पाउंड | 5.1 | 9.6 | 138 | 2.7 | 54 | 290.7 | 8.4 | 5.4 | 83 | 1912 |
आड़ू (क्या-क्या किया जा सकता है) | नंबर 2 1/2 | 16.8 | 3.7 | 20 | 0.4 | 10 | 21.5 | 0.5 | 1 | 31 | 196 |
नाशपाती (कैन) | नंबर 2 1/2 | 20.4 | 3.0 | 8 | 0.3 | 8 | 0.8 | 0.8 | 0.8 | 5 | 81 |
अनन्नास (कर सकता है) | नंबर 2 1/2 | 21.3 | 2.4 | 16 | 0.4 | 8 | 2 | 2.8 | 0.8 | 7 | 399 |
एस्पैरेगस (यह हो सकता है) | नंबर 2 | 78 जीबी में से | 0.4 | 33 | 0.3 | 12 | 16.3 | 1.4 | 2.1 | 17 | 272 |
ग्रीन बीन्स (कर सकते हैं) | नंबर 2 | 10 | 1.0 | 54 | 2 | 65 | 53.9 | 1.6 | 4.3 | 32 | 431 |
पोर्क और बीन (कर सकते हैं) | 16 आउंस | 7.1 | 7.5 | 364 | 4 | 134 | 3.5 | 8.3 | 7.7 | 56 | 0 |
फोड़ा (कैन) | नंबर 2 | 10.4 | 5.2 | 136 | 0.2 | 16 | 12 | 1.6 | 2.7 | 42 | 218 |
मटर (कर सकते हैं) | नंबर 2 | 13.8 | 2.3 | 136 | 0.6 | 45 | 34.9 | 4.9 | 2.5 | 37 | 370 |
टमाटर (कर सकते हैं) | नंबर 2 | 8.6 | 1.3 | 63 | 0.7 | 38 | 53.2 | 3.4 | 2.5 | 36 | 1253 |
टमाटर का सूप (कैन) | 10 1/2 आउंस | 7.6 | 1.6 | 71 | 0.6 | 43 | 57.9 | 3.5 | 2.4 | 67 | 862 |
आड़ू, सूखे हुए | 1 पाउंड | 15.7 | 8.5 | 87 | 1.7 | 173 | 86.8 | 1.2 | 4.3 | 55 | 57 |
आलून, सूखे हुए | 1 पाउंड | 9 | 78 जीबी में से | 99 | 2.5 | 154 | 85.7 | 3.9 | 4.3 | 65 | 257 |
रेज़िन, सूखे हुए | 15 आउंस | 9.4 | 13.5 | 104 | 2.5 | 136 | 4.5 | 6.3 | 1.4 | 24 | 136 |
मटर, सूखे हुए | 1 पाउंड | 7.9 | 20.0 | 1367 | 4.2 | 345 | 2.9 | 28.7 | 18.4 | 162 | 0 |
लिमा बीन, सूखे हुए | 1 पाउंड | 8.9 | 17.4 | 1055 | 3.7 | 459 | 5.1 | 26.9 | 38.2 | 93 | 0 |
नेवी बीन, सूखे हुए | 1 पाउंड | 5.9 | 26.9 | 1691 | 11.4 | 792 | 0 | 38.4 | 78 जीबी में से | 217 | 0 |
कॉफ़ी | 1 पाउंड | 78 जीबी में से | 0 | 0 | 0 | 0 | 0 | 4 | 5.1 | 50 | 0 |
चाय | 1/4 पाउंड | 17.4 | 0 | 0 | 0 | 0 | 0 | 0 | 2.3 | 42 | 0 |
कोकोआ | 8 आउंस | 8.6 | 8.7 | 237 | 3 | 72 | 0 | 2 | 11.9 | 40 | 0 |
चॉकलेट | 8 आउंस | 16.2 | 8.0 | 77 | 1.3 | 39 | 0 | 0.9 | 3.4 | 14 | 0 |
शुगर | 10 पाउंड | 51.7 | 34.9 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
कॉर्न सिरप | 24 आउंस | 13.7 | 14.7 | 0 | 0.5 | 74 | 0 | 0 | 0 | 5 | 0 |
मोलासेस | 18 आउंस | 13.6 | 9.0 | 0 | 10.3 | 244 | 0 | यूरो | 7.5 | 146 | 0 |
स्ट्रॉबेरी प्रिज़र्व | 1 पाउंड | 20.5 | 6.4 | 11 | 0.4 | 7 | 0.2 | 0.2 | 0.4 | 3 | 0 |
कीमत के हिसाब से हमने सभी पोषक तत्वों को सामान्य कीमत पर तय किया है, इसलिए हमारा मकसद सिर्फ़ खाने की चीज़ों की संख्या को कम करना है.
1944 में, स्टिगलर ने सबसे अच्छे जवाब की गणना की, जिसमें उन्हें दुख भी हुआ:
...सीधे तौर पर, लीनियर फ़ंक्शन की कम से कम वैल्यू का पता लगाने का कोई सीधा तरीका नहीं है.
उन्हें एक डाइट मिली, जिसकी कीमत 1939 डॉलर में हर साल 39.93 डॉलर थी. 1947 में, जैक लेडरमैन ने इष्टतम समाधान तय करने के लिए सिंप्लेक्स तरीके (उस समय, हाल ही के आविष्कार!) का इस्तेमाल किया. डेस्क कैलकुलेटर पर मौजूद नौ क्लर्कों को इस सवाल का जवाब देने में 120 कामकाजी दिन लगे.
लीनियर सॉल्वर की मदद से हल करना
यहां दिए गए सेक्शन में, स्टिगलर डाइट से जुड़ी समस्या को हल करने वाला प्रोग्राम बताया गया है.
लीनियर सॉल्वर रैपर इंपोर्ट करना
OR-टूल लीनियर सॉल्वर रैपर इंपोर्ट करें. यह [GLOP](/ऑप्टिमाइज़ेशन/mip/Glop0 लीनियर सॉल्वर) के लिए एक इंटरफ़ेस है, जैसा कि यहां दिखाया गया है.
Python
from ortools.linear_solver import pywraplp
C++
#include <array> #include <memory> #include <string> #include <utility> // std::pair #include <vector> #include "absl/flags/flag.h" #include "absl/log/flags.h" #include "ortools/base/init_google.h" #include "ortools/base/logging.h" #include "ortools/linear_solver/linear_solver.h"
Java
import com.google.ortools.Loader; import com.google.ortools.linearsolver.MPConstraint; import com.google.ortools.linearsolver.MPObjective; import com.google.ortools.linearsolver.MPSolver; import com.google.ortools.linearsolver.MPVariable; import java.util.ArrayList; import java.util.List;
C#
using System; using System.Collections.Generic; using Google.OrTools.LinearSolver;
समस्या के लिए डेटा
यह कोड, कम से कम पोषक तत्वों की ज़रूरी शर्तों के लिए एक कलेक्शन nutrients
बनाता है. साथ ही, किसी भी सलूशन में न्यूट्रिशनल डेटा टेबल के लिए, एक ऐरे data
बनाता है.
Python
# Nutrient minimums. nutrients = [ ["Calories (kcal)", 3], ["Protein (g)", 70], ["Calcium (g)", 0.8], ["Iron (mg)", 12], ["Vitamin A (KIU)", 5], ["Vitamin B1 (mg)", 1.8], ["Vitamin B2 (mg)", 2.7], ["Niacin (mg)", 18], ["Vitamin C (mg)", 75], ] # Commodity, Unit, 1939 price (cents), Calories (kcal), Protein (g), # Calcium (g), Iron (mg), Vitamin A (KIU), Vitamin B1 (mg), Vitamin B2 (mg), # Niacin (mg), Vitamin C (mg) data = [ # fmt: off ['Wheat Flour (Enriched)', '10 lb.', 36, 44.7, 1411, 2, 365, 0, 55.4, 33.3, 441, 0], ['Macaroni', '1 lb.', 14.1, 11.6, 418, 0.7, 54, 0, 3.2, 1.9, 68, 0], ['Wheat Cereal (Enriched)', '28 oz.', 24.2, 11.8, 377, 14.4, 175, 0, 14.4, 8.8, 114, 0], ['Corn Flakes', '8 oz.', 7.1, 11.4, 252, 0.1, 56, 0, 13.5, 2.3, 68, 0], ['Corn Meal', '1 lb.', 4.6, 36.0, 897, 1.7, 99, 30.9, 17.4, 7.9, 106, 0], ['Hominy Grits', '24 oz.', 8.5, 28.6, 680, 0.8, 80, 0, 10.6, 1.6, 110, 0], ['Rice', '1 lb.', 7.5, 21.2, 460, 0.6, 41, 0, 2, 4.8, 60, 0], ['Rolled Oats', '1 lb.', 7.1, 25.3, 907, 5.1, 341, 0, 37.1, 8.9, 64, 0], ['White Bread (Enriched)', '1 lb.', 7.9, 15.0, 488, 2.5, 115, 0, 13.8, 8.5, 126, 0], ['Whole Wheat Bread', '1 lb.', 9.1, 12.2, 484, 2.7, 125, 0, 13.9, 6.4, 160, 0], ['Rye Bread', '1 lb.', 9.1, 12.4, 439, 1.1, 82, 0, 9.9, 3, 66, 0], ['Pound Cake', '1 lb.', 24.8, 8.0, 130, 0.4, 31, 18.9, 2.8, 3, 17, 0], ['Soda Crackers', '1 lb.', 15.1, 12.5, 288, 0.5, 50, 0, 0, 0, 0, 0], ['Milk', '1 qt.', 11, 6.1, 310, 10.5, 18, 16.8, 4, 16, 7, 177], ['Evaporated Milk (can)', '14.5 oz.', 6.7, 8.4, 422, 15.1, 9, 26, 3, 23.5, 11, 60], ['Butter', '1 lb.', 30.8, 10.8, 9, 0.2, 3, 44.2, 0, 0.2, 2, 0], ['Oleomargarine', '1 lb.', 16.1, 20.6, 17, 0.6, 6, 55.8, 0.2, 0, 0, 0], ['Eggs', '1 doz.', 32.6, 2.9, 238, 1.0, 52, 18.6, 2.8, 6.5, 1, 0], ['Cheese (Cheddar)', '1 lb.', 24.2, 7.4, 448, 16.4, 19, 28.1, 0.8, 10.3, 4, 0], ['Cream', '1/2 pt.', 14.1, 3.5, 49, 1.7, 3, 16.9, 0.6, 2.5, 0, 17], ['Peanut Butter', '1 lb.', 17.9, 15.7, 661, 1.0, 48, 0, 9.6, 8.1, 471, 0], ['Mayonnaise', '1/2 pt.', 16.7, 8.6, 18, 0.2, 8, 2.7, 0.4, 0.5, 0, 0], ['Crisco', '1 lb.', 20.3, 20.1, 0, 0, 0, 0, 0, 0, 0, 0], ['Lard', '1 lb.', 9.8, 41.7, 0, 0, 0, 0.2, 0, 0.5, 5, 0], ['Sirloin Steak', '1 lb.', 39.6, 2.9, 166, 0.1, 34, 0.2, 2.1, 2.9, 69, 0], ['Round Steak', '1 lb.', 36.4, 2.2, 214, 0.1, 32, 0.4, 2.5, 2.4, 87, 0], ['Rib Roast', '1 lb.', 29.2, 3.4, 213, 0.1, 33, 0, 0, 2, 0, 0], ['Chuck Roast', '1 lb.', 22.6, 3.6, 309, 0.2, 46, 0.4, 1, 4, 120, 0], ['Plate', '1 lb.', 14.6, 8.5, 404, 0.2, 62, 0, 0.9, 0, 0, 0], ['Liver (Beef)', '1 lb.', 26.8, 2.2, 333, 0.2, 139, 169.2, 6.4, 50.8, 316, 525], ['Leg of Lamb', '1 lb.', 27.6, 3.1, 245, 0.1, 20, 0, 2.8, 3.9, 86, 0], ['Lamb Chops (Rib)', '1 lb.', 36.6, 3.3, 140, 0.1, 15, 0, 1.7, 2.7, 54, 0], ['Pork Chops', '1 lb.', 30.7, 3.5, 196, 0.2, 30, 0, 17.4, 2.7, 60, 0], ['Pork Loin Roast', '1 lb.', 24.2, 4.4, 249, 0.3, 37, 0, 18.2, 3.6, 79, 0], ['Bacon', '1 lb.', 25.6, 10.4, 152, 0.2, 23, 0, 1.8, 1.8, 71, 0], ['Ham, smoked', '1 lb.', 27.4, 6.7, 212, 0.2, 31, 0, 9.9, 3.3, 50, 0], ['Salt Pork', '1 lb.', 16, 18.8, 164, 0.1, 26, 0, 1.4, 1.8, 0, 0], ['Roasting Chicken', '1 lb.', 30.3, 1.8, 184, 0.1, 30, 0.1, 0.9, 1.8, 68, 46], ['Veal Cutlets', '1 lb.', 42.3, 1.7, 156, 0.1, 24, 0, 1.4, 2.4, 57, 0], ['Salmon, Pink (can)', '16 oz.', 13, 5.8, 705, 6.8, 45, 3.5, 1, 4.9, 209, 0], ['Apples', '1 lb.', 4.4, 5.8, 27, 0.5, 36, 7.3, 3.6, 2.7, 5, 544], ['Bananas', '1 lb.', 6.1, 4.9, 60, 0.4, 30, 17.4, 2.5, 3.5, 28, 498], ['Lemons', '1 doz.', 26, 1.0, 21, 0.5, 14, 0, 0.5, 0, 4, 952], ['Oranges', '1 doz.', 30.9, 2.2, 40, 1.1, 18, 11.1, 3.6, 1.3, 10, 1998], ['Green Beans', '1 lb.', 7.1, 2.4, 138, 3.7, 80, 69, 4.3, 5.8, 37, 862], ['Cabbage', '1 lb.', 3.7, 2.6, 125, 4.0, 36, 7.2, 9, 4.5, 26, 5369], ['Carrots', '1 bunch', 4.7, 2.7, 73, 2.8, 43, 188.5, 6.1, 4.3, 89, 608], ['Celery', '1 stalk', 7.3, 0.9, 51, 3.0, 23, 0.9, 1.4, 1.4, 9, 313], ['Lettuce', '1 head', 8.2, 0.4, 27, 1.1, 22, 112.4, 1.8, 3.4, 11, 449], ['Onions', '1 lb.', 3.6, 5.8, 166, 3.8, 59, 16.6, 4.7, 5.9, 21, 1184], ['Potatoes', '15 lb.', 34, 14.3, 336, 1.8, 118, 6.7, 29.4, 7.1, 198, 2522], ['Spinach', '1 lb.', 8.1, 1.1, 106, 0, 138, 918.4, 5.7, 13.8, 33, 2755], ['Sweet Potatoes', '1 lb.', 5.1, 9.6, 138, 2.7, 54, 290.7, 8.4, 5.4, 83, 1912], ['Peaches (can)', 'No. 2 1/2', 16.8, 3.7, 20, 0.4, 10, 21.5, 0.5, 1, 31, 196], ['Pears (can)', 'No. 2 1/2', 20.4, 3.0, 8, 0.3, 8, 0.8, 0.8, 0.8, 5, 81], ['Pineapple (can)', 'No. 2 1/2', 21.3, 2.4, 16, 0.4, 8, 2, 2.8, 0.8, 7, 399], ['Asparagus (can)', 'No. 2', 27.7, 0.4, 33, 0.3, 12, 16.3, 1.4, 2.1, 17, 272], ['Green Beans (can)', 'No. 2', 10, 1.0, 54, 2, 65, 53.9, 1.6, 4.3, 32, 431], ['Pork and Beans (can)', '16 oz.', 7.1, 7.5, 364, 4, 134, 3.5, 8.3, 7.7, 56, 0], ['Corn (can)', 'No. 2', 10.4, 5.2, 136, 0.2, 16, 12, 1.6, 2.7, 42, 218], ['Peas (can)', 'No. 2', 13.8, 2.3, 136, 0.6, 45, 34.9, 4.9, 2.5, 37, 370], ['Tomatoes (can)', 'No. 2', 8.6, 1.3, 63, 0.7, 38, 53.2, 3.4, 2.5, 36, 1253], ['Tomato Soup (can)', '10 1/2 oz.', 7.6, 1.6, 71, 0.6, 43, 57.9, 3.5, 2.4, 67, 862], ['Peaches, Dried', '1 lb.', 15.7, 8.5, 87, 1.7, 173, 86.8, 1.2, 4.3, 55, 57], ['Prunes, Dried', '1 lb.', 9, 12.8, 99, 2.5, 154, 85.7, 3.9, 4.3, 65, 257], ['Raisins, Dried', '15 oz.', 9.4, 13.5, 104, 2.5, 136, 4.5, 6.3, 1.4, 24, 136], ['Peas, Dried', '1 lb.', 7.9, 20.0, 1367, 4.2, 345, 2.9, 28.7, 18.4, 162, 0], ['Lima Beans, Dried', '1 lb.', 8.9, 17.4, 1055, 3.7, 459, 5.1, 26.9, 38.2, 93, 0], ['Navy Beans, Dried', '1 lb.', 5.9, 26.9, 1691, 11.4, 792, 0, 38.4, 24.6, 217, 0], ['Coffee', '1 lb.', 22.4, 0, 0, 0, 0, 0, 4, 5.1, 50, 0], ['Tea', '1/4 lb.', 17.4, 0, 0, 0, 0, 0, 0, 2.3, 42, 0], ['Cocoa', '8 oz.', 8.6, 8.7, 237, 3, 72, 0, 2, 11.9, 40, 0], ['Chocolate', '8 oz.', 16.2, 8.0, 77, 1.3, 39, 0, 0.9, 3.4, 14, 0], ['Sugar', '10 lb.', 51.7, 34.9, 0, 0, 0, 0, 0, 0, 0, 0], ['Corn Syrup', '24 oz.', 13.7, 14.7, 0, 0.5, 74, 0, 0, 0, 5, 0], ['Molasses', '18 oz.', 13.6, 9.0, 0, 10.3, 244, 0, 1.9, 7.5, 146, 0], ['Strawberry Preserves', '1 lb.', 20.5, 6.4, 11, 0.4, 7, 0.2, 0.2, 0.4, 3, 0], # fmt: on ]
C++
// Nutrient minimums. const std::vector<std::pair<std::string, double>> nutrients = { {"Calories (kcal)", 3.0}, {"Protein (g)", 70.0}, {"Calcium (g)", 0.8}, {"Iron (mg)", 12.0}, {"Vitamin A (kIU)", 5.0}, {"Vitamin B1 (mg)", 1.8}, {"Vitamin B2 (mg)", 2.7}, {"Niacin (mg)", 18.0}, {"Vitamin C (mg)", 75.0}}; struct Commodity { std::string name; //!< Commodity name std::string unit; //!< Unit double price; //!< 1939 price per unit (cents) //! Calories (kcal), //! Protein (g), //! Calcium (g), //! Iron (mg), //! Vitamin A (kIU), //! Vitamin B1 (mg), //! Vitamin B2 (mg), //! Niacin (mg), //! Vitamin C (mg) std::array<double, 9> nutrients; }; std::vector<Commodity> data = { {"Wheat Flour (Enriched)", "10 lb.", 36, {44.7, 1411, 2, 365, 0, 55.4, 33.3, 441, 0}}, {"Macaroni", "1 lb.", 14.1, {11.6, 418, 0.7, 54, 0, 3.2, 1.9, 68, 0}}, {"Wheat Cereal (Enriched)", "28 oz.", 24.2, {11.8, 377, 14.4, 175, 0, 14.4, 8.8, 114, 0}}, {"Corn Flakes", "8 oz.", 7.1, {11.4, 252, 0.1, 56, 0, 13.5, 2.3, 68, 0}}, {"Corn Meal", "1 lb.", 4.6, {36.0, 897, 1.7, 99, 30.9, 17.4, 7.9, 106, 0}}, {"Hominy Grits", "24 oz.", 8.5, {28.6, 680, 0.8, 80, 0, 10.6, 1.6, 110, 0}}, {"Rice", "1 lb.", 7.5, {21.2, 460, 0.6, 41, 0, 2, 4.8, 60, 0}}, {"Rolled Oats", "1 lb.", 7.1, {25.3, 907, 5.1, 341, 0, 37.1, 8.9, 64, 0}}, {"White Bread (Enriched)", "1 lb.", 7.9, {15.0, 488, 2.5, 115, 0, 13.8, 8.5, 126, 0}}, {"Whole Wheat Bread", "1 lb.", 9.1, {12.2, 484, 2.7, 125, 0, 13.9, 6.4, 160, 0}}, {"Rye Bread", "1 lb.", 9.1, {12.4, 439, 1.1, 82, 0, 9.9, 3, 66, 0}}, {"Pound Cake", "1 lb.", 24.8, {8.0, 130, 0.4, 31, 18.9, 2.8, 3, 17, 0}}, {"Soda Crackers", "1 lb.", 15.1, {12.5, 288, 0.5, 50, 0, 0, 0, 0, 0}}, {"Milk", "1 qt.", 11, {6.1, 310, 10.5, 18, 16.8, 4, 16, 7, 177}}, {"Evaporated Milk (can)", "14.5 oz.", 6.7, {8.4, 422, 15.1, 9, 26, 3, 23.5, 11, 60}}, {"Butter", "1 lb.", 30.8, {10.8, 9, 0.2, 3, 44.2, 0, 0.2, 2, 0}}, {"Oleomargarine", "1 lb.", 16.1, {20.6, 17, 0.6, 6, 55.8, 0.2, 0, 0, 0}}, {"Eggs", "1 doz.", 32.6, {2.9, 238, 1.0, 52, 18.6, 2.8, 6.5, 1, 0}}, {"Cheese (Cheddar)", "1 lb.", 24.2, {7.4, 448, 16.4, 19, 28.1, 0.8, 10.3, 4, 0}}, {"Cream", "1/2 pt.", 14.1, {3.5, 49, 1.7, 3, 16.9, 0.6, 2.5, 0, 17}}, {"Peanut Butter", "1 lb.", 17.9, {15.7, 661, 1.0, 48, 0, 9.6, 8.1, 471, 0}}, {"Mayonnaise", "1/2 pt.", 16.7, {8.6, 18, 0.2, 8, 2.7, 0.4, 0.5, 0, 0}}, {"Crisco", "1 lb.", 20.3, {20.1, 0, 0, 0, 0, 0, 0, 0, 0}}, {"Lard", "1 lb.", 9.8, {41.7, 0, 0, 0, 0.2, 0, 0.5, 5, 0}}, {"Sirloin Steak", "1 lb.", 39.6, {2.9, 166, 0.1, 34, 0.2, 2.1, 2.9, 69, 0}}, {"Round Steak", "1 lb.", 36.4, {2.2, 214, 0.1, 32, 0.4, 2.5, 2.4, 87, 0}}, {"Rib Roast", "1 lb.", 29.2, {3.4, 213, 0.1, 33, 0, 0, 2, 0, 0}}, {"Chuck Roast", "1 lb.", 22.6, {3.6, 309, 0.2, 46, 0.4, 1, 4, 120, 0}}, {"Plate", "1 lb.", 14.6, {8.5, 404, 0.2, 62, 0, 0.9, 0, 0, 0}}, {"Liver (Beef)", "1 lb.", 26.8, {2.2, 333, 0.2, 139, 169.2, 6.4, 50.8, 316, 525}}, {"Leg of Lamb", "1 lb.", 27.6, {3.1, 245, 0.1, 20, 0, 2.8, 3.9, 86, 0}}, {"Lamb Chops (Rib)", "1 lb.", 36.6, {3.3, 140, 0.1, 15, 0, 1.7, 2.7, 54, 0}}, {"Pork Chops", "1 lb.", 30.7, {3.5, 196, 0.2, 30, 0, 17.4, 2.7, 60, 0}}, {"Pork Loin Roast", "1 lb.", 24.2, {4.4, 249, 0.3, 37, 0, 18.2, 3.6, 79, 0}}, {"Bacon", "1 lb.", 25.6, {10.4, 152, 0.2, 23, 0, 1.8, 1.8, 71, 0}}, {"Ham, smoked", "1 lb.", 27.4, {6.7, 212, 0.2, 31, 0, 9.9, 3.3, 50, 0}}, {"Salt Pork", "1 lb.", 16, {18.8, 164, 0.1, 26, 0, 1.4, 1.8, 0, 0}}, {"Roasting Chicken", "1 lb.", 30.3, {1.8, 184, 0.1, 30, 0.1, 0.9, 1.8, 68, 46}}, {"Veal Cutlets", "1 lb.", 42.3, {1.7, 156, 0.1, 24, 0, 1.4, 2.4, 57, 0}}, {"Salmon, Pink (can)", "16 oz.", 13, {5.8, 705, 6.8, 45, 3.5, 1, 4.9, 209, 0}}, {"Apples", "1 lb.", 4.4, {5.8, 27, 0.5, 36, 7.3, 3.6, 2.7, 5, 544}}, {"Bananas", "1 lb.", 6.1, {4.9, 60, 0.4, 30, 17.4, 2.5, 3.5, 28, 498}}, {"Lemons", "1 doz.", 26, {1.0, 21, 0.5, 14, 0, 0.5, 0, 4, 952}}, {"Oranges", "1 doz.", 30.9, {2.2, 40, 1.1, 18, 11.1, 3.6, 1.3, 10, 1998}}, {"Green Beans", "1 lb.", 7.1, {2.4, 138, 3.7, 80, 69, 4.3, 5.8, 37, 862}}, {"Cabbage", "1 lb.", 3.7, {2.6, 125, 4.0, 36, 7.2, 9, 4.5, 26, 5369}}, {"Carrots", "1 bunch", 4.7, {2.7, 73, 2.8, 43, 188.5, 6.1, 4.3, 89, 608}}, {"Celery", "1 stalk", 7.3, {0.9, 51, 3.0, 23, 0.9, 1.4, 1.4, 9, 313}}, {"Lettuce", "1 head", 8.2, {0.4, 27, 1.1, 22, 112.4, 1.8, 3.4, 11, 449}}, {"Onions", "1 lb.", 3.6, {5.8, 166, 3.8, 59, 16.6, 4.7, 5.9, 21, 1184}}, {"Potatoes", "15 lb.", 34, {14.3, 336, 1.8, 118, 6.7, 29.4, 7.1, 198, 2522}}, {"Spinach", "1 lb.", 8.1, {1.1, 106, 0, 138, 918.4, 5.7, 13.8, 33, 2755}}, {"Sweet Potatoes", "1 lb.", 5.1, {9.6, 138, 2.7, 54, 290.7, 8.4, 5.4, 83, 1912}}, {"Peaches (can)", "No. 2 1/2", 16.8, {3.7, 20, 0.4, 10, 21.5, 0.5, 1, 31, 196}}, {"Pears (can)", "No. 2 1/2", 20.4, {3.0, 8, 0.3, 8, 0.8, 0.8, 0.8, 5, 81}}, {"Pineapple (can)", "No. 2 1/2", 21.3, {2.4, 16, 0.4, 8, 2, 2.8, 0.8, 7, 399}}, {"Asparagus (can)", "No. 2", 27.7, {0.4, 33, 0.3, 12, 16.3, 1.4, 2.1, 17, 272}}, {"Green Beans (can)", "No. 2", 10, {1.0, 54, 2, 65, 53.9, 1.6, 4.3, 32, 431}}, {"Pork and Beans (can)", "16 oz.", 7.1, {7.5, 364, 4, 134, 3.5, 8.3, 7.7, 56, 0}}, {"Corn (can)", "No. 2", 10.4, {5.2, 136, 0.2, 16, 12, 1.6, 2.7, 42, 218}}, {"Peas (can)", "No. 2", 13.8, {2.3, 136, 0.6, 45, 34.9, 4.9, 2.5, 37, 370}}, {"Tomatoes (can)", "No. 2", 8.6, {1.3, 63, 0.7, 38, 53.2, 3.4, 2.5, 36, 1253}}, {"Tomato Soup (can)", "10 1/2 oz.", 7.6, {1.6, 71, 0.6, 43, 57.9, 3.5, 2.4, 67, 862}}, {"Peaches, Dried", "1 lb.", 15.7, {8.5, 87, 1.7, 173, 86.8, 1.2, 4.3, 55, 57}}, {"Prunes, Dried", "1 lb.", 9, {12.8, 99, 2.5, 154, 85.7, 3.9, 4.3, 65, 257}}, {"Raisins, Dried", "15 oz.", 9.4, {13.5, 104, 2.5, 136, 4.5, 6.3, 1.4, 24, 136}}, {"Peas, Dried", "1 lb.", 7.9, {20.0, 1367, 4.2, 345, 2.9, 28.7, 18.4, 162, 0}}, {"Lima Beans, Dried", "1 lb.", 8.9, {17.4, 1055, 3.7, 459, 5.1, 26.9, 38.2, 93, 0}}, {"Navy Beans, Dried", "1 lb.", 5.9, {26.9, 1691, 11.4, 792, 0, 38.4, 24.6, 217, 0}}, {"Coffee", "1 lb.", 22.4, {0, 0, 0, 0, 0, 4, 5.1, 50, 0}}, {"Tea", "1/4 lb.", 17.4, {0, 0, 0, 0, 0, 0, 2.3, 42, 0}}, {"Cocoa", "8 oz.", 8.6, {8.7, 237, 3, 72, 0, 2, 11.9, 40, 0}}, {"Chocolate", "8 oz.", 16.2, {8.0, 77, 1.3, 39, 0, 0.9, 3.4, 14, 0}}, {"Sugar", "10 lb.", 51.7, {34.9, 0, 0, 0, 0, 0, 0, 0, 0}}, {"Corn Syrup", "24 oz.", 13.7, {14.7, 0, 0.5, 74, 0, 0, 0, 5, 0}}, {"Molasses", "18 oz.", 13.6, {9.0, 0, 10.3, 244, 0, 1.9, 7.5, 146, 0}}, {"Strawberry Preserves", "1 lb.", 20.5, {6.4, 11, 0.4, 7, 0.2, 0.2, 0.4, 3, 0}}};
Java
// Nutrient minimums. List<Object[]> nutrients = new ArrayList<>(); nutrients.add(new Object[] {"Calories (kcal)", 3.0}); nutrients.add(new Object[] {"Protein (g)", 70.0}); nutrients.add(new Object[] {"Calcium (g)", 0.8}); nutrients.add(new Object[] {"Iron (mg)", 12.0}); nutrients.add(new Object[] {"Vitamin A (kIU)", 5.0}); nutrients.add(new Object[] {"Vitamin B1 (mg)", 1.8}); nutrients.add(new Object[] {"Vitamin B2 (mg)", 2.7}); nutrients.add(new Object[] {"Niacin (mg)", 18.0}); nutrients.add(new Object[] {"Vitamin C (mg)", 75.0}); List<Object[]> data = new ArrayList<>(); data.add(new Object[] {"Wheat Flour (Enriched)", "10 lb.", 36, new double[] {44.7, 1411, 2, 365, 0, 55.4, 33.3, 441, 0}}); data.add(new Object[] { "Macaroni", "1 lb.", 14.1, new double[] {11.6, 418, 0.7, 54, 0, 3.2, 1.9, 68, 0}}); data.add(new Object[] {"Wheat Cereal (Enriched)", "28 oz.", 24.2, new double[] {11.8, 377, 14.4, 175, 0, 14.4, 8.8, 114, 0}}); data.add(new Object[] { "Corn Flakes", "8 oz.", 7.1, new double[] {11.4, 252, 0.1, 56, 0, 13.5, 2.3, 68, 0}}); data.add(new Object[] { "Corn Meal", "1 lb.", 4.6, new double[] {36.0, 897, 1.7, 99, 30.9, 17.4, 7.9, 106, 0}}); data.add(new Object[] { "Hominy Grits", "24 oz.", 8.5, new double[] {28.6, 680, 0.8, 80, 0, 10.6, 1.6, 110, 0}}); data.add( new Object[] {"Rice", "1 lb.", 7.5, new double[] {21.2, 460, 0.6, 41, 0, 2, 4.8, 60, 0}}); data.add(new Object[] { "Rolled Oats", "1 lb.", 7.1, new double[] {25.3, 907, 5.1, 341, 0, 37.1, 8.9, 64, 0}}); data.add(new Object[] {"White Bread (Enriched)", "1 lb.", 7.9, new double[] {15.0, 488, 2.5, 115, 0, 13.8, 8.5, 126, 0}}); data.add(new Object[] {"Whole Wheat Bread", "1 lb.", 9.1, new double[] {12.2, 484, 2.7, 125, 0, 13.9, 6.4, 160, 0}}); data.add(new Object[] { "Rye Bread", "1 lb.", 9.1, new double[] {12.4, 439, 1.1, 82, 0, 9.9, 3, 66, 0}}); data.add(new Object[] { "Pound Cake", "1 lb.", 24.8, new double[] {8.0, 130, 0.4, 31, 18.9, 2.8, 3, 17, 0}}); data.add(new Object[] { "Soda Crackers", "1 lb.", 15.1, new double[] {12.5, 288, 0.5, 50, 0, 0, 0, 0, 0}}); data.add( new Object[] {"Milk", "1 qt.", 11, new double[] {6.1, 310, 10.5, 18, 16.8, 4, 16, 7, 177}}); data.add(new Object[] {"Evaporated Milk (can)", "14.5 oz.", 6.7, new double[] {8.4, 422, 15.1, 9, 26, 3, 23.5, 11, 60}}); data.add( new Object[] {"Butter", "1 lb.", 30.8, new double[] {10.8, 9, 0.2, 3, 44.2, 0, 0.2, 2, 0}}); data.add(new Object[] { "Oleomargarine", "1 lb.", 16.1, new double[] {20.6, 17, 0.6, 6, 55.8, 0.2, 0, 0, 0}}); data.add(new Object[] { "Eggs", "1 doz.", 32.6, new double[] {2.9, 238, 1.0, 52, 18.6, 2.8, 6.5, 1, 0}}); data.add(new Object[] {"Cheese (Cheddar)", "1 lb.", 24.2, new double[] {7.4, 448, 16.4, 19, 28.1, 0.8, 10.3, 4, 0}}); data.add(new Object[] { "Cream", "1/2 pt.", 14.1, new double[] {3.5, 49, 1.7, 3, 16.9, 0.6, 2.5, 0, 17}}); data.add(new Object[] { "Peanut Butter", "1 lb.", 17.9, new double[] {15.7, 661, 1.0, 48, 0, 9.6, 8.1, 471, 0}}); data.add(new Object[] { "Mayonnaise", "1/2 pt.", 16.7, new double[] {8.6, 18, 0.2, 8, 2.7, 0.4, 0.5, 0, 0}}); data.add(new Object[] {"Crisco", "1 lb.", 20.3, new double[] {20.1, 0, 0, 0, 0, 0, 0, 0, 0}}); data.add(new Object[] {"Lard", "1 lb.", 9.8, new double[] {41.7, 0, 0, 0, 0.2, 0, 0.5, 5, 0}}); data.add(new Object[] { "Sirloin Steak", "1 lb.", 39.6, new double[] {2.9, 166, 0.1, 34, 0.2, 2.1, 2.9, 69, 0}}); data.add(new Object[] { "Round Steak", "1 lb.", 36.4, new double[] {2.2, 214, 0.1, 32, 0.4, 2.5, 2.4, 87, 0}}); data.add( new Object[] {"Rib Roast", "1 lb.", 29.2, new double[] {3.4, 213, 0.1, 33, 0, 0, 2, 0, 0}}); data.add(new Object[] { "Chuck Roast", "1 lb.", 22.6, new double[] {3.6, 309, 0.2, 46, 0.4, 1, 4, 120, 0}}); data.add( new Object[] {"Plate", "1 lb.", 14.6, new double[] {8.5, 404, 0.2, 62, 0, 0.9, 0, 0, 0}}); data.add(new Object[] {"Liver (Beef)", "1 lb.", 26.8, new double[] {2.2, 333, 0.2, 139, 169.2, 6.4, 50.8, 316, 525}}); data.add(new Object[] { "Leg of Lamb", "1 lb.", 27.6, new double[] {3.1, 245, 0.1, 20, 0, 2.8, 3.9, 86, 0}}); data.add(new Object[] { "Lamb Chops (Rib)", "1 lb.", 36.6, new double[] {3.3, 140, 0.1, 15, 0, 1.7, 2.7, 54, 0}}); data.add(new Object[] { "Pork Chops", "1 lb.", 30.7, new double[] {3.5, 196, 0.2, 30, 0, 17.4, 2.7, 60, 0}}); data.add(new Object[] { "Pork Loin Roast", "1 lb.", 24.2, new double[] {4.4, 249, 0.3, 37, 0, 18.2, 3.6, 79, 0}}); data.add(new Object[] { "Bacon", "1 lb.", 25.6, new double[] {10.4, 152, 0.2, 23, 0, 1.8, 1.8, 71, 0}}); data.add(new Object[] { "Ham, smoked", "1 lb.", 27.4, new double[] {6.7, 212, 0.2, 31, 0, 9.9, 3.3, 50, 0}}); data.add(new Object[] { "Salt Pork", "1 lb.", 16, new double[] {18.8, 164, 0.1, 26, 0, 1.4, 1.8, 0, 0}}); data.add(new Object[] {"Roasting Chicken", "1 lb.", 30.3, new double[] {1.8, 184, 0.1, 30, 0.1, 0.9, 1.8, 68, 46}}); data.add(new Object[] { "Veal Cutlets", "1 lb.", 42.3, new double[] {1.7, 156, 0.1, 24, 0, 1.4, 2.4, 57, 0}}); data.add(new Object[] { "Salmon, Pink (can)", "16 oz.", 13, new double[] {5.8, 705, 6.8, 45, 3.5, 1, 4.9, 209, 0}}); data.add(new Object[] { "Apples", "1 lb.", 4.4, new double[] {5.8, 27, 0.5, 36, 7.3, 3.6, 2.7, 5, 544}}); data.add(new Object[] { "Bananas", "1 lb.", 6.1, new double[] {4.9, 60, 0.4, 30, 17.4, 2.5, 3.5, 28, 498}}); data.add( new Object[] {"Lemons", "1 doz.", 26, new double[] {1.0, 21, 0.5, 14, 0, 0.5, 0, 4, 952}}); data.add(new Object[] { "Oranges", "1 doz.", 30.9, new double[] {2.2, 40, 1.1, 18, 11.1, 3.6, 1.3, 10, 1998}}); data.add(new Object[] { "Green Beans", "1 lb.", 7.1, new double[] {2.4, 138, 3.7, 80, 69, 4.3, 5.8, 37, 862}}); data.add(new Object[] { "Cabbage", "1 lb.", 3.7, new double[] {2.6, 125, 4.0, 36, 7.2, 9, 4.5, 26, 5369}}); data.add(new Object[] { "Carrots", "1 bunch", 4.7, new double[] {2.7, 73, 2.8, 43, 188.5, 6.1, 4.3, 89, 608}}); data.add(new Object[] { "Celery", "1 stalk", 7.3, new double[] {0.9, 51, 3.0, 23, 0.9, 1.4, 1.4, 9, 313}}); data.add(new Object[] { "Lettuce", "1 head", 8.2, new double[] {0.4, 27, 1.1, 22, 112.4, 1.8, 3.4, 11, 449}}); data.add(new Object[] { "Onions", "1 lb.", 3.6, new double[] {5.8, 166, 3.8, 59, 16.6, 4.7, 5.9, 21, 1184}}); data.add(new Object[] { "Potatoes", "15 lb.", 34, new double[] {14.3, 336, 1.8, 118, 6.7, 29.4, 7.1, 198, 2522}}); data.add(new Object[] { "Spinach", "1 lb.", 8.1, new double[] {1.1, 106, 0, 138, 918.4, 5.7, 13.8, 33, 2755}}); data.add(new Object[] {"Sweet Potatoes", "1 lb.", 5.1, new double[] {9.6, 138, 2.7, 54, 290.7, 8.4, 5.4, 83, 1912}}); data.add(new Object[] {"Peaches (can)", "No. 2 1/2", 16.8, new double[] {3.7, 20, 0.4, 10, 21.5, 0.5, 1, 31, 196}}); data.add(new Object[] { "Pears (can)", "No. 2 1/2", 20.4, new double[] {3.0, 8, 0.3, 8, 0.8, 0.8, 0.8, 5, 81}}); data.add(new Object[] { "Pineapple (can)", "No. 2 1/2", 21.3, new double[] {2.4, 16, 0.4, 8, 2, 2.8, 0.8, 7, 399}}); data.add(new Object[] {"Asparagus (can)", "No. 2", 27.7, new double[] {0.4, 33, 0.3, 12, 16.3, 1.4, 2.1, 17, 272}}); data.add(new Object[] { "Green Beans (can)", "No. 2", 10, new double[] {1.0, 54, 2, 65, 53.9, 1.6, 4.3, 32, 431}}); data.add(new Object[] {"Pork and Beans (can)", "16 oz.", 7.1, new double[] {7.5, 364, 4, 134, 3.5, 8.3, 7.7, 56, 0}}); data.add(new Object[] { "Corn (can)", "No. 2", 10.4, new double[] {5.2, 136, 0.2, 16, 12, 1.6, 2.7, 42, 218}}); data.add(new Object[] { "Peas (can)", "No. 2", 13.8, new double[] {2.3, 136, 0.6, 45, 34.9, 4.9, 2.5, 37, 370}}); data.add(new Object[] { "Tomatoes (can)", "No. 2", 8.6, new double[] {1.3, 63, 0.7, 38, 53.2, 3.4, 2.5, 36, 1253}}); data.add(new Object[] {"Tomato Soup (can)", "10 1/2 oz.", 7.6, new double[] {1.6, 71, 0.6, 43, 57.9, 3.5, 2.4, 67, 862}}); data.add(new Object[] { "Peaches, Dried", "1 lb.", 15.7, new double[] {8.5, 87, 1.7, 173, 86.8, 1.2, 4.3, 55, 57}}); data.add(new Object[] { "Prunes, Dried", "1 lb.", 9, new double[] {12.8, 99, 2.5, 154, 85.7, 3.9, 4.3, 65, 257}}); data.add(new Object[] {"Raisins, Dried", "15 oz.", 9.4, new double[] {13.5, 104, 2.5, 136, 4.5, 6.3, 1.4, 24, 136}}); data.add(new Object[] { "Peas, Dried", "1 lb.", 7.9, new double[] {20.0, 1367, 4.2, 345, 2.9, 28.7, 18.4, 162, 0}}); data.add(new Object[] {"Lima Beans, Dried", "1 lb.", 8.9, new double[] {17.4, 1055, 3.7, 459, 5.1, 26.9, 38.2, 93, 0}}); data.add(new Object[] {"Navy Beans, Dried", "1 lb.", 5.9, new double[] {26.9, 1691, 11.4, 792, 0, 38.4, 24.6, 217, 0}}); data.add(new Object[] {"Coffee", "1 lb.", 22.4, new double[] {0, 0, 0, 0, 0, 4, 5.1, 50, 0}}); data.add(new Object[] {"Tea", "1/4 lb.", 17.4, new double[] {0, 0, 0, 0, 0, 0, 2.3, 42, 0}}); data.add( new Object[] {"Cocoa", "8 oz.", 8.6, new double[] {8.7, 237, 3, 72, 0, 2, 11.9, 40, 0}}); data.add(new Object[] { "Chocolate", "8 oz.", 16.2, new double[] {8.0, 77, 1.3, 39, 0, 0.9, 3.4, 14, 0}}); data.add(new Object[] {"Sugar", "10 lb.", 51.7, new double[] {34.9, 0, 0, 0, 0, 0, 0, 0, 0}}); data.add(new Object[] { "Corn Syrup", "24 oz.", 13.7, new double[] {14.7, 0, 0.5, 74, 0, 0, 0, 5, 0}}); data.add(new Object[] { "Molasses", "18 oz.", 13.6, new double[] {9.0, 0, 10.3, 244, 0, 1.9, 7.5, 146, 0}}); data.add(new Object[] {"Strawberry Preserves", "1 lb.", 20.5, new double[] {6.4, 11, 0.4, 7, 0.2, 0.2, 0.4, 3, 0}});
C#
// Nutrient minimums. (String Name, double Value)[] nutrients = new[] { ("Calories (kcal)", 3.0), ("Protein (g)", 70.0), ("Calcium (g)", 0.8), ("Iron (mg)", 12.0), ("Vitamin A (kIU)", 5.0), ("Vitamin B1 (mg)", 1.8), ("Vitamin B2 (mg)", 2.7), ("Niacin (mg)", 18.0), ("Vitamin C (mg)", 75.0) }; (String Name, String Unit, double Price, double[] Nutrients)[] data = new[] { ("Wheat Flour (Enriched)", "10 lb.", 36, new double[] { 44.7, 1411, 2, 365, 0, 55.4, 33.3, 441, 0 }), ("Macaroni", "1 lb.", 14.1, new double[] { 11.6, 418, 0.7, 54, 0, 3.2, 1.9, 68, 0 }), ("Wheat Cereal (Enriched)", "28 oz.", 24.2, new double[] { 11.8, 377, 14.4, 175, 0, 14.4, 8.8, 114, 0 }), ("Corn Flakes", "8 oz.", 7.1, new double[] { 11.4, 252, 0.1, 56, 0, 13.5, 2.3, 68, 0 }), ("Corn Meal", "1 lb.", 4.6, new double[] { 36.0, 897, 1.7, 99, 30.9, 17.4, 7.9, 106, 0 }), ("Hominy Grits", "24 oz.", 8.5, new double[] { 28.6, 680, 0.8, 80, 0, 10.6, 1.6, 110, 0 }), ("Rice", "1 lb.", 7.5, new double[] { 21.2, 460, 0.6, 41, 0, 2, 4.8, 60, 0 }), ("Rolled Oats", "1 lb.", 7.1, new double[] { 25.3, 907, 5.1, 341, 0, 37.1, 8.9, 64, 0 }), ("White Bread (Enriched)", "1 lb.", 7.9, new double[] { 15.0, 488, 2.5, 115, 0, 13.8, 8.5, 126, 0 }), ("Whole Wheat Bread", "1 lb.", 9.1, new double[] { 12.2, 484, 2.7, 125, 0, 13.9, 6.4, 160, 0 }), ("Rye Bread", "1 lb.", 9.1, new double[] { 12.4, 439, 1.1, 82, 0, 9.9, 3, 66, 0 }), ("Pound Cake", "1 lb.", 24.8, new double[] { 8.0, 130, 0.4, 31, 18.9, 2.8, 3, 17, 0 }), ("Soda Crackers", "1 lb.", 15.1, new double[] { 12.5, 288, 0.5, 50, 0, 0, 0, 0, 0 }), ("Milk", "1 qt.", 11, new double[] { 6.1, 310, 10.5, 18, 16.8, 4, 16, 7, 177 }), ("Evaporated Milk (can)", "14.5 oz.", 6.7, new double[] { 8.4, 422, 15.1, 9, 26, 3, 23.5, 11, 60 }), ("Butter", "1 lb.", 30.8, new double[] { 10.8, 9, 0.2, 3, 44.2, 0, 0.2, 2, 0 }), ("Oleomargarine", "1 lb.", 16.1, new double[] { 20.6, 17, 0.6, 6, 55.8, 0.2, 0, 0, 0 }), ("Eggs", "1 doz.", 32.6, new double[] { 2.9, 238, 1.0, 52, 18.6, 2.8, 6.5, 1, 0 }), ("Cheese (Cheddar)", "1 lb.", 24.2, new double[] { 7.4, 448, 16.4, 19, 28.1, 0.8, 10.3, 4, 0 }), ("Cream", "1/2 pt.", 14.1, new double[] { 3.5, 49, 1.7, 3, 16.9, 0.6, 2.5, 0, 17 }), ("Peanut Butter", "1 lb.", 17.9, new double[] { 15.7, 661, 1.0, 48, 0, 9.6, 8.1, 471, 0 }), ("Mayonnaise", "1/2 pt.", 16.7, new double[] { 8.6, 18, 0.2, 8, 2.7, 0.4, 0.5, 0, 0 }), ("Crisco", "1 lb.", 20.3, new double[] { 20.1, 0, 0, 0, 0, 0, 0, 0, 0 }), ("Lard", "1 lb.", 9.8, new double[] { 41.7, 0, 0, 0, 0.2, 0, 0.5, 5, 0 }), ("Sirloin Steak", "1 lb.", 39.6, new double[] { 2.9, 166, 0.1, 34, 0.2, 2.1, 2.9, 69, 0 }), ("Round Steak", "1 lb.", 36.4, new double[] { 2.2, 214, 0.1, 32, 0.4, 2.5, 2.4, 87, 0 }), ("Rib Roast", "1 lb.", 29.2, new double[] { 3.4, 213, 0.1, 33, 0, 0, 2, 0, 0 }), ("Chuck Roast", "1 lb.", 22.6, new double[] { 3.6, 309, 0.2, 46, 0.4, 1, 4, 120, 0 }), ("Plate", "1 lb.", 14.6, new double[] { 8.5, 404, 0.2, 62, 0, 0.9, 0, 0, 0 }), ("Liver (Beef)", "1 lb.", 26.8, new double[] { 2.2, 333, 0.2, 139, 169.2, 6.4, 50.8, 316, 525 }), ("Leg of Lamb", "1 lb.", 27.6, new double[] { 3.1, 245, 0.1, 20, 0, 2.8, 3.9, 86, 0 }), ("Lamb Chops (Rib)", "1 lb.", 36.6, new double[] { 3.3, 140, 0.1, 15, 0, 1.7, 2.7, 54, 0 }), ("Pork Chops", "1 lb.", 30.7, new double[] { 3.5, 196, 0.2, 30, 0, 17.4, 2.7, 60, 0 }), ("Pork Loin Roast", "1 lb.", 24.2, new double[] { 4.4, 249, 0.3, 37, 0, 18.2, 3.6, 79, 0 }), ("Bacon", "1 lb.", 25.6, new double[] { 10.4, 152, 0.2, 23, 0, 1.8, 1.8, 71, 0 }), ("Ham, smoked", "1 lb.", 27.4, new double[] { 6.7, 212, 0.2, 31, 0, 9.9, 3.3, 50, 0 }), ("Salt Pork", "1 lb.", 16, new double[] { 18.8, 164, 0.1, 26, 0, 1.4, 1.8, 0, 0 }), ("Roasting Chicken", "1 lb.", 30.3, new double[] { 1.8, 184, 0.1, 30, 0.1, 0.9, 1.8, 68, 46 }), ("Veal Cutlets", "1 lb.", 42.3, new double[] { 1.7, 156, 0.1, 24, 0, 1.4, 2.4, 57, 0 }), ("Salmon, Pink (can)", "16 oz.", 13, new double[] { 5.8, 705, 6.8, 45, 3.5, 1, 4.9, 209, 0 }), ("Apples", "1 lb.", 4.4, new double[] { 5.8, 27, 0.5, 36, 7.3, 3.6, 2.7, 5, 544 }), ("Bananas", "1 lb.", 6.1, new double[] { 4.9, 60, 0.4, 30, 17.4, 2.5, 3.5, 28, 498 }), ("Lemons", "1 doz.", 26, new double[] { 1.0, 21, 0.5, 14, 0, 0.5, 0, 4, 952 }), ("Oranges", "1 doz.", 30.9, new double[] { 2.2, 40, 1.1, 18, 11.1, 3.6, 1.3, 10, 1998 }), ("Green Beans", "1 lb.", 7.1, new double[] { 2.4, 138, 3.7, 80, 69, 4.3, 5.8, 37, 862 }), ("Cabbage", "1 lb.", 3.7, new double[] { 2.6, 125, 4.0, 36, 7.2, 9, 4.5, 26, 5369 }), ("Carrots", "1 bunch", 4.7, new double[] { 2.7, 73, 2.8, 43, 188.5, 6.1, 4.3, 89, 608 }), ("Celery", "1 stalk", 7.3, new double[] { 0.9, 51, 3.0, 23, 0.9, 1.4, 1.4, 9, 313 }), ("Lettuce", "1 head", 8.2, new double[] { 0.4, 27, 1.1, 22, 112.4, 1.8, 3.4, 11, 449 }), ("Onions", "1 lb.", 3.6, new double[] { 5.8, 166, 3.8, 59, 16.6, 4.7, 5.9, 21, 1184 }), ("Potatoes", "15 lb.", 34, new double[] { 14.3, 336, 1.8, 118, 6.7, 29.4, 7.1, 198, 2522 }), ("Spinach", "1 lb.", 8.1, new double[] { 1.1, 106, 0, 138, 918.4, 5.7, 13.8, 33, 2755 }), ("Sweet Potatoes", "1 lb.", 5.1, new double[] { 9.6, 138, 2.7, 54, 290.7, 8.4, 5.4, 83, 1912 }), ("Peaches (can)", "No. 2 1/2", 16.8, new double[] { 3.7, 20, 0.4, 10, 21.5, 0.5, 1, 31, 196 }), ("Pears (can)", "No. 2 1/2", 20.4, new double[] { 3.0, 8, 0.3, 8, 0.8, 0.8, 0.8, 5, 81 }), ("Pineapple (can)", "No. 2 1/2", 21.3, new double[] { 2.4, 16, 0.4, 8, 2, 2.8, 0.8, 7, 399 }), ("Asparagus (can)", "No. 2", 27.7, new double[] { 0.4, 33, 0.3, 12, 16.3, 1.4, 2.1, 17, 272 }), ("Green Beans (can)", "No. 2", 10, new double[] { 1.0, 54, 2, 65, 53.9, 1.6, 4.3, 32, 431 }), ("Pork and Beans (can)", "16 oz.", 7.1, new double[] { 7.5, 364, 4, 134, 3.5, 8.3, 7.7, 56, 0 }), ("Corn (can)", "No. 2", 10.4, new double[] { 5.2, 136, 0.2, 16, 12, 1.6, 2.7, 42, 218 }), ("Peas (can)", "No. 2", 13.8, new double[] { 2.3, 136, 0.6, 45, 34.9, 4.9, 2.5, 37, 370 }), ("Tomatoes (can)", "No. 2", 8.6, new double[] { 1.3, 63, 0.7, 38, 53.2, 3.4, 2.5, 36, 1253 }), ("Tomato Soup (can)", "10 1/2 oz.", 7.6, new double[] { 1.6, 71, 0.6, 43, 57.9, 3.5, 2.4, 67, 862 }), ("Peaches, Dried", "1 lb.", 15.7, new double[] { 8.5, 87, 1.7, 173, 86.8, 1.2, 4.3, 55, 57 }), ("Prunes, Dried", "1 lb.", 9, new double[] { 12.8, 99, 2.5, 154, 85.7, 3.9, 4.3, 65, 257 }), ("Raisins, Dried", "15 oz.", 9.4, new double[] { 13.5, 104, 2.5, 136, 4.5, 6.3, 1.4, 24, 136 }), ("Peas, Dried", "1 lb.", 7.9, new double[] { 20.0, 1367, 4.2, 345, 2.9, 28.7, 18.4, 162, 0 }), ("Lima Beans, Dried", "1 lb.", 8.9, new double[] { 17.4, 1055, 3.7, 459, 5.1, 26.9, 38.2, 93, 0 }), ("Navy Beans, Dried", "1 lb.", 5.9, new double[] { 26.9, 1691, 11.4, 792, 0, 38.4, 24.6, 217, 0 }), ("Coffee", "1 lb.", 22.4, new double[] { 0, 0, 0, 0, 0, 4, 5.1, 50, 0 }), ("Tea", "1/4 lb.", 17.4, new double[] { 0, 0, 0, 0, 0, 0, 2.3, 42, 0 }), ("Cocoa", "8 oz.", 8.6, new double[] { 8.7, 237, 3, 72, 0, 2, 11.9, 40, 0 }), ("Chocolate", "8 oz.", 16.2, new double[] { 8.0, 77, 1.3, 39, 0, 0.9, 3.4, 14, 0 }), ("Sugar", "10 lb.", 51.7, new double[] { 34.9, 0, 0, 0, 0, 0, 0, 0, 0 }), ("Corn Syrup", "24 oz.", 13.7, new double[] { 14.7, 0, 0.5, 74, 0, 0, 0, 5, 0 }), ("Molasses", "18 oz.", 13.6, new double[] { 9.0, 0, 10.3, 244, 0, 1.9, 7.5, 146, 0 }), ("Strawberry Preserves", "1 lb.", 20.5, new double[] { 6.4, 11, 0.4, 7, 0.2, 0.2, 0.4, 3, 0 }) };
एलपी सॉल्वर का एलान करना
यह कोड, MPsolver
रैपर को इंस्टैंशिएट करता है.
Python
# Instantiate a Glop solver and naming it. solver = pywraplp.Solver.CreateSolver("GLOP") if not solver: return
C++
// Create the linear solver with the GLOP backend. std::unique_ptr<MPSolver> solver(MPSolver::CreateSolver("GLOP"));
Java
// Create the linear solver with the GLOP backend. MPSolver solver = MPSolver.createSolver("GLOP"); if (solver == null) { System.out.println("Could not create solver GLOP"); return; }
C#
// Create the linear solver with the GLOP backend. Solver solver = Solver.CreateSolver("GLOP"); if (solver is null) { return; }
वैरिएबल बनाना
नीचे दिया गया कोड, समस्या के लिए वैरिएबल बनाता है.
Python
# Declare an array to hold our variables. foods = [solver.NumVar(0.0, solver.infinity(), item[0]) for item in data] print("Number of variables =", solver.NumVariables())
C++
std::vector<MPVariable*> foods; const double infinity = solver->infinity(); for (const Commodity& commodity : data) { foods.push_back(solver->MakeNumVar(0.0, infinity, commodity.name)); } LOG(INFO) << "Number of variables = " << solver->NumVariables();
Java
double infinity = java.lang.Double.POSITIVE_INFINITY; List<MPVariable> foods = new ArrayList<>(); for (int i = 0; i < data.size(); ++i) { foods.add(solver.makeNumVar(0.0, infinity, (String) data.get(i)[0])); } System.out.println("Number of variables = " + solver.numVariables());
C#
List<Variable> foods = new List<Variable>(); for (int i = 0; i < data.Length; ++i) { foods.Add(solver.MakeNumVar(0.0, double.PositiveInfinity, data[i].Name)); } Console.WriteLine($"Number of variables = {solver.NumVariables()}");
तरीका MakeNumVar
, टेबल की हर लाइन के लिए food[i]
नाम का एक वैरिएबल बनाता है.
जैसा कि पहले बताया गया था, पोषण का डेटा डॉलर के हिसाब से होता है. इसलिए, food[i]
कमोडिटी i
पर खर्च की जाने वाली रकम है.
सीमा तय करना
स्टिगलर के खान-पान में रुकावट के मामले में, सभी तरह के खाद्य पदार्थों
के पोषक तत्वों की कुल मात्रा ज़रूरी होती है, जो हर पोषक तत्व के लिए कम से कम ज़रूरी हो.
इसके बाद, हम इन कंस्ट्रेंट को असमानताओं के तौर पर लिखते हैं, जिनमें data
,
nutrients
, और food[i]
वैरिएबल शामिल होते हैं.
सबसे पहले, खाने के j
से मिले पोषक तत्व i
के हिसाब से, हर डॉलर
data[j][i+3]
में पता चलता है (हम कॉलम इंडेक्स में 3 जोड़ देते हैं, क्योंकि पोषक तत्व का डेटा data
के चौथे कॉलम में शुरू होता है.) खाने पर खर्च होने वाली रकम j
food[j]
है, इसलिए j
खाने से मिले पोषक तत्व i
की मात्रा\(data[j][i+3] \cdot food[j]\)है.
आखिर में, न्यूट्रिशन i
के लिए ज़रूरी कम से कम nutrients[i][1]
है. इसलिए, कंस्ट्रेंट i को इस तरह लिखा जा सकता है:
Python
# Create the constraints, one per nutrient. constraints = [] for i, nutrient in enumerate(nutrients): constraints.append(solver.Constraint(nutrient[1], solver.infinity())) for j, item in enumerate(data): constraints[i].SetCoefficient(foods[j], item[i + 3]) print("Number of constraints =", solver.NumConstraints())
C++
// Create the constraints, one per nutrient. std::vector<MPConstraint*> constraints; for (std::size_t i = 0; i < nutrients.size(); ++i) { constraints.push_back( solver->MakeRowConstraint(nutrients[i].second, infinity)); for (std::size_t j = 0; j < data.size(); ++j) { constraints.back()->SetCoefficient(foods[j], data[j].nutrients[i]); } } LOG(INFO) << "Number of constraints = " << solver->NumConstraints();
Java
MPConstraint[] constraints = new MPConstraint[nutrients.size()]; for (int i = 0; i < nutrients.size(); ++i) { constraints[i] = solver.makeConstraint( (double) nutrients.get(i)[1], infinity, (String) nutrients.get(i)[0]); for (int j = 0; j < data.size(); ++j) { constraints[i].setCoefficient(foods.get(j), ((double[]) data.get(j)[3])[i]); } // constraints.add(constraint); } System.out.println("Number of constraints = " + solver.numConstraints());
C#
List<Constraint> constraints = new List<Constraint>(); for (int i = 0; i < nutrients.Length; ++i) { Constraint constraint = solver.MakeConstraint(nutrients[i].Value, double.PositiveInfinity, nutrients[i].Name); for (int j = 0; j < data.Length; ++j) { constraint.SetCoefficient(foods[j], data[j].Nutrients[i]); } constraints.Add(constraint); } Console.WriteLine($"Number of constraints = {solver.NumConstraints()}");
Python तरीका Constraint
(C++ वाले तरीके के मुताबिक
MakeRowConstraint
), समस्या के लिए कंस्ट्रेंट बनाता है. हर i
के लिए,
constraint(nutrients[i][1], solver.infinity)
इससे एक कंस्ट्रेंट बनता है, जिसमें food[j]
वैरिएबल का लीनियर कॉम्बिनेशन
nutrients[i][1]
से ज़्यादा या उसके बराबर होता है.
लीनियर एक्सप्रेशन के गुणांकों को
SetCoefficient
इस तरह से तय किया जाता है: SetCoefficient(food[j], data[j][i+3]
यह food[j]
का गुणांक data[j][i+3]
पर सेट होता है.
इन सबको एक साथ रखकर, कोड ऊपर (1) में बताई गई कंस्ट्रेंट के बारे में बताता है.
मकसद बनाना
नीचे दिया गया कोड समस्या का मकसद फ़ंक्शन बताता है.
Python
# Objective function: Minimize the sum of (price-normalized) foods. objective = solver.Objective() for food in foods: objective.SetCoefficient(food, 1) objective.SetMinimization()
C++
MPObjective* const objective = solver->MutableObjective(); for (size_t i = 0; i < data.size(); ++i) { objective->SetCoefficient(foods[i], 1); } objective->SetMinimization();
Java
MPObjective objective = solver.objective(); for (int i = 0; i < data.size(); ++i) { objective.setCoefficient(foods.get(i), 1); } objective.setMinimization();
C#
Objective objective = solver.Objective(); for (int i = 0; i < data.Length; ++i) { objective.SetCoefficient(foods[i], 1); } objective.SetMinimization();
मकसद फ़ंक्शन, खाने की कुल कीमत है, जो कि वैरिएबल food[i]
का कुल योग होता है.
यह तरीका
SetCoefficient
मकसद फ़ंक्शन के गुणांक सेट करता है. इस मामले में ये सभी 1
होते हैं.
आखिर में, SetMinimization
इसे छोटा करने की समस्या के तौर पर एलान करता है.
सॉल्वर को शुरू करें
यह कोड, सॉल्वर को शुरू करता है.
Python
print(f"Solving with {solver.SolverVersion()}") status = solver.Solve()
C++
const MPSolver::ResultStatus result_status = solver->Solve();
Java
final MPSolver.ResultStatus resultStatus = solver.solve();
C#
Solver.ResultStatus resultStatus = solver.Solve();
Glop एक सामान्य कंप्यूटर पर 300 मिलीसेकंड से भी कम समय में समस्या को हल कर देता है:
समाधान दिखाएं
यह कोड दिखाता है कि सलूशन क्या है.
Python
# Check that the problem has an optimal solution. if status != solver.OPTIMAL: print("The problem does not have an optimal solution!") if status == solver.FEASIBLE: print("A potentially suboptimal solution was found.") else: print("The solver could not solve the problem.") exit(1) # Display the amounts (in dollars) to purchase of each food. nutrients_result = [0] * len(nutrients) print("\nAnnual Foods:") for i, food in enumerate(foods): if food.solution_value() > 0.0: print("{}: ${}".format(data[i][0], 365.0 * food.solution_value())) for j, _ in enumerate(nutrients): nutrients_result[j] += data[i][j + 3] * food.solution_value() print("\nOptimal annual price: ${:.4f}".format(365.0 * objective.Value())) print("\nNutrients per day:") for i, nutrient in enumerate(nutrients): print( "{}: {:.2f} (min {})".format(nutrient[0], nutrients_result[i], nutrient[1]) )
C++
// Check that the problem has an optimal solution. if (result_status != MPSolver::OPTIMAL) { LOG(INFO) << "The problem does not have an optimal solution!"; if (result_status == MPSolver::FEASIBLE) { LOG(INFO) << "A potentially suboptimal solution was found"; } else { LOG(INFO) << "The solver could not solve the problem."; return; } } std::vector<double> nutrients_result(nutrients.size()); LOG(INFO) << ""; LOG(INFO) << "Annual Foods:"; for (std::size_t i = 0; i < data.size(); ++i) { if (foods[i]->solution_value() > 0.0) { LOG(INFO) << data[i].name << ": $" << std::to_string(365. * foods[i]->solution_value()); for (std::size_t j = 0; j < nutrients.size(); ++j) { nutrients_result[j] += data[i].nutrients[j] * foods[i]->solution_value(); } } } LOG(INFO) << ""; LOG(INFO) << "Optimal annual price: $" << std::to_string(365. * objective->Value()); LOG(INFO) << ""; LOG(INFO) << "Nutrients per day:"; for (std::size_t i = 0; i < nutrients.size(); ++i) { LOG(INFO) << nutrients[i].first << ": " << std::to_string(nutrients_result[i]) << " (min " << std::to_string(nutrients[i].second) << ")"; }
Java
// Check that the problem has an optimal solution. if (resultStatus != MPSolver.ResultStatus.OPTIMAL) { System.err.println("The problem does not have an optimal solution!"); if (resultStatus == MPSolver.ResultStatus.FEASIBLE) { System.err.println("A potentially suboptimal solution was found."); } else { System.err.println("The solver could not solve the problem."); return; } } // Display the amounts (in dollars) to purchase of each food. double[] nutrientsResult = new double[nutrients.size()]; System.out.println("\nAnnual Foods:"); for (int i = 0; i < foods.size(); ++i) { if (foods.get(i).solutionValue() > 0.0) { System.out.println((String) data.get(i)[0] + ": $" + 365 * foods.get(i).solutionValue()); for (int j = 0; j < nutrients.size(); ++j) { nutrientsResult[j] += ((double[]) data.get(i)[3])[j] * foods.get(i).solutionValue(); } } } System.out.println("\nOptimal annual price: $" + 365 * objective.value()); System.out.println("\nNutrients per day:"); for (int i = 0; i < nutrients.size(); ++i) { System.out.println( nutrients.get(i)[0] + ": " + nutrientsResult[i] + " (min " + nutrients.get(i)[1] + ")"); }
C#
// Check that the problem has an optimal solution. if (resultStatus != Solver.ResultStatus.OPTIMAL) { Console.WriteLine("The problem does not have an optimal solution!"); if (resultStatus == Solver.ResultStatus.FEASIBLE) { Console.WriteLine("A potentially suboptimal solution was found."); } else { Console.WriteLine("The solver could not solve the problem."); return; } } // Display the amounts (in dollars) to purchase of each food. double[] nutrientsResult = new double[nutrients.Length]; Console.WriteLine("\nAnnual Foods:"); for (int i = 0; i < foods.Count; ++i) { if (foods[i].SolutionValue() > 0.0) { Console.WriteLine($"{data[i].Name}: ${365 * foods[i].SolutionValue():N2}"); for (int j = 0; j < nutrients.Length; ++j) { nutrientsResult[j] += data[i].Nutrients[j] * foods[i].SolutionValue(); } } } Console.WriteLine($"\nOptimal annual price: ${365 * objective.Value():N2}"); Console.WriteLine("\nNutrients per day:"); for (int i = 0; i < nutrients.Length; ++i) { Console.WriteLine($"{nutrients[i].Name}: {nutrientsResult[i]:N2} (min {nutrients[i].Value})"); }
यहां प्रोग्राम से जुड़ा आउटपुट दिया गया है.
make rpy_stigler_diet "/usr/bin/python3.11" ortools/linear_solver/samples/stigler_diet.py Number of variables = 77 Number of constraints = 9 Annual Foods: Wheat Flour (Enriched): $10.774457511918223 Liver (Beef): $0.6907834111074193 Cabbage: $4.093268864842877 Spinach: $1.8277960703546996 Navy Beans, Dried: $22.275425687243036 Optimal annual price: $39.6617 Nutrients per day: Calories (kcal): 3.00 (min 3) Protein (g): 147.41 (min 70) Calcium (g): 0.80 (min 0.8) Iron (mg): 60.47 (min 12) Vitamin A (KIU): 5.00 (min 5) Vitamin B1 (mg): 4.12 (min 1.8) Vitamin B2 (mg): 2.70 (min 2.7) Niacin (mg): 27.32 (min 18) Vitamin C (mg): 75.00 (min 75) Advanced usage: Problem solved in 1 milliseconds Problem solved in 14 iterations
प्रोग्राम का कोड पूरा करें
Stigler के डाइट प्रोग्राम का पूरा कोड नीचे दिखाया गया है.
Python
"""The Stigler diet problem. A description of the problem can be found here: https://en.wikipedia.org/wiki/Stigler_diet. """ from ortools.linear_solver import pywraplp def main(): """Entry point of the program.""" # Instantiate the data problem. # Nutrient minimums. nutrients = [ ["Calories (kcal)", 3], ["Protein (g)", 70], ["Calcium (g)", 0.8], ["Iron (mg)", 12], ["Vitamin A (KIU)", 5], ["Vitamin B1 (mg)", 1.8], ["Vitamin B2 (mg)", 2.7], ["Niacin (mg)", 18], ["Vitamin C (mg)", 75], ] # Commodity, Unit, 1939 price (cents), Calories (kcal), Protein (g), # Calcium (g), Iron (mg), Vitamin A (KIU), Vitamin B1 (mg), Vitamin B2 (mg), # Niacin (mg), Vitamin C (mg) data = [ # fmt: off ['Wheat Flour (Enriched)', '10 lb.', 36, 44.7, 1411, 2, 365, 0, 55.4, 33.3, 441, 0], ['Macaroni', '1 lb.', 14.1, 11.6, 418, 0.7, 54, 0, 3.2, 1.9, 68, 0], ['Wheat Cereal (Enriched)', '28 oz.', 24.2, 11.8, 377, 14.4, 175, 0, 14.4, 8.8, 114, 0], ['Corn Flakes', '8 oz.', 7.1, 11.4, 252, 0.1, 56, 0, 13.5, 2.3, 68, 0], ['Corn Meal', '1 lb.', 4.6, 36.0, 897, 1.7, 99, 30.9, 17.4, 7.9, 106, 0], ['Hominy Grits', '24 oz.', 8.5, 28.6, 680, 0.8, 80, 0, 10.6, 1.6, 110, 0], ['Rice', '1 lb.', 7.5, 21.2, 460, 0.6, 41, 0, 2, 4.8, 60, 0], ['Rolled Oats', '1 lb.', 7.1, 25.3, 907, 5.1, 341, 0, 37.1, 8.9, 64, 0], ['White Bread (Enriched)', '1 lb.', 7.9, 15.0, 488, 2.5, 115, 0, 13.8, 8.5, 126, 0], ['Whole Wheat Bread', '1 lb.', 9.1, 12.2, 484, 2.7, 125, 0, 13.9, 6.4, 160, 0], ['Rye Bread', '1 lb.', 9.1, 12.4, 439, 1.1, 82, 0, 9.9, 3, 66, 0], ['Pound Cake', '1 lb.', 24.8, 8.0, 130, 0.4, 31, 18.9, 2.8, 3, 17, 0], ['Soda Crackers', '1 lb.', 15.1, 12.5, 288, 0.5, 50, 0, 0, 0, 0, 0], ['Milk', '1 qt.', 11, 6.1, 310, 10.5, 18, 16.8, 4, 16, 7, 177], ['Evaporated Milk (can)', '14.5 oz.', 6.7, 8.4, 422, 15.1, 9, 26, 3, 23.5, 11, 60], ['Butter', '1 lb.', 30.8, 10.8, 9, 0.2, 3, 44.2, 0, 0.2, 2, 0], ['Oleomargarine', '1 lb.', 16.1, 20.6, 17, 0.6, 6, 55.8, 0.2, 0, 0, 0], ['Eggs', '1 doz.', 32.6, 2.9, 238, 1.0, 52, 18.6, 2.8, 6.5, 1, 0], ['Cheese (Cheddar)', '1 lb.', 24.2, 7.4, 448, 16.4, 19, 28.1, 0.8, 10.3, 4, 0], ['Cream', '1/2 pt.', 14.1, 3.5, 49, 1.7, 3, 16.9, 0.6, 2.5, 0, 17], ['Peanut Butter', '1 lb.', 17.9, 15.7, 661, 1.0, 48, 0, 9.6, 8.1, 471, 0], ['Mayonnaise', '1/2 pt.', 16.7, 8.6, 18, 0.2, 8, 2.7, 0.4, 0.5, 0, 0], ['Crisco', '1 lb.', 20.3, 20.1, 0, 0, 0, 0, 0, 0, 0, 0], ['Lard', '1 lb.', 9.8, 41.7, 0, 0, 0, 0.2, 0, 0.5, 5, 0], ['Sirloin Steak', '1 lb.', 39.6, 2.9, 166, 0.1, 34, 0.2, 2.1, 2.9, 69, 0], ['Round Steak', '1 lb.', 36.4, 2.2, 214, 0.1, 32, 0.4, 2.5, 2.4, 87, 0], ['Rib Roast', '1 lb.', 29.2, 3.4, 213, 0.1, 33, 0, 0, 2, 0, 0], ['Chuck Roast', '1 lb.', 22.6, 3.6, 309, 0.2, 46, 0.4, 1, 4, 120, 0], ['Plate', '1 lb.', 14.6, 8.5, 404, 0.2, 62, 0, 0.9, 0, 0, 0], ['Liver (Beef)', '1 lb.', 26.8, 2.2, 333, 0.2, 139, 169.2, 6.4, 50.8, 316, 525], ['Leg of Lamb', '1 lb.', 27.6, 3.1, 245, 0.1, 20, 0, 2.8, 3.9, 86, 0], ['Lamb Chops (Rib)', '1 lb.', 36.6, 3.3, 140, 0.1, 15, 0, 1.7, 2.7, 54, 0], ['Pork Chops', '1 lb.', 30.7, 3.5, 196, 0.2, 30, 0, 17.4, 2.7, 60, 0], ['Pork Loin Roast', '1 lb.', 24.2, 4.4, 249, 0.3, 37, 0, 18.2, 3.6, 79, 0], ['Bacon', '1 lb.', 25.6, 10.4, 152, 0.2, 23, 0, 1.8, 1.8, 71, 0], ['Ham, smoked', '1 lb.', 27.4, 6.7, 212, 0.2, 31, 0, 9.9, 3.3, 50, 0], ['Salt Pork', '1 lb.', 16, 18.8, 164, 0.1, 26, 0, 1.4, 1.8, 0, 0], ['Roasting Chicken', '1 lb.', 30.3, 1.8, 184, 0.1, 30, 0.1, 0.9, 1.8, 68, 46], ['Veal Cutlets', '1 lb.', 42.3, 1.7, 156, 0.1, 24, 0, 1.4, 2.4, 57, 0], ['Salmon, Pink (can)', '16 oz.', 13, 5.8, 705, 6.8, 45, 3.5, 1, 4.9, 209, 0], ['Apples', '1 lb.', 4.4, 5.8, 27, 0.5, 36, 7.3, 3.6, 2.7, 5, 544], ['Bananas', '1 lb.', 6.1, 4.9, 60, 0.4, 30, 17.4, 2.5, 3.5, 28, 498], ['Lemons', '1 doz.', 26, 1.0, 21, 0.5, 14, 0, 0.5, 0, 4, 952], ['Oranges', '1 doz.', 30.9, 2.2, 40, 1.1, 18, 11.1, 3.6, 1.3, 10, 1998], ['Green Beans', '1 lb.', 7.1, 2.4, 138, 3.7, 80, 69, 4.3, 5.8, 37, 862], ['Cabbage', '1 lb.', 3.7, 2.6, 125, 4.0, 36, 7.2, 9, 4.5, 26, 5369], ['Carrots', '1 bunch', 4.7, 2.7, 73, 2.8, 43, 188.5, 6.1, 4.3, 89, 608], ['Celery', '1 stalk', 7.3, 0.9, 51, 3.0, 23, 0.9, 1.4, 1.4, 9, 313], ['Lettuce', '1 head', 8.2, 0.4, 27, 1.1, 22, 112.4, 1.8, 3.4, 11, 449], ['Onions', '1 lb.', 3.6, 5.8, 166, 3.8, 59, 16.6, 4.7, 5.9, 21, 1184], ['Potatoes', '15 lb.', 34, 14.3, 336, 1.8, 118, 6.7, 29.4, 7.1, 198, 2522], ['Spinach', '1 lb.', 8.1, 1.1, 106, 0, 138, 918.4, 5.7, 13.8, 33, 2755], ['Sweet Potatoes', '1 lb.', 5.1, 9.6, 138, 2.7, 54, 290.7, 8.4, 5.4, 83, 1912], ['Peaches (can)', 'No. 2 1/2', 16.8, 3.7, 20, 0.4, 10, 21.5, 0.5, 1, 31, 196], ['Pears (can)', 'No. 2 1/2', 20.4, 3.0, 8, 0.3, 8, 0.8, 0.8, 0.8, 5, 81], ['Pineapple (can)', 'No. 2 1/2', 21.3, 2.4, 16, 0.4, 8, 2, 2.8, 0.8, 7, 399], ['Asparagus (can)', 'No. 2', 27.7, 0.4, 33, 0.3, 12, 16.3, 1.4, 2.1, 17, 272], ['Green Beans (can)', 'No. 2', 10, 1.0, 54, 2, 65, 53.9, 1.6, 4.3, 32, 431], ['Pork and Beans (can)', '16 oz.', 7.1, 7.5, 364, 4, 134, 3.5, 8.3, 7.7, 56, 0], ['Corn (can)', 'No. 2', 10.4, 5.2, 136, 0.2, 16, 12, 1.6, 2.7, 42, 218], ['Peas (can)', 'No. 2', 13.8, 2.3, 136, 0.6, 45, 34.9, 4.9, 2.5, 37, 370], ['Tomatoes (can)', 'No. 2', 8.6, 1.3, 63, 0.7, 38, 53.2, 3.4, 2.5, 36, 1253], ['Tomato Soup (can)', '10 1/2 oz.', 7.6, 1.6, 71, 0.6, 43, 57.9, 3.5, 2.4, 67, 862], ['Peaches, Dried', '1 lb.', 15.7, 8.5, 87, 1.7, 173, 86.8, 1.2, 4.3, 55, 57], ['Prunes, Dried', '1 lb.', 9, 12.8, 99, 2.5, 154, 85.7, 3.9, 4.3, 65, 257], ['Raisins, Dried', '15 oz.', 9.4, 13.5, 104, 2.5, 136, 4.5, 6.3, 1.4, 24, 136], ['Peas, Dried', '1 lb.', 7.9, 20.0, 1367, 4.2, 345, 2.9, 28.7, 18.4, 162, 0], ['Lima Beans, Dried', '1 lb.', 8.9, 17.4, 1055, 3.7, 459, 5.1, 26.9, 38.2, 93, 0], ['Navy Beans, Dried', '1 lb.', 5.9, 26.9, 1691, 11.4, 792, 0, 38.4, 24.6, 217, 0], ['Coffee', '1 lb.', 22.4, 0, 0, 0, 0, 0, 4, 5.1, 50, 0], ['Tea', '1/4 lb.', 17.4, 0, 0, 0, 0, 0, 0, 2.3, 42, 0], ['Cocoa', '8 oz.', 8.6, 8.7, 237, 3, 72, 0, 2, 11.9, 40, 0], ['Chocolate', '8 oz.', 16.2, 8.0, 77, 1.3, 39, 0, 0.9, 3.4, 14, 0], ['Sugar', '10 lb.', 51.7, 34.9, 0, 0, 0, 0, 0, 0, 0, 0], ['Corn Syrup', '24 oz.', 13.7, 14.7, 0, 0.5, 74, 0, 0, 0, 5, 0], ['Molasses', '18 oz.', 13.6, 9.0, 0, 10.3, 244, 0, 1.9, 7.5, 146, 0], ['Strawberry Preserves', '1 lb.', 20.5, 6.4, 11, 0.4, 7, 0.2, 0.2, 0.4, 3, 0], # fmt: on ] # Instantiate a Glop solver and naming it. solver = pywraplp.Solver.CreateSolver("GLOP") if not solver: return # Declare an array to hold our variables. foods = [solver.NumVar(0.0, solver.infinity(), item[0]) for item in data] print("Number of variables =", solver.NumVariables()) # Create the constraints, one per nutrient. constraints = [] for i, nutrient in enumerate(nutrients): constraints.append(solver.Constraint(nutrient[1], solver.infinity())) for j, item in enumerate(data): constraints[i].SetCoefficient(foods[j], item[i + 3]) print("Number of constraints =", solver.NumConstraints()) # Objective function: Minimize the sum of (price-normalized) foods. objective = solver.Objective() for food in foods: objective.SetCoefficient(food, 1) objective.SetMinimization() print(f"Solving with {solver.SolverVersion()}") status = solver.Solve() # Check that the problem has an optimal solution. if status != solver.OPTIMAL: print("The problem does not have an optimal solution!") if status == solver.FEASIBLE: print("A potentially suboptimal solution was found.") else: print("The solver could not solve the problem.") exit(1) # Display the amounts (in dollars) to purchase of each food. nutrients_result = [0] * len(nutrients) print("\nAnnual Foods:") for i, food in enumerate(foods): if food.solution_value() > 0.0: print("{}: ${}".format(data[i][0], 365.0 * food.solution_value())) for j, _ in enumerate(nutrients): nutrients_result[j] += data[i][j + 3] * food.solution_value() print("\nOptimal annual price: ${:.4f}".format(365.0 * objective.Value())) print("\nNutrients per day:") for i, nutrient in enumerate(nutrients): print( "{}: {:.2f} (min {})".format(nutrient[0], nutrients_result[i], nutrient[1]) ) print("\nAdvanced usage:") print(f"Problem solved in {solver.wall_time():d} milliseconds") print(f"Problem solved in {solver.iterations():d} iterations") if __name__ == "__main__": main()
C++
// The Stigler diet problem. #include <array> #include <memory> #include <string> #include <utility> // std::pair #include <vector> #include "absl/flags/flag.h" #include "absl/log/flags.h" #include "ortools/base/init_google.h" #include "ortools/base/logging.h" #include "ortools/linear_solver/linear_solver.h" namespace operations_research { void StiglerDiet() { // Nutrient minimums. const std::vector<std::pair<std::string, double>> nutrients = { {"Calories (kcal)", 3.0}, {"Protein (g)", 70.0}, {"Calcium (g)", 0.8}, {"Iron (mg)", 12.0}, {"Vitamin A (kIU)", 5.0}, {"Vitamin B1 (mg)", 1.8}, {"Vitamin B2 (mg)", 2.7}, {"Niacin (mg)", 18.0}, {"Vitamin C (mg)", 75.0}}; struct Commodity { std::string name; //!< Commodity name std::string unit; //!< Unit double price; //!< 1939 price per unit (cents) //! Calories (kcal), //! Protein (g), //! Calcium (g), //! Iron (mg), //! Vitamin A (kIU), //! Vitamin B1 (mg), //! Vitamin B2 (mg), //! Niacin (mg), //! Vitamin C (mg) std::array<double, 9> nutrients; }; std::vector<Commodity> data = { {"Wheat Flour (Enriched)", "10 lb.", 36, {44.7, 1411, 2, 365, 0, 55.4, 33.3, 441, 0}}, {"Macaroni", "1 lb.", 14.1, {11.6, 418, 0.7, 54, 0, 3.2, 1.9, 68, 0}}, {"Wheat Cereal (Enriched)", "28 oz.", 24.2, {11.8, 377, 14.4, 175, 0, 14.4, 8.8, 114, 0}}, {"Corn Flakes", "8 oz.", 7.1, {11.4, 252, 0.1, 56, 0, 13.5, 2.3, 68, 0}}, {"Corn Meal", "1 lb.", 4.6, {36.0, 897, 1.7, 99, 30.9, 17.4, 7.9, 106, 0}}, {"Hominy Grits", "24 oz.", 8.5, {28.6, 680, 0.8, 80, 0, 10.6, 1.6, 110, 0}}, {"Rice", "1 lb.", 7.5, {21.2, 460, 0.6, 41, 0, 2, 4.8, 60, 0}}, {"Rolled Oats", "1 lb.", 7.1, {25.3, 907, 5.1, 341, 0, 37.1, 8.9, 64, 0}}, {"White Bread (Enriched)", "1 lb.", 7.9, {15.0, 488, 2.5, 115, 0, 13.8, 8.5, 126, 0}}, {"Whole Wheat Bread", "1 lb.", 9.1, {12.2, 484, 2.7, 125, 0, 13.9, 6.4, 160, 0}}, {"Rye Bread", "1 lb.", 9.1, {12.4, 439, 1.1, 82, 0, 9.9, 3, 66, 0}}, {"Pound Cake", "1 lb.", 24.8, {8.0, 130, 0.4, 31, 18.9, 2.8, 3, 17, 0}}, {"Soda Crackers", "1 lb.", 15.1, {12.5, 288, 0.5, 50, 0, 0, 0, 0, 0}}, {"Milk", "1 qt.", 11, {6.1, 310, 10.5, 18, 16.8, 4, 16, 7, 177}}, {"Evaporated Milk (can)", "14.5 oz.", 6.7, {8.4, 422, 15.1, 9, 26, 3, 23.5, 11, 60}}, {"Butter", "1 lb.", 30.8, {10.8, 9, 0.2, 3, 44.2, 0, 0.2, 2, 0}}, {"Oleomargarine", "1 lb.", 16.1, {20.6, 17, 0.6, 6, 55.8, 0.2, 0, 0, 0}}, {"Eggs", "1 doz.", 32.6, {2.9, 238, 1.0, 52, 18.6, 2.8, 6.5, 1, 0}}, {"Cheese (Cheddar)", "1 lb.", 24.2, {7.4, 448, 16.4, 19, 28.1, 0.8, 10.3, 4, 0}}, {"Cream", "1/2 pt.", 14.1, {3.5, 49, 1.7, 3, 16.9, 0.6, 2.5, 0, 17}}, {"Peanut Butter", "1 lb.", 17.9, {15.7, 661, 1.0, 48, 0, 9.6, 8.1, 471, 0}}, {"Mayonnaise", "1/2 pt.", 16.7, {8.6, 18, 0.2, 8, 2.7, 0.4, 0.5, 0, 0}}, {"Crisco", "1 lb.", 20.3, {20.1, 0, 0, 0, 0, 0, 0, 0, 0}}, {"Lard", "1 lb.", 9.8, {41.7, 0, 0, 0, 0.2, 0, 0.5, 5, 0}}, {"Sirloin Steak", "1 lb.", 39.6, {2.9, 166, 0.1, 34, 0.2, 2.1, 2.9, 69, 0}}, {"Round Steak", "1 lb.", 36.4, {2.2, 214, 0.1, 32, 0.4, 2.5, 2.4, 87, 0}}, {"Rib Roast", "1 lb.", 29.2, {3.4, 213, 0.1, 33, 0, 0, 2, 0, 0}}, {"Chuck Roast", "1 lb.", 22.6, {3.6, 309, 0.2, 46, 0.4, 1, 4, 120, 0}}, {"Plate", "1 lb.", 14.6, {8.5, 404, 0.2, 62, 0, 0.9, 0, 0, 0}}, {"Liver (Beef)", "1 lb.", 26.8, {2.2, 333, 0.2, 139, 169.2, 6.4, 50.8, 316, 525}}, {"Leg of Lamb", "1 lb.", 27.6, {3.1, 245, 0.1, 20, 0, 2.8, 3.9, 86, 0}}, {"Lamb Chops (Rib)", "1 lb.", 36.6, {3.3, 140, 0.1, 15, 0, 1.7, 2.7, 54, 0}}, {"Pork Chops", "1 lb.", 30.7, {3.5, 196, 0.2, 30, 0, 17.4, 2.7, 60, 0}}, {"Pork Loin Roast", "1 lb.", 24.2, {4.4, 249, 0.3, 37, 0, 18.2, 3.6, 79, 0}}, {"Bacon", "1 lb.", 25.6, {10.4, 152, 0.2, 23, 0, 1.8, 1.8, 71, 0}}, {"Ham, smoked", "1 lb.", 27.4, {6.7, 212, 0.2, 31, 0, 9.9, 3.3, 50, 0}}, {"Salt Pork", "1 lb.", 16, {18.8, 164, 0.1, 26, 0, 1.4, 1.8, 0, 0}}, {"Roasting Chicken", "1 lb.", 30.3, {1.8, 184, 0.1, 30, 0.1, 0.9, 1.8, 68, 46}}, {"Veal Cutlets", "1 lb.", 42.3, {1.7, 156, 0.1, 24, 0, 1.4, 2.4, 57, 0}}, {"Salmon, Pink (can)", "16 oz.", 13, {5.8, 705, 6.8, 45, 3.5, 1, 4.9, 209, 0}}, {"Apples", "1 lb.", 4.4, {5.8, 27, 0.5, 36, 7.3, 3.6, 2.7, 5, 544}}, {"Bananas", "1 lb.", 6.1, {4.9, 60, 0.4, 30, 17.4, 2.5, 3.5, 28, 498}}, {"Lemons", "1 doz.", 26, {1.0, 21, 0.5, 14, 0, 0.5, 0, 4, 952}}, {"Oranges", "1 doz.", 30.9, {2.2, 40, 1.1, 18, 11.1, 3.6, 1.3, 10, 1998}}, {"Green Beans", "1 lb.", 7.1, {2.4, 138, 3.7, 80, 69, 4.3, 5.8, 37, 862}}, {"Cabbage", "1 lb.", 3.7, {2.6, 125, 4.0, 36, 7.2, 9, 4.5, 26, 5369}}, {"Carrots", "1 bunch", 4.7, {2.7, 73, 2.8, 43, 188.5, 6.1, 4.3, 89, 608}}, {"Celery", "1 stalk", 7.3, {0.9, 51, 3.0, 23, 0.9, 1.4, 1.4, 9, 313}}, {"Lettuce", "1 head", 8.2, {0.4, 27, 1.1, 22, 112.4, 1.8, 3.4, 11, 449}}, {"Onions", "1 lb.", 3.6, {5.8, 166, 3.8, 59, 16.6, 4.7, 5.9, 21, 1184}}, {"Potatoes", "15 lb.", 34, {14.3, 336, 1.8, 118, 6.7, 29.4, 7.1, 198, 2522}}, {"Spinach", "1 lb.", 8.1, {1.1, 106, 0, 138, 918.4, 5.7, 13.8, 33, 2755}}, {"Sweet Potatoes", "1 lb.", 5.1, {9.6, 138, 2.7, 54, 290.7, 8.4, 5.4, 83, 1912}}, {"Peaches (can)", "No. 2 1/2", 16.8, {3.7, 20, 0.4, 10, 21.5, 0.5, 1, 31, 196}}, {"Pears (can)", "No. 2 1/2", 20.4, {3.0, 8, 0.3, 8, 0.8, 0.8, 0.8, 5, 81}}, {"Pineapple (can)", "No. 2 1/2", 21.3, {2.4, 16, 0.4, 8, 2, 2.8, 0.8, 7, 399}}, {"Asparagus (can)", "No. 2", 27.7, {0.4, 33, 0.3, 12, 16.3, 1.4, 2.1, 17, 272}}, {"Green Beans (can)", "No. 2", 10, {1.0, 54, 2, 65, 53.9, 1.6, 4.3, 32, 431}}, {"Pork and Beans (can)", "16 oz.", 7.1, {7.5, 364, 4, 134, 3.5, 8.3, 7.7, 56, 0}}, {"Corn (can)", "No. 2", 10.4, {5.2, 136, 0.2, 16, 12, 1.6, 2.7, 42, 218}}, {"Peas (can)", "No. 2", 13.8, {2.3, 136, 0.6, 45, 34.9, 4.9, 2.5, 37, 370}}, {"Tomatoes (can)", "No. 2", 8.6, {1.3, 63, 0.7, 38, 53.2, 3.4, 2.5, 36, 1253}}, {"Tomato Soup (can)", "10 1/2 oz.", 7.6, {1.6, 71, 0.6, 43, 57.9, 3.5, 2.4, 67, 862}}, {"Peaches, Dried", "1 lb.", 15.7, {8.5, 87, 1.7, 173, 86.8, 1.2, 4.3, 55, 57}}, {"Prunes, Dried", "1 lb.", 9, {12.8, 99, 2.5, 154, 85.7, 3.9, 4.3, 65, 257}}, {"Raisins, Dried", "15 oz.", 9.4, {13.5, 104, 2.5, 136, 4.5, 6.3, 1.4, 24, 136}}, {"Peas, Dried", "1 lb.", 7.9, {20.0, 1367, 4.2, 345, 2.9, 28.7, 18.4, 162, 0}}, {"Lima Beans, Dried", "1 lb.", 8.9, {17.4, 1055, 3.7, 459, 5.1, 26.9, 38.2, 93, 0}}, {"Navy Beans, Dried", "1 lb.", 5.9, {26.9, 1691, 11.4, 792, 0, 38.4, 24.6, 217, 0}}, {"Coffee", "1 lb.", 22.4, {0, 0, 0, 0, 0, 4, 5.1, 50, 0}}, {"Tea", "1/4 lb.", 17.4, {0, 0, 0, 0, 0, 0, 2.3, 42, 0}}, {"Cocoa", "8 oz.", 8.6, {8.7, 237, 3, 72, 0, 2, 11.9, 40, 0}}, {"Chocolate", "8 oz.", 16.2, {8.0, 77, 1.3, 39, 0, 0.9, 3.4, 14, 0}}, {"Sugar", "10 lb.", 51.7, {34.9, 0, 0, 0, 0, 0, 0, 0, 0}}, {"Corn Syrup", "24 oz.", 13.7, {14.7, 0, 0.5, 74, 0, 0, 0, 5, 0}}, {"Molasses", "18 oz.", 13.6, {9.0, 0, 10.3, 244, 0, 1.9, 7.5, 146, 0}}, {"Strawberry Preserves", "1 lb.", 20.5, {6.4, 11, 0.4, 7, 0.2, 0.2, 0.4, 3, 0}}}; // Create the linear solver with the GLOP backend. std::unique_ptr<MPSolver> solver(MPSolver::CreateSolver("GLOP")); std::vector<MPVariable*> foods; const double infinity = solver->infinity(); for (const Commodity& commodity : data) { foods.push_back(solver->MakeNumVar(0.0, infinity, commodity.name)); } LOG(INFO) << "Number of variables = " << solver->NumVariables(); // Create the constraints, one per nutrient. std::vector<MPConstraint*> constraints; for (std::size_t i = 0; i < nutrients.size(); ++i) { constraints.push_back( solver->MakeRowConstraint(nutrients[i].second, infinity)); for (std::size_t j = 0; j < data.size(); ++j) { constraints.back()->SetCoefficient(foods[j], data[j].nutrients[i]); } } LOG(INFO) << "Number of constraints = " << solver->NumConstraints(); MPObjective* const objective = solver->MutableObjective(); for (size_t i = 0; i < data.size(); ++i) { objective->SetCoefficient(foods[i], 1); } objective->SetMinimization(); const MPSolver::ResultStatus result_status = solver->Solve(); // Check that the problem has an optimal solution. if (result_status != MPSolver::OPTIMAL) { LOG(INFO) << "The problem does not have an optimal solution!"; if (result_status == MPSolver::FEASIBLE) { LOG(INFO) << "A potentially suboptimal solution was found"; } else { LOG(INFO) << "The solver could not solve the problem."; return; } } std::vector<double> nutrients_result(nutrients.size()); LOG(INFO) << ""; LOG(INFO) << "Annual Foods:"; for (std::size_t i = 0; i < data.size(); ++i) { if (foods[i]->solution_value() > 0.0) { LOG(INFO) << data[i].name << ": $" << std::to_string(365. * foods[i]->solution_value()); for (std::size_t j = 0; j < nutrients.size(); ++j) { nutrients_result[j] += data[i].nutrients[j] * foods[i]->solution_value(); } } } LOG(INFO) << ""; LOG(INFO) << "Optimal annual price: $" << std::to_string(365. * objective->Value()); LOG(INFO) << ""; LOG(INFO) << "Nutrients per day:"; for (std::size_t i = 0; i < nutrients.size(); ++i) { LOG(INFO) << nutrients[i].first << ": " << std::to_string(nutrients_result[i]) << " (min " << std::to_string(nutrients[i].second) << ")"; } LOG(INFO) << ""; LOG(INFO) << "Advanced usage:"; LOG(INFO) << "Problem solved in " << solver->wall_time() << " milliseconds"; LOG(INFO) << "Problem solved in " << solver->iterations() << " iterations"; } } // namespace operations_research int main(int argc, char** argv) { InitGoogle(argv[0], &argc, &argv, true); absl::SetFlag(&FLAGS_stderrthreshold, 0); operations_research::StiglerDiet(); return EXIT_SUCCESS; }
Java
// The Stigler diet problem. package com.google.ortools.linearsolver.samples; import com.google.ortools.Loader; import com.google.ortools.linearsolver.MPConstraint; import com.google.ortools.linearsolver.MPObjective; import com.google.ortools.linearsolver.MPSolver; import com.google.ortools.linearsolver.MPVariable; import java.util.ArrayList; import java.util.List; /** Stigler diet example. */ public final class StiglerDiet { public static void main(String[] args) { Loader.loadNativeLibraries(); // Nutrient minimums. List<Object[]> nutrients = new ArrayList<>(); nutrients.add(new Object[] {"Calories (kcal)", 3.0}); nutrients.add(new Object[] {"Protein (g)", 70.0}); nutrients.add(new Object[] {"Calcium (g)", 0.8}); nutrients.add(new Object[] {"Iron (mg)", 12.0}); nutrients.add(new Object[] {"Vitamin A (kIU)", 5.0}); nutrients.add(new Object[] {"Vitamin B1 (mg)", 1.8}); nutrients.add(new Object[] {"Vitamin B2 (mg)", 2.7}); nutrients.add(new Object[] {"Niacin (mg)", 18.0}); nutrients.add(new Object[] {"Vitamin C (mg)", 75.0}); List<Object[]> data = new ArrayList<>(); data.add(new Object[] {"Wheat Flour (Enriched)", "10 lb.", 36, new double[] {44.7, 1411, 2, 365, 0, 55.4, 33.3, 441, 0}}); data.add(new Object[] { "Macaroni", "1 lb.", 14.1, new double[] {11.6, 418, 0.7, 54, 0, 3.2, 1.9, 68, 0}}); data.add(new Object[] {"Wheat Cereal (Enriched)", "28 oz.", 24.2, new double[] {11.8, 377, 14.4, 175, 0, 14.4, 8.8, 114, 0}}); data.add(new Object[] { "Corn Flakes", "8 oz.", 7.1, new double[] {11.4, 252, 0.1, 56, 0, 13.5, 2.3, 68, 0}}); data.add(new Object[] { "Corn Meal", "1 lb.", 4.6, new double[] {36.0, 897, 1.7, 99, 30.9, 17.4, 7.9, 106, 0}}); data.add(new Object[] { "Hominy Grits", "24 oz.", 8.5, new double[] {28.6, 680, 0.8, 80, 0, 10.6, 1.6, 110, 0}}); data.add( new Object[] {"Rice", "1 lb.", 7.5, new double[] {21.2, 460, 0.6, 41, 0, 2, 4.8, 60, 0}}); data.add(new Object[] { "Rolled Oats", "1 lb.", 7.1, new double[] {25.3, 907, 5.1, 341, 0, 37.1, 8.9, 64, 0}}); data.add(new Object[] {"White Bread (Enriched)", "1 lb.", 7.9, new double[] {15.0, 488, 2.5, 115, 0, 13.8, 8.5, 126, 0}}); data.add(new Object[] {"Whole Wheat Bread", "1 lb.", 9.1, new double[] {12.2, 484, 2.7, 125, 0, 13.9, 6.4, 160, 0}}); data.add(new Object[] { "Rye Bread", "1 lb.", 9.1, new double[] {12.4, 439, 1.1, 82, 0, 9.9, 3, 66, 0}}); data.add(new Object[] { "Pound Cake", "1 lb.", 24.8, new double[] {8.0, 130, 0.4, 31, 18.9, 2.8, 3, 17, 0}}); data.add(new Object[] { "Soda Crackers", "1 lb.", 15.1, new double[] {12.5, 288, 0.5, 50, 0, 0, 0, 0, 0}}); data.add( new Object[] {"Milk", "1 qt.", 11, new double[] {6.1, 310, 10.5, 18, 16.8, 4, 16, 7, 177}}); data.add(new Object[] {"Evaporated Milk (can)", "14.5 oz.", 6.7, new double[] {8.4, 422, 15.1, 9, 26, 3, 23.5, 11, 60}}); data.add( new Object[] {"Butter", "1 lb.", 30.8, new double[] {10.8, 9, 0.2, 3, 44.2, 0, 0.2, 2, 0}}); data.add(new Object[] { "Oleomargarine", "1 lb.", 16.1, new double[] {20.6, 17, 0.6, 6, 55.8, 0.2, 0, 0, 0}}); data.add(new Object[] { "Eggs", "1 doz.", 32.6, new double[] {2.9, 238, 1.0, 52, 18.6, 2.8, 6.5, 1, 0}}); data.add(new Object[] {"Cheese (Cheddar)", "1 lb.", 24.2, new double[] {7.4, 448, 16.4, 19, 28.1, 0.8, 10.3, 4, 0}}); data.add(new Object[] { "Cream", "1/2 pt.", 14.1, new double[] {3.5, 49, 1.7, 3, 16.9, 0.6, 2.5, 0, 17}}); data.add(new Object[] { "Peanut Butter", "1 lb.", 17.9, new double[] {15.7, 661, 1.0, 48, 0, 9.6, 8.1, 471, 0}}); data.add(new Object[] { "Mayonnaise", "1/2 pt.", 16.7, new double[] {8.6, 18, 0.2, 8, 2.7, 0.4, 0.5, 0, 0}}); data.add(new Object[] {"Crisco", "1 lb.", 20.3, new double[] {20.1, 0, 0, 0, 0, 0, 0, 0, 0}}); data.add(new Object[] {"Lard", "1 lb.", 9.8, new double[] {41.7, 0, 0, 0, 0.2, 0, 0.5, 5, 0}}); data.add(new Object[] { "Sirloin Steak", "1 lb.", 39.6, new double[] {2.9, 166, 0.1, 34, 0.2, 2.1, 2.9, 69, 0}}); data.add(new Object[] { "Round Steak", "1 lb.", 36.4, new double[] {2.2, 214, 0.1, 32, 0.4, 2.5, 2.4, 87, 0}}); data.add( new Object[] {"Rib Roast", "1 lb.", 29.2, new double[] {3.4, 213, 0.1, 33, 0, 0, 2, 0, 0}}); data.add(new Object[] { "Chuck Roast", "1 lb.", 22.6, new double[] {3.6, 309, 0.2, 46, 0.4, 1, 4, 120, 0}}); data.add( new Object[] {"Plate", "1 lb.", 14.6, new double[] {8.5, 404, 0.2, 62, 0, 0.9, 0, 0, 0}}); data.add(new Object[] {"Liver (Beef)", "1 lb.", 26.8, new double[] {2.2, 333, 0.2, 139, 169.2, 6.4, 50.8, 316, 525}}); data.add(new Object[] { "Leg of Lamb", "1 lb.", 27.6, new double[] {3.1, 245, 0.1, 20, 0, 2.8, 3.9, 86, 0}}); data.add(new Object[] { "Lamb Chops (Rib)", "1 lb.", 36.6, new double[] {3.3, 140, 0.1, 15, 0, 1.7, 2.7, 54, 0}}); data.add(new Object[] { "Pork Chops", "1 lb.", 30.7, new double[] {3.5, 196, 0.2, 30, 0, 17.4, 2.7, 60, 0}}); data.add(new Object[] { "Pork Loin Roast", "1 lb.", 24.2, new double[] {4.4, 249, 0.3, 37, 0, 18.2, 3.6, 79, 0}}); data.add(new Object[] { "Bacon", "1 lb.", 25.6, new double[] {10.4, 152, 0.2, 23, 0, 1.8, 1.8, 71, 0}}); data.add(new Object[] { "Ham, smoked", "1 lb.", 27.4, new double[] {6.7, 212, 0.2, 31, 0, 9.9, 3.3, 50, 0}}); data.add(new Object[] { "Salt Pork", "1 lb.", 16, new double[] {18.8, 164, 0.1, 26, 0, 1.4, 1.8, 0, 0}}); data.add(new Object[] {"Roasting Chicken", "1 lb.", 30.3, new double[] {1.8, 184, 0.1, 30, 0.1, 0.9, 1.8, 68, 46}}); data.add(new Object[] { "Veal Cutlets", "1 lb.", 42.3, new double[] {1.7, 156, 0.1, 24, 0, 1.4, 2.4, 57, 0}}); data.add(new Object[] { "Salmon, Pink (can)", "16 oz.", 13, new double[] {5.8, 705, 6.8, 45, 3.5, 1, 4.9, 209, 0}}); data.add(new Object[] { "Apples", "1 lb.", 4.4, new double[] {5.8, 27, 0.5, 36, 7.3, 3.6, 2.7, 5, 544}}); data.add(new Object[] { "Bananas", "1 lb.", 6.1, new double[] {4.9, 60, 0.4, 30, 17.4, 2.5, 3.5, 28, 498}}); data.add( new Object[] {"Lemons", "1 doz.", 26, new double[] {1.0, 21, 0.5, 14, 0, 0.5, 0, 4, 952}}); data.add(new Object[] { "Oranges", "1 doz.", 30.9, new double[] {2.2, 40, 1.1, 18, 11.1, 3.6, 1.3, 10, 1998}}); data.add(new Object[] { "Green Beans", "1 lb.", 7.1, new double[] {2.4, 138, 3.7, 80, 69, 4.3, 5.8, 37, 862}}); data.add(new Object[] { "Cabbage", "1 lb.", 3.7, new double[] {2.6, 125, 4.0, 36, 7.2, 9, 4.5, 26, 5369}}); data.add(new Object[] { "Carrots", "1 bunch", 4.7, new double[] {2.7, 73, 2.8, 43, 188.5, 6.1, 4.3, 89, 608}}); data.add(new Object[] { "Celery", "1 stalk", 7.3, new double[] {0.9, 51, 3.0, 23, 0.9, 1.4, 1.4, 9, 313}}); data.add(new Object[] { "Lettuce", "1 head", 8.2, new double[] {0.4, 27, 1.1, 22, 112.4, 1.8, 3.4, 11, 449}}); data.add(new Object[] { "Onions", "1 lb.", 3.6, new double[] {5.8, 166, 3.8, 59, 16.6, 4.7, 5.9, 21, 1184}}); data.add(new Object[] { "Potatoes", "15 lb.", 34, new double[] {14.3, 336, 1.8, 118, 6.7, 29.4, 7.1, 198, 2522}}); data.add(new Object[] { "Spinach", "1 lb.", 8.1, new double[] {1.1, 106, 0, 138, 918.4, 5.7, 13.8, 33, 2755}}); data.add(new Object[] {"Sweet Potatoes", "1 lb.", 5.1, new double[] {9.6, 138, 2.7, 54, 290.7, 8.4, 5.4, 83, 1912}}); data.add(new Object[] {"Peaches (can)", "No. 2 1/2", 16.8, new double[] {3.7, 20, 0.4, 10, 21.5, 0.5, 1, 31, 196}}); data.add(new Object[] { "Pears (can)", "No. 2 1/2", 20.4, new double[] {3.0, 8, 0.3, 8, 0.8, 0.8, 0.8, 5, 81}}); data.add(new Object[] { "Pineapple (can)", "No. 2 1/2", 21.3, new double[] {2.4, 16, 0.4, 8, 2, 2.8, 0.8, 7, 399}}); data.add(new Object[] {"Asparagus (can)", "No. 2", 27.7, new double[] {0.4, 33, 0.3, 12, 16.3, 1.4, 2.1, 17, 272}}); data.add(new Object[] { "Green Beans (can)", "No. 2", 10, new double[] {1.0, 54, 2, 65, 53.9, 1.6, 4.3, 32, 431}}); data.add(new Object[] {"Pork and Beans (can)", "16 oz.", 7.1, new double[] {7.5, 364, 4, 134, 3.5, 8.3, 7.7, 56, 0}}); data.add(new Object[] { "Corn (can)", "No. 2", 10.4, new double[] {5.2, 136, 0.2, 16, 12, 1.6, 2.7, 42, 218}}); data.add(new Object[] { "Peas (can)", "No. 2", 13.8, new double[] {2.3, 136, 0.6, 45, 34.9, 4.9, 2.5, 37, 370}}); data.add(new Object[] { "Tomatoes (can)", "No. 2", 8.6, new double[] {1.3, 63, 0.7, 38, 53.2, 3.4, 2.5, 36, 1253}}); data.add(new Object[] {"Tomato Soup (can)", "10 1/2 oz.", 7.6, new double[] {1.6, 71, 0.6, 43, 57.9, 3.5, 2.4, 67, 862}}); data.add(new Object[] { "Peaches, Dried", "1 lb.", 15.7, new double[] {8.5, 87, 1.7, 173, 86.8, 1.2, 4.3, 55, 57}}); data.add(new Object[] { "Prunes, Dried", "1 lb.", 9, new double[] {12.8, 99, 2.5, 154, 85.7, 3.9, 4.3, 65, 257}}); data.add(new Object[] {"Raisins, Dried", "15 oz.", 9.4, new double[] {13.5, 104, 2.5, 136, 4.5, 6.3, 1.4, 24, 136}}); data.add(new Object[] { "Peas, Dried", "1 lb.", 7.9, new double[] {20.0, 1367, 4.2, 345, 2.9, 28.7, 18.4, 162, 0}}); data.add(new Object[] {"Lima Beans, Dried", "1 lb.", 8.9, new double[] {17.4, 1055, 3.7, 459, 5.1, 26.9, 38.2, 93, 0}}); data.add(new Object[] {"Navy Beans, Dried", "1 lb.", 5.9, new double[] {26.9, 1691, 11.4, 792, 0, 38.4, 24.6, 217, 0}}); data.add(new Object[] {"Coffee", "1 lb.", 22.4, new double[] {0, 0, 0, 0, 0, 4, 5.1, 50, 0}}); data.add(new Object[] {"Tea", "1/4 lb.", 17.4, new double[] {0, 0, 0, 0, 0, 0, 2.3, 42, 0}}); data.add( new Object[] {"Cocoa", "8 oz.", 8.6, new double[] {8.7, 237, 3, 72, 0, 2, 11.9, 40, 0}}); data.add(new Object[] { "Chocolate", "8 oz.", 16.2, new double[] {8.0, 77, 1.3, 39, 0, 0.9, 3.4, 14, 0}}); data.add(new Object[] {"Sugar", "10 lb.", 51.7, new double[] {34.9, 0, 0, 0, 0, 0, 0, 0, 0}}); data.add(new Object[] { "Corn Syrup", "24 oz.", 13.7, new double[] {14.7, 0, 0.5, 74, 0, 0, 0, 5, 0}}); data.add(new Object[] { "Molasses", "18 oz.", 13.6, new double[] {9.0, 0, 10.3, 244, 0, 1.9, 7.5, 146, 0}}); data.add(new Object[] {"Strawberry Preserves", "1 lb.", 20.5, new double[] {6.4, 11, 0.4, 7, 0.2, 0.2, 0.4, 3, 0}}); // Create the linear solver with the GLOP backend. MPSolver solver = MPSolver.createSolver("GLOP"); if (solver == null) { System.out.println("Could not create solver GLOP"); return; } double infinity = java.lang.Double.POSITIVE_INFINITY; List<MPVariable> foods = new ArrayList<>(); for (int i = 0; i < data.size(); ++i) { foods.add(solver.makeNumVar(0.0, infinity, (String) data.get(i)[0])); } System.out.println("Number of variables = " + solver.numVariables()); MPConstraint[] constraints = new MPConstraint[nutrients.size()]; for (int i = 0; i < nutrients.size(); ++i) { constraints[i] = solver.makeConstraint( (double) nutrients.get(i)[1], infinity, (String) nutrients.get(i)[0]); for (int j = 0; j < data.size(); ++j) { constraints[i].setCoefficient(foods.get(j), ((double[]) data.get(j)[3])[i]); } // constraints.add(constraint); } System.out.println("Number of constraints = " + solver.numConstraints()); MPObjective objective = solver.objective(); for (int i = 0; i < data.size(); ++i) { objective.setCoefficient(foods.get(i), 1); } objective.setMinimization(); final MPSolver.ResultStatus resultStatus = solver.solve(); // Check that the problem has an optimal solution. if (resultStatus != MPSolver.ResultStatus.OPTIMAL) { System.err.println("The problem does not have an optimal solution!"); if (resultStatus == MPSolver.ResultStatus.FEASIBLE) { System.err.println("A potentially suboptimal solution was found."); } else { System.err.println("The solver could not solve the problem."); return; } } // Display the amounts (in dollars) to purchase of each food. double[] nutrientsResult = new double[nutrients.size()]; System.out.println("\nAnnual Foods:"); for (int i = 0; i < foods.size(); ++i) { if (foods.get(i).solutionValue() > 0.0) { System.out.println((String) data.get(i)[0] + ": $" + 365 * foods.get(i).solutionValue()); for (int j = 0; j < nutrients.size(); ++j) { nutrientsResult[j] += ((double[]) data.get(i)[3])[j] * foods.get(i).solutionValue(); } } } System.out.println("\nOptimal annual price: $" + 365 * objective.value()); System.out.println("\nNutrients per day:"); for (int i = 0; i < nutrients.size(); ++i) { System.out.println( nutrients.get(i)[0] + ": " + nutrientsResult[i] + " (min " + nutrients.get(i)[1] + ")"); } System.out.println("\nAdvanced usage:"); System.out.println("Problem solved in " + solver.wallTime() + " milliseconds"); System.out.println("Problem solved in " + solver.iterations() + " iterations"); } private StiglerDiet() {} }
C#
// The Stigler diet problem. using System; using System.Collections.Generic; using Google.OrTools.LinearSolver; public class StiglerDiet { static void Main() { // Nutrient minimums. (String Name, double Value)[] nutrients = new[] { ("Calories (kcal)", 3.0), ("Protein (g)", 70.0), ("Calcium (g)", 0.8), ("Iron (mg)", 12.0), ("Vitamin A (kIU)", 5.0), ("Vitamin B1 (mg)", 1.8), ("Vitamin B2 (mg)", 2.7), ("Niacin (mg)", 18.0), ("Vitamin C (mg)", 75.0) }; (String Name, String Unit, double Price, double[] Nutrients)[] data = new[] { ("Wheat Flour (Enriched)", "10 lb.", 36, new double[] { 44.7, 1411, 2, 365, 0, 55.4, 33.3, 441, 0 }), ("Macaroni", "1 lb.", 14.1, new double[] { 11.6, 418, 0.7, 54, 0, 3.2, 1.9, 68, 0 }), ("Wheat Cereal (Enriched)", "28 oz.", 24.2, new double[] { 11.8, 377, 14.4, 175, 0, 14.4, 8.8, 114, 0 }), ("Corn Flakes", "8 oz.", 7.1, new double[] { 11.4, 252, 0.1, 56, 0, 13.5, 2.3, 68, 0 }), ("Corn Meal", "1 lb.", 4.6, new double[] { 36.0, 897, 1.7, 99, 30.9, 17.4, 7.9, 106, 0 }), ("Hominy Grits", "24 oz.", 8.5, new double[] { 28.6, 680, 0.8, 80, 0, 10.6, 1.6, 110, 0 }), ("Rice", "1 lb.", 7.5, new double[] { 21.2, 460, 0.6, 41, 0, 2, 4.8, 60, 0 }), ("Rolled Oats", "1 lb.", 7.1, new double[] { 25.3, 907, 5.1, 341, 0, 37.1, 8.9, 64, 0 }), ("White Bread (Enriched)", "1 lb.", 7.9, new double[] { 15.0, 488, 2.5, 115, 0, 13.8, 8.5, 126, 0 }), ("Whole Wheat Bread", "1 lb.", 9.1, new double[] { 12.2, 484, 2.7, 125, 0, 13.9, 6.4, 160, 0 }), ("Rye Bread", "1 lb.", 9.1, new double[] { 12.4, 439, 1.1, 82, 0, 9.9, 3, 66, 0 }), ("Pound Cake", "1 lb.", 24.8, new double[] { 8.0, 130, 0.4, 31, 18.9, 2.8, 3, 17, 0 }), ("Soda Crackers", "1 lb.", 15.1, new double[] { 12.5, 288, 0.5, 50, 0, 0, 0, 0, 0 }), ("Milk", "1 qt.", 11, new double[] { 6.1, 310, 10.5, 18, 16.8, 4, 16, 7, 177 }), ("Evaporated Milk (can)", "14.5 oz.", 6.7, new double[] { 8.4, 422, 15.1, 9, 26, 3, 23.5, 11, 60 }), ("Butter", "1 lb.", 30.8, new double[] { 10.8, 9, 0.2, 3, 44.2, 0, 0.2, 2, 0 }), ("Oleomargarine", "1 lb.", 16.1, new double[] { 20.6, 17, 0.6, 6, 55.8, 0.2, 0, 0, 0 }), ("Eggs", "1 doz.", 32.6, new double[] { 2.9, 238, 1.0, 52, 18.6, 2.8, 6.5, 1, 0 }), ("Cheese (Cheddar)", "1 lb.", 24.2, new double[] { 7.4, 448, 16.4, 19, 28.1, 0.8, 10.3, 4, 0 }), ("Cream", "1/2 pt.", 14.1, new double[] { 3.5, 49, 1.7, 3, 16.9, 0.6, 2.5, 0, 17 }), ("Peanut Butter", "1 lb.", 17.9, new double[] { 15.7, 661, 1.0, 48, 0, 9.6, 8.1, 471, 0 }), ("Mayonnaise", "1/2 pt.", 16.7, new double[] { 8.6, 18, 0.2, 8, 2.7, 0.4, 0.5, 0, 0 }), ("Crisco", "1 lb.", 20.3, new double[] { 20.1, 0, 0, 0, 0, 0, 0, 0, 0 }), ("Lard", "1 lb.", 9.8, new double[] { 41.7, 0, 0, 0, 0.2, 0, 0.5, 5, 0 }), ("Sirloin Steak", "1 lb.", 39.6, new double[] { 2.9, 166, 0.1, 34, 0.2, 2.1, 2.9, 69, 0 }), ("Round Steak", "1 lb.", 36.4, new double[] { 2.2, 214, 0.1, 32, 0.4, 2.5, 2.4, 87, 0 }), ("Rib Roast", "1 lb.", 29.2, new double[] { 3.4, 213, 0.1, 33, 0, 0, 2, 0, 0 }), ("Chuck Roast", "1 lb.", 22.6, new double[] { 3.6, 309, 0.2, 46, 0.4, 1, 4, 120, 0 }), ("Plate", "1 lb.", 14.6, new double[] { 8.5, 404, 0.2, 62, 0, 0.9, 0, 0, 0 }), ("Liver (Beef)", "1 lb.", 26.8, new double[] { 2.2, 333, 0.2, 139, 169.2, 6.4, 50.8, 316, 525 }), ("Leg of Lamb", "1 lb.", 27.6, new double[] { 3.1, 245, 0.1, 20, 0, 2.8, 3.9, 86, 0 }), ("Lamb Chops (Rib)", "1 lb.", 36.6, new double[] { 3.3, 140, 0.1, 15, 0, 1.7, 2.7, 54, 0 }), ("Pork Chops", "1 lb.", 30.7, new double[] { 3.5, 196, 0.2, 30, 0, 17.4, 2.7, 60, 0 }), ("Pork Loin Roast", "1 lb.", 24.2, new double[] { 4.4, 249, 0.3, 37, 0, 18.2, 3.6, 79, 0 }), ("Bacon", "1 lb.", 25.6, new double[] { 10.4, 152, 0.2, 23, 0, 1.8, 1.8, 71, 0 }), ("Ham, smoked", "1 lb.", 27.4, new double[] { 6.7, 212, 0.2, 31, 0, 9.9, 3.3, 50, 0 }), ("Salt Pork", "1 lb.", 16, new double[] { 18.8, 164, 0.1, 26, 0, 1.4, 1.8, 0, 0 }), ("Roasting Chicken", "1 lb.", 30.3, new double[] { 1.8, 184, 0.1, 30, 0.1, 0.9, 1.8, 68, 46 }), ("Veal Cutlets", "1 lb.", 42.3, new double[] { 1.7, 156, 0.1, 24, 0, 1.4, 2.4, 57, 0 }), ("Salmon, Pink (can)", "16 oz.", 13, new double[] { 5.8, 705, 6.8, 45, 3.5, 1, 4.9, 209, 0 }), ("Apples", "1 lb.", 4.4, new double[] { 5.8, 27, 0.5, 36, 7.3, 3.6, 2.7, 5, 544 }), ("Bananas", "1 lb.", 6.1, new double[] { 4.9, 60, 0.4, 30, 17.4, 2.5, 3.5, 28, 498 }), ("Lemons", "1 doz.", 26, new double[] { 1.0, 21, 0.5, 14, 0, 0.5, 0, 4, 952 }), ("Oranges", "1 doz.", 30.9, new double[] { 2.2, 40, 1.1, 18, 11.1, 3.6, 1.3, 10, 1998 }), ("Green Beans", "1 lb.", 7.1, new double[] { 2.4, 138, 3.7, 80, 69, 4.3, 5.8, 37, 862 }), ("Cabbage", "1 lb.", 3.7, new double[] { 2.6, 125, 4.0, 36, 7.2, 9, 4.5, 26, 5369 }), ("Carrots", "1 bunch", 4.7, new double[] { 2.7, 73, 2.8, 43, 188.5, 6.1, 4.3, 89, 608 }), ("Celery", "1 stalk", 7.3, new double[] { 0.9, 51, 3.0, 23, 0.9, 1.4, 1.4, 9, 313 }), ("Lettuce", "1 head", 8.2, new double[] { 0.4, 27, 1.1, 22, 112.4, 1.8, 3.4, 11, 449 }), ("Onions", "1 lb.", 3.6, new double[] { 5.8, 166, 3.8, 59, 16.6, 4.7, 5.9, 21, 1184 }), ("Potatoes", "15 lb.", 34, new double[] { 14.3, 336, 1.8, 118, 6.7, 29.4, 7.1, 198, 2522 }), ("Spinach", "1 lb.", 8.1, new double[] { 1.1, 106, 0, 138, 918.4, 5.7, 13.8, 33, 2755 }), ("Sweet Potatoes", "1 lb.", 5.1, new double[] { 9.6, 138, 2.7, 54, 290.7, 8.4, 5.4, 83, 1912 }), ("Peaches (can)", "No. 2 1/2", 16.8, new double[] { 3.7, 20, 0.4, 10, 21.5, 0.5, 1, 31, 196 }), ("Pears (can)", "No. 2 1/2", 20.4, new double[] { 3.0, 8, 0.3, 8, 0.8, 0.8, 0.8, 5, 81 }), ("Pineapple (can)", "No. 2 1/2", 21.3, new double[] { 2.4, 16, 0.4, 8, 2, 2.8, 0.8, 7, 399 }), ("Asparagus (can)", "No. 2", 27.7, new double[] { 0.4, 33, 0.3, 12, 16.3, 1.4, 2.1, 17, 272 }), ("Green Beans (can)", "No. 2", 10, new double[] { 1.0, 54, 2, 65, 53.9, 1.6, 4.3, 32, 431 }), ("Pork and Beans (can)", "16 oz.", 7.1, new double[] { 7.5, 364, 4, 134, 3.5, 8.3, 7.7, 56, 0 }), ("Corn (can)", "No. 2", 10.4, new double[] { 5.2, 136, 0.2, 16, 12, 1.6, 2.7, 42, 218 }), ("Peas (can)", "No. 2", 13.8, new double[] { 2.3, 136, 0.6, 45, 34.9, 4.9, 2.5, 37, 370 }), ("Tomatoes (can)", "No. 2", 8.6, new double[] { 1.3, 63, 0.7, 38, 53.2, 3.4, 2.5, 36, 1253 }), ("Tomato Soup (can)", "10 1/2 oz.", 7.6, new double[] { 1.6, 71, 0.6, 43, 57.9, 3.5, 2.4, 67, 862 }), ("Peaches, Dried", "1 lb.", 15.7, new double[] { 8.5, 87, 1.7, 173, 86.8, 1.2, 4.3, 55, 57 }), ("Prunes, Dried", "1 lb.", 9, new double[] { 12.8, 99, 2.5, 154, 85.7, 3.9, 4.3, 65, 257 }), ("Raisins, Dried", "15 oz.", 9.4, new double[] { 13.5, 104, 2.5, 136, 4.5, 6.3, 1.4, 24, 136 }), ("Peas, Dried", "1 lb.", 7.9, new double[] { 20.0, 1367, 4.2, 345, 2.9, 28.7, 18.4, 162, 0 }), ("Lima Beans, Dried", "1 lb.", 8.9, new double[] { 17.4, 1055, 3.7, 459, 5.1, 26.9, 38.2, 93, 0 }), ("Navy Beans, Dried", "1 lb.", 5.9, new double[] { 26.9, 1691, 11.4, 792, 0, 38.4, 24.6, 217, 0 }), ("Coffee", "1 lb.", 22.4, new double[] { 0, 0, 0, 0, 0, 4, 5.1, 50, 0 }), ("Tea", "1/4 lb.", 17.4, new double[] { 0, 0, 0, 0, 0, 0, 2.3, 42, 0 }), ("Cocoa", "8 oz.", 8.6, new double[] { 8.7, 237, 3, 72, 0, 2, 11.9, 40, 0 }), ("Chocolate", "8 oz.", 16.2, new double[] { 8.0, 77, 1.3, 39, 0, 0.9, 3.4, 14, 0 }), ("Sugar", "10 lb.", 51.7, new double[] { 34.9, 0, 0, 0, 0, 0, 0, 0, 0 }), ("Corn Syrup", "24 oz.", 13.7, new double[] { 14.7, 0, 0.5, 74, 0, 0, 0, 5, 0 }), ("Molasses", "18 oz.", 13.6, new double[] { 9.0, 0, 10.3, 244, 0, 1.9, 7.5, 146, 0 }), ("Strawberry Preserves", "1 lb.", 20.5, new double[] { 6.4, 11, 0.4, 7, 0.2, 0.2, 0.4, 3, 0 }) }; // Create the linear solver with the GLOP backend. Solver solver = Solver.CreateSolver("GLOP"); if (solver is null) { return; } List<Variable> foods = new List<Variable>(); for (int i = 0; i < data.Length; ++i) { foods.Add(solver.MakeNumVar(0.0, double.PositiveInfinity, data[i].Name)); } Console.WriteLine($"Number of variables = {solver.NumVariables()}"); List<Constraint> constraints = new List<Constraint>(); for (int i = 0; i < nutrients.Length; ++i) { Constraint constraint = solver.MakeConstraint(nutrients[i].Value, double.PositiveInfinity, nutrients[i].Name); for (int j = 0; j < data.Length; ++j) { constraint.SetCoefficient(foods[j], data[j].Nutrients[i]); } constraints.Add(constraint); } Console.WriteLine($"Number of constraints = {solver.NumConstraints()}"); Objective objective = solver.Objective(); for (int i = 0; i < data.Length; ++i) { objective.SetCoefficient(foods[i], 1); } objective.SetMinimization(); Solver.ResultStatus resultStatus = solver.Solve(); // Check that the problem has an optimal solution. if (resultStatus != Solver.ResultStatus.OPTIMAL) { Console.WriteLine("The problem does not have an optimal solution!"); if (resultStatus == Solver.ResultStatus.FEASIBLE) { Console.WriteLine("A potentially suboptimal solution was found."); } else { Console.WriteLine("The solver could not solve the problem."); return; } } // Display the amounts (in dollars) to purchase of each food. double[] nutrientsResult = new double[nutrients.Length]; Console.WriteLine("\nAnnual Foods:"); for (int i = 0; i < foods.Count; ++i) { if (foods[i].SolutionValue() > 0.0) { Console.WriteLine($"{data[i].Name}: ${365 * foods[i].SolutionValue():N2}"); for (int j = 0; j < nutrients.Length; ++j) { nutrientsResult[j] += data[i].Nutrients[j] * foods[i].SolutionValue(); } } } Console.WriteLine($"\nOptimal annual price: ${365 * objective.Value():N2}"); Console.WriteLine("\nNutrients per day:"); for (int i = 0; i < nutrients.Length; ++i) { Console.WriteLine($"{nutrients[i].Name}: {nutrientsResult[i]:N2} (min {nutrients[i].Value})"); } Console.WriteLine("\nAdvanced usage:"); Console.WriteLine($"Problem solved in {solver.WallTime()} milliseconds"); Console.WriteLine($"Problem solved in {solver.Iterations()} iterations"); } }