C++ 显示实现利润最大化的步骤

C++ 显示实现利润最大化的步骤,c++,algorithm,C++,Algorithm,我正在传递一个包含如下数据的排序向量: Job Details {Start Time, Finish Time, Profit} Job 1: {1 , 2 , 50 } Job 2: {3 , 5 , 20 } Job 3: {6 , 19 , 100 } Job 4: {2 , 100 , 200 }

我正在传递一个包含如下数据的排序向量:

Job Details {Start Time, Finish Time, Profit}
Job 1:      {1         , 2          , 50    }
Job 2:      {3         , 5          , 20    }
Job 3:      {6         , 19         , 100   }
Job 4:      {2         , 100        , 200   }
代码通过检查所有不重叠的路径(例如作业1、2、3或作业1、4)来查找哪些作业最有利于盈利,并确定作业1、4为最佳值。我试图构建一个函数,显示代码如何获得最佳解决方案的路径

例如,作业1-->作业4-->250美元

但是,我对实施感到迷茫

Main.cpp


你可以简单地考虑加权图<代码> g <代码>哪里

  • 节点是一个作业
  • 如果
    a.endTime
  • 边(A,B)
    的权重是
    B。利润
    (走到B的路径意味着做作业B)
您希望获得
G
的最大权重路径

通常算法希望函数最小化,因此让我们取权重
-B.price

我们总是可以引用该算法,甚至在前面的链接中提供了路径重建算法

自制的 但我们还是自制吧,因为这似乎是一些家庭作业

你可以用蛮力的方法(效率比弗洛伊德·沃沙尔低,但更容易掌握)检查所有最长的路径

创建一个<代码>根>代码>节点,为孩子添加所有与它们各自的权重相关的作业,然后考虑递归函数:

def get_longest_path(node):
    if !node.children 
        return 0

    best_all = {
        w: weight(node, node.children[0]), 
        path: [node, get_longest_path(node.children[0])]
    }

    for node.children as child //starting from 1

        best_path_i = get_longest_path(child)
        //if we found a path with lower total weight (that is, with maximal profit)
        if best_path_i != 0 && best_path_i.weight < best_all.weight
            best_all = {
                w: weight(node, child), 
                path:[node, best_path_i]
            }

    return best_all

get_longest_path(root)

没有处理过的循环,但是你没有一个工作可以逆转时间,我猜

< P>你可以简单地考虑一个赋权图<代码> G <代码>哪里

  • 节点是一个作业
  • 如果
    a.endTime
  • 边(A,B)
    的权重是
    B。利润
    (走到B的路径意味着做作业B)
您希望获得
G
的最大权重路径

通常算法希望函数最小化,因此让我们取权重
-B.price

我们总是可以引用该算法,甚至在前面的链接中提供了路径重建算法

自制的 但我们还是自制吧,因为这似乎是一些家庭作业

你可以用蛮力的方法(效率比弗洛伊德·沃沙尔低,但更容易掌握)检查所有最长的路径

创建一个<代码>根>代码>节点,为孩子添加所有与它们各自的权重相关的作业,然后考虑递归函数:

def get_longest_path(node):
    if !node.children 
        return 0

    best_all = {
        w: weight(node, node.children[0]), 
        path: [node, get_longest_path(node.children[0])]
    }

    for node.children as child //starting from 1

        best_path_i = get_longest_path(child)
        //if we found a path with lower total weight (that is, with maximal profit)
        if best_path_i != 0 && best_path_i.weight < best_all.weight
            best_all = {
                w: weight(node, child), 
                path:[node, best_path_i]
            }

    return best_all

get_longest_path(root)

没有处理循环,但您没有反转时间的作业,我想这一算法可以非常类似于一个字符串的递归置换实现,比如说一个ABC
ABC
,它生成
ABC、ACB、BAC、BCA、CAB、CBA

这是一个简单的演示


如果不满足某个条件(例如,字母表中后一个字母比前一个字母低),您可以修改此选项以“修剪”树,因此您将获得
ABC
,因为它是唯一一个每个后续字母都较低的
(A该算法可以非常类似于字符串
ABC
的递归置换实现,它产生
ABC、ACB、BAC、BCA、CAB、CBA

这是一个简单的演示


如果不满足某个条件(例如,字母表中后一个字母比前一个字母低),您可以修改此选项以“修剪”树,因此您将获得
ABC
,因为它是唯一一个每个后续字母都较低的
(A你能使用完整的代码吗?包括
测试
struct?你能使用完整的代码吗?包括
测试
struct吗?
#include "Task.h"

Task::Task()
{

}

Task::Task(string inLabel, int inStartTime, int inEndTime, int inValue)
{
    label = inLabel;
    startTime = inStartTime;
    endTime = inEndTime;
    value = inValue;
}

void Task::setLabel(string inLabel)
{
    label = inLabel;
}

string Task::getLabel()
{
    return label;
}

void Task::setStartTime(int inStartTime)
{
    startTime = inStartTime;
}

int Task::getStartTime()
{
    return startTime;
}

void Task::setEndTime(int inEndTime)
{
    endTime = inEndTime;
}

int Task::getEndTime()
{
    return endTime;
}

void Task::setValue(int inValue)
{
    value = inValue;
}

int Task::getValue()
{
    return value;
}
def get_longest_path(node):
    if !node.children 
        return 0

    best_all = {
        w: weight(node, node.children[0]), 
        path: [node, get_longest_path(node.children[0])]
    }

    for node.children as child //starting from 1

        best_path_i = get_longest_path(child)
        //if we found a path with lower total weight (that is, with maximal profit)
        if best_path_i != 0 && best_path_i.weight < best_all.weight
            best_all = {
                w: weight(node, child), 
                path:[node, best_path_i]
            }

    return best_all

get_longest_path(root)
cache = {}
def get_longest_path(node):
    if !node.children 
        return 0

    //node.id is jobId
    if node.id in cache
        return cache[node.id]

    best_all = {
        w: weight(node,node.children[0]), 
        path: [node, get_longest_path(node.children[0])]
    }

    for node.children as child //starting from 1

        best_path_i = get_longest_path(child)
        //if we found a path with lower total weight (that is, with maximal profit)
        if best_path_i != 0 && best_path_i.weight < best_all.weight
            best_all = {
                w: weight(node, child), 
                path:[node, best_path_i]
            }
    cache[node.id] = best_all
    return best_all

get_longest_path(root)
#include <iostream>
#include <vector>

using namespace std;

struct Task {
    // global counter tracking how many instances
    static int counter;
    int startTime;
    int endTime;
    int value;
    int label;
    Task(int inStartTime, int inEndTime, int inValue) {
        startTime = inStartTime;
        endTime = inEndTime;
        value = inValue;
        label = Task::counter++;
    }
};
// store an index to each Task to keep track
int Task::counter = 1;

// build a search tree of all possible Task sequences
// pruning if next Task and current Task overlap
void jobSearchTree(vector<Task> jobSequence,
           vector<Task> possibleJobs,
           vector<vector<Task>> &possibleJobSequences) {

    for (int i = 0; i < possibleJobs.size(); i++) {
        vector<Task> l;
        for (int j = 0; j < jobSequence.size(); j++)
        {
            l.push_back(jobSequence.at(j));
        }
        l.push_back(possibleJobs[i]);
        // initial recursive call
        if (!jobSequence.size()) {
            vector<Task> searchJobs(possibleJobs);
            searchJobs.erase(searchJobs.begin() + i);
            jobSearchTree(l, searchJobs, possibleJobSequences);
        }
        // test if jobs occur sequentially
        else if (l.at(l.size()-2).endTime <= l.at(l.size()-1).startTime)                {
            // add the Task sequence
            possibleJobSequences.push_back(l);
            vector<Task> searchJobs(possibleJobs);
            // remove this Task from the search
            searchJobs.erase(searchJobs.begin() + i);
            // recursive call with Task sequence as the head
            // and the remaining possible jobs as the tail
            jobSearchTree(l, searchJobs, possibleJobSequences);
        }
    }
}

vector<int> getBestJobSequence(vector<vector<Task>> possibleJobSequences) {
    int maxProfit = 0;
    int totalProfit = 0;
    vector<Task> bestJobSequence;
    for (auto jobSequence : possibleJobSequences) {
        totalProfit = 0;
        for (auto Task : jobSequence) {
            totalProfit += Task.value;
        }
        if (totalProfit > maxProfit) {
            maxProfit = totalProfit;
            bestJobSequence = jobSequence;
        }
    }
    vector<int> jobIds;
    for (auto Task : bestJobSequence) {
        jobIds.push_back(Task.label);
    }
    return jobIds;
}

int main()
{
    Task s1(1, 2, 50);
    Task s2(3, 5, 20);
    Task s3(6, 19, 100);
    Task s4(2, 100, 200);
    vector<Task> allJobs = {s1, s3, s4};

    vector<vector<Task>> possibleJobSequences;
    vector<Task> currentJobSequence;
    jobSearchTree(currentJobSequence, allJobs, possibleJobSequences);
    vector<int> bestJobSequence = getBestJobSequence(possibleJobSequences);
    for (auto job : bestJobSequence) {
        cout << job << endl;
    }
    return 0;
}