- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
寻求一些帮助来解决无限期问题、成本最小化问题以及一些必须访问的状态。
我们有一个预算 b 和一个成本矩阵 M,它表示状态之间旅行的扣除额(Mij 表示从 i 到 j 的旅行成本),类似于经典的旅行商问题。在这种情况下,时间可能是负数,表示预算增加,Mij 不一定等于 Mji。同样在这种情况下,M 是 4x4,但情况可能并非如此,通常可以说 3 <= len(M) <= 5,因为我认为这可能需要一些带有大量操作的蛮力方法......
0 1 -3 1
6 0 2 2
4 2 0 3
1 2 3 0
每一行代表给定状态 i,然后每一列代表前往 j 的成本。
因此问题是:给定 b 和 M,不包括 state=0 和 state=len(M) 我们可以到达并最终到达 state=len(M) 且 b >= 的唯一状态的最大数量是多少0.
鉴于上面的 M,并且 b=0,那么我认为输出将是 [2],路径是 [0] -> [2] -> [3],完整的展示如下所示:
state nextstate deduction time
-- 0 --- 0
0 2 -3 3
2 3 3 0
我试图将这个问题作为一个强化学习问题来解决,使用 e-greedy 解决方案和启发式策略来选择下一个状态,我也将其视为 TSP 并查看了使用 Floyd-Warshall 的解决方案,但是我不太确定如何在问题设置中适应约束。
我认为有一种方法可以找到直接的解决方案,我的直觉似乎能够查看一般的 M 和给定的 b 并提出解决方案,但我无法清楚地表述算法...
对于如何清晰地构建这个框架并提出直接解决方案,我们表示赞赏。
最佳答案
如果您的成本矩阵包含负循环,那么最终可以访问所有状态。您可以使用 Bellman-Ford检测循环,因此答案的其余部分假定不存在这样的循环。
该算法由三部分组成。首先,它找到从开始状态到结束状态成本低于预算的所有路径。对于每条这样的路径,都会跟踪所访问的状态和总成本。然后它会找到所有源自(并终止于)结束状态的循环,并跟踪已访问状态和总成本。
在已知所有路径和循环之后,算法开始向路径添加循环。如果该循环添加新状态并且总成本在预算范围内,则添加成功。添加一直持续到无法向现有路径添加循环为止。最后,包含最多访问状态的路径被选为结果。
以下是上述内容的非精化实现:
M = [
[0, 2, 2, 2, -1],
[6, 0, 2, 2, -1],
[6, 3, 0, 2, -1],
[6, 3, 2, 0, -1],
[6, 3, 2, 2, 0]
]
BUDGET = 1
SOURCE = 0
DEST = len(M) - 1
def all_paths_step(source, dest, visited, cost):
for i in range(len(M)):
if i in visited:
continue
new_cost = cost + M[source][i]
new_set = visited | {i}
if i == dest:
yield new_set, new_cost
elif i not in visited:
yield from all_paths_step(i, dest, new_set, new_cost)
def all_paths(source, dest, cost=0):
result = {}
for states, cost in all_paths_step(source, dest, frozenset([source]), cost):
result[states] = min(result.get(states, float('inf')), cost)
return result
to_dest = all_paths(SOURCE, DEST)
loops = {}
for i in range(len(M)):
if i == DEST:
continue
for states, cost in all_paths(i, len(M) - 1, M[len(M) - 1][i]).items():
loops[states] = min(loops.get(states, float('inf')), cost)
possible = {visited: cost for visited, cost in to_dest.items() if cost <= BUDGET}
process = set(possible.keys())
while process:
process_next = set()
while process:
states = process.pop()
for path, cost in loops.items():
cost += possible[states]
new_states = states | path
if path <= states or cost >= possible.get(new_states, BUDGET + 1):
continue
possible[new_states] = cost
process_next.add(new_states)
process = process_next
print('result: {}'.format(max(possible, key=len)) if possible else 'none')
输出,无特定顺序的访问状态:
result: frozenset({0, 2, 3, 4})
关于java - 构建无限期的 MDP,使用必访状态实现成本最小化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40077864/
我正在对用 Java 语言编写的程序进行逆向工程。到目前为止,一切都很有意义,除了一段我根本无法理解的代码。该程序本身是流行游戏Minecraft的服务器,尽管我强烈认为这个问题与其本身无关。让我向您
在 Python 的时间模块中,有一个 sleep() 函数,可以让 Python 等待 x 秒后再继续执行程序。有没有办法无限期地执行此操作直到满足条件?例如: while True: ti
我有一个 php 脚本,它可能需要 2 到 10 分钟才能执行。它从网络上获取信息,因此它的时间取决于许多其他事物的通话速度。 我曾经每 15 分钟在 cron 上运行一次脚本,但有时只需要 2 分钟
我运行 Mac OSX 10.7 和 Xcode 4.2.1,一切都很好,直到几个小时前,当我尝试运行模拟器时,我的 xcode 突然挂起!这是发生了什么 代码构建成功,但它无限期地显示“Attach
我目前正在阅读 Ivor Horton 的 Beginning C。无论如何,我不确定的 for 在继续之前打印了我的 printf 语句两次。我确定我做错了什么,但我直接从书中复制了代码。如果重要的
我正在使用一个在下面设置 session 变量/cookie 的登录系统。 Chrome,它可以让你轻松地查看你的 cookie,显然将其标记为“当我关闭浏览器时”过期的 PHPSESSID。果然,当
任务是:尝试使用最基本的形式(如“ping 8.8.8.8”)在 python 中发送 ping。一段时间后终止 ping 命令(在终端中,将执行 Ctrl+C)并获得其输出。显示 ping 统计信息
我是一名优秀的程序员,十分优秀!