File size: 19,880 Bytes
1cce1df
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5d38ada
1cce1df
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" href="./favicon.ico" />
    <!-- Preload is necessary because we show these images when we disconnect from the server,
    but at that point we cannot load these images from the server -->
    <link rel="preload" href="./assets/gradient-yHQUC_QB.png" as="image" />
    <link rel="preload" href="./assets/noise-60BoTA8O.png" as="image" />
    <!-- Preload the fonts -->
    <link rel="preload" href="./assets/Lora-VariableFont_wght-B2ootaw-.ttf" as="font" crossorigin="anonymous" />
    <link rel="preload" href="./assets/PTSans-Regular-CxL0S8W7.ttf" as="font" crossorigin="anonymous" />
    <link rel="preload" href="./assets/PTSans-Bold-D9fedIX3.ttf" as="font" crossorigin="anonymous" />
    <link rel="preload" href="./assets/FiraMono-Regular-BTCkDNvf.ttf" as="font" crossorigin="anonymous" />
    <link rel="preload" href="./assets/FiraMono-Medium-DU3aDxX5.ttf" as="font" crossorigin="anonymous" />
    <link rel="preload" href="./assets/FiraMono-Bold-CLVRCuM9.ttf" as="font" crossorigin="anonymous" />

    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <meta name="description" content="a marimo app" />
    <link rel="apple-touch-icon" href="./apple-touch-icon.png" />
    <link rel="manifest" href="./manifest.json" />

    <script data-marimo="true">
      function __resizeIframe(obj) {
        var scrollbarHeight = 20; // Max between windows, mac, and linux

        function setHeight() {
          var element = obj.contentWindow.document.documentElement;
          // If there is no vertical scrollbar, we don't need to resize the iframe
          if (element.scrollHeight === element.clientHeight) {
            return;
          }

          // Create a new height that includes the scrollbar height if it's visible
          var hasHorizontalScrollbar = element.scrollWidth > element.clientWidth;
          var newHeight = element.scrollHeight + (hasHorizontalScrollbar ? scrollbarHeight : 0);

          // Only update the height if it's different from the current height
          if (obj.style.height !== `${newHeight}px`) {
            obj.style.height = `${newHeight}px`;
          }
        }

        // Resize the iframe to the height of the content and bottom scrollbar height
        setHeight();

        // Resize the iframe when the content changes
        const resizeObserver = new ResizeObserver((entries) => {
          setHeight();
        });
        resizeObserver.observe(obj.contentWindow.document.body);
      }
    </script>
    <marimo-filename hidden>notebook.py</marimo-filename>
    <marimo-mode data-mode='edit' hidden></marimo-mode>
    <marimo-version data-version='0.11.9' hidden></marimo-version>
    <marimo-user-config data-config='{"completion": {"activate_on_typing": true, "copilot": false}, "display": {"cell_output": "above", "dataframes": "rich", "code_editor_font_size": 14, "default_width": "medium", "theme": "light"}, "formatting": {"line_length": 79}, "keymap": {"preset": "default", "overrides": {}}, "runtime": {"auto_instantiate": true, "auto_reload": "off", "on_cell_change": "autorun", "watcher_on_save": "lazy", "output_max_bytes": 8000000, "std_stream_max_bytes": 1000000}, "save": {"autosave": "off", "autosave_delay": 1000, "format_on_save": false}, "package_management": {"manager": "pip"}, "server": {"browser": "default", "follow_symlink": false}, "snippets": {"custom_paths": [], "include_default_snippets": true}}' data-overrides='{}' hidden></marimo-user-config>
    <marimo-app-config data-config='{"width": "compact"}' hidden></marimo-app-config>
    <marimo-server-token data-token='123' hidden></marimo-server-token>
    <title>02 linear program</title>
    <script type="module" crossorigin src="./assets/index-BiV-b1K2.js"></script>
    <link rel="stylesheet" crossorigin href="./assets/index-DkqMrX_B.css">
  <marimo-wasm hidden=""></marimo-wasm>
    <script>
        if (window.location.protocol === 'file:') {
            alert('Warning: This file must be served by an HTTP server to function correctly.');
        }
    </script>
    
    <style>
        #save-button {
            display: none !important;
        }
        #filename-input {
            display: none !important;
        }
    </style>
    <marimo-code hidden="" data-show-code="false">import%20marimo%0A%0A__generated_with%20%3D%20%220.11.9%22%0Aapp%20%3D%20marimo.App()%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20import%20marimo%20as%20mo%0A%20%20%20%20return%20(mo%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20r%22%22%22%0A%20%20%20%20%20%20%20%20%23%20Linear%20program%0A%0A%20%20%20%20%20%20%20%20A%20linear%20program%20is%20an%20optimization%20problem%20with%20a%20linear%20objective%20and%20affine%0A%20%20%20%20%20%20%20%20inequality%20constraints.%20A%20common%20standard%20form%20is%20the%20following%3A%0A%0A%20%20%20%20%20%20%20%20%5C%5B%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%5Cbegin%7Barray%7D%7Bll%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%5Ctext%7Bminimize%7D%20%20%20%26%20c%5ETx%20%5C%5C%0A%20%20%20%20%20%20%20%20%20%20%20%20%5Ctext%7Bsubject%20to%7D%20%26%20Ax%20%5Cleq%20b.%0A%20%20%20%20%20%20%20%20%20%20%20%20%5Cend%7Barray%7D%0A%20%20%20%20%20%20%20%20%5C%5D%0A%0A%20%20%20%20%20%20%20%20Here%20%24A%20%5Cin%20%5Cmathcal%7BR%7D%5E%7Bm%20%5Ctimes%20n%7D%24%2C%20%24b%20%5Cin%20%5Cmathcal%7BR%7D%5Em%24%2C%20and%20%24c%20%5Cin%20%5Cmathcal%7BR%7D%5En%24%20are%20problem%20data%20and%20%24x%20%5Cin%20%5Cmathcal%7BR%7D%5E%7Bn%7D%24%20is%20the%20optimization%20variable.%20The%20inequality%20constraint%20%24Ax%20%5Cleq%20b%24%20is%20elementwise.%0A%0A%20%20%20%20%20%20%20%20For%20example%2C%20we%20might%20have%20%24n%24%20different%20products%2C%20each%20constructed%20out%20of%20%24m%24%20components.%20Each%20entry%20%24A_%7Bij%7D%24%20is%20the%20amount%20of%20component%20%24i%24%20required%20to%20build%20one%20unit%20of%20product%20%24j%24.%20Each%20entry%20%24b_i%24%20is%20the%20total%20amount%20of%20component%20%24i%24%20available.%20We%20lose%20%24c_j%24%20for%20each%20unit%20of%20product%20%24j%24%20(%24c_j%20%3C%200%24%20indicates%20profit).%20Our%20goal%20then%20is%20to%20choose%20how%20many%20units%20of%20each%20product%20%24j%24%20to%20make%2C%20%24x_j%24%2C%20in%20order%20to%20minimize%20loss%20without%20exceeding%20our%20budget%20for%20any%20component.%0A%0A%20%20%20%20%20%20%20%20In%20addition%20to%20a%20solution%20%24x%5E%5Cstar%24%2C%20we%20obtain%20a%20dual%20solution%20%24%5Clambda%5E%5Cstar%24.%20A%20positive%20entry%20%24%5Clambda%5E%5Cstar_i%24%20indicates%20that%20the%20constraint%20%24a_i%5ETx%20%5Cleq%20b_i%24%20holds%20with%20equality%20for%20%24x%5E%5Cstar%24%20and%20suggests%20that%20changing%20%24b_i%24%20would%20change%20the%20optimal%20value.%0A%0A%20%20%20%20%20%20%20%20**Why%20linear%20programming%3F**%20Linear%20programming%20is%20a%20way%20to%20achieve%20an%20optimal%20outcome%2C%20such%20as%20maximum%20utility%20or%20lowest%20cost%2C%20subject%20to%20a%20linear%20objective%20function%20and%20affine%20constraints.%20Developed%20in%20the%2020th%20century%2C%20linear%20programming%20is%20widely%20used%20today%20to%20solve%20problems%20in%20resource%20allocation%2C%20scheduling%2C%20transportation%2C%20and%20more.%20The%20discovery%20of%20polynomial-time%20algorithms%20to%20solve%20linear%20programs%20was%20of%20tremendous%20worldwide%20importance%20and%20entered%20the%20public%20discourse%2C%20even%20making%20the%20front%20page%20of%20the%20New%20York%20Times.%0A%0A%20%20%20%20%20%20%20%20In%20the%20late%2020th%20and%20early%2021st%20century%2C%20researchers%20generalized%20linear%20programming%20to%20a%20much%20wider%20class%20of%20problems%20called%20convex%20optimization%20problems.%20Nearly%20all%20convex%20optimization%20problems%20can%20be%20solved%20efficiently%20and%20reliably%2C%20and%20even%20more%20difficult%20problems%20are%20readily%20solved%20by%20a%20sequence%20of%20convex%20optimization%20problems.%20Today%2C%20convex%20optimization%20is%20used%20to%20fit%20machine%20learning%20models%2C%20land%20rockets%20in%20real-time%20at%20SpaceX%2C%20plan%20trajectories%20for%20self-driving%20cars%20at%20Waymo%2C%20execute%20many%20billions%20of%20dollars%20of%20financial%20trades%20a%20day%2C%20and%20much%20more.%0A%0A%20%20%20%20%20%20%20%20This%20marimo%20learn%20course%20uses%20CVXPY%2C%20a%20modeling%20language%20for%20convex%20optimization%20problems%20developed%20originally%20at%20Stanford%2C%20to%20construct%20and%20solve%20convex%20programs.%0A%20%20%20%20%20%20%20%20%22%22%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20f%22%22%22%0A%20%20%20%20%20%20%20%20%7Bmo.image(%22https%3A%2F%2Fwww.debugmind.com%2Fwp-content%2Fuploads%2F2020%2F01%2Fspacex-1.jpg%22)%7D%0A%20%20%20%20%20%20%20%20_SpaceX%20solves%20convex%20optimization%20problems%20onboard%20to%20land%20its%20rockets%2C%20using%20CVXGEN%2C%20a%20code%20generator%20for%20quadratic%20programming%20developed%20at%20Stephen%20Boyd%E2%80%99s%20Stanford%20lab.%20Photo%20by%20SpaceX%2C%20licensed%20CC%20BY-NC%202.0._%0A%20%20%20%20%20%20%20%20%22%22%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20r%22%22%22%0A%20%20%20%20%20%20%20%20%23%23%20Example%0A%0A%20%20%20%20%20%20%20%20Here%20we%20use%20CVXPY%20to%20construct%20and%20solve%20a%20linear%20program.%0A%20%20%20%20%20%20%20%20%22%22%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20import%20cvxpy%20as%20cp%0A%20%20%20%20import%20numpy%20as%20np%0A%20%20%20%20return%20cp%2C%20np%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(np)%3A%0A%20%20%20%20A%20%3D%20np.array(%0A%20%20%20%20%20%20%20%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%5B0.76103773%2C%200.12167502%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%5B0.44386323%2C%200.33367433%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%5B1.49407907%2C%20-0.20515826%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%5B0.3130677%2C%20-0.85409574%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%5B-2.55298982%2C%200.6536186%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%5B0.8644362%2C%20-0.74216502%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%5B2.26975462%2C%20-1.45436567%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%5B0.04575852%2C%20-0.18718385%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%5B1.53277921%2C%201.46935877%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%5B0.15494743%2C%200.37816252%5D%2C%0A%20%20%20%20%20%20%20%20%5D%0A%20%20%20%20)%0A%0A%20%20%20%20b%20%3D%20np.array(%0A%20%20%20%20%20%20%20%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%202.05062369%2C%0A%20%20%20%20%20%20%20%20%20%20%20%200.94934659%2C%0A%20%20%20%20%20%20%20%20%20%20%20%200.89559424%2C%0A%20%20%20%20%20%20%20%20%20%20%20%201.04389978%2C%0A%20%20%20%20%20%20%20%20%20%20%20%202.45035643%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20-0.95479445%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20-0.83801349%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20-0.26562529%2C%0A%20%20%20%20%20%20%20%20%20%20%20%202.35763652%2C%0A%20%20%20%20%20%20%20%20%20%20%20%200.98286942%2C%0A%20%20%20%20%20%20%20%20%5D%0A%20%20%20%20)%0A%20%20%20%20return%20A%2C%20b%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22We've%20randomly%20generated%20problem%20data%20%24A%24%20and%20%24B%24.%20The%20vector%20for%20%24c%24%20is%20shown%20below.%20Try%20playing%20with%20the%20value%20of%20%24c%24%20by%20dragging%20the%20components%2C%20and%20see%20how%20the%20level%20curves%20change%20in%20the%20visualization%20below.%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo%2C%20np)%3A%0A%20%20%20%20from%20wigglystuff%20import%20Matrix%0A%0A%20%20%20%20c_widget%20%3D%20mo.ui.anywidget(Matrix(matrix%3Dnp.array(%5B%5B0.1%2C%20-0.2%5D%5D)%2C%20step%3D0.01))%0A%20%20%20%20c_widget%0A%20%20%20%20return%20Matrix%2C%20c_widget%0A%0A%0A%40app.cell%0Adef%20_(c_widget%2C%20np)%3A%0A%20%20%20%20c%20%3D%20np.array(c_widget.value%5B%22matrix%22%5D%5B0%5D)%0A%20%20%20%20return%20(c%2C)%0A%0A%0A%40app.cell%0Adef%20_(A%2C%20b%2C%20c%2C%20cp)%3A%0A%20%20%20%20x%20%3D%20cp.Variable(A.shape%5B1%5D)%0A%20%20%20%20prob%20%3D%20cp.Problem(cp.Minimize(c.T%20%40%20x)%2C%20%5BA%20%40%20x%20%3C%3D%20b%5D)%0A%20%20%20%20_%20%3D%20prob.solve()%0A%20%20%20%20x_star%20%3D%20x.value%0A%20%20%20%20return%20prob%2C%20x%2C%20x_star%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22Below%2C%20we%20plot%20the%20feasible%20region%20of%20the%20problem%20%E2%80%94%20the%20intersection%20of%20the%20inequalities%20%E2%80%94%20and%20the%20level%20curves%20of%20the%20objective%20function.%20The%20optimal%20value%20%24x%5E%5Cstar%24%20is%20the%20point%20farthest%20in%20the%20feasible%20region%20in%20the%20direction%20%24-c%24.%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(A%2C%20b%2C%20c%2C%20make_plot%2C%20x_star)%3A%0A%20%20%20%20make_plot(A%2C%20b%2C%20c%2C%20x_star)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(np)%3A%0A%20%20%20%20import%20matplotlib.pyplot%20as%20plt%0A%0A%0A%20%20%20%20def%20make_plot(A%2C%20b%2C%20c%2C%20x_star)%3A%0A%20%20%20%20%20%20%20%20%23%20Define%20a%20grid%20over%20a%20region%20that%20covers%20the%20feasible%20set.%0A%20%20%20%20%20%20%20%20%23%20You%20might%20need%20to%20adjust%20these%20limits.%0A%20%20%20%20%20%20%20%20x_vals%20%3D%20np.linspace(-1%2C%201%2C%20400)%0A%20%20%20%20%20%20%20%20y_vals%20%3D%20np.linspace(1%2C%203%2C%20400)%0A%20%20%20%20%20%20%20%20X%2C%20Y%20%3D%20np.meshgrid(x_vals%2C%20y_vals)%0A%0A%20%20%20%20%20%20%20%20%23%20Flatten%20the%20grid%20points%20into%20an%20(N%2C2)%20array.%0A%20%20%20%20%20%20%20%20points%20%3D%20np.vstack(%5BX.ravel()%2C%20Y.ravel()%5D).T%0A%0A%20%20%20%20%20%20%20%20%23%20For%20each%20point%2C%20check%20if%20it%20satisfies%20all%20the%20constraints%3A%20A%20%40%20x%20%3C%3D%20b.%0A%20%20%20%20%20%20%20%20%23%20A%20dot%20product%3A%20shape%20of%20A%20%40%20x.T%20will%20be%20(m%2C%20N).%20We%20add%20a%20little%20tolerance.%0A%20%20%20%20%20%20%20%20feasible%20%3D%20np.all(np.dot(A%2C%20points.T)%20%3C%3D%20(b%5B%3A%2C%20None%5D%20%2B%201e-8)%2C%20axis%3D0)%0A%20%20%20%20%20%20%20%20feasible%20%3D%20feasible.reshape(X.shape)%0A%0A%20%20%20%20%20%20%20%20%23%20Create%20the%20figure%20with%20a%20white%20background.%0A%20%20%20%20%20%20%20%20fig%20%3D%20plt.figure(figsize%3D(8%2C%206)%2C%20facecolor%3D%22white%22)%0A%20%20%20%20%20%20%20%20ax%20%3D%20fig.add_subplot(111)%0A%20%20%20%20%20%20%20%20ax.set_facecolor(%22white%22)%0A%0A%20%20%20%20%20%20%20%20%23%20Plot%20the%20feasible%20region.%0A%20%20%20%20%20%20%20%20%23%20Since%20%22feasible%22%20is%20a%20boolean%20array%20(False%3D0%2C%20True%3D1)%2C%20we%20set%20contour%20levels%20so%20that%0A%20%20%20%20%20%20%20%20%23%20the%20region%20with%20value%201%20(feasible)%20gets%20filled.%0A%20%20%20%20%20%20%20%20ax.contourf(%0A%20%20%20%20%20%20%20%20%20%20%20%20X%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20Y%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20feasible.astype(float)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20levels%3D%5B-0.5%2C%200.5%2C%201.5%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20colors%3D%5B%22white%22%2C%20%22gray%22%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20alpha%3D0.5%2C%0A%20%20%20%20%20%20%20%20)%0A%0A%20%20%20%20%20%20%20%20%23%20Plot%20level%20curves%20of%20the%20objective%20function%20c%5ET%20x.%0A%20%20%20%20%20%20%20%20%23%20Compute%20c%5ET%20x%20over%20the%20grid%3A%0A%20%20%20%20%20%20%20%20Z%20%3D%20c%5B0%5D%20*%20X%20%2B%20c%5B1%5D%20*%20Y%0A%20%20%20%20%20%20%20%20%23%20Choose%20several%20levels%20for%20the%20iso-cost%20lines.%0A%20%20%20%20%20%20%20%20levels%20%3D%20np.linspace(np.min(Z)%2C%20np.max(Z)%2C%2020)%0A%20%20%20%20%20%20%20%20contours%20%3D%20ax.contour(%0A%20%20%20%20%20%20%20%20%20%20%20%20X%2C%20Y%2C%20Z%2C%20levels%3Dlevels%2C%20colors%3D%22gray%22%2C%20linestyles%3D%22--%22%2C%20linewidths%3D1%0A%20%20%20%20%20%20%20%20)%0A%0A%20%20%20%20%20%20%20%20%23%20Draw%20the%20vector%20-c%20as%20an%20arrow%20starting%20at%20x_star.%0A%20%20%20%20%20%20%20%20norm_c%20%3D%20np.linalg.norm(c)%0A%20%20%20%20%20%20%20%20if%20norm_c%20%3E%200%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20head_width%20%3D%20norm_c%20*%200.1%0A%20%20%20%20%20%20%20%20%20%20%20%20head_length%20%3D%20norm_c%20*%200.1%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20The%20arrow%20starts%20at%20x_star%20and%20points%20in%20the%20-c%20direction.%0A%20%20%20%20%20%20%20%20%20%20%20%20ax.arrow(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20x_star%5B0%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20x_star%5B1%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20-c%5B0%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20-c%5B1%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20head_width%3Dhead_width%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20head_length%3Dhead_length%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fc%3D%22black%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20ec%3D%22black%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20length_includes_head%3DTrue%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20Label%20the%20arrow%20near%20its%20tip.%0A%20%20%20%20%20%20%20%20%20%20%20%20ax.text(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20x_star%5B0%5D%20-%20c%5B0%5D%20*%201.05%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20x_star%5B1%5D%20-%20c%5B1%5D%20*%201.05%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20r%22%24-c%24%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20color%3D%22black%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fontsize%3D12%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20)%0A%0A%20%20%20%20%20%20%20%20%23%20Optionally%2C%20mark%20and%20label%20the%20point%20x_star.%0A%20%20%20%20%20%20%20%20ax.plot(x_star%5B0%5D%2C%20x_star%5B1%5D%2C%20%22ko%22%2C%20markersize%3D5)%0A%20%20%20%20%20%20%20%20ax.text(%0A%20%20%20%20%20%20%20%20%20%20%20%20x_star%5B0%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20x_star%5B1%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20r%22%24%5Cmathbf%7Bx%7D%5E%5Cstar%24%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20color%3D%22black%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20fontsize%3D12%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20verticalalignment%3D%22bottom%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20horizontalalignment%3D%22right%22%2C%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20%23%20Label%20the%20axes%20and%20set%20title.%0A%20%20%20%20%20%20%20%20ax.set_xlabel(%22%24x_1%24%22)%0A%20%20%20%20%20%20%20%20ax.set_ylabel(%22%24x_2%24%22)%0A%20%20%20%20%20%20%20%20ax.set_title(%22Feasible%20Region%20and%20Level%20Curves%20of%20%24c%5ETx%24%22)%0A%20%20%20%20%20%20%20%20ax.set_xlim(np.min(x_vals)%2C%20np.max(x_vals))%0A%20%20%20%20%20%20%20%20ax.set_ylim(np.min(y_vals)%2C%20np.max(y_vals))%0A%20%20%20%20%20%20%20%20return%20ax%0A%20%20%20%20return%20make_plot%2C%20plt%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo%2C%20prob%2C%20x)%3A%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20f%22%22%22%0A%20%20%20%20%20%20%20%20The%20optimal%20value%20is%20%7Bprob.value%3A.04f%7D.%0A%0A%20%20%20%20%20%20%20%20A%20solution%20%24x%24%20is%20%7Bmo.as_html(list(x.value))%7D%0A%20%20%20%20%20%20%20%20A%20dual%20solution%20is%20is%20%7Bmo.as_html(list(prob.constraints%5B0%5D.dual_value))%7D%0A%20%20%20%20%20%20%20%20%22%22%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20app.run()%0A</marimo-code></head>
  <body>
    <div id="root"></div>
  </body>
</html>