【问题标题】:Algorithm for resolving conflicts with overlapping choices解决重叠选择冲突的算法
【发布时间】:2014-03-19 15:41:37
【问题描述】:

我有一个计算问题,我有一组可以只赠送一次的标签,以及许多项目,每个项目都有一组他们可以接受的可能的标签选择。我需要以这样一种方式分配标签,即只要有问题的解决方案,每个项目都会获得一个标签。

举个具体的例子,如果我有这样的字典:

options = {
  'a': [1],
  'b': [2, 3],
  'c': [1, 2]
}

..那么解决方案是:

 {'a': 1, 'b': 3, 'c': 2}

我还需要能够扩展问题以处理多个约束,例如

[1], ['A', 'B']         # -> (1, A) or (1, B)
[1, 2, 3], ['A', 'C']   # -> (3, C)
[1, 2], ['A', 'C']      # -> (2, A) or (2, B)

我已经尝试为简单的情况提出基于优先级队列的可行解决方案,但是由于多个约束而完全崩溃。我可以使用itertools.permutations 强制解决方案,但我更喜欢高效的实现。是否有任何已知的算法可能适用于这个问题?

【问题讨论】:

  • 如果有多个解决方案,比如你有 options = {'a': [1,2],'b': [2, 3],'c': [1, 2 ]),然后是解决方案 {'a': [1,2], 'b': 3, 'c': [1,2]} 还是你想得到一组所有的解决方案?
  • 只有一种解决方案。这个问题的范围是避免不完整的解决方案,而不是列举所有的可能性。

标签: python algorithm constraint-programming


【解决方案1】:

形式上,您在示例中遇到的是一个简单的约束满足问题,其中包含三个变量['a', 'b', 'c'],每个变量都有一个有限的整数域和“全不同”约束。

使用适当的启发式回溯搜索可以在实践中相当快地解决此类问题。例如

def backtracking(domains):
    if any(len(dom) == 0 for var, dom in domains.iteritems()):
        return None
    if all(len(dom) == 1 for var, dom in domains.iteritems()):
        return domains

    # minimum remaining values heuristic: process variables with few possible
    # values first (fail-first strategy)
    order = sorted(domains.iteritems(), key=lambda (var, dom): len(dom))
    for var, dom in order:
        if len(dom) == 1:
            continue

        for value in list(dom):
            doms = {v: d - {value} for v, d in domains.iteritems()
                                   if v != var}
            doms[var] = {value}

            solution = backtracking(doms)
            if solution is not None:
                return solution

print(backtracking({v: set(d) for v, d in options.iteritems()}))

【讨论】:

  • 这看起来确实适用于简单的情况,我相信如果成本更高,它可以扩展到复杂的情况。
  • 在更详细地查看解决方案后,只是一些 cmets:如果原始案例已经存在失败状态,则此解决方案将失败,例如如果options = {'a': [1, 2], 'b': [3], 'c': [3]}。否则,可以通过将d - {value}又名拒绝步骤)更改为更合适的方式轻松扩展解决方案。
【解决方案2】:

我会使用回溯来解决这个问题。 根据是否可以实现贪心算法的约束,一次选择 1 个标签以实现全局最优

【讨论】:

    【解决方案3】:

    您不必为了解决这个问题而实施一个完整的回溯系统。许多研究人员已经构建了系统和建模语言来促进此类问题的解决。

    您的问题是一个非常经典的约束满足问题,我们有 AllDifferent 约束。我建议你使用像 minizinc (http://www.minizinc.org/) 这样的高级建模语言,你会自己看到不同之处。这是一个以这种格式编写的简单模型(针对您的问题):

    include "globals.mzn";
    var {1} : a;
    var {2,3} : b;
    var {1,2} : c;
    constraint alldifferent([a,b,c]);
    
    solve  satisfy;
    
    output ["a :  ", show(a), "\n" ,
            "b :  ", show(b), "\n" ,
            "c :  ", show(c), "\n" ];
    

    如果这是您第一次使用 minizinc,您可以从最新的教程 here 开始。

    【讨论】:

      【解决方案4】:

      它确实是一个非常基本的 AllDifferent 约束。如果对 python 感兴趣,请使用 https://pypi.python.org/pypi/python-constraint

      problem = Problem()
      problem.addVariable("a", [1, 2])
      problem.addVariable( "b", [2, 3])
      problem.addVariable("c", [1, 2])
      problem.addConstraint(AllDifferentConstraint())
      print problem.getSolution()
      

      (如果存在,会给你第一个找到的 或

      print sorted(sorted(x.items()) for x in problem.getSolutions())
      

      将给出所有解决方案)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-08-21
        • 2015-05-07
        • 2013-05-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多