题目描述
公司创新实验室正在研究如何最小化资源成本,最大化资源利用率,请你设计算法帮他们
解决一个任务混部问题:有
taskNum
项任务,每个任务有开始时间(
startTime),结束时间(endTime),并行度
(parallelism)
三个属性,并行度是指这个任务运行时将 会占用的服务器数量,一个服务器在每个时刻可以被任意任务使用但最多被一个任务占用
,任务运行完会立即释放(结束时刻不占用)。任务混部问题是指给定一批任务,让这批
任务由同一批服务器承载运行,请你计算完成这批任务混部最少需要多少服务器,从而最
大化控制资源成本。
输入描述:txt文本
2023-03-13 10:00:00, 2023-08-31 23:59:00, 3
2023-05-13 10:00:00, 2023-05-31 23:59:00, 4
2023-05-01 10:00:00, 2023-08-31 23:59:00, 7
输出描述
一个整数,表示最少需要的服务器数量
package main
import (
"bufio"
"fmt"
"io"
"os"
"sort"
"strconv"
"strings"
"time"
)
func main() {
//创建文件
f, erro := os.Open("./OD_practice/data/servers_runtime.txt")
if erro != nil {
fmt.Println(erro.Error())
return
}
defer f.Close()
servers := [][]int64{}
lines := bufio.NewReader(f)
for {
content, _, erro := lines.ReadLine()
if erro == io.EOF {
fmt.Println("Reading to end of the file")
break
}
line := strings.Split(string(content), ", ")
//fmt.Println(line)
servers = append(servers, readLines(line))
}
/**
servers := [][]int64{
{1, 20, 3},
{2, 3, 8},
{6, 9, 3},
{8, 20, 11},
}**/
result := maxServers(servers)
fmt.Println(result)
}
/**
题目: 有task项任务,每项任务有属性: 开始时间,结束时间,需要服务器数量, 求同时需要服务器数量最大值是多少
抽象问题: 需要求出重叠区间内,个数组对应服务器总和。
方法: 重叠区间求法 可以用动态规划,先按照开始时间排序, 遍历排序之后的数组,每加入一个新的数组,判断它之前的任务是否结束,如果已经结束,减去结束的任务数,加上新的任务数,如果没有结束,直接叠加。
**/
func maxServers(tasks [][]int64) int {
maxServer := 0
servers := 0
//排序:
sort.Slice(tasks, func(i, j int) bool { return tasks[i][0] < tasks[j][0] })
n := len(tasks)
for task := 0; task < n; task++ {
servers += int(tasks[task][2])
for i := 0; i < task; i++ {
if tasks[i][1] <= tasks[task][0] && tasks[i][1] > tasks[task-1][0] { // 此处必须判断 停止时间在上一个服务器开启之后,在此服务器开启之前。否则已经停止的任务数会重复减
servers -= int(tasks[i][2])
}
}
maxServer = max(maxServer, servers)
}
return maxServer
}
func max(a int, b int) int {
if a > b {
return a
} else {
return b
}
}
func readLines(strs []string) []int64 {
//fmt.Println(strs[0])
//start, erro := time.Parse("2023-01-13 10:00:00", strs[0])
start, erro := time.Parse("2006-01-01 15:01:00", strs[0])
if erro != nil {
panic("Reading data error:" + erro.Error())
}
//end, erro1 := time.Parse("2023-01-13 10:00:00", strs[1])
end, erro1 := time.Parse("2006-01-02 15:04:05", strs[1])
if erro1 != nil {
panic("Reading data error:" + erro.Error())
}
number, erro2 := strconv.Atoi(strs[2])
if erro2 != nil {
panic("Reading data error:" + erro.Error())
}
return []int64{start.Unix(), end.Unix(), int64(number)}
}