├── .gitignore ├── images ├── peko128.png ├── peko16.png ├── peko32.png └── peko48.png ├── components ├── extra.html ├── popup.css ├── popup.html ├── extra.js └── popup.js ├── background.js ├── manifest.json ├── contents ├── calculate.js ├── content.js └── solver.js ├── LICENSE ├── options ├── options.css ├── options.js └── options.html └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .idea -------------------------------------------------------------------------------- /images/peko128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeeJiangWei/pcr-calculator/HEAD/images/peko128.png -------------------------------------------------------------------------------- /images/peko16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeeJiangWei/pcr-calculator/HEAD/images/peko16.png -------------------------------------------------------------------------------- /images/peko32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeeJiangWei/pcr-calculator/HEAD/images/peko32.png -------------------------------------------------------------------------------- /images/peko48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LeeJiangWei/pcr-calculator/HEAD/images/peko48.png -------------------------------------------------------------------------------- /components/extra.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 规划结果 6 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /components/popup.css: -------------------------------------------------------------------------------- 1 | html { 2 | width: 500px; 3 | } 4 | 5 | .center { 6 | width: 90%; 7 | margin: 0 auto 0; 8 | } 9 | 10 | .button { 11 | padding: 10px; 12 | border: none; 13 | border-radius: 5px; 14 | font-size: 15px; 15 | margin-bottom: 5px; 16 | margin-right: 5px; 17 | } 18 | 19 | .button { 20 | transition-duration: 0.4s; 21 | } 22 | 23 | .button:hover { 24 | background-color: #4CAF50; /* Green */ 25 | color: white; 26 | } 27 | 28 | .mount { 29 | margin: 10px auto; 30 | } 31 | 32 | th, td { 33 | font-size: 1.25em; 34 | padding: 5px; 35 | text-align: left; 36 | } 37 | 38 | p { 39 | font-size: 1.1em; 40 | } -------------------------------------------------------------------------------- /components/popup.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |

欢迎使用PCR刷图计算器

10 |

使用说明:选好角色、库存以及地图选项后,按顺序点击下面这三个按钮。如果更改了选项,需要重新点击相应的按钮。

11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | -------------------------------------------------------------------------------- /background.js: -------------------------------------------------------------------------------- 1 | chrome.runtime.onInstalled.addListener(function () { 2 | chrome.declarativeContent.onPageChanged.removeRules(undefined, function () { 3 | chrome.declarativeContent.onPageChanged.addRules([ 4 | { 5 | conditions: [ 6 | new chrome.declarativeContent.PageStateMatcher({ 7 | pageUrl: { hostEquals: "pcredivewiki.tw" }, 8 | }), 9 | ], 10 | actions: [new chrome.declarativeContent.ShowPageAction()], 11 | }, 12 | ]); 13 | }); 14 | chrome.storage.local.set({ 15 | options: { 16 | algorithm: "lp", 17 | metric: "farmTime", 18 | multiplier: 1, 19 | displayInt: false, 20 | timeOut: 1000, 21 | }, 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "公主连结刷图计算器", 3 | "version": "1.0.7", 4 | "description": "这个扩展为手机游戏“公主连结: Re Dive”的非官方Wiki网站提供了额外的功能,可以为你计算出游玩计划,以尽量地节省游戏资源(体力值)。", 5 | "permissions": [ 6 | "declarativeContent", 7 | "storage", 8 | "activeTab" 9 | ], 10 | "background": { 11 | "scripts": [ 12 | "background.js" 13 | ], 14 | "persistent": false 15 | }, 16 | "content_scripts": [ 17 | { 18 | "matches": ["https://pcredivewiki.tw/Armory"], 19 | "css": [], 20 | "js": ["contents/content.js", "contents/solver.js"] 21 | } 22 | ], 23 | "options_page": "options/options.html", 24 | "page_action": { 25 | "default_popup": "components/popup.html" 26 | }, 27 | "icons": { 28 | "16": "images/peko16.png", 29 | "32": "images/peko32.png", 30 | "48": "images/peko48.png", 31 | "128": "images/peko128.png" 32 | }, 33 | "manifest_version": 2 34 | } -------------------------------------------------------------------------------- /contents/calculate.js: -------------------------------------------------------------------------------- 1 | chrome.storage.local.get(["mapData", "demands", "options"], function (items) { 2 | const { mapData, demands, options } = items; 3 | calculate(mapData, demands, options); 4 | }); 5 | 6 | function calculate(mapData, demands, options) { 7 | const { algorithm, timeOut, metric } = options; 8 | 9 | let ints = Object.assign({}, mapData); 10 | for (let key in ints) { 11 | ints[key] = 1; 12 | } 13 | 14 | const model = { 15 | optimize: metric, 16 | opType: "min", 17 | constraints: demands, 18 | variables: mapData, 19 | options: { 20 | timeout: timeOut, 21 | }, 22 | }; 23 | 24 | if (algorithm === "ip") { 25 | model.ints = ints; 26 | } 27 | 28 | const t0 = performance.now(); 29 | const result = solver.Solve(model); 30 | const t1 = performance.now(); 31 | result.usedTime = t1 - t0; 32 | 33 | chrome.storage.local.set({ plan: result }); 34 | } 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 LeeJiangWei 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /options/options.css: -------------------------------------------------------------------------------- 1 | .center { 2 | width: 40%; 3 | margin: auto; 4 | } 5 | 6 | .container > * { 7 | margin-bottom: 10px; 8 | } 9 | 10 | .divider { 11 | height: 1px; 12 | background-color: lightgray; 13 | } 14 | 15 | input { 16 | outline: none; 17 | } 18 | 19 | label { 20 | margin-right: 20px; 21 | } 22 | 23 | .comment { 24 | font-size: 80%; 25 | color:grey; 26 | } 27 | 28 | .radio, .checkbox { 29 | width: 1.2rem; 30 | height: 1.2rem; 31 | background-color: #ffffff; 32 | border: solid 1px #dddddd; 33 | -webkit-border-radius: 0.6rem; 34 | border-radius: 0.6rem; 35 | font-size: 0.8rem; 36 | margin: 0; 37 | padding: 0; 38 | position: relative; 39 | display: inline-block; 40 | vertical-align: top; 41 | cursor: default; 42 | -webkit-appearance: none; /**隐藏原生控件**/ 43 | } 44 | 45 | .checkbox { 46 | border-radius: 0.1rem; /**复选框的圆角要小一些**/ 47 | } 48 | 49 | .number { 50 | width: 6rem; 51 | height: 1.2rem; 52 | background-color: #ffffff; 53 | border: solid 1px #dddddd; 54 | -webkit-border-radius: 0.6rem; 55 | font-size: 0.8rem; 56 | margin: 0; 57 | padding: 0; 58 | position: relative; 59 | display: inline-block; 60 | vertical-align: top; 61 | border-radius: 0.1rem; 62 | } 63 | 64 | /**选择后的样式**/ 65 | .radio:checked, .checkbox:checked { 66 | background-color: #04c9e8; 67 | border: solid 1px #00adc8; 68 | box-shadow: 0 1px 1px rgba(0, 0, 0, .1); 69 | text-align: center; 70 | background-clip: padding-box; 71 | } 72 | 73 | /**选择后 里面小对勾样式**/ 74 | .radio:checked:before, .checkbox:checked:before { 75 | content: ''; 76 | width: 0.5rem; 77 | height: 0.3rem; 78 | border: 1px solid #ffffff; 79 | border-top: none; 80 | border-right: none; 81 | position: absolute; 82 | top: 50%; 83 | left: 50%; 84 | margin-left: -0.25rem; 85 | margin-top: -0.25rem; 86 | -webkit-transform: rotate(-45deg); 87 | transform: rotate(-45deg); 88 | } -------------------------------------------------------------------------------- /options/options.js: -------------------------------------------------------------------------------- 1 | let form = document.getElementsByTagName("form")[0]; 2 | form.addEventListener("change", onFormChanged); 3 | window.addEventListener("load", onFormLoaded); 4 | 5 | const algorithmRadios = document.getElementsByName("algorithm"); 6 | const multiplierRadios = document.getElementsByName("multiplier"); 7 | const metricRadios = document.getElementsByName("metric"); 8 | const displayIntCheckbox = document.getElementById("displayIntCheckbox"); 9 | const timeOutInput = document.getElementById("timeOutInput"); 10 | 11 | function onFormChanged() { 12 | let options = { 13 | algorithm: "lp", 14 | metric: "farmTime", 15 | multiplier: 1, 16 | displayInt: false, 17 | timeOut: 1000, 18 | }; 19 | 20 | for (let radio of algorithmRadios) { 21 | if (radio.checked) { 22 | options.algorithm = radio.value; 23 | } 24 | } 25 | 26 | for (let radio of metricRadios) { 27 | if (radio.checked) { 28 | options.metric = radio.value; 29 | } 30 | } 31 | 32 | for (let radio of multiplierRadios) { 33 | if (radio.checked) { 34 | options.multiplier = parseInt(radio.value); 35 | } 36 | } 37 | 38 | options.displayInt = displayIntCheckbox.checked; 39 | 40 | options.timeOut = parseFloat(timeOutInput.value); 41 | 42 | chrome.storage.local.set({ options }, function () { 43 | console.log("Options saved successfully."); 44 | }); 45 | } 46 | 47 | function onFormLoaded() { 48 | chrome.storage.local.get("options", function (items) { 49 | const { options } = items; 50 | 51 | for (let radio of algorithmRadios) { 52 | radio.checked = options.algorithm === radio.value; 53 | } 54 | for (let radio of metricRadios) { 55 | radio.checked = options.metric === radio.value; 56 | } 57 | for (let radio of multiplierRadios) { 58 | radio.checked = options.multiplier === parseInt(radio.value); 59 | } 60 | displayIntCheckbox.checked = options.displayInt; 61 | timeOutInput.value = options.timeOut; 62 | }); 63 | } 64 | -------------------------------------------------------------------------------- /components/extra.js: -------------------------------------------------------------------------------- 1 | chrome.storage.local.get(["options", "plan"], function (items) { 2 | const { plan, options } = items; 3 | const { multiplier, displayInt } = options; 4 | const sort = "down"; 5 | const axis = "mapName"; 6 | 7 | let html = "", 8 | totalFarmTime = 0, 9 | totalApCost = 0; 10 | let planArr = []; 11 | 12 | for (let mapName in plan) { 13 | if (!isNaN(parseInt(mapName))) { 14 | const chapterIndex = parseInt(mapName.slice(0, mapName.indexOf("-"))); 15 | const mapIndex = parseInt( 16 | mapName.slice(mapName.indexOf("-") + 1, mapName.length) 17 | ); 18 | 19 | const apCost = Math.min(7 + Math.ceil(chapterIndex / 3), 10); 20 | let farmTime = parseFloat((plan[mapName] / multiplier).toFixed(2)); 21 | farmTime = displayInt ? Math.ceil(farmTime) : farmTime; 22 | const summedApCost = parseFloat((farmTime * apCost).toFixed(2)); 23 | 24 | totalFarmTime += farmTime; 25 | totalApCost += summedApCost; 26 | planArr.push({ 27 | mapName, 28 | chapterIndex, 29 | mapIndex, 30 | farmTime, 31 | summedApCost, 32 | }); 33 | } 34 | } 35 | 36 | planArr = planArr.sort(function (a, b) { 37 | if (sort === "no") return 0; 38 | 39 | let result = 0; 40 | if (axis === "mapName") { 41 | result = 42 | a.chapterIndex * 100 + a.mapIndex - b.chapterIndex * 100 - b.mapIndex; 43 | } else if (axis === "farmTime") { 44 | result = a.farmTime - b.farmTime; 45 | } else if (axis === "summedApCost") { 46 | result = a.summedApCost - b.summedApCost; 47 | } else { 48 | result = 0; 49 | } 50 | 51 | if (sort === "down") { 52 | result *= -1; 53 | } 54 | 55 | return result; 56 | }); 57 | 58 | planArr.forEach(function (item) { 59 | const { mapName, farmTime, summedApCost } = item; 60 | html += `${mapName}${farmTime}${summedApCost}`; 61 | }); 62 | 63 | html = `${html}
关卡名建议次数体力消耗
总计${ 64 | displayInt ? Math.ceil(totalFarmTime) : totalFarmTime.toFixed(2) 65 | }${ 66 | displayInt ? Math.ceil(totalApCost) : totalApCost.toFixed(2) 67 | }
`; 68 | 69 | let table = document.createElement("div"); 70 | table.innerHTML = html; 71 | document.getElementById("mount").appendChild(table); 72 | }); 73 | -------------------------------------------------------------------------------- /options/options.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 公主连结刷图计算器 6 | 7 | 8 | 9 |
10 |

公主连结刷图计算器

11 |
12 |
13 |

选项

14 |
15 |

算法

16 | 17 | 18 | 19 | 20 |

注:整数规划是NP完全问题,随着问题规模的增长,耗时会变得难以置信的长。出于程序完整性,我还是提供了这个功能,但除非计算的装备很少,不然请不要用此算法。

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 |

您的star是我更新项目的最大动力 :)

47 | Github项目地址 48 |

如果在使用过程中遇到任何问题、困难、bug,欢迎在Github上提交issue。

49 |

作者已弃坑PCR,更新看缘分 :)

50 | 51 |
52 | 53 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # pcr-calculator 2 | 用于【蘭德索爾圖書館】的公主连结R刷图规划工具,使用Chrome extension开发 3 | 4 | ## ⚠重要提醒 5 | 由于本人已经弃坑且缺乏时间与兴趣,该项目已经停止维护了,感谢大家的支持! 6 | 7 | ## 安装 8 | ~~辣鸡Google开发者注册账户要5美元,👴现在不知道怎么办了~~ 9 | + 在Chrome应用商店中安装(推荐,但需要科学上网) 10 | + 终于过审啦,再也不用被停用开发者模式的提示烦了。点此进入Chrome商店页面:[公主连接刷图计算器](https://chrome.google.com/webstore/detail/%E5%85%AC%E4%B8%BB%E8%BF%9E%E7%BB%93%E5%88%B7%E5%9B%BE%E8%AE%A1%E7%AE%97%E5%99%A8/ogbcpldmfpobkcoefefcegmajngogejd) 11 | + 以开发者模式安装 12 | 1. 下载源代码,解压 13 | 2. Chrome浏览器地址栏输入`chrome://extensions/`,进入扩展管理界面 14 | 3. 右上角打开`开发者模式` 15 | 4. 左上角点击`加载已解压的扩展程序`,选择源代码的根目录 16 | 17 | ## 使用方法 18 | 1. 访问[【蘭德索爾圖書館】](https://pcredivewiki.tw)的[【裝備庫】](https://pcredivewiki.tw/Armory)页面 19 | 2. 加入你想要练的角色 20 | 3. 点击右上角的`···`图标,右键点击扩展图标,选择`在工具栏中显示` 21 | 4. 点击右上角的扩展图标,按照弹出框说明操作即可 22 | 5. 如果不小心把弹出框关闭了,直接再次点击计算按钮就可以获得上次计算的结果(因为装备需求和地图数据是储存在本地的) 23 | 24 | ## 备注 25 | + 除非装备很少,否则请不要使用整数规划功能,因为实在太慢了,而且结果差别不大。计算的时候会导致该页面进程阻塞,使用的时候记得设置短一点的超时时间。如果不想等了,直接关闭标签页来结束进程。 26 | + 代价度量方法,基本上选哪个结果都不大,因为不同的地图体力消耗差别太小了,7章以后甚至全是一样的10点(大概)。 27 | 28 | ## Screenshot 29 | ![screenshot](https://user-images.githubusercontent.com/49602584/81465241-2e6dfb80-91fb-11ea-8e6f-f82e1839df0e.png) 30 | ![screenshot](https://user-images.githubusercontent.com/49602584/81642099-2b6e4780-9455-11ea-9073-2baa754a30a9.png) 31 | 32 | ## Troubleshooting 33 | + 点击了按钮,但是看上去好像并没有反应 34 | + 确保自己处于[装备库页面](https://pcredivewiki.tw/Armory)(`/Armory`)。虽然在图书馆的其他页面也能打开,但是不会有效果。 35 | + 如果是先进入了图书馆的主页(或者其他页面),然后再通过点击导航栏的按钮进入装备库页面,也可能会有这样的结果,我猜测这可能是由于图书馆的页面跳转并非浏览器的默认行为(类似于React的Link),从而导致即使代码里限定了执行注入脚本的路径,脚本还是会被错误地注入到其他页面,从而导致运行时错误。解决方法很简单,直接进入装备库页面,或者在装备库页面刷新一下就可以了。目前暂时不知道如何解决此问题,欢迎提出建议。 36 | + 可能与网络问题有关,功能在页面完全加载后才会生效,尝试等待页面加载完毕后再操作。 37 | + 如果重新加载了扩展,则需要刷新页面。 38 | + 点击前两个按钮有反应,但计算按钮无反应 39 | + 这是v0.2.0版本的一个bug,原因是设置未能正确地初始化,解决方法是进入选项页面,随便改动一下选项,触发自动保存即可。 40 | + 最新版(应该)已经没有这个问题了(?)。 41 | + 读取地图掉落数据有问题,或前后不一致 42 | + 读取掉落数据前,程序会自动将单页显示设为“全部”。由于页面更新需要一定的时间,程序将等待一小段时间。如果这段时间里页面更新还没完成,则可能导致程序读取的数据不完整。尝试在等地图数据全部显示后再点击解析按钮。 43 | + 计算的装备越多,页面更新时间越长。可以多点几次按钮来缓解你的等待焦虑。 44 | + 计算失败 45 | + 可能地图上限设置过低,存在现有地图中不掉落的装备,则约束条件无法满足。更改地图上限后重新解析并计算。 46 | + 可能未能正确解析所有地图,解决方法参加“读取地图掉落数据有问题”。 47 | + 这里没有我的问题 48 | + 如果你熟悉Web开发,可以尝试按F12进入console,看看有无输出错误信息,是不是网络问题,或者哪个脚本加载失败了。 49 | + 你可以通过提交issue的方式来说明问题,需要说清楚能够再现问题的步骤。 50 | + 或者联系我的QQ:865285578 或邮箱:ljwskrskr@gmail.com 51 | 52 | ## TODO List 53 | - [x] 支持整数规划 54 | - [x] 支持使用体力消耗作为代价度量 55 | - [x] 加入N2,N3等活动选项 56 | - [x] 弹出新标签页来显示计算结果,方便参看 57 | - [x] 将结果映射回原页面,方便参看 58 | - [ ] 点击表头可以排序 59 | - [ ] 将规划导出为CSV文件 60 | - [ ] ~~增加便捷的更改库存工具~~(暂时没有好的想法) 61 | - [ ] ~~支持贪心策略~~(出力不讨好,先搁置了) 62 | -------------------------------------------------------------------------------- /contents/content.js: -------------------------------------------------------------------------------- 1 | window.addEventListener("load", f); 2 | 3 | function f() { 4 | const buttons = document.querySelector( 5 | "#app > div.main > div > div.item-box > div.row.mb-3 > div:nth-child(2) > div > h3 > div > div:nth-child(1) > div" 6 | ); 7 | 8 | const recipeModeButton = buttons.children[1]; 9 | const mapDropModeButton = buttons.children[2]; 10 | 11 | const addCharacterButton = document.querySelector( 12 | "#app > div.main > div > div.item-box > div.row.mb-3 > div:nth-child(1) > div.row.mb-1 > div > div > button:nth-child(1)" 13 | ); 14 | addCharacterButton.addEventListener("click", removeExtraNodes); 15 | 16 | chrome.runtime.onMessage.addListener(function ( 17 | message, 18 | sender, 19 | sendResponse 20 | ) { 21 | if (message.info === "parseRecipe") { 22 | recipeModeButton.dispatchEvent(new Event("click")); 23 | setTimeout(function () { 24 | if (getDemands()) { 25 | sendResponse({ info: "success" }); 26 | } else { 27 | sendResponse({ info: "failure" }); 28 | } 29 | }, 500); 30 | } else if (message.info === "parseMapDrop") { 31 | mapDropModeButton.dispatchEvent(new Event("click")); 32 | removeExtraNodes(); 33 | setTimeout(function () { 34 | if (getMapData()) { 35 | sendResponse({ info: "success" }); 36 | } else { 37 | sendResponse({ info: "failure" }); 38 | } 39 | }, 500); 40 | } else if (message.info === "mapTable") { 41 | mapDropModeButton.dispatchEvent(new Event("click")); 42 | if (mapTable()) { 43 | sendResponse({ info: "success" }); 44 | } else { 45 | sendResponse({ info: "failure" }); 46 | } 47 | } else { 48 | sendResponse({ info: "failure" }); 49 | } 50 | return true; 51 | }); 52 | } 53 | 54 | function mapTable() { 55 | removeExtraNodes(); 56 | chrome.storage.local.get(["plan", "options"], function (items) { 57 | let { plan, options } = items; 58 | const { multiplier, displayInt } = options; 59 | 60 | // 包含一组th的父元素 61 | let thead = document.querySelector( 62 | "#app > div.main > div > div.item-box > div.row.mb-3 > div:nth-child(3) > table > thead > tr:nth-child(2)" 63 | ); 64 | let th = document.createElement("th"); 65 | th.innerText = "建议次数"; 66 | th.style.verticalAlign = "baseline"; 67 | th.className = "extra"; 68 | thead.appendChild(th); 69 | 70 | let tbody = document.querySelector( 71 | "#app > div.main > div > div.item-box > div.row.mb-3 > div:nth-child(3) > table > tbody" 72 | ); 73 | 74 | Array.from(tbody.children).forEach(function (tr) { 75 | const mapName = tr.children[0].innerText; 76 | tr.children[0].setAttribute("rowspan", "1"); 77 | if (plan[mapName]) { 78 | let td = document.createElement("td"); 79 | td.innerText = displayInt 80 | ? Math.ceil(plan[mapName] / multiplier) 81 | : (plan[mapName] / multiplier).toFixed(2); 82 | td.className = "extra"; 83 | tr.appendChild(td); 84 | } else { 85 | tr.style.display = "none"; 86 | } 87 | }); 88 | }); 89 | return true; 90 | } 91 | 92 | function removeExtraNodes() { 93 | let nodes = document.getElementsByClassName("extra"); 94 | if (nodes) { 95 | Array.from(nodes).forEach(function (node) { 96 | node.remove(); 97 | }); 98 | } 99 | } 100 | 101 | function getDemands() { 102 | if (!document.getElementsByClassName("recipe-mode")[0]) return false; 103 | 104 | const demandCardTable = document.getElementsByClassName("recipe-mode")[0] 105 | .children[0]; 106 | 107 | let result = {}; 108 | for (let item of demandCardTable.children) { 109 | const name = item.getElementsByTagName("h6")[0].innerText; 110 | const number = item.getElementsByClassName("badge-danger")[0].innerText; 111 | result[name] = { min: parseInt(number) }; 112 | } 113 | 114 | chrome.storage.local.set({ demands: result }, function () { 115 | console.log("Demands storage complete."); 116 | }); 117 | 118 | return true; 119 | } 120 | 121 | function getMapData() { 122 | const rowsPerPageSelect = document.querySelector( 123 | "#app > div.main > div > div.item-box > div.row.mb-3 > div:nth-child(3) > div > div:nth-child(3) > div > div > select" 124 | ); 125 | if (!rowsPerPageSelect) return false; 126 | 127 | if (rowsPerPageSelect.value == 1000) { 128 | return getData(); 129 | } else { 130 | rowsPerPageSelect.value = 1000; 131 | rowsPerPageSelect.dispatchEvent(new Event("change")); 132 | setTimeout(getData, 500); 133 | return true; 134 | } 135 | } 136 | 137 | function getData() { 138 | if (!document.getElementsByClassName("mapDrop-table")[0]) return false; 139 | 140 | const mapDropTable = document.getElementsByClassName("mapDrop-table")[1]; 141 | const tableRows = mapDropTable.getElementsByTagName("tr"); 142 | 143 | let result = {}; 144 | for (let tr of tableRows) { 145 | if (!tr.children[1]) continue; 146 | 147 | const mapName = tr.children[0].innerText; 148 | let dropData = {}; 149 | 150 | const items = tr.getElementsByClassName("mapDrop-item"); 151 | for (let item of items) { 152 | const number = item.getElementsByClassName("text-center py-1 d-block")[0] 153 | .innerText; 154 | if (!number || number === "0") continue; 155 | 156 | const name = item.getElementsByTagName("img")[0].title; 157 | const dropRate = item.getElementsByTagName("h6")[0].innerText; 158 | dropData[name] = parseFloat(dropRate) / 100.0; 159 | dropData.farmTime = 1; 160 | } 161 | const chapterIndex = mapName.slice(0, mapName.indexOf("-")); 162 | const apCost = Math.min(7 + Math.ceil(chapterIndex / 3), 10); 163 | result[mapName] = dropData; 164 | result[mapName].apCost = apCost; 165 | } 166 | 167 | chrome.storage.local.set({ mapData: result }, function () { 168 | console.log("MapData Storage complete."); 169 | }); 170 | 171 | return true; 172 | } 173 | -------------------------------------------------------------------------------- /components/popup.js: -------------------------------------------------------------------------------- 1 | calulateButton = document.getElementById("calculate"); 2 | parseRecipeButton = document.getElementById("recipe"); 3 | parseMapDropButton = document.getElementById("mapDrop"); 4 | optionsButton = document.getElementById("options"); 5 | 6 | chrome.storage.onChanged.addListener(function (changes, areaName) { 7 | const plan = changes.plan.newValue; 8 | if (plan.feasible) { 9 | mountMessage("计算完成!用时 " + plan.usedTime + " 毫秒,你还可以:"); 10 | mountExtraButtons(); 11 | generateTable(plan); 12 | } else { 13 | mountMessage( 14 | "计算失败。可能的原因:" + 15 | "
1. 地图上限设置过低,存在现有地图中不掉落的装备" + 16 | "
2. 未能正确解析所有地图,请确保地图掉落选项里的每页选项选择为“全部”" 17 | ); 18 | } 19 | }); 20 | 21 | calulateButton.addEventListener("click", function () { 22 | chrome.tabs.executeScript({ file: "/contents/calculate.js" }); 23 | }); 24 | 25 | parseRecipeButton.addEventListener("click", function () { 26 | chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) { 27 | chrome.tabs.sendMessage(tabs[0].id, { info: "parseRecipe" }, function ( 28 | response 29 | ) { 30 | if (response.info === "success") { 31 | mountMessage("成功解析需求!"); 32 | } else { 33 | mountMessage("解析需求失败!"); 34 | } 35 | }); 36 | }); 37 | }); 38 | 39 | parseMapDropButton.addEventListener("click", function () { 40 | chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) { 41 | chrome.tabs.sendMessage(tabs[0].id, { info: "parseMapDrop" }, function ( 42 | response 43 | ) { 44 | if (response.info === "success") { 45 | mountMessage("成功解析地图掉落!"); 46 | } else { 47 | mountMessage("解析地图掉落失败!"); 48 | } 49 | }); 50 | }); 51 | }); 52 | 53 | optionsButton.addEventListener("click", function () { 54 | if (chrome.runtime.openOptionsPage) { 55 | chrome.runtime.openOptionsPage(); 56 | } else { 57 | window.open(chrome.runtime.getURL("/options/options.html")); 58 | } 59 | }); 60 | 61 | // let th = document.getElementById("thName"); 62 | // th.addEventListener("click", onTableHeadClicked); 63 | 64 | function mountMessage(message) { 65 | document.getElementById("mount").innerHTML = message; 66 | } 67 | 68 | function mountExtraButtons() { 69 | let extraButton = document.createElement("button"); 70 | extraButton.innerText = "在新标签页中显示"; 71 | extraButton.className = "button"; 72 | extraButton.addEventListener("click", function () { 73 | chrome.tabs.create({ url: "/components/extra.html" }); 74 | }); 75 | 76 | let mapButton = document.createElement("button"); 77 | mapButton.innerText = "映射回原页面"; 78 | mapButton.className = "button"; 79 | mapButton.addEventListener("click", function () { 80 | chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) { 81 | chrome.tabs.sendMessage(tabs[0].id, { info: "mapTable" }, function ( 82 | response 83 | ) { 84 | if (response.info === "success") { 85 | mountMessage("成功映射至页面!"); 86 | } else { 87 | mountMessage("映射至页面失败!"); 88 | } 89 | }); 90 | }); 91 | }); 92 | 93 | let mountNode = document.getElementById("mount"); 94 | mountNode.appendChild(document.createElement("br")); 95 | mountNode.appendChild(extraButton); 96 | mountNode.appendChild(mapButton); 97 | } 98 | 99 | // TODO: Click table head to sort on that attr 100 | // function onTableHeadClicked() { 101 | // chrome.storage.local.get("plan", function (items) { 102 | // const { plan } = items; 103 | // generateTable(plan, "up", "farmTime"); 104 | // }); 105 | // } 106 | 107 | function generateTable(plan, sort = "down", axis = "mapName") { 108 | chrome.storage.local.get("options", function (items) { 109 | const { multiplier, displayInt } = items.options; 110 | 111 | let html = "", 112 | totalFarmTime = 0, 113 | totalApCost = 0; 114 | 115 | let planArr = []; 116 | 117 | for (let mapName in plan) { 118 | if (!isNaN(parseInt(mapName))) { 119 | const chapterIndex = parseInt(mapName.slice(0, mapName.indexOf("-"))); 120 | const mapIndex = parseInt( 121 | mapName.slice(mapName.indexOf("-") + 1, mapName.length) 122 | ); 123 | 124 | const apCost = Math.min(7 + Math.ceil(chapterIndex / 3), 10); 125 | let farmTime = parseFloat((plan[mapName] / multiplier).toFixed(2)); 126 | farmTime = displayInt ? Math.ceil(farmTime) : farmTime; 127 | const summedApCost = parseFloat((farmTime * apCost).toFixed(2)); 128 | 129 | totalFarmTime += farmTime; 130 | totalApCost += summedApCost; 131 | planArr.push({ 132 | mapName, 133 | chapterIndex, 134 | mapIndex, 135 | farmTime, 136 | summedApCost, 137 | }); 138 | } 139 | } 140 | 141 | planArr = planArr.sort(function (a, b) { 142 | if (sort === "no") return 0; 143 | 144 | let result = 0; 145 | if (axis === "mapName") { 146 | result = 147 | a.chapterIndex * 100 + a.mapIndex - b.chapterIndex * 100 - b.mapIndex; 148 | } else if (axis === "farmTime") { 149 | result = a.farmTime - b.farmTime; 150 | } else if (axis === "summedApCost") { 151 | result = a.summedApCost - b.summedApCost; 152 | } else { 153 | result = 0; 154 | } 155 | 156 | if (sort === "down") { 157 | result *= -1; 158 | } 159 | 160 | return result; 161 | }); 162 | 163 | planArr.forEach(function (item) { 164 | const { mapName, farmTime, summedApCost } = item; 165 | html += `${mapName}${farmTime}${summedApCost}`; 166 | }); 167 | 168 | html = `${html}
关卡名建议次数体力消耗
总计${ 169 | displayInt ? Math.ceil(totalFarmTime) : totalFarmTime.toFixed(2) 170 | }${ 171 | displayInt ? Math.ceil(totalApCost) : totalApCost.toFixed(2) 172 | }
`; 173 | 174 | let table = document.createElement("div"); 175 | table.innerHTML = html; 176 | document.getElementById("mount").appendChild(table); 177 | }); 178 | } 179 | -------------------------------------------------------------------------------- /contents/solver.js: -------------------------------------------------------------------------------- 1 | "object" == typeof exports && (module.exports = require("./main")), 2 | (function a(n, o, h) { 3 | function l(e, t) { 4 | if (!o[e]) { 5 | if (!n[e]) { 6 | var i = "function" == typeof require && require; 7 | if (!t && i) return i(e, !0); 8 | if (u) return u(e, !0); 9 | var r = new Error("Cannot find module '" + e + "'"); 10 | throw ((r.code = "MODULE_NOT_FOUND"), r); 11 | } 12 | var s = (o[e] = { exports: {} }); 13 | n[e][0].call( 14 | s.exports, 15 | function (t) { 16 | return l(n[e][1][t] || t); 17 | }, 18 | s, 19 | s.exports, 20 | a, 21 | n, 22 | o, 23 | h 24 | ); 25 | } 26 | return o[e].exports; 27 | } 28 | 29 | for ( 30 | var u = "function" == typeof require && require, t = 0; 31 | t < h.length; 32 | t++ 33 | ) 34 | l(h[t]); 35 | return l; 36 | })( 37 | { 38 | 1: [function (t, e, i) {}, {}], 39 | 2: [ 40 | function (t, e, i) { 41 | e.exports = function (t) { 42 | return t.length 43 | ? (function (t) { 44 | var e = { 45 | is_blank: /^\W{0,}$/, 46 | is_objective: /(max|min)(imize){0,}\:/i, 47 | is_int: /^(?!\/\*)\W{0,}int/i, 48 | is_bin: /^(?!\/\*)\W{0,}bin/i, 49 | is_constraint: /(\>|\<){0,}\=/i, 50 | is_unrestricted: /^\S{0,}unrestricted/i, 51 | parse_lhs: /(\-|\+){0,1}\s{0,1}\d{0,}\.{0,}\d{0,}\s{0,}[A-Za-z]\S{0,}/gi, 52 | parse_rhs: /(\-|\+){0,1}\d{1,}\.{0,}\d{0,}\W{0,}\;{0,1}$/i, 53 | parse_dir: /(\>|\<){0,}\=/gi, 54 | parse_int: /[^\s|^\,]+/gi, 55 | parse_bin: /[^\s|^\,]+/gi, 56 | get_num: /(\-|\+){0,1}(\W|^)\d+\.{0,1}\d{0,}/g, 57 | get_word: /[A-Za-z].*/, 58 | }, 59 | i = { 60 | opType: "", 61 | optimize: "_obj", 62 | constraints: {}, 63 | variables: {}, 64 | }, 65 | r = { ">=": "min", "<=": "max", "=": "equal" }, 66 | s = "", 67 | a = null, 68 | n = "", 69 | o = "", 70 | h = "", 71 | l = 0; 72 | "string" == typeof t && (t = t.split("\n")); 73 | for (var u = 0; u < t.length; u++) 74 | if ( 75 | ((h = "__" + u), 76 | (s = t[u]), 77 | 0, 78 | (a = null), 79 | e.is_objective.test(s)) 80 | ) 81 | (i.opType = s.match(/(max|min)/gi)[0]), 82 | (a = s 83 | .match(e.parse_lhs) 84 | .map(function (t) { 85 | return t.replace(/\s+/, ""); 86 | }) 87 | .slice(1)).forEach(function (t) { 88 | (n = 89 | null === (n = t.match(e.get_num)) 90 | ? "-" === t.substr(0, 1) 91 | ? -1 92 | : 1 93 | : n[0]), 94 | (n = parseFloat(n)), 95 | (o = t.match(e.get_word)[0].replace(/\;$/, "")), 96 | (i.variables[o] = i.variables[o] || {}), 97 | (i.variables[o]._obj = n); 98 | }); 99 | else if (e.is_int.test(s)) 100 | (a = s.match(e.parse_int).slice(1)), 101 | (i.ints = i.ints || {}), 102 | a.forEach(function (t) { 103 | (t = t.replace(";", "")), (i.ints[t] = 1); 104 | }); 105 | else if (e.is_bin.test(s)) 106 | (a = s.match(e.parse_bin).slice(1)), 107 | (i.binaries = i.binaries || {}), 108 | a.forEach(function (t) { 109 | (t = t.replace(";", "")), (i.binaries[t] = 1); 110 | }); 111 | else if (e.is_constraint.test(s)) { 112 | var d = s.indexOf(":"); 113 | (a = (-1 === d ? s : s.slice(d + 1)) 114 | .match(e.parse_lhs) 115 | .map(function (t) { 116 | return t.replace(/\s+/, ""); 117 | })).forEach(function (t) { 118 | (n = 119 | null === (n = t.match(e.get_num)) 120 | ? "-" === t.substr(0, 1) 121 | ? -1 122 | : 1 123 | : n[0]), 124 | (n = parseFloat(n)), 125 | (o = t.match(e.get_word)[0]), 126 | (i.variables[o] = i.variables[o] || {}), 127 | (i.variables[o][h] = n); 128 | }), 129 | (l = parseFloat(s.match(e.parse_rhs)[0])), 130 | (s = r[s.match(e.parse_dir)[0]]), 131 | (i.constraints[h] = i.constraints[h] || {}), 132 | (i.constraints[h][s] = l); 133 | } else 134 | e.is_unrestricted.test(s) && 135 | ((a = s.match(e.parse_int).slice(1)), 136 | (i.unrestricted = i.unrestricted || {}), 137 | a.forEach(function (t) { 138 | (t = t.replace(";", "")), (i.unrestricted[t] = 1); 139 | })); 140 | return i; 141 | })(t) 142 | : (function (t) { 143 | if (!t) 144 | throw new Error("Solver requires a model to operate on"); 145 | var e = "", 146 | i = { max: "<=", min: ">=", equal: "=" }, 147 | r = new RegExp("[^A-Za-z0-9_[{}/.&#$%~'@^]", "gi"); 148 | if (t.opType) 149 | for (var s in ((e += t.opType + ":"), t.variables)) 150 | (t.variables[s][s] = t.variables[s][s] 151 | ? t.variables[s][s] 152 | : 1), 153 | t.variables[s][t.optimize] && 154 | (e += 155 | " " + 156 | t.variables[s][t.optimize] + 157 | " " + 158 | s.replace(r, "_")); 159 | else e += "max:"; 160 | for (var a in ((e += ";\n\n"), t.constraints)) 161 | for (var n in t.constraints[a]) 162 | if (void 0 !== i[n]) { 163 | for (var o in t.variables) 164 | void 0 !== t.variables[o][a] && 165 | (e += 166 | " " + 167 | t.variables[o][a] + 168 | " " + 169 | o.replace(r, "_")); 170 | (e += " " + i[n] + " " + t.constraints[a][n]), 171 | (e += ";\n"); 172 | } 173 | if (t.ints) 174 | for (var h in ((e += "\n\n"), t.ints)) 175 | e += "int " + h.replace(r, "_") + ";\n"; 176 | if (t.unrestricted) 177 | for (var l in ((e += "\n\n"), t.unrestricted)) 178 | e += "unrestricted " + l.replace(r, "_") + ";\n"; 179 | return e; 180 | })(t); 181 | }; 182 | }, 183 | {}, 184 | ], 185 | 3: [ 186 | function (n, t, e) { 187 | function o(t) { 188 | return (t = (t = (t = t.replace("\\r\\n", "\r\n")).split("\r\n")) 189 | .filter(function (t) { 190 | return ( 191 | !0 !== new RegExp(" 0$", "gi").test(t) && 192 | !1 !== new RegExp("\\d$", "gi").test(t) 193 | ); 194 | }) 195 | .map(function (t) { 196 | return t.split(/\:{0,1} +(?=\d)/); 197 | }) 198 | .reduce(function (t, e, i) { 199 | return (t[e[0]] = e[1]), t; 200 | }, {})); 201 | } 202 | 203 | (e.reformat = n("./Reformat.js")), 204 | (e.solve = function (a) { 205 | return new Promise(function (r, s) { 206 | "undefined" != typeof window && 207 | s("Function Not Available in Browser"); 208 | var t = n("./Reformat.js")(a); 209 | a.external || 210 | s( 211 | "Data for this function must be contained in the 'external' attribute. Not seeing anything there." 212 | ), 213 | a.external.binPath || 214 | s( 215 | "No Executable | Binary path provided in arguments as 'binPath'" 216 | ), 217 | a.external.args || 218 | s( 219 | "No arguments array for cli | bash provided on 'args' attribute" 220 | ), 221 | a.external.tempName || 222 | s( 223 | "No 'tempName' given. This is necessary to produce a staging file for the solver to operate on" 224 | ), 225 | n("fs").writeFile(a.external.tempName, t, function (t, e) { 226 | if (t) s(t); 227 | else { 228 | var i = n("child_process").execFile; 229 | a.external.args.push(a.external.tempName), 230 | i(a.external.binPath, a.external.args, function (t, e) { 231 | if (t) 232 | if (1 === t.code) r(o(e)); 233 | else { 234 | var i = { 235 | code: t.code, 236 | meaning: { 237 | "-2": "Out of Memory", 238 | 1: "SUBOPTIMAL", 239 | 2: "INFEASIBLE", 240 | 3: "UNBOUNDED", 241 | 4: "DEGENERATE", 242 | 5: "NUMFAILURE", 243 | 6: "USER-ABORT", 244 | 7: "TIMEOUT", 245 | 9: "PRESOLVED", 246 | 25: "ACCURACY ERROR", 247 | 255: "FILE-ERROR", 248 | }[t.code], 249 | data: e, 250 | }; 251 | s(i); 252 | } 253 | else r(o(e)); 254 | }); 255 | } 256 | }); 257 | }); 258 | }); 259 | }, 260 | { "./Reformat.js": 2, child_process: 1, fs: 1 }, 261 | ], 262 | 4: [ 263 | function (t, e, i) { 264 | e.exports = { lpsolve: t("./lpsolve/main.js") }; 265 | }, 266 | { "./lpsolve/main.js": 3 }, 267 | ], 268 | 5: [ 269 | function (t, e, i) { 270 | var r = t("./Tableau/Tableau.js"), 271 | s = (t("./Tableau/branchAndCut.js"), t("./expressions.js")), 272 | a = s.Constraint, 273 | F = s.Equality, 274 | o = s.Variable, 275 | h = s.IntegerVariable; 276 | s.Term; 277 | 278 | function n(t, e) { 279 | (this.tableau = new r(t)), 280 | (this.name = e), 281 | (this.variables = []), 282 | (this.integerVariables = []), 283 | (this.unrestrictedVariables = {}), 284 | (this.constraints = []), 285 | (this.nConstraints = 0), 286 | (this.nVariables = 0), 287 | (this.isMinimization = !0), 288 | (this.tableauInitialized = !1), 289 | (this.relaxationIndex = 1), 290 | (this.useMIRCuts = !1), 291 | (this.checkForCycles = !0), 292 | (this.messages = []); 293 | } 294 | 295 | ((e.exports = n).prototype.minimize = function () { 296 | return (this.isMinimization = !0), this; 297 | }), 298 | (n.prototype.maximize = function () { 299 | return (this.isMinimization = !1), this; 300 | }), 301 | (n.prototype._getNewElementIndex = function () { 302 | if (0 < this.availableIndexes.length) 303 | return this.availableIndexes.pop(); 304 | var t = this.lastElementIndex; 305 | return (this.lastElementIndex += 1), t; 306 | }), 307 | (n.prototype._addConstraint = function (t) { 308 | var e = t.slack; 309 | (this.tableau.variablesPerIndex[e.index] = e), 310 | this.constraints.push(t), 311 | (this.nConstraints += 1), 312 | !0 === this.tableauInitialized && this.tableau.addConstraint(t); 313 | }), 314 | (n.prototype.smallerThan = function (t) { 315 | var e = new a(t, !0, this.tableau.getNewElementIndex(), this); 316 | return this._addConstraint(e), e; 317 | }), 318 | (n.prototype.greaterThan = function (t) { 319 | var e = new a(t, !1, this.tableau.getNewElementIndex(), this); 320 | return this._addConstraint(e), e; 321 | }), 322 | (n.prototype.equal = function (t) { 323 | var e = new a(t, !0, this.tableau.getNewElementIndex(), this); 324 | this._addConstraint(e); 325 | var i = new a(t, !1, this.tableau.getNewElementIndex(), this); 326 | return this._addConstraint(i), new F(e, i); 327 | }), 328 | (n.prototype.addVariable = function (t, e, i, r, s) { 329 | if ("string" == typeof s) 330 | switch (s) { 331 | case "required": 332 | s = 0; 333 | break; 334 | case "strong": 335 | s = 1; 336 | break; 337 | case "medium": 338 | s = 2; 339 | break; 340 | case "weak": 341 | s = 3; 342 | break; 343 | default: 344 | s = 0; 345 | } 346 | var a, 347 | n = this.tableau.getNewElementIndex(); 348 | return ( 349 | null == e && (e = "v" + n), 350 | null == t && (t = 0), 351 | null == s && (s = 0), 352 | i 353 | ? ((a = new h(e, t, n, s)), this.integerVariables.push(a)) 354 | : (a = new o(e, t, n, s)), 355 | this.variables.push(a), 356 | (this.tableau.variablesPerIndex[n] = a), 357 | r && (this.unrestrictedVariables[n] = !0), 358 | (this.nVariables += 1), 359 | !0 === this.tableauInitialized && this.tableau.addVariable(a), 360 | a 361 | ); 362 | }), 363 | (n.prototype._removeConstraint = function (t) { 364 | var e = this.constraints.indexOf(t); 365 | -1 !== e 366 | ? (this.constraints.splice(e, 1), 367 | (this.nConstraints -= 1), 368 | !0 === this.tableauInitialized && 369 | this.tableau.removeConstraint(t), 370 | t.relaxation && this.removeVariable(t.relaxation)) 371 | : console.warn( 372 | "[Model.removeConstraint] Constraint not present in model" 373 | ); 374 | }), 375 | (n.prototype.removeConstraint = function (t) { 376 | return ( 377 | t.isEquality 378 | ? (this._removeConstraint(t.upperBound), 379 | this._removeConstraint(t.lowerBound)) 380 | : this._removeConstraint(t), 381 | this 382 | ); 383 | }), 384 | (n.prototype.removeVariable = function (t) { 385 | var e = this.variables.indexOf(t); 386 | if (-1 !== e) 387 | return ( 388 | this.variables.splice(e, 1), 389 | !0 === this.tableauInitialized && 390 | this.tableau.removeVariable(t), 391 | this 392 | ); 393 | console.warn( 394 | "[Model.removeVariable] Variable not present in model" 395 | ); 396 | }), 397 | (n.prototype.updateRightHandSide = function (t, e) { 398 | return ( 399 | !0 === this.tableauInitialized && 400 | this.tableau.updateRightHandSide(t, e), 401 | this 402 | ); 403 | }), 404 | (n.prototype.updateConstraintCoefficient = function (t, e, i) { 405 | return ( 406 | !0 === this.tableauInitialized && 407 | this.tableau.updateConstraintCoefficient(t, e, i), 408 | this 409 | ); 410 | }), 411 | (n.prototype.setCost = function (t, e) { 412 | var i = t - e.cost; 413 | return ( 414 | !1 === this.isMinimization && (i = -i), 415 | (e.cost = t), 416 | this.tableau.updateCost(e, i), 417 | this 418 | ); 419 | }), 420 | (n.prototype.loadJson = function (t) { 421 | this.isMinimization = "max" !== t.opType; 422 | for ( 423 | var e = t.variables, 424 | i = t.constraints, 425 | r = {}, 426 | s = {}, 427 | a = Object.keys(i), 428 | n = a.length, 429 | o = 0; 430 | o < n; 431 | o += 1 432 | ) { 433 | var h, 434 | l, 435 | u = a[o], 436 | d = i[u], 437 | c = d.equal, 438 | v = d.weight, 439 | p = d.priority, 440 | f = void 0 !== v || void 0 !== p; 441 | if (void 0 === c) { 442 | var x = d.min; 443 | void 0 !== x && 444 | ((h = this.greaterThan(x)), (r[u] = h), f && h.relax(v, p)); 445 | var b = d.max; 446 | void 0 !== b && 447 | ((l = this.smallerThan(b)), (s[u] = l), f && l.relax(v, p)); 448 | } else { 449 | (h = this.greaterThan(c)), 450 | (r[u] = h), 451 | (l = this.smallerThan(c)), 452 | (s[u] = l); 453 | var m = new F(h, l); 454 | f && m.relax(v, p); 455 | } 456 | } 457 | var y = Object.keys(e), 458 | I = y.length; 459 | (this.tolerance = t.tolerance || 0), 460 | t.timeout && (this.timeout = t.timeout), 461 | t.options && 462 | (t.options.timeout && (this.timeout = t.options.timeout), 463 | 0 === this.tolerance && 464 | (this.tolerance = t.options.tolerance || 0), 465 | t.options.useMIRCuts && 466 | (this.useMIRCuts = t.options.useMIRCuts), 467 | void 0 === t.options.exitOnCycles 468 | ? (this.checkForCycles = !0) 469 | : (this.checkForCycles = t.options.exitOnCycles)); 470 | for ( 471 | var g = t.ints || {}, 472 | w = t.binaries || {}, 473 | C = t.unrestricted || {}, 474 | B = t.optimize, 475 | V = 0; 476 | V < I; 477 | V += 1 478 | ) { 479 | var j = y[V], 480 | O = e[j], 481 | R = O[B] || 0, 482 | M = !!w[j], 483 | E = !!g[j] || M, 484 | _ = !!C[j], 485 | T = this.addVariable(R, j, E, _); 486 | M && this.smallerThan(1).addTerm(1, T); 487 | var S = Object.keys(O); 488 | for (o = 0; o < S.length; o += 1) { 489 | var z = S[o]; 490 | if (z !== B) { 491 | var P = O[z], 492 | N = r[z]; 493 | void 0 !== N && N.addTerm(P, T); 494 | var k = s[z]; 495 | void 0 !== k && k.addTerm(P, T); 496 | } 497 | } 498 | } 499 | return this; 500 | }), 501 | (n.prototype.getNumberOfIntegerVariables = function () { 502 | return this.integerVariables.length; 503 | }), 504 | (n.prototype.solve = function () { 505 | return ( 506 | !1 === this.tableauInitialized && 507 | (this.tableau.setModel(this), (this.tableauInitialized = !0)), 508 | this.tableau.solve() 509 | ); 510 | }), 511 | (n.prototype.isFeasible = function () { 512 | return this.tableau.feasible; 513 | }), 514 | (n.prototype.save = function () { 515 | return this.tableau.save(); 516 | }), 517 | (n.prototype.restore = function () { 518 | return this.tableau.restore(); 519 | }), 520 | (n.prototype.activateMIRCuts = function (t) { 521 | this.useMIRCuts = t; 522 | }), 523 | (n.prototype.debug = function (t) { 524 | this.checkForCycles = t; 525 | }), 526 | (n.prototype.log = function (t) { 527 | return this.tableau.log(t); 528 | }); 529 | }, 530 | { 531 | "./Tableau/Tableau.js": 9, 532 | "./Tableau/branchAndCut.js": 11, 533 | "./expressions.js": 20, 534 | }, 535 | ], 536 | 6: [ 537 | function (t, e, i) { 538 | e.exports = function (t, e) { 539 | var i, 540 | r, 541 | s, 542 | a, 543 | n, 544 | o = e.optimize, 545 | h = JSON.parse(JSON.stringify(e.optimize)), 546 | l = Object.keys(e.optimize), 547 | u = 0, 548 | d = {}, 549 | c = "", 550 | v = {}, 551 | p = []; 552 | for (delete e.optimize, r = 0; r < l.length; r++) h[l[r]] = 0; 553 | for (r = 0; r < l.length; r++) { 554 | for (n in ((e.optimize = l[r]), 555 | (e.opType = o[l[r]]), 556 | (i = t.Solve(e, void 0, void 0, !0)), 557 | l)) 558 | if (!e.variables[l[n]]) 559 | for (a in ((i[l[n]] = i[l[n]] ? i[l[n]] : 0), e.variables)) 560 | e.variables[a][l[n]] && 561 | i[a] && 562 | (i[l[n]] += i[a] * e.variables[a][l[n]]); 563 | for (c = "base", s = 0; s < l.length; s++) 564 | i[l[s]] 565 | ? (c += "-" + ((1e3 * i[l[s]]) | 0) / 1e3) 566 | : (c += "-0"); 567 | if (!d[c]) { 568 | for (d[c] = 1, u++, s = 0; s < l.length; s++) 569 | i[l[s]] && (h[l[s]] += i[l[s]]); 570 | delete i.feasible, delete i.result, p.push(i); 571 | } 572 | } 573 | for (r = 0; r < l.length; r++) 574 | e.constraints[l[r]] = { equal: h[l[r]] / u }; 575 | for (r in ((e.optimize = "cheater-" + Math.random()), 576 | (e.opType = "max"), 577 | e.variables)) 578 | e.variables[r].cheater = 1; 579 | for (r in p) 580 | for (a in p[r]) v[a] = v[a] || { min: 1e99, max: -1e99 }; 581 | for (r in v) 582 | for (a in p) 583 | p[a][r] 584 | ? (p[a][r] > v[r].max && (v[r].max = p[a][r]), 585 | p[a][r] < v[r].min && (v[r].min = p[a][r])) 586 | : ((p[a][r] = 0), (v[r].min = 0)); 587 | return { 588 | midpoint: (i = t.Solve(e, void 0, void 0, !0)), 589 | vertices: p, 590 | ranges: v, 591 | }; 592 | }; 593 | }, 594 | {}, 595 | ], 596 | 7: [ 597 | function (t, e, i) { 598 | var a = t("./Solution.js"); 599 | 600 | function r(t, e, i, r, s) { 601 | a.call(this, t, e, i, r), (this.iter = s); 602 | } 603 | 604 | ((e.exports = r).prototype = Object.create(a.prototype)), 605 | (r.constructor = r); 606 | }, 607 | { "./Solution.js": 8 }, 608 | ], 609 | 8: [ 610 | function (t, e, i) { 611 | function r(t, e, i, r) { 612 | (this.feasible = i), 613 | (this.evaluation = e), 614 | (this.bounded = r), 615 | (this._tableau = t); 616 | } 617 | 618 | (e.exports = r).prototype.generateSolutionSet = function () { 619 | for ( 620 | var t = {}, 621 | e = this._tableau, 622 | i = e.varIndexByRow, 623 | r = e.variablesPerIndex, 624 | s = e.matrix, 625 | a = e.rhsColumn, 626 | n = e.height - 1, 627 | o = Math.round(1 / e.precision), 628 | h = 1; 629 | h <= n; 630 | h += 1 631 | ) { 632 | var l = r[i[h]]; 633 | if (void 0 !== l && !0 !== l.isSlack) { 634 | var u = s[h][a]; 635 | t[l.id] = Math.round((Number.EPSILON + u) * o) / o; 636 | } 637 | } 638 | return t; 639 | }; 640 | }, 641 | {}, 642 | ], 643 | 9: [ 644 | function (t, e, i) { 645 | var r = t("./Solution.js"), 646 | s = t("./MilpSolution.js"); 647 | 648 | function a(t) { 649 | (this.model = null), 650 | (this.matrix = null), 651 | (this.width = 0), 652 | (this.height = 0), 653 | (this.costRowIndex = 0), 654 | (this.rhsColumn = 0), 655 | (this.variablesPerIndex = []), 656 | (this.unrestrictedVars = null), 657 | (this.feasible = !0), 658 | (this.evaluation = 0), 659 | (this.simplexIters = 0), 660 | (this.varIndexByRow = null), 661 | (this.varIndexByCol = null), 662 | (this.rowByVarIndex = null), 663 | (this.colByVarIndex = null), 664 | (this.precision = t || 1e-8), 665 | (this.optionalObjectives = []), 666 | (this.objectivesByPriority = {}), 667 | (this.savedState = null), 668 | (this.availableIndexes = []), 669 | (this.lastElementIndex = 0), 670 | (this.variables = null), 671 | (this.nVars = 0), 672 | (this.bounded = !0), 673 | (this.unboundedVarIndex = null), 674 | (this.branchAndCutIterations = 0); 675 | } 676 | 677 | function n(t, e) { 678 | (this.priority = t), (this.reducedCosts = new Array(e)); 679 | for (var i = 0; i < e; i += 1) this.reducedCosts[i] = 0; 680 | } 681 | 682 | ((e.exports = a).prototype.solve = function () { 683 | return ( 684 | 0 < this.model.getNumberOfIntegerVariables() 685 | ? this.branchAndCut() 686 | : this.simplex(), 687 | this.updateVariableValues(), 688 | this.getSolution() 689 | ); 690 | }), 691 | (n.prototype.copy = function () { 692 | var t = new n(this.priority, this.reducedCosts.length); 693 | return (t.reducedCosts = this.reducedCosts.slice()), t; 694 | }), 695 | (a.prototype.setOptionalObjective = function (t, e, i) { 696 | var r = this.objectivesByPriority[t]; 697 | void 0 === r && 698 | ((r = new n(t, Math.max(this.width, e + 1))), 699 | (this.objectivesByPriority[t] = r), 700 | this.optionalObjectives.push(r), 701 | this.optionalObjectives.sort(function (t, e) { 702 | return t.priority - e.priority; 703 | })); 704 | r.reducedCosts[e] = i; 705 | }), 706 | (a.prototype.initialize = function (t, e, i, r) { 707 | (this.variables = i), 708 | (this.unrestrictedVars = r), 709 | (this.width = t), 710 | (this.height = e); 711 | for (var s = new Array(t), a = 0; a < t; a++) s[a] = 0; 712 | this.matrix = new Array(e); 713 | for (var n = 0; n < e; n++) this.matrix[n] = s.slice(); 714 | (this.varIndexByRow = new Array(this.height)), 715 | (this.varIndexByCol = new Array(this.width)), 716 | (this.varIndexByRow[0] = -1), 717 | (this.varIndexByCol[0] = -1), 718 | (this.nVars = t + e - 2), 719 | (this.rowByVarIndex = new Array(this.nVars)), 720 | (this.colByVarIndex = new Array(this.nVars)), 721 | (this.lastElementIndex = this.nVars); 722 | }), 723 | (a.prototype._resetMatrix = function () { 724 | var t, 725 | e, 726 | i = this.model.variables, 727 | r = this.model.constraints, 728 | s = i.length, 729 | a = r.length, 730 | n = this.matrix[0], 731 | o = !0 === this.model.isMinimization ? -1 : 1; 732 | for (t = 0; t < s; t += 1) { 733 | var h = i[t], 734 | l = h.priority, 735 | u = o * h.cost; 736 | 0 === l 737 | ? (n[t + 1] = u) 738 | : this.setOptionalObjective(l, t + 1, u), 739 | (e = i[t].index), 740 | (this.rowByVarIndex[e] = -1), 741 | (this.colByVarIndex[e] = t + 1), 742 | (this.varIndexByCol[t + 1] = e); 743 | } 744 | for (var d = 1, c = 0; c < a; c += 1) { 745 | var v, 746 | p, 747 | f = r[c], 748 | x = f.index; 749 | (this.rowByVarIndex[x] = d), 750 | (this.colByVarIndex[x] = -1), 751 | (this.varIndexByRow[d] = x); 752 | var b = f.terms, 753 | m = b.length, 754 | y = this.matrix[d++]; 755 | if (f.isUpperBound) { 756 | for (v = 0; v < m; v += 1) 757 | (p = b[v]), 758 | (y[this.colByVarIndex[p.variable.index]] = p.coefficient); 759 | y[0] = f.rhs; 760 | } else { 761 | for (v = 0; v < m; v += 1) 762 | (p = b[v]), 763 | (y[ 764 | this.colByVarIndex[p.variable.index] 765 | ] = -p.coefficient); 766 | y[0] = -f.rhs; 767 | } 768 | } 769 | }), 770 | (a.prototype.setModel = function (t) { 771 | var e = (this.model = t).nVariables + 1, 772 | i = t.nConstraints + 1; 773 | return ( 774 | this.initialize(e, i, t.variables, t.unrestrictedVariables), 775 | this._resetMatrix(), 776 | this 777 | ); 778 | }), 779 | (a.prototype.getNewElementIndex = function () { 780 | if (0 < this.availableIndexes.length) 781 | return this.availableIndexes.pop(); 782 | var t = this.lastElementIndex; 783 | return (this.lastElementIndex += 1), t; 784 | }), 785 | (a.prototype.density = function () { 786 | for (var t = 0, e = this.matrix, i = 0; i < this.height; i++) 787 | for (var r = e[i], s = 0; s < this.width; s++) 788 | 0 !== r[s] && (t += 1); 789 | return t / (this.height * this.width); 790 | }), 791 | (a.prototype.setEvaluation = function () { 792 | var t = Math.round(1 / this.precision), 793 | e = this.matrix[this.costRowIndex][this.rhsColumn], 794 | i = Math.round((Number.EPSILON + e) * t) / t; 795 | (this.evaluation = i), 796 | 0 === this.simplexIters && (this.bestPossibleEval = i); 797 | }), 798 | (a.prototype.getSolution = function () { 799 | var t = 800 | !0 === this.model.isMinimization 801 | ? this.evaluation 802 | : -this.evaluation; 803 | return 0 < this.model.getNumberOfIntegerVariables() 804 | ? new s( 805 | this, 806 | t, 807 | this.feasible, 808 | this.bounded, 809 | this.branchAndCutIterations 810 | ) 811 | : new r(this, t, this.feasible, this.bounded); 812 | }); 813 | }, 814 | { "./MilpSolution.js": 7, "./Solution.js": 8 }, 815 | ], 816 | 10: [ 817 | function (t, e, i) { 818 | var n = t("./Tableau.js"); 819 | (n.prototype.copy = function () { 820 | var t = new n(this.precision); 821 | (t.width = this.width), 822 | (t.height = this.height), 823 | (t.nVars = this.nVars), 824 | (t.model = this.model), 825 | (t.variables = this.variables), 826 | (t.variablesPerIndex = this.variablesPerIndex), 827 | (t.unrestrictedVars = this.unrestrictedVars), 828 | (t.lastElementIndex = this.lastElementIndex), 829 | (t.varIndexByRow = this.varIndexByRow.slice()), 830 | (t.varIndexByCol = this.varIndexByCol.slice()), 831 | (t.rowByVarIndex = this.rowByVarIndex.slice()), 832 | (t.colByVarIndex = this.colByVarIndex.slice()), 833 | (t.availableIndexes = this.availableIndexes.slice()); 834 | for (var e = [], i = 0; i < this.optionalObjectives.length; i++) 835 | e[i] = this.optionalObjectives[i].copy(); 836 | t.optionalObjectives = e; 837 | for ( 838 | var r = this.matrix, s = new Array(this.height), a = 0; 839 | a < this.height; 840 | a++ 841 | ) 842 | s[a] = r[a].slice(); 843 | return (t.matrix = s), t; 844 | }), 845 | (n.prototype.save = function () { 846 | this.savedState = this.copy(); 847 | }), 848 | (n.prototype.restore = function () { 849 | if (null !== this.savedState) { 850 | var t, 851 | e, 852 | i = this.savedState, 853 | r = i.matrix; 854 | for ( 855 | this.nVars = i.nVars, 856 | this.model = i.model, 857 | this.variables = i.variables, 858 | this.variablesPerIndex = i.variablesPerIndex, 859 | this.unrestrictedVars = i.unrestrictedVars, 860 | this.lastElementIndex = i.lastElementIndex, 861 | this.width = i.width, 862 | this.height = i.height, 863 | t = 0; 864 | t < this.height; 865 | t += 1 866 | ) { 867 | var s = r[t], 868 | a = this.matrix[t]; 869 | for (e = 0; e < this.width; e += 1) a[e] = s[e]; 870 | } 871 | var n = i.varIndexByRow; 872 | for (e = 0; e < this.height; e += 1) 873 | this.varIndexByRow[e] = n[e]; 874 | for (; this.varIndexByRow.length > this.height; ) 875 | this.varIndexByRow.pop(); 876 | var o = i.varIndexByCol; 877 | for (t = 0; t < this.width; t += 1) 878 | this.varIndexByCol[t] = o[t]; 879 | for (; this.varIndexByCol.length > this.width; ) 880 | this.varIndexByCol.pop(); 881 | for ( 882 | var h = i.rowByVarIndex, l = i.colByVarIndex, u = 0; 883 | u < this.nVars; 884 | u += 1 885 | ) 886 | (this.rowByVarIndex[u] = h[u]), 887 | (this.colByVarIndex[u] = l[u]); 888 | if ( 889 | 0 < i.optionalObjectives.length && 890 | 0 < this.optionalObjectives.length 891 | ) { 892 | (this.optionalObjectives = []), 893 | (this.optionalObjectivePerPriority = {}); 894 | for (var d = 0; d < i.optionalObjectives.length; d++) { 895 | var c = i.optionalObjectives[d].copy(); 896 | (this.optionalObjectives[d] = c), 897 | (this.optionalObjectivePerPriority[c.priority] = c); 898 | } 899 | } 900 | } 901 | }); 902 | }, 903 | { "./Tableau.js": 9 }, 904 | ], 905 | 11: [ 906 | function (t, e, i) { 907 | var r = t("./Tableau.js"); 908 | 909 | function O(t, e, i) { 910 | (this.type = t), (this.varIndex = e), (this.value = i); 911 | } 912 | 913 | function R(t, e) { 914 | (this.relaxedEvaluation = t), (this.cuts = e); 915 | } 916 | 917 | function M(t, e) { 918 | return e.relaxedEvaluation - t.relaxedEvaluation; 919 | } 920 | 921 | (r.prototype.applyCuts = function (t) { 922 | if ( 923 | (this.restore(), 924 | this.addCutConstraints(t), 925 | this.simplex(), 926 | this.model.useMIRCuts) 927 | ) 928 | for (var e = !0; e; ) { 929 | var i = this.computeFractionalVolume(!0); 930 | this.applyMIRCuts(), 931 | this.simplex(), 932 | 0.9 * i <= this.computeFractionalVolume(!0) && (e = !1); 933 | } 934 | }), 935 | (r.prototype.branchAndCut = function () { 936 | var t = [], 937 | e = 0, 938 | i = this.model.tolerance, 939 | r = !0, 940 | s = 1e99; 941 | this.model.timeout && (s = Date.now() + this.model.timeout); 942 | for ( 943 | var a = 1 / 0, n = null, o = [], h = 0; 944 | h < this.optionalObjectives.length; 945 | h += 1 946 | ) 947 | o.push(1 / 0); 948 | var l, 949 | u = new R(-1 / 0, []); 950 | for (t.push(u); 0 < t.length && !0 === r && Date.now() < s; ) 951 | if ( 952 | ((l = this.model.isMinimization 953 | ? this.bestPossibleEval * (1 + i) 954 | : this.bestPossibleEval * (1 - i)), 955 | 0 < i && a < l && (r = !1), 956 | !((u = t.pop()).relaxedEvaluation > a)) 957 | ) { 958 | var d = u.cuts; 959 | if ((this.applyCuts(d), e++, !1 !== this.feasible)) { 960 | var c = this.evaluation; 961 | if (!(a < c)) { 962 | if (c === a) { 963 | for ( 964 | var v = !0, p = 0; 965 | p < this.optionalObjectives.length && 966 | !(this.optionalObjectives[p].reducedCosts[0] > o[p]); 967 | p += 1 968 | ) 969 | if ( 970 | this.optionalObjectives[p].reducedCosts[0] < o[p] 971 | ) { 972 | v = !1; 973 | break; 974 | } 975 | if (v) continue; 976 | } 977 | if (!0 === this.isIntegral()) { 978 | if (((this.__isIntegral = !0), 1 === e)) 979 | return void (this.branchAndCutIterations = e); 980 | (n = u), (a = c); 981 | for ( 982 | var f = 0; 983 | f < this.optionalObjectives.length; 984 | f += 1 985 | ) 986 | o[f] = this.optionalObjectives[f].reducedCosts[0]; 987 | } else { 988 | 1 === e && this.save(); 989 | for ( 990 | var x = this.getMostFractionalVar(), 991 | b = x.index, 992 | m = [], 993 | y = [], 994 | I = d.length, 995 | g = 0; 996 | g < I; 997 | g += 1 998 | ) { 999 | var w = d[g]; 1000 | w.varIndex === b 1001 | ? "min" === w.type 1002 | ? y.push(w) 1003 | : m.push(w) 1004 | : (m.push(w), y.push(w)); 1005 | } 1006 | var C = Math.ceil(x.value), 1007 | B = Math.floor(x.value), 1008 | V = new O("min", b, C); 1009 | m.push(V); 1010 | var j = new O("max", b, B); 1011 | y.push(j), 1012 | t.push(new R(c, m)), 1013 | t.push(new R(c, y)), 1014 | t.sort(M); 1015 | } 1016 | } 1017 | } 1018 | } 1019 | null !== n && this.applyCuts(n.cuts), 1020 | (this.branchAndCutIterations = e); 1021 | }); 1022 | }, 1023 | { "./Tableau.js": 9 }, 1024 | ], 1025 | 12: [ 1026 | function (t, e, i) { 1027 | var r = t("./Tableau.js"); 1028 | 1029 | function d(t, e) { 1030 | (this.index = t), (this.value = e); 1031 | } 1032 | 1033 | (r.prototype.getMostFractionalVar = function () { 1034 | for ( 1035 | var t = 0, 1036 | e = null, 1037 | i = null, 1038 | r = this.model.integerVariables, 1039 | s = r.length, 1040 | a = 0; 1041 | a < s; 1042 | a++ 1043 | ) { 1044 | var n = r[a].index, 1045 | o = this.rowByVarIndex[n]; 1046 | if (-1 !== o) { 1047 | var h = this.matrix[o][this.rhsColumn], 1048 | l = Math.abs(h - Math.round(h)); 1049 | t < l && ((t = l), (e = n), (i = h)); 1050 | } 1051 | } 1052 | return new d(e, i); 1053 | }), 1054 | (r.prototype.getFractionalVarWithLowestCost = function () { 1055 | for ( 1056 | var t = 1 / 0, 1057 | e = null, 1058 | i = null, 1059 | r = this.model.integerVariables, 1060 | s = r.length, 1061 | a = 0; 1062 | a < s; 1063 | a++ 1064 | ) { 1065 | var n = r[a], 1066 | o = n.index, 1067 | h = this.rowByVarIndex[o]; 1068 | if (-1 !== h) { 1069 | var l = this.matrix[h][this.rhsColumn]; 1070 | if (Math.abs(l - Math.round(l)) > this.precision) { 1071 | var u = n.cost; 1072 | u < t && ((t = u), (e = o), (i = l)); 1073 | } 1074 | } 1075 | } 1076 | return new d(e, i); 1077 | }); 1078 | }, 1079 | { "./Tableau.js": 9 }, 1080 | ], 1081 | 13: [ 1082 | function (t, e, i) { 1083 | var r = t("./Tableau.js"), 1084 | b = t("../expressions.js").SlackVariable; 1085 | (r.prototype.addCutConstraints = function (t) { 1086 | for ( 1087 | var e, i = t.length, r = this.height, s = r + i, a = r; 1088 | a < s; 1089 | a += 1 1090 | ) 1091 | void 0 === this.matrix[a] && 1092 | (this.matrix[a] = this.matrix[a - 1].slice()); 1093 | (this.height = s), (this.nVars = this.width + this.height - 2); 1094 | for (var n = this.width - 1, o = 0; o < i; o += 1) { 1095 | var h = t[o], 1096 | l = r + o, 1097 | u = "min" === h.type ? -1 : 1, 1098 | d = h.varIndex, 1099 | c = this.rowByVarIndex[d], 1100 | v = this.matrix[l]; 1101 | if (-1 === c) { 1102 | for (v[this.rhsColumn] = u * h.value, e = 1; e <= n; e += 1) 1103 | v[e] = 0; 1104 | v[this.colByVarIndex[d]] = u; 1105 | } else { 1106 | var p = this.matrix[c], 1107 | f = p[this.rhsColumn]; 1108 | for ( 1109 | v[this.rhsColumn] = u * (h.value - f), e = 1; 1110 | e <= n; 1111 | e += 1 1112 | ) 1113 | v[e] = -u * p[e]; 1114 | } 1115 | var x = this.getNewElementIndex(); 1116 | (this.varIndexByRow[l] = x), 1117 | (this.rowByVarIndex[x] = l), 1118 | (this.colByVarIndex[x] = -1), 1119 | (this.variablesPerIndex[x] = new b("s" + x, x)), 1120 | (this.nVars += 1); 1121 | } 1122 | }), 1123 | (r.prototype._addLowerBoundMIRCut = function (t) { 1124 | if (t === this.costRowIndex) return !1; 1125 | this.model; 1126 | var e = this.matrix; 1127 | if (!this.variablesPerIndex[this.varIndexByRow[t]].isInteger) 1128 | return !1; 1129 | var i = e[t][this.rhsColumn], 1130 | r = i - Math.floor(i); 1131 | if (r < this.precision || 1 - this.precision < r) return !1; 1132 | var s = this.height; 1133 | (e[s] = e[s - 1].slice()), (this.height += 1), (this.nVars += 1); 1134 | var a = this.getNewElementIndex(); 1135 | (this.varIndexByRow[s] = a), 1136 | (this.rowByVarIndex[a] = s), 1137 | (this.colByVarIndex[a] = -1), 1138 | (this.variablesPerIndex[a] = new b("s" + a, a)), 1139 | (e[s][this.rhsColumn] = Math.floor(i)); 1140 | for (var n = 1; n < this.varIndexByCol.length; n += 1) { 1141 | if (this.variablesPerIndex[this.varIndexByCol[n]].isInteger) { 1142 | var o = e[t][n], 1143 | h = 1144 | Math.floor(o) + 1145 | Math.max(0, o - Math.floor(o) - r) / (1 - r); 1146 | e[s][n] = h; 1147 | } else e[s][n] = Math.min(0, e[t][n] / (1 - r)); 1148 | } 1149 | for (var l = 0; l < this.width; l += 1) e[s][l] -= e[t][l]; 1150 | return !0; 1151 | }), 1152 | (r.prototype._addUpperBoundMIRCut = function (t) { 1153 | if (t === this.costRowIndex) return !1; 1154 | this.model; 1155 | var e = this.matrix; 1156 | if (!this.variablesPerIndex[this.varIndexByRow[t]].isInteger) 1157 | return !1; 1158 | var i = e[t][this.rhsColumn], 1159 | r = i - Math.floor(i); 1160 | if (r < this.precision || 1 - this.precision < r) return !1; 1161 | var s = this.height; 1162 | (e[s] = e[s - 1].slice()), (this.height += 1), (this.nVars += 1); 1163 | var a = this.getNewElementIndex(); 1164 | (this.varIndexByRow[s] = a), 1165 | (this.rowByVarIndex[a] = s), 1166 | (this.colByVarIndex[a] = -1), 1167 | (this.variablesPerIndex[a] = new b("s" + a, a)), 1168 | (e[s][this.rhsColumn] = -r); 1169 | for (var n = 1; n < this.varIndexByCol.length; n += 1) { 1170 | var o = this.variablesPerIndex[this.varIndexByCol[n]], 1171 | h = e[t][n], 1172 | l = h - Math.floor(h); 1173 | o.isInteger 1174 | ? (e[s][n] = l <= r ? -l : (-(1 - l) * r) / l) 1175 | : (e[s][n] = 0 <= h ? -h : (h * r) / (1 - r)); 1176 | } 1177 | return !0; 1178 | }), 1179 | (r.prototype.applyMIRCuts = function () {}); 1180 | }, 1181 | { "../expressions.js": 20, "./Tableau.js": 9 }, 1182 | ], 1183 | 14: [ 1184 | function (t, e, i) { 1185 | var r = t("./Tableau.js"); 1186 | (r.prototype._putInBase = function (t) { 1187 | var e = this.rowByVarIndex[t]; 1188 | if (-1 === e) { 1189 | for ( 1190 | var i = this.colByVarIndex[t], r = 1; 1191 | r < this.height; 1192 | r += 1 1193 | ) { 1194 | var s = this.matrix[r][i]; 1195 | if (s < -this.precision || this.precision < s) { 1196 | e = r; 1197 | break; 1198 | } 1199 | } 1200 | this.pivot(e, i); 1201 | } 1202 | return e; 1203 | }), 1204 | (r.prototype._takeOutOfBase = function (t) { 1205 | var e = this.colByVarIndex[t]; 1206 | if (-1 === e) { 1207 | for ( 1208 | var i = this.rowByVarIndex[t], r = this.matrix[i], s = 1; 1209 | s < this.height; 1210 | s += 1 1211 | ) { 1212 | var a = r[s]; 1213 | if (a < -this.precision || this.precision < a) { 1214 | e = s; 1215 | break; 1216 | } 1217 | } 1218 | this.pivot(i, e); 1219 | } 1220 | return e; 1221 | }), 1222 | (r.prototype.updateVariableValues = function () { 1223 | for ( 1224 | var t = this.variables.length, 1225 | e = Math.round(1 / this.precision), 1226 | i = 0; 1227 | i < t; 1228 | i += 1 1229 | ) { 1230 | var r = this.variables[i], 1231 | s = r.index, 1232 | a = this.rowByVarIndex[s]; 1233 | if (-1 === a) r.value = 0; 1234 | else { 1235 | var n = this.matrix[a][this.rhsColumn]; 1236 | r.value = Math.round((n + Number.EPSILON) * e) / e; 1237 | } 1238 | } 1239 | }), 1240 | (r.prototype.updateRightHandSide = function (t, e) { 1241 | var i = this.height - 1, 1242 | r = this.rowByVarIndex[t.index]; 1243 | if (-1 === r) { 1244 | for ( 1245 | var s = this.colByVarIndex[t.index], a = 0; 1246 | a <= i; 1247 | a += 1 1248 | ) { 1249 | var n = this.matrix[a]; 1250 | n[this.rhsColumn] -= e * n[s]; 1251 | } 1252 | var o = this.optionalObjectives.length; 1253 | if (0 < o) 1254 | for (var h = 0; h < o; h += 1) { 1255 | var l = this.optionalObjectives[h].reducedCosts; 1256 | l[this.rhsColumn] -= e * l[s]; 1257 | } 1258 | } else this.matrix[r][this.rhsColumn] -= e; 1259 | }), 1260 | (r.prototype.updateConstraintCoefficient = function (t, e, i) { 1261 | if (t.index === e.index) 1262 | throw new Error( 1263 | "[Tableau.updateConstraintCoefficient] constraint index should not be equal to variable index !" 1264 | ); 1265 | var r = this._putInBase(t.index), 1266 | s = this.colByVarIndex[e.index]; 1267 | if (-1 === s) 1268 | for ( 1269 | var a = this.rowByVarIndex[e.index], n = 0; 1270 | n < this.width; 1271 | n += 1 1272 | ) 1273 | this.matrix[r][n] += i * this.matrix[a][n]; 1274 | else this.matrix[r][s] -= i; 1275 | }), 1276 | (r.prototype.updateCost = function (t, e) { 1277 | var i = t.index, 1278 | r = this.width - 1, 1279 | s = this.colByVarIndex[i]; 1280 | if (-1 === s) { 1281 | var a, 1282 | n = this.matrix[this.rowByVarIndex[i]]; 1283 | if (0 === t.priority) { 1284 | var o = this.matrix[0]; 1285 | for (a = 0; a <= r; a += 1) o[a] += e * n[a]; 1286 | } else { 1287 | var h = this.objectivesByPriority[t.priority].reducedCosts; 1288 | for (a = 0; a <= r; a += 1) h[a] += e * n[a]; 1289 | } 1290 | } else this.matrix[0][s] -= e; 1291 | }), 1292 | (r.prototype.addConstraint = function (t) { 1293 | var e = t.isUpperBound ? 1 : -1, 1294 | i = this.height, 1295 | r = this.matrix[i]; 1296 | void 0 === r && 1297 | ((r = this.matrix[0].slice()), (this.matrix[i] = r)); 1298 | for (var s = this.width - 1, a = 0; a <= s; a += 1) r[a] = 0; 1299 | r[this.rhsColumn] = e * t.rhs; 1300 | for (var n = t.terms, o = n.length, h = 0; h < o; h += 1) { 1301 | var l = n[h], 1302 | u = l.coefficient, 1303 | d = l.variable.index, 1304 | c = this.rowByVarIndex[d]; 1305 | if (-1 === c) r[this.colByVarIndex[d]] += e * u; 1306 | else { 1307 | var v = this.matrix[c]; 1308 | v[this.rhsColumn]; 1309 | for (a = 0; a <= s; a += 1) r[a] -= e * u * v[a]; 1310 | } 1311 | } 1312 | var p = t.index; 1313 | (this.varIndexByRow[i] = p), 1314 | (this.rowByVarIndex[p] = i), 1315 | (this.colByVarIndex[p] = -1), 1316 | (this.height += 1); 1317 | }), 1318 | (r.prototype.removeConstraint = function (t) { 1319 | var e = t.index, 1320 | i = this.height - 1, 1321 | r = this._putInBase(e), 1322 | s = this.matrix[i]; 1323 | (this.matrix[i] = this.matrix[r]), 1324 | (this.matrix[r] = s), 1325 | (this.varIndexByRow[r] = this.varIndexByRow[i]), 1326 | (this.varIndexByRow[i] = -1), 1327 | (this.rowByVarIndex[e] = -1), 1328 | (this.availableIndexes[this.availableIndexes.length] = e), 1329 | (t.slack.index = -1), 1330 | (this.height -= 1); 1331 | }), 1332 | (r.prototype.addVariable = function (t) { 1333 | var e = this.height - 1, 1334 | i = this.width, 1335 | r = !0 === this.model.isMinimization ? -t.cost : t.cost, 1336 | s = t.priority, 1337 | a = this.optionalObjectives.length; 1338 | if (0 < a) 1339 | for (var n = 0; n < a; n += 1) 1340 | this.optionalObjectives[n].reducedCosts[i] = 0; 1341 | 0 === s 1342 | ? (this.matrix[0][i] = r) 1343 | : (this.setOptionalObjective(s, i, r), (this.matrix[0][i] = 0)); 1344 | for (var o = 1; o <= e; o += 1) this.matrix[o][i] = 0; 1345 | var h = t.index; 1346 | (this.varIndexByCol[i] = h), 1347 | (this.rowByVarIndex[h] = -1), 1348 | (this.colByVarIndex[h] = i), 1349 | (this.width += 1); 1350 | }), 1351 | (r.prototype.removeVariable = function (t) { 1352 | var e = t.index, 1353 | i = this._takeOutOfBase(e), 1354 | r = this.width - 1; 1355 | if (i !== r) { 1356 | for (var s = this.height - 1, a = 0; a <= s; a += 1) { 1357 | var n = this.matrix[a]; 1358 | n[i] = n[r]; 1359 | } 1360 | var o = this.optionalObjectives.length; 1361 | if (0 < o) 1362 | for (var h = 0; h < o; h += 1) { 1363 | var l = this.optionalObjectives[h].reducedCosts; 1364 | l[i] = l[r]; 1365 | } 1366 | var u = this.varIndexByCol[r]; 1367 | (this.varIndexByCol[i] = u), (this.colByVarIndex[u] = i); 1368 | } 1369 | (this.varIndexByCol[r] = -1), 1370 | (this.colByVarIndex[e] = -1), 1371 | (this.availableIndexes[this.availableIndexes.length] = e), 1372 | (t.index = -1), 1373 | (this.width -= 1); 1374 | }); 1375 | }, 1376 | { "./Tableau.js": 9 }, 1377 | ], 1378 | 15: [ 1379 | function (t, e, i) { 1380 | t("./simplex.js"), 1381 | t("./cuttingStrategies.js"), 1382 | t("./dynamicModification.js"), 1383 | t("./log.js"), 1384 | t("./backup.js"), 1385 | t("./branchingStrategies.js"), 1386 | t("./integerProperties.js"), 1387 | (e.exports = t("./Tableau.js")); 1388 | }, 1389 | { 1390 | "./Tableau.js": 9, 1391 | "./backup.js": 10, 1392 | "./branchingStrategies.js": 12, 1393 | "./cuttingStrategies.js": 13, 1394 | "./dynamicModification.js": 14, 1395 | "./integerProperties.js": 16, 1396 | "./log.js": 17, 1397 | "./simplex.js": 18, 1398 | }, 1399 | ], 1400 | 16: [ 1401 | function (t, e, i) { 1402 | var r = t("./Tableau.js"); 1403 | (r.prototype.countIntegerValues = function () { 1404 | for (var t = 0, e = 1; e < this.height; e += 1) 1405 | if (this.variablesPerIndex[this.varIndexByRow[e]].isInteger) { 1406 | var i = this.matrix[e][this.rhsColumn]; 1407 | (i -= Math.floor(i)) < this.precision && 1408 | -i < this.precision && 1409 | (t += 1); 1410 | } 1411 | return t; 1412 | }), 1413 | (r.prototype.isIntegral = function () { 1414 | for ( 1415 | var t = this.model.integerVariables, e = t.length, i = 0; 1416 | i < e; 1417 | i++ 1418 | ) { 1419 | var r = this.rowByVarIndex[t[i].index]; 1420 | if (-1 !== r) { 1421 | var s = this.matrix[r][this.rhsColumn]; 1422 | if (Math.abs(s - Math.round(s)) > this.precision) return !1; 1423 | } 1424 | } 1425 | return !0; 1426 | }), 1427 | (r.prototype.computeFractionalVolume = function (t) { 1428 | for (var e = -1, i = 1; i < this.height; i += 1) 1429 | if (this.variablesPerIndex[this.varIndexByRow[i]].isInteger) { 1430 | var r = this.matrix[i][this.rhsColumn]; 1431 | if ( 1432 | ((r = Math.abs(r)), 1433 | Math.min(r - Math.floor(r), Math.floor(r + 1)) < 1434 | this.precision) 1435 | ) { 1436 | if (!t) return 0; 1437 | } else -1 === e ? (e = r) : (e *= r); 1438 | } 1439 | return -1 === e ? 0 : e; 1440 | }); 1441 | }, 1442 | { "./Tableau.js": 9 }, 1443 | ], 1444 | 17: [ 1445 | function (t, e, i) { 1446 | t("./Tableau.js").prototype.log = function (t, e) { 1447 | console.log("****", t, "****"), 1448 | console.log("Nb Variables", this.width - 1), 1449 | console.log("Nb Constraints", this.height - 1), 1450 | console.log("Basic Indexes", this.varIndexByRow), 1451 | console.log("Non Basic Indexes", this.varIndexByCol), 1452 | console.log("Rows", this.rowByVarIndex), 1453 | console.log("Cols", this.colByVarIndex); 1454 | var i, 1455 | r, 1456 | s, 1457 | a, 1458 | n, 1459 | o, 1460 | h, 1461 | l, 1462 | u, 1463 | d, 1464 | c, 1465 | v = "", 1466 | p = [" "]; 1467 | for (r = 1; r < this.width; r += 1) 1468 | (n = this.varIndexByCol[r]), 1469 | (h = (o = 1470 | void 0 === (a = this.variablesPerIndex[n]) ? "c" + n : a.id) 1471 | .length), 1472 | Math.abs(h - 5), 1473 | (l = " "), 1474 | (u = "\t"), 1475 | 5 < h ? (l += " ") : (u += "\t"), 1476 | (p[r] = l), 1477 | (v += u + o); 1478 | console.log(v); 1479 | var f = this.matrix[this.costRowIndex], 1480 | x = "\t"; 1481 | for (i = 1; i < this.width; i += 1) 1482 | (x += "\t"), (x += p[i]), (x += f[i].toFixed(5)); 1483 | for ( 1484 | x += "\t" + p[0] + f[0].toFixed(5), console.log(x + "\tZ"), s = 1; 1485 | s < this.height; 1486 | s += 1 1487 | ) { 1488 | for (d = this.matrix[s], c = "\t", r = 1; r < this.width; r += 1) 1489 | c += "\t" + p[r] + d[r].toFixed(5); 1490 | (c += "\t" + p[0] + d[0].toFixed(5)), 1491 | (n = this.varIndexByRow[s]), 1492 | (o = 1493 | void 0 === (a = this.variablesPerIndex[n]) ? "c" + n : a.id), 1494 | console.log(c + "\t" + o); 1495 | } 1496 | console.log(""); 1497 | var b = this.optionalObjectives.length; 1498 | if (0 < b) { 1499 | console.log(" Optional objectives:"); 1500 | for (var m = 0; m < b; m += 1) { 1501 | var y = this.optionalObjectives[m].reducedCosts, 1502 | I = ""; 1503 | for (i = 1; i < this.width; i += 1) 1504 | (I += y[i] < 0 ? "" : " "), 1505 | (I += p[i]), 1506 | (I += y[i].toFixed(5)); 1507 | (I += (y[0] < 0 ? "" : " ") + p[0] + y[0].toFixed(5)), 1508 | console.log(I + " z" + m); 1509 | } 1510 | } 1511 | return ( 1512 | console.log("Feasible?", this.feasible), 1513 | console.log("evaluation", this.evaluation), 1514 | this 1515 | ); 1516 | }; 1517 | }, 1518 | { "./Tableau.js": 9 }, 1519 | ], 1520 | 18: [ 1521 | function (t, e, i) { 1522 | var r = t("./Tableau.js"); 1523 | (r.prototype.simplex = function () { 1524 | return ( 1525 | (this.bounded = !0), 1526 | this.phase1(), 1527 | !0 === this.feasible && this.phase2(), 1528 | this 1529 | ); 1530 | }), 1531 | (r.prototype.phase1 = function () { 1532 | for ( 1533 | var t = this.model.checkForCycles, 1534 | e = [], 1535 | i = this.matrix, 1536 | r = this.rhsColumn, 1537 | s = this.width - 1, 1538 | a = this.height - 1, 1539 | n = 0; 1540 | ; 1541 | 1542 | ) { 1543 | for (var o = 0, h = -this.precision, l = 1; l <= a; l++) { 1544 | !0 === this.unrestrictedVars[this.varIndexByRow[l]]; 1545 | var u = i[l][r]; 1546 | u < h && ((h = u), (o = l)); 1547 | } 1548 | if (0 === o) return (this.feasible = !0), n; 1549 | for ( 1550 | var d = 0, c = -1 / 0, v = i[0], p = i[o], f = 1; 1551 | f <= s; 1552 | f++ 1553 | ) { 1554 | var x = p[f]; 1555 | if ( 1556 | !0 === this.unrestrictedVars[this.varIndexByCol[f]] || 1557 | x < -this.precision 1558 | ) { 1559 | var b = -v[f] / x; 1560 | c < b && ((c = b), (d = f)); 1561 | } 1562 | } 1563 | if (0 === d) return (this.feasible = !1), n; 1564 | if (t) { 1565 | e.push([this.varIndexByRow[o], this.varIndexByCol[d]]); 1566 | var m = this.checkForCycles(e); 1567 | if (0 < m.length) 1568 | return ( 1569 | this.model.messages.push("Cycle in phase 1"), 1570 | this.model.messages.push("Start :" + m[0]), 1571 | this.model.messages.push("Length :" + m[1]), 1572 | (this.feasible = !1), 1573 | n 1574 | ); 1575 | } 1576 | this.pivot(o, d), (n += 1); 1577 | } 1578 | }), 1579 | (r.prototype.phase2 = function () { 1580 | for ( 1581 | var t, 1582 | e, 1583 | i = this.model.checkForCycles, 1584 | r = [], 1585 | s = this.matrix, 1586 | a = this.rhsColumn, 1587 | n = this.width - 1, 1588 | o = this.height - 1, 1589 | h = this.precision, 1590 | l = this.optionalObjectives.length, 1591 | u = null, 1592 | d = 0; 1593 | ; 1594 | 1595 | ) { 1596 | var c = s[this.costRowIndex]; 1597 | 0 < l && (u = []); 1598 | for (var v = 0, p = h, f = !1, x = 1; x <= n; x++) 1599 | (t = c[x]), 1600 | (e = !0 === this.unrestrictedVars[this.varIndexByCol[x]]), 1601 | 0 < l && -h < t && t < h 1602 | ? u.push(x) 1603 | : e && t < 0 1604 | ? p < -t && ((p = -t), (v = x), (f = !0)) 1605 | : p < t && ((p = t), (v = x), (f = !1)); 1606 | if (0 < l) 1607 | for (var b = 0; 0 === v && 0 < u.length && b < l; ) { 1608 | var m = [], 1609 | y = this.optionalObjectives[b].reducedCosts; 1610 | p = h; 1611 | for (var I = 0; I < u.length; I++) 1612 | (t = y[(x = u[I])]), 1613 | (e = 1614 | !0 === this.unrestrictedVars[this.varIndexByCol[x]]), 1615 | -h < t && t < h 1616 | ? m.push(x) 1617 | : e && t < 0 1618 | ? p < -t && ((p = -t), (v = x), (f = !0)) 1619 | : p < t && ((p = t), (v = x), (f = !1)); 1620 | (u = m), (b += 1); 1621 | } 1622 | if (0 === v) 1623 | return this.setEvaluation(), (this.simplexIters += 1), d; 1624 | for ( 1625 | var g = 0, w = 1 / 0, C = (this.varIndexByRow, 1); 1626 | C <= o; 1627 | C++ 1628 | ) { 1629 | var B = s[C], 1630 | V = B[a], 1631 | j = B[v]; 1632 | if (!(-h < j && j < h)) { 1633 | if (0 < j && V < h && -h < V) { 1634 | (w = 0), (g = C); 1635 | break; 1636 | } 1637 | var O = f ? -V / j : V / j; 1638 | h < O && O < w && ((w = O), (g = C)); 1639 | } 1640 | } 1641 | if (w === 1 / 0) 1642 | return ( 1643 | (this.evaluation = -1 / 0), 1644 | (this.bounded = !1), 1645 | (this.unboundedVarIndex = this.varIndexByCol[v]), 1646 | d 1647 | ); 1648 | if (i) { 1649 | r.push([this.varIndexByRow[g], this.varIndexByCol[v]]); 1650 | var R = this.checkForCycles(r); 1651 | if (0 < R.length) 1652 | return ( 1653 | this.model.messages.push("Cycle in phase 2"), 1654 | this.model.messages.push("Start :" + R[0]), 1655 | this.model.messages.push("Length :" + R[1]), 1656 | (this.feasible = !1), 1657 | d 1658 | ); 1659 | } 1660 | this.pivot(g, v, !0), (d += 1); 1661 | } 1662 | }); 1663 | var y = []; 1664 | (r.prototype.pivot = function (t, e) { 1665 | var i = this.matrix, 1666 | r = i[t][e], 1667 | s = this.height - 1, 1668 | a = this.width - 1, 1669 | n = this.varIndexByRow[t], 1670 | o = this.varIndexByCol[e]; 1671 | (this.varIndexByRow[t] = o), 1672 | (this.varIndexByCol[e] = n), 1673 | (this.rowByVarIndex[o] = t), 1674 | (this.rowByVarIndex[n] = -1), 1675 | (this.colByVarIndex[o] = -1), 1676 | (this.colByVarIndex[n] = e); 1677 | for (var h, l, u, d = i[t], c = 0, v = 0; v <= a; v++) 1678 | -1e-16 <= d[v] && d[v] <= 1e-16 1679 | ? (d[v] = 0) 1680 | : ((d[v] /= r), (y[c] = v), (c += 1)); 1681 | d[e] = 1 / r; 1682 | this.precision; 1683 | for (var p = 0; p <= s; p++) 1684 | if (p !== t && !(-1e-16 <= i[p][e] && i[p][e] <= 1e-16)) { 1685 | var f = i[p]; 1686 | if (-1e-16 <= (h = f[e]) && h <= 1e-16) 0 !== h && (f[e] = 0); 1687 | else { 1688 | for (l = 0; l < c; l++) 1689 | -1e-16 <= (u = d[(v = y[l])]) && u <= 1e-16 1690 | ? 0 !== u && (d[v] = 0) 1691 | : (f[v] = f[v] - h * u); 1692 | f[e] = -h / r; 1693 | } 1694 | } 1695 | var x = this.optionalObjectives.length; 1696 | if (0 < x) 1697 | for (var b = 0; b < x; b += 1) { 1698 | var m = this.optionalObjectives[b].reducedCosts; 1699 | if (0 !== (h = m[e])) { 1700 | for (l = 0; l < c; l++) 1701 | 0 !== (u = d[(v = y[l])]) && (m[v] = m[v] - h * u); 1702 | m[e] = -h / r; 1703 | } 1704 | } 1705 | }), 1706 | (r.prototype.checkForCycles = function (t) { 1707 | for (var e = 0; e < t.length - 1; e++) 1708 | for (var i = e + 1; i < t.length; i++) { 1709 | var r = t[e], 1710 | s = t[i]; 1711 | if (r[0] === s[0] && r[1] === s[1]) { 1712 | if (i - e > t.length - i) break; 1713 | for (var a = !0, n = 1; n < i - e; n++) { 1714 | var o = t[e + n], 1715 | h = t[i + n]; 1716 | if (o[0] !== h[0] || o[1] !== h[1]) { 1717 | a = !1; 1718 | break; 1719 | } 1720 | } 1721 | if (a) return [e, i - e]; 1722 | } 1723 | } 1724 | return []; 1725 | }); 1726 | }, 1727 | { "./Tableau.js": 9 }, 1728 | ], 1729 | 19: [ 1730 | function (t, e, i) { 1731 | i.CleanObjectiveAttributes = function (t) { 1732 | var e, i, r; 1733 | if ("string" == typeof t.optimize) { 1734 | if (t.constraints[t.optimize]) { 1735 | for (i in ((e = Math.random()), t.variables)) 1736 | t.variables[i][t.optimize] && 1737 | (t.variables[i][e] = t.variables[i][t.optimize]); 1738 | return ( 1739 | (t.constraints[e] = t.constraints[t.optimize]), 1740 | delete t.constraints[t.optimize], 1741 | t 1742 | ); 1743 | } 1744 | return t; 1745 | } 1746 | for (r in t.optimize) 1747 | if (t.constraints[r]) 1748 | if ("equal" === t.constraints[r]) delete t.optimize[r]; 1749 | else { 1750 | for (i in ((e = Math.random()), t.variables)) 1751 | t.variables[i][r] && 1752 | (t.variables[i][e] = t.variables[i][r]); 1753 | (t.constraints[e] = t.constraints[r]), 1754 | delete t.constraints[r]; 1755 | } 1756 | return t; 1757 | }; 1758 | }, 1759 | {}, 1760 | ], 1761 | 20: [ 1762 | function (t, e, i) { 1763 | function s(t, e, i, r) { 1764 | (this.id = t), 1765 | (this.cost = e), 1766 | (this.index = i), 1767 | (this.value = 0), 1768 | (this.priority = r); 1769 | } 1770 | 1771 | function r(t, e, i, r) { 1772 | s.call(this, t, e, i, r); 1773 | } 1774 | 1775 | function a(t, e) { 1776 | s.call(this, t, 0, e, 0); 1777 | } 1778 | 1779 | function n(t, e) { 1780 | (this.variable = t), (this.coefficient = e); 1781 | } 1782 | 1783 | function o(t, e, i) { 1784 | return 0 === i || "required" === i 1785 | ? null 1786 | : ((e = e || 1), 1787 | (i = i || 1), 1788 | !1 === t.isMinimization && (e = -e), 1789 | t.addVariable(e, "r" + t.relaxationIndex++, !1, !1, i)); 1790 | } 1791 | 1792 | function h(t, e, i, r) { 1793 | (this.slack = new a("s" + i, i)), 1794 | (this.index = i), 1795 | (this.model = r), 1796 | (this.rhs = t), 1797 | (this.isUpperBound = e), 1798 | (this.terms = []), 1799 | (this.termsByVarIndex = {}), 1800 | (this.relaxation = null); 1801 | } 1802 | 1803 | function l(t, e) { 1804 | (this.upperBound = t), 1805 | (this.lowerBound = e), 1806 | (this.model = t.model), 1807 | (this.rhs = t.rhs), 1808 | (this.relaxation = null); 1809 | } 1810 | 1811 | (a.prototype.isSlack = r.prototype.isInteger = !0), 1812 | (h.prototype.addTerm = function (t, e) { 1813 | var i = e.index, 1814 | r = this.termsByVarIndex[i]; 1815 | if (void 0 === r) 1816 | (r = new n(e, t)), 1817 | (this.termsByVarIndex[i] = r), 1818 | this.terms.push(r), 1819 | !0 === this.isUpperBound && (t = -t), 1820 | this.model.updateConstraintCoefficient(this, e, t); 1821 | else { 1822 | var s = r.coefficient + t; 1823 | this.setVariableCoefficient(s, e); 1824 | } 1825 | return this; 1826 | }), 1827 | (h.prototype.removeTerm = function (t) { 1828 | return this; 1829 | }), 1830 | (h.prototype.setRightHandSide = function (t) { 1831 | if (t !== this.rhs) { 1832 | var e = t - this.rhs; 1833 | !0 === this.isUpperBound && (e = -e), 1834 | (this.rhs = t), 1835 | this.model.updateRightHandSide(this, e); 1836 | } 1837 | return this; 1838 | }), 1839 | (h.prototype.setVariableCoefficient = function (t, e) { 1840 | var i = e.index; 1841 | if (-1 !== i) { 1842 | var r = this.termsByVarIndex[i]; 1843 | if (void 0 === r) this.addTerm(t, e); 1844 | else if (t !== r.coefficient) { 1845 | var s = t - r.coefficient; 1846 | !0 === this.isUpperBound && (s = -s), 1847 | (r.coefficient = t), 1848 | this.model.updateConstraintCoefficient(this, e, s); 1849 | } 1850 | return this; 1851 | } 1852 | console.warn( 1853 | "[Constraint.setVariableCoefficient] Trying to change coefficient of inexistant variable." 1854 | ); 1855 | }), 1856 | (h.prototype.relax = function (t, e) { 1857 | (this.relaxation = o(this.model, t, e)), 1858 | this._relax(this.relaxation); 1859 | }), 1860 | (h.prototype._relax = function (t) { 1861 | null !== t && 1862 | (this.isUpperBound 1863 | ? this.setVariableCoefficient(-1, t) 1864 | : this.setVariableCoefficient(1, t)); 1865 | }), 1866 | (l.prototype.isEquality = !0), 1867 | (l.prototype.addTerm = function (t, e) { 1868 | return ( 1869 | this.upperBound.addTerm(t, e), 1870 | this.lowerBound.addTerm(t, e), 1871 | this 1872 | ); 1873 | }), 1874 | (l.prototype.removeTerm = function (t) { 1875 | return ( 1876 | this.upperBound.removeTerm(t), 1877 | this.lowerBound.removeTerm(t), 1878 | this 1879 | ); 1880 | }), 1881 | (l.prototype.setRightHandSide = function (t) { 1882 | this.upperBound.setRightHandSide(t), 1883 | this.lowerBound.setRightHandSide(t), 1884 | (this.rhs = t); 1885 | }), 1886 | (l.prototype.relax = function (t, e) { 1887 | (this.relaxation = o(this.model, t, e)), 1888 | (this.upperBound.relaxation = this.relaxation), 1889 | this.upperBound._relax(this.relaxation), 1890 | (this.lowerBound.relaxation = this.relaxation), 1891 | this.lowerBound._relax(this.relaxation); 1892 | }), 1893 | (e.exports = { 1894 | Constraint: h, 1895 | Variable: s, 1896 | IntegerVariable: r, 1897 | SlackVariable: a, 1898 | Equality: l, 1899 | Term: n, 1900 | }); 1901 | }, 1902 | {}, 1903 | ], 1904 | 21: [ 1905 | function (h, t, e) { 1906 | function i() { 1907 | "use strict"; 1908 | (this.Model = l), 1909 | (this.branchAndCut = s), 1910 | (this.Constraint = n), 1911 | (this.Variable = o), 1912 | (this.Numeral = d), 1913 | (this.Term = c), 1914 | (this.Tableau = r), 1915 | (this.lastSolvedModel = null), 1916 | (this.External = v), 1917 | (this.Solve = function (t, e, i, r) { 1918 | if (r) for (var s in u) t = u[s](t); 1919 | if (!t) 1920 | throw new Error("Solver requires a model to operate on"); 1921 | if ( 1922 | "object" == typeof t.optimize && 1923 | Object.keys(1 < t.optimize) 1924 | ) 1925 | return h("./Polyopt")(this, t); 1926 | if (t.external) { 1927 | var a = Object.keys(v); 1928 | if (((a = JSON.stringify(a)), !t.external.solver)) 1929 | throw new Error( 1930 | "The model you provided has an 'external' object that doesn't have a solver attribute. Use one of the following:" + 1931 | a 1932 | ); 1933 | if (!v[t.external.solver]) 1934 | throw new Error( 1935 | "No support (yet) for " + 1936 | t.external.solver + 1937 | ". Please use one of these instead:" + 1938 | a 1939 | ); 1940 | return v[t.external.solver].solve(t); 1941 | } 1942 | t instanceof l == !1 && (t = new l(e).loadJson(t)); 1943 | var n = t.solve(); 1944 | if ( 1945 | ((this.lastSolvedModel = t), 1946 | (n.solutionSet = n.generateSolutionSet()), 1947 | i) 1948 | ) 1949 | return n; 1950 | var o = {}; 1951 | return ( 1952 | (o.feasible = n.feasible), 1953 | (o.result = n.evaluation), 1954 | (o.bounded = n.bounded), 1955 | n._tableau.__isIntegral && (o.isIntegral = !0), 1956 | Object.keys(n.solutionSet).forEach(function (t) { 1957 | 0 !== n.solutionSet[t] && (o[t] = n.solutionSet[t]); 1958 | }), 1959 | o 1960 | ); 1961 | }), 1962 | (this.ReformatLP = h("./External/lpsolve/Reformat.js")), 1963 | (this.MultiObjective = function (t) { 1964 | return h("./Polyopt")(this, t); 1965 | }); 1966 | } 1967 | 1968 | var r = h("./Tableau/index.js"), 1969 | l = h("./Model"), 1970 | s = h("./Tableau/branchAndCut"), 1971 | a = h("./expressions.js"), 1972 | u = h("./Validation"), 1973 | n = a.Constraint, 1974 | o = a.Variable, 1975 | d = a.Numeral, 1976 | c = a.Term, 1977 | v = h("./External/main.js"); 1978 | "function" == typeof define 1979 | ? define([], function () { 1980 | return new i(); 1981 | }) 1982 | : "object" == typeof window 1983 | ? (window.solver = new i()) 1984 | : "object" == typeof self && (self.solver = new i()), 1985 | (t.exports = new i()); 1986 | }, 1987 | { 1988 | "./External/lpsolve/Reformat.js": 2, 1989 | "./External/main.js": 4, 1990 | "./Model": 5, 1991 | "./Polyopt": 6, 1992 | "./Tableau/branchAndCut": 11, 1993 | "./Tableau/index.js": 15, 1994 | "./Validation": 19, 1995 | "./expressions.js": 20, 1996 | }, 1997 | ], 1998 | }, 1999 | {}, 2000 | [21] 2001 | ); 2002 | --------------------------------------------------------------------------------