具有一定依赖性/约束的算法遍历图

发布于 2025-02-11 09:45:30 字数 598 浏览 4 评论 0原文

因此,我正在建立一个操作管道,该管道允许用户在数据范围内应用某些数据操作。 操作使它们可能具有“一输入 - >两个输出”或“一输入 - > One-On-On-On-On-On-On-On-On-On-On-On-On-Onputs”或“两输入 - > One-On-On-On-On-On-On-On-On-On-On-On-On-On-On-On-On-Entput”。

我需要从标记为[S1,S2,S3,S4]的起点遍历图形,并到达终点 重要的是要注意的是,要执行操作2,我们需要使操作1和操作5已经执行。类似地,与执行操作7一样,操作3和6需要已执行。

请注意,这比有向的无环图更简单,因为我们具有清晰的起点和终点,并且流量是单向的[图像中的左 - >右],

已知哪些操作是标记为S1,S2,S3的起点,S4。我需要执行所有操作并到达终端点。我只需要伪代码。

So I am building a operations pipeline that allows user to apply certain Data operations on dataframes.
The operations are such that they may have "one-input-->two-outputs" or "one-input-->one-output" or "two-inputs-->one-output".

enter image description here

I need to traverse the graph from the starting points labelled as [S1, S2, S3, S4] and reach the end points
The important thing to note is that in order to execute operation2, we need to have operation1 and operation5 already executed. similarly to execute operation7, operations 3 and 6 need to be already executed.

Note that this is simpler than a directed acyclic graph as we have clear start and end points and the flow is unidirectional [left-->right in the image]

It is known which operations are the starting points marked as S1,s2,s3,s4. I need to execute all operations and reach the terminal points. I just the need the pseudocode.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

爱给你人给你 2025-02-18 09:45:30

这看起来是某种任务调度问题,因为问题缺少许多重要细节,因此无法确切说出什么样或提供任何具体建议。

  1. 每个任务需要多长时间。每个任务都需要同一时间吗
    在每个处理器上。 (如果任务不花时间,那么没有等待
    重新生气,问题变得微不足道)

  2. 有多少个处理器可用。 (可以以合理的方式完成任务,或一个一个或仅相似的少数数字。)

  3. 您要优化什么?总时间完成所有任务。最小化处理器数量。其他。

  4. 您想看到的输出是什么。

有关于任务调度问题的大量文献。一个合理的起点是 https://en.wikipedia.org/wikipedia.org/wiki/wiki/scheduling_(计算)

由于您几乎没有关于问题的信息,因此您可以最好地找到可行的执行订单,假设没有副任务执行。

  1. 添加一个启动节点,并带有链接到每个S节点。

  1. 对树进行广度搜索,并在访问时记录节点。

This looks to be some kind of task scheduling problem, It is impossible to say exactly what kind or offer any concrete suggestion because the question is missing many important details.

  1. How long does each task take. Does each task take the same time
    on every processor. ( If task take no time, then no waiting is
    reuired and the problem becomes trivial )

  2. How many processors are available. ( Can tasks be completed in parrallel, or one by one, or only a small number in parallels. )

  3. What do you want to optimize for? Total time to complete all tasks. Minimize number of processors. Something else.

  4. What is the output you want to see.

There is a vast literature on task scheduling problems. A reasonable starting point would be https://en.wikipedia.org/wiki/Scheduling_(computing)

Since you have almost no information about the problem the best you can acieve is to find a feasible execution order, assuming no parralel task execution.

  1. Add a starting node, with links to each of the s nodes.

enter image description here

  1. Do a breadth first search of the tree, recording the nodes as they are visited.
猫七 2025-02-18 09:45:30

这是您可以解决此问题的一种方式,我在下面发布了一个JavaScript snuppet,它打印出操作顺序。第一部分是表示图形,例如:

[
  [[inputs], [outputs]]  // where the index is the operation #
]

下一步将确定操作顺序以及您希望系统执行这些操作的方式。我根据图提出了以下序列:

0, 1, 5, 2, 3, 4, 6, 7, 8, 9, 10

例如,这是有意义的,因为步骤#2要等到步骤#5完成以下内容等,否则才能完成。由此,我们可以为我们的算法提出几个规则:

  1. 按升序横穿图形,
  2. 可以执行并标记为完成,如果:
  3. 所有输入也标记为完整的
  4. 输入,输入为null null 则指示序列的第一个操作
  5. 如果输入未完成回溯操作,
  6. ,直到我们击中null一旦完成所有输出操作,直到我们击中null

此方法的一个问题是上图是脱节的,因此我们确实需要运行每个s1s2s3s4

// The index numbers are just for illustration
const operationsGraph = {
  0: [null, [1]],
  1: [[0], [2]],
  2: [[1, 5], [3]],
  3: [[2], [4, 7]],
  4: [[3], null],
  5: [null, [2]],
  6: [null, [7]],
  7: [[3, 6], [8]],
  8: [[7], null],
  9: [null, [10]],
  10: [[9], null],
};

// Convert the graph to an array
const operation = Object.values(operationsGraph);

// Create an array to keep track of the completed operations
const completed = Array(operation.length).fill(false);

/**
 * The algorithm works as follows:
 *
 *  1. move along path until (2 inputs needed)
 *  2. backtrack until base case
 *  3. continue in lowest completed order
 *
 *   [complete] <--- [current] ----> [complete]
 */

function traverse(pointer) {
  // if this step has been completed return
  if (completed[pointer]) return true;
  // extract the prev and next operations
  const prev = operation[pointer][0];
  const next = operation[pointer][1];
  // backtrack each previous operation
  prev?.forEach((op) => traverse(op));
  // if the previous step is complete and this operation
  // has been completed then mark as completed and print
  if (isComplete(prev) && completed[pointer] === false) {
    // update the completed flag
    completed[pointer] = true;
    // run the operation here
    console.log('running: ', pointer);
  }
  // iterate the next steps in the sequence
  next?.forEach((op) => traverse(op));
}

// helper function to check if a step is complete
function isComplete(step) {
  if (step === null) return true;
  return step.every((i) => completed[i]);
}

// run each of the sequences
function main() {
  const s1 = traverse(0);
  const s2 = traverse(5);
  const s3 = traverse(6);
  const s4 = traverse(9);
}

main()

This is one way you could handle this problem, I've posted a JavaScript snuppet below which prints out the order of operations. The first part is representing the graph, for example:

[
  [[inputs], [outputs]]  // where the index is the operation #
]

The next step would be determining the order of operations and how you want the system to execute these operations. I came up with the following sequence based on the diagram:

0, 1, 5, 2, 3, 4, 6, 7, 8, 9, 10

Which makes sense since step #2 for example cannot complete until step #5 is finished so on and so forth. From this we can come up with a couple rules for our algorithm:

  1. Traverse the graph in ascending order
  2. An operation can be executed and marked complete if:
  3. All of the inputs are also marked as complete
  4. The inputs are null indicating the first operation of a sequence
  5. If the inputs are not complete backtrack operations until we hit null
  6. Once complete traverse all output operations until we hit null

One issue with this approach is the above graph is disjointed and so we do need to run the traverse function for each s1, s2, s3, s4

// The index numbers are just for illustration
const operationsGraph = {
  0: [null, [1]],
  1: [[0], [2]],
  2: [[1, 5], [3]],
  3: [[2], [4, 7]],
  4: [[3], null],
  5: [null, [2]],
  6: [null, [7]],
  7: [[3, 6], [8]],
  8: [[7], null],
  9: [null, [10]],
  10: [[9], null],
};

// Convert the graph to an array
const operation = Object.values(operationsGraph);

// Create an array to keep track of the completed operations
const completed = Array(operation.length).fill(false);

/**
 * The algorithm works as follows:
 *
 *  1. move along path until (2 inputs needed)
 *  2. backtrack until base case
 *  3. continue in lowest completed order
 *
 *   [complete] <--- [current] ----> [complete]
 */

function traverse(pointer) {
  // if this step has been completed return
  if (completed[pointer]) return true;
  // extract the prev and next operations
  const prev = operation[pointer][0];
  const next = operation[pointer][1];
  // backtrack each previous operation
  prev?.forEach((op) => traverse(op));
  // if the previous step is complete and this operation
  // has been completed then mark as completed and print
  if (isComplete(prev) && completed[pointer] === false) {
    // update the completed flag
    completed[pointer] = true;
    // run the operation here
    console.log('running: ', pointer);
  }
  // iterate the next steps in the sequence
  next?.forEach((op) => traverse(op));
}

// helper function to check if a step is complete
function isComplete(step) {
  if (step === null) return true;
  return step.every((i) => completed[i]);
}

// run each of the sequences
function main() {
  const s1 = traverse(0);
  const s2 = traverse(5);
  const s3 = traverse(6);
  const s4 = traverse(9);
}

main()

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文