- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个优化问题:
a,b,c,d,e
;约束条件:
a >= x
b >= y
e > c
e > d
x 和y 是整型参数。
目标:
maximize (c + d) * 2 + e
minimize a
minimize b
minimize e - c
minimize e - d
说明:
我有大约 80-90 行;第一行是初始化,然后每行最多包含 4 组“增量”指令。解决问题在于每行选择一组指令。以下是第一行作为示例:
{a = 0; b = 0; c = 0; d = 0; e = 0}
{b += 360} OR {b += 160; c += 160} OR {b += 160; d += 160} OR {b += 160; e += 160}
{a += 360} OR {a += 160; c += 160} OR {a += 160; d += 160} OR {a += 160; e += 160}
{c += 1697; d += 1697} OR {c += 1697; d += 1019; e += 678} OR {c += 1019; d += 1697; e += 678}
一个例子:
假设 x = 1200
,y = 170
,我们有以下六行指令:
{b += 360} OR {b += 160; c += 160} OR {b += 160; d += 160} OR {b += 160; e += 160}
{a += 360} OR {a += 160; c += 160} OR {a += 160; d += 160} OR {a += 160; e += 160}
{c += 1697; e += 1697} OR {c += 1697; e += 1019; d += 678} OR {c += 1019; e += 1697; d += 678}
{b += 360} OR {b += 160; c += 160} OR {b += 160; d += 160} OR {b += 160; e += 160}
{a += 360} OR {a += 160; c += 160} OR {a += 160; d += 160} OR {a += 160; e += 160}
{a += 1149; d += 939} OR {a += 1149; d += 939; e += 678} OR {a += 939; d += 678; e += 1149}
此示例中的一个可能解决方案是从每一行中选择第一组指令:
{b += 360},
{a += 360},
{c += 1697; e += 1697},
{b += 360},
{a += 360},
{a += 1149; d += 939}
然后我们得到这些值:
a = 1869, b = 720, c = 1697, d = 939, e = 1697
有目标:
(c + d) * 2 + e = 6969 (to be maximized)
a = 1869 (to be minimized but >= 1200)
b = 720 (to be minimised but >= 170)
e - c = 0 (to be minimized but >= 0)
e - d = 758 (to be minimized but >= 0)
但更好的解决方案是选择这 6 组指令:
{b += 160; d += 160},
{a += 160; d += 160},
{c += 1697; e += 1019; d += 678},
{b += 160; d += 160},
{a += 160; d += 160},
{a += 939; d += 678; e += 1149}
a = 1259, b = 320, c = 1697, d = 1996, e = 2168
(c + d) * 2 + e = 9554 (to be maximized)
a = 1259 (to be minimized but >= 1200)
b = 320 (to be minimised but >= 170)
e - c = 471 (to be minimized but >= 0)
e - d = 172 (to be minimized but >= 0)
我已经解决了暴力破解它的问题,但是通过 80-90 行指令,它有大约 876488338465357824 种可能的组合,所以这不是执行此操作的有效方法。
我不需要它非常完美,一个好的近似值可能就足够了。
任何解决这个问题的工具推荐都是有帮助的,欢迎任何帮助我搜索合适算法和类似问题的关键字。
最佳答案
N
通过从列表中选择随机指令来随机候选解决方案;N
, 随机地使用目标函数作为权重,这样好的解决方案更有可能存活下来;请注意,您的问题是一个多目标问题。上面的算法假设一个单一的目标。有许多不同的方法可以将多目标问题转化为或多或少相似的单目标问题,选择如何做到这一点将导致不同的解决方案。
为简单起见,我编写了一个单目标函数作为 5 个目标的加权和:目标现在是最大化 10 * ((c+d)*2+e) - a - b - (e-c) - (e-d)
.
另一种简单的可能性是将一些目标转化为约束,例如:
minimize c - e
进入约束e - c < 100
;minimize c - e
进入约束e < 2 * c
;minimize a
进入约束a < 2 * x
.您可以通过修改系数来尝试这些更改 params['objective']
和功能satisfies_constraints
在下面的代码中。
from more_itertools import random_product
import random
from itertools import chain
raw_data = '''{b += 360} OR {b += 160; c += 160} OR {b += 160; d += 160} OR {b += 160; e += 160}
{a += 360} OR {a += 160; c += 160} OR {a += 160; d += 160} OR {a += 160; e += 160}
{c += 1697; e += 1697} OR {c += 1697; e += 1019; d += 678} OR {c += 1019; e += 1697; d += 678}
{b += 360} OR {b += 160; c += 160} OR {b += 160; d += 160} OR {b += 160; e += 160}
{a += 360} OR {a += 160; c += 160} OR {a += 160; d += 160} OR {a += 160; e += 160}
{a += 1149; d += 939} OR {a += 1149; d += 939; e += 678} OR {a += 939; d += 678; e += 1149}'''
# input: string "{a += 1149; d += 939}"
# output: list [1149, 0, 0, 939, 0]
def parse_instructionset(s):
instructions_list = [instruction.split('+=') for instruction in s.strip()[1:-1].split(';')]
instructions_dict = { k.strip(): int(v) for k,v in instructions_list }
return [instructions_dict.get(k, 0) for k in 'abcde']
# output: list of lists of lists
# representing lines of disjonctions of instruction sets
def parse_data(raw_data):
rows = [line.split('OR') for line in raw_data.split('\n')]
return [[parse_instructionset(s) for s in row] for row in rows]
# for r in parse_data(raw_data):
# print(r)
# [[0, 360, 0, 0, 0], [0, 160, 160, 0, 0], [0, 160, 0, 160, 0], [0, 160, 0, 0, 160]]
# [[360, 0, 0, 0, 0], [160, 0, 160, 0, 0], [160, 0, 0, 160, 0], [160, 0, 0, 0, 160]]
# [[0, 0, 1697, 0, 1697], [0, 0, 1697, 678, 1019], [0, 0, 1019, 678, 1697]]
# [[0, 360, 0, 0, 0], [0, 160, 160, 0, 0], [0, 160, 0, 160, 0], [0, 160, 0, 0, 160]]
# [[360, 0, 0, 0, 0], [160, 0, 160, 0, 0], [160, 0, 0, 160, 0], [160, 0, 0, 0, 160]]
# [[1149, 0, 0, 939, 0], [1149, 0, 0, 939, 678], [939, 0, 0, 678, 1149]]
# used a weighted sum to turn the multiobjective into one objective
params = {
'objective': [-1, -1, 20+1, 20+1, 10-2], # 10 * ((c+d)*2+e) - a - b - (e - c) - (e - d)}
'x': 1200, # lower bound for 'a'
'y': 170, # lower bound for 'b'
'poolsize': 50, # number of candidate solutions to keep at each iteration
'nbupgrades': 5, # number of new solutions to generate from each candidate
'distance': 2, # number of instruction sets to randomly modify to get a new solution
'nbiter': 100 # number of iterations
}
# sum increments to get a,b,c,d,e from the chosen instruction sets
def get_abcde(solution):
return [sum(increment[k] for increment in solution) for k in range(5)]
# return boolean to check that candidate is valid
def satisfies_constraints(abcde, x=params['x'], y=params['y']):
a,b,c,d,e = abcde
return a >= x and b >= y and e > c and e > d
# compute value of objective function for candidate
def get_objective(abcde, objective_coeffs=params['objective']):
return sum(c*v for c,v in zip(objective_coeffs, abcde))
# populate pool with <pool_size> random candidates
def initialise_pool(data, pool_size=params['poolsize']):
solutions = [random_product(*data) for _ in range(pool_size)]
abcdes = [get_abcde(sol) for sol in solutions]
return [(get_objective(abcde), abcde, sol) for abcde,sol in zip(abcdes, solutions)]
# build pool of new candidates from current pool of candidates
def upgrade_pool(pool, data, nb_upgrades=params['nbupgrades'], distance=params['distance']):
# copy current candidates
new_pool = list(pool)
# add new candidates
for _,abcde,solution in pool:
for _ in range(nb_upgrades):
for row_index in [random.randrange(len(data)) for _ in range(distance)]:
new_instruction = random.choice(data[row_index])
new_abcde = [[abcde[k] + new_instruction[k] - solution[row_index][k]] for k in range(5)]
new_solution = list(chain(solution[:row_index], [new_instruction], solution[row_index+1:]))
abcde = get_abcde(new_solution)
if satisfies_constraints(abcde):
new_pool.append((get_objective(abcde), abcde, new_solution))
# crop down to <pool_size>
new_pool = crop(new_pool, len(pool))
return new_pool
# remove excess candidates
# candidates to keep are chosen randomly
# using value of objective as weight
# randomness is very important here, DO NOT simply keep the n candidates with highest objective
def crop(pool, n):
return random.choices(pool, weights=[obj for obj,_,_ in pool], k=n)
def main_loop(data, nb_iter=params['nbiter'], pool=None):
if not pool:
pool = initialise_pool(data)
for _ in range(nb_iter):
pool = upgrade_pool(pool, data)
return pool
if __name__ == '__main__':
data = parse_data(raw_data)
pool = main_loop(data)
pool.sort(key=lambda triplet:triplet[0], reverse=True)
print('Best 2 and worst 2:')
for objective, abcde, _ in pool[:2] + pool[-2:]:
print(objective, abcde)
print()
print('Best:')
obj, abcde, sol = pool[0]
print('objective={}'.format(obj))
print('(c+d)*2+e=', (abcde[2]+abcde[3])*2+abcde[4])
print('a,b,c,d,e={}'.format(abcde))
print('increments=[')
for increment in sol:
print(' ', increment, ',')
print(']')
objective=93318
(c+d)*2+e= 9554
a,b,c,d,e=[1259, 320, 2017, 1676, 2168]
increments=[
[0, 160, 0, 160, 0] ,
[160, 0, 0, 160, 0] ,
[0, 0, 1697, 678, 1019] ,
[0, 160, 160, 0, 0] ,
[160, 0, 160, 0, 0] ,
[939, 0, 0, 678, 1149] ,
]
关于algorithm - 我什至无法表达这个问题,我需要从一大组数字中选出 3 个非常接近的数字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69991678/
我希望 Eclipse 调试器观察某个表达式何时变为真(其值发生变化)并在发生这种情况时停止。这在我看来非常有用和基本,所以我认为必须有一种方法可以在 eclipse 中做到这一点(如在 gdb 中)
我正在使用 SPEL 表达式,当我的应用程序启动时,我收到此错误。 ftpOutboundGateway.setRenameExpressionString("'/processed/headers[
我不是 visual studio 程序员,但我需要快速创建一个应用程序来显示图像并使用 slider 操纵它的高度和宽度。我已经完成了快速谷歌和所有关于使用 picturebox(picbox) 作
我在玩弄 Boost Xpressive,但遇到了以下代码片段的问题 #include #include #include using namespace std; using namespac
今年我一直在想,2022年我想做些什么,做哪方面的改变,这周末在家终于想到了! 2021 轻描淡写 年底就一直想对2021年写一篇总结的,起码不得写个千八百字,可是思来想去不知道怎么写,直到最后都没想
这个问题在这里已经有了答案: Italic greek letters / latex-style math in plot titles (2 个回答) 8年前关闭。 我应该怎么做才能让 R 在图例
有没有办法为 jade 模板错误提供自定义异常处理程序? 例如 // server.js app = express(); app.set('view engine', jade); app.loca
我需要了解使用路由在 Express 应用程序中流程的工作原理,我有这些路线 app.use(require('./routes/reportsRouter')); app.use(require('
在一条 route 我有这个: if (elements.length <= 0) { var msg = 'no elements found
完整的代码如下 - 很简单,我想添加、删除或更新帖子 - 当我自己做其中一件事时,它可以工作,但一起它会中断 我在 NodeJS MySQL 中搜索了很多我用它来查询数据库 var mysql = r
下面的CSS选择器有没有更优雅的写法? input:not([type="image"]):not([type="submit"]) 我想匹配所有不是 image 类型或 submit 类型的 HTM
当我尝试全局安装 express-generator 时,它说它成功了。我什至可以在我的全局应用程序列表中看到它但是当我尝试运行 express我遇到标题问题:zsh: command not fou
这不是一个很好的问题,但它是这样的: 我正在结合 DataFrame 的几列进行非常简单的计算,但前提是一列具有特定值。想法是: if df.x==1: df.y = df.y - df.a/
我有一个网站 -https://example.com- 调用 API -https://api.example.com-。该 API 是用 Express 编写的,其使用 CORS package允
当我使用 Express 框架时,我将“.html”文件放入文件夹 View 中,然后将“.js”和“.css”文件放入 public 中。当我运行我的应用程序时,我可以获得 js 和 css,但我无
有一个简单的应用程序 var express = require('express'); var http = require('http'); var path=require('path'); v
我正在构建一个基于express的REST API,我想在用户的请求中使用错误的HTTP动词时发出警告。 目前,我正在添加 app.all('/', (req, res) => { answe
对于用于在 connect/express 中对 session 数据进行加密散列的 key 长度有什么建议吗?我看到了从 60 多个字符串到规范的“键盘猫”的所有内容。 对于我的直接用例,我打算对整
Redis 的HDEL 的时间复杂度是O(N)(其中N 是要移除的字段数)。我有一个用例,其中字段必须为每个操作进行类型转换。我将如何表达新的时间复杂度? O(N*2)? 最佳答案 时间复杂度将相同:
我看到我可以像这样指定 gradle 依赖项: dependencies { compile 'com.fasterxml.jackson.core:jackson-annotations:2
我是一名优秀的程序员,十分优秀!