【问题标题】:Bipartite Matching with a constraint带约束的二分匹配
【发布时间】:2020-10-14 12:34:28
【问题描述】:

我正在尝试在两组顶点之间进行匹配,一组代表两支球队之间的相遇,另一组代表可能发生相遇的时间段。邻接图表示两个团队在任何给定时间段内会面的可用性。这将是二分匹配。问题是我想限制这一点,这样任何团队都不会被分配到连续的时间段,更具体地说是连续两天的时间段。

所以,我尝试在向匹配添加边之前添加一个检查,在扩充路径的末尾,检查前一天和第二天的时间段,如果它们已与任何匹配比赛中即将比赛的球队。我用 Hopcroft-Karp 和 DFS 试过了。没用。

这不再是二分匹配了吗?

任何帮助将不胜感激。

编辑:

正如下面答案中所建议的,我正在尝试将其实现为整数线性程序。以下代码很大程度上基于示例from Google OR-tools on assignment matching 事实上,它似乎可以正常匹配,但没有我指定的约束。

// [START program]
// [START import]
import com.google.ortools.linearsolver.MPConstraint;
import com.google.ortools.linearsolver.MPObjective;
import com.google.ortools.linearsolver.MPSolver;
import com.google.ortools.linearsolver.MPVariable;
// [END import]

/** MIP example that solves an assignment problem. */
public class GameMatching {
    static {
        System.loadLibrary("jniortools");
    }

    public static void main(String[] args) {
        // Data
        // [START data_model]
        // Adjacency matrix represents which games can happen on which dates
        int[][] adj = {
          {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
          {1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
          {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
          {0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1},
          {1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
          {1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
          {1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
          {1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
          {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
          {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
          {0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1},
          {1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
          {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
          {1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
          {0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1},
          {1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
          {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
          {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
          {1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
          {1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
          {0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
          {1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
          {1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
          {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
          {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
          {1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
          {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
          {0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
          {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
          {0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        };

        int numGames = adj.length;
        int numDates = adj[0].length;

        //represents which game time slots are on a given day (4 games on sundays, 2 on weekdays)
        int[][] days = {
              {0, 1, 2, 3},
              {4, 5},
              {6, 7},
              {8, 9, 10, 11},
              {12, 13},
              {14, 15},
              {16, 17},
              {18, 19},
              {20, 21, 22, 23},
              {24, 25},
              {26, 27},
              {28, 29},
              {30, 31},
              {32, 33, 34, 35},
              {36, 37},
              {38, 39},
              {40, 41},
              {42, 43},
              {44, 45, 46, 47},
              {48, 49},
              {50, 51},
              {52, 53, 54, 55},
              {56, 57},
              {58, 59},
              {60, 61},
              {62, 63},
              {64, 65, 66, 67},
              {68, 69},
              {70, 71},
              {72, 73},
              {74, 75},
              {76, 77, 78, 79}
        };
        //represents what day of the week is a day, a team can play thursday and sunday, but not sunday and monday 0 is sunday, 1 is monday...
        int[] weekDays = {0, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0};

        // teamToGames[i][j] represents a team i's, games j
        int[][] teamToGames = {
              {1, 3, 9, 16, 18, 26},
              {0, 8, 12, 16, 23, 28},
              {1, 5, 7, 13, 21, 27},
              {2, 5, 14, 17, 22, 26},
              {7, 15, 19, 21, 24, 28},
              {3, 10, 14, 20, 27, 29},
              {2, 6, 9, 13, 23, 29},
              {6, 8, 11, 18, 19, 25},
              {8, 4, 10, 11, 17, 24},
              {4, 12, 15, 20, 22, 25},
        };
       
        // [END data_model]

        // Solver
        // [START solver]
        // Create the linear solver with the CBC backend.
        MPSolver solver = new MPSolver("AssignmentMip", MPSolver.OptimizationProblemType.CBC_MIXED_INTEGER_PROGRAMMING);
        // [END solver]

        // Variables
        // [START variables]
        // x[i][j] is an array of 0-1 variables, which will be 1
        // if a game i is assigned to date j.
        MPVariable[][] match = new MPVariable[numGames][numDates];
        for (int i = 0; i < numGames; ++i) {
            for (int j = 0; j < numDates; ++j) {
                match[i][j] = solver.makeIntVar(0, 1, "");
            }
        }

        // [END variables]

        // Constraints
        // [START constraints]
        // Each game is assigned to at most one date.
        for (int i = 0; i < numGames; ++i) {
            MPConstraint constraint = solver.makeConstraint(0, 1, "");
            for (int j = 0; j < numDates; ++j) {
                constraint.setCoefficient(match[i][j], 1);
            }
        }
        // Each date is assigned to at most one game.
        for (int j = 0; j < numDates; ++j) {
            MPConstraint constraint = solver.makeConstraint(0, 1, "");
            for (int i = 0; i < numGames; ++i) {
                constraint.setCoefficient(match[i][j], 1);
            }
        }
        // Can only assign respecting adj matrix
        for (int i = 0; i < numGames; ++i) {
            for (int j = 0; j < numDates; ++j) {
                MPConstraint constraint = solver.makeConstraint(0, adj[i][j], "");
                constraint.setCoefficient(match[i][j], 1);
            }
        }

        // Cannot assign team to consecutive dates
        for (int i = 0; i < teamToGames.length; ++i) {
            for (int j = 0; j < days.length - 1; ++j) {
                if (weekDays[j] != 4) {
                    MPConstraint constraint = solver.makeConstraint(0, 1, "");
                    for (int k = 0; k < teamToGames[i].length; ++k) {
                        for (int l = 0; l < days[j].length; ++l) {
                            constraint.setCoefficient(match[teamToGames[i][k]][l], 1);
                        }
                        for (int l = 0; l < days[j+1].length; ++l) {
                            constraint.setCoefficient(match[teamToGames[i][k]][l], 1);
                        }
                    }
                }
            }
        }

        // [END constraints]

        // Objective
        // [START objective]
        MPObjective objective = solver.objective();
        for (int i = 0; i < numGames; ++i) {
            for (int j = 0; j < numDates; ++j) {
                objective.setCoefficient(match[i][j], 1);
            }
        }

        objective.setMaximization();
        // [END objective]

        // Solve
        // [START solve]
        MPSolver.ResultStatus resultStatus = solver.solve();
        // [END solve]

        // Print solution.
        // [START print_solution]
        // Check that the problem has a feasible solution.
        if (resultStatus == MPSolver.ResultStatus.OPTIMAL || resultStatus == MPSolver.ResultStatus.FEASIBLE) {
            System.out.println("Total matches: " + objective.value() + "\n");
            for (int i = 0; i < numGames; ++i) {
                for (int j = 0; j < numDates; ++j) {
                    // Test if x[i][j] is 0 or 1 (with tolerance for floating point
                    // arithmetic).
                    if (match[i][j].solutionValue() > 0.5) {
                        System.out.println("Game " + i + " assigned to date " + j);
                    }
                }
            }
        } else {
            System.err.println("No solution found.");
        }
        // [END print_solution]
    }

    // private GameMatching() {
    // }
}
// [END program]

编辑 这是显然有效的代码。我需要做最后一件事。最好在同一天进行两场比赛(如果其他限制条件允许的话),而不是在两个不同的日子中的每一天进行一场比赛。我的第一个想法是找到一种方法将每天的游戏限制为 0 或 2(或在周日更多),但这可能并不总是可行的。因此,对于我如何做到这一点的任何帮助,我们将不胜感激。

提前谢谢你。

【问题讨论】:

  • 请澄清您的问题并提及您在算法或代码中所做的工作
  • 对不起@גלעדברקן,这只是我正在尝试的东西,我没有让你提供工作代码。我现在就在上面。
  • 好主意,您必须尝试使连续一天的约束起作用。为了获得更多关注,您可能会考虑提出额外的问题 - 很高兴一天有两场比赛 - 作为 SO 的另一个问题,包括迄今为止的工作。 (通常,将问题编辑为另一个问题通常不会引起太多关注,因为大多数人已经阅读并继续前进。)
  • 要在每个日期偏好两场比赛,一个想法可能是有一个变量reward,将其设置为最大化目标。我们维护一个约束,即必须分配每个“游戏”(特定的团队对)(关联约束的值必须为 1)。我们创建所有我们认为有效的两场比赛日期的比赛对。然后,这些对中的每个游戏分配都与添加到 reward 的值相关联,而不是像现在这样完成的分配。这些将需要一个额外的约束,要么都被分配,要么都不分配。

标签: algorithm data-structures graph computer-science depth-first-search


【解决方案1】:

我们可以有一个整数线性程序,其中团队要满足的每个约束都包含两个额外的before 变量。例如,A 队在第 4 天开会:

{
  A_meets_on_4: 1,
  A_meets_before_4: 1,
  A_meets_before_5: 1
}

如果我们尝试将 A 分配给 3,我们会得到:

{
  A_meets_on_3: 1,
  A_meets_before_3: 1,
  A_meets_before_4: 1
}

如果我们尝试将 A 分配给 5,我们会得到:

{
  A_meets_on_5: 1,
  A_meets_before_5: 1,
  A_meets_before_6: 1
}

现在如果我们尝试分配,比如 3 和 4,我们一起得到:

{
  A_meets_on_3: 1,
  A_meets_on_4: 1,
  A_meets_before_3: 1,
  A_meets_before_4: 2
  A_meets_before_5: 1
}

但如果我们将所有 before 变量(如 A_meets_before_4)限制为小于 2,则不允许这样做。

如果我们尝试将 A 分配给 3 和 5,我们一起得到:

{
  A_meets_on_3: 1,
  A_meets_on_5: 1,
  A_meets_before_3: 1,
  A_meets_before_4: 1
  A_meets_before_5: 1
  A_meets_before_6: 1
}

这是允许的。

【讨论】:

  • 感谢您的回复。我不熟悉线性规划。我发现这个developers.google.com/optimization/assignment/… 似乎是一个不错的起点。据我了解,对于每个团队,我必须为每个时间段添加一个整数变量,前一个,后一个,值为 1,然后添加所有变量必须小于的约束比2,这是正确的吗?但在这种情况下,我将如何处理每次会议涉及 2 个团队?
  • @vsoued 据我所知(而且我对整数线性规划的经验也很少,在实际环境中只使用过一次),分配任何一次相遇都意味着一系列像我提到的那样的变量,每个团队一个;除了任何其他限制之外,例如每个团队的总人数。
  • @vsoued 我在实际设置中使用的求解器是this one——那里的 README 文件将变量声明显示为 JSON,类似于我给出的示例。对于常规的 ILP 求解器,我们会稍微不同地编写公式。我不知道该怎么写,但我相信 SO 上的其他人可以提供帮助。
  • 如果我理解正确,@גלעד ברקן,这意味着两个单独匹配项的值需要以某种方式重叠并相加,以便对总和设置约束,对吗?我为此头疼。在 json 中查看您的示例确实使这更容易可视化,但我仍然缺乏对 lp 的基本了解
  • @vsoued 不确定我是否关注。 “两个单独的比赛”是什么意思?什么是“匹配”?
猜你喜欢
  • 2020-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-01
  • 2015-11-10
相关资源
最近更新 更多