pcm-coordinator/pkg/scheduler/strategies/priceBasedStrategy.go

142 lines
4.3 KiB
Go

/*
Copyright (c) [2023] [pcm]
[pcm-coordinator] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPaRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
package strategies
import (
"errors"
"gitlink.org.cn/jcce-pcm/pcm-coordinator/pkg/scheduler/algorithm/providerPricing"
)
type pricingStrategy struct {
ProviderList []*providerPricing.Provider
Task *providerPricing.Task
StrategyList []*providerPricing.Strategy
}
func NewPricingStrategy(task *providerPricing.Task, providers ...*providerPricing.Provider) *pricingStrategy {
var providerList []*providerPricing.Provider
var res [][]int
for _, p := range providers {
p.GenMaxResourceNum(task)
providerList = append(providerList, p)
}
providerPricing.Back_trace_task(task.Replicas, 0, providerList, 0, &res, 0)
var strategyList []*providerPricing.Strategy
for _, r := range res {
var path []int
var pathlist [][]int
var resourcePerProvider []int
for j, p := range providerList {
if r[j] > p.MaxReplicas {
resourcePerProvider = append(resourcePerProvider, p.MaxReplicas)
} else {
resourcePerProvider = append(resourcePerProvider, r[j])
}
}
providerPricing.Back_trace_resource(resourcePerProvider, 0, path, &pathlist)
strategy := providerPricing.NewStrategy()
strategy.Tasksolution = r
strategy.Resourcesolution = pathlist
strategyList = append(strategyList, strategy)
}
return &pricingStrategy{ProviderList: providerList, Task: task, StrategyList: strategyList}
}
func (ps *pricingStrategy) computeMaxScore() (*providerPricing.Task, error) {
maxStrategy := providerPricing.NewStrategy()
var maxprofit float64
//先计算出最大的利润值
for _, strategy := range ps.StrategyList {
for _, resourceSolu := range strategy.Resourcesolution {
profit := providerPricing.ComputeProfit(ps.Task, strategy.Tasksolution, resourceSolu, ps.ProviderList)
if profit > maxprofit {
maxprofit = profit
}
}
}
for _, strategy := range ps.StrategyList {
for _, resourceSolu := range strategy.Resourcesolution {
profit := providerPricing.ComputeProfit(ps.Task, strategy.Tasksolution, resourceSolu, ps.ProviderList)
highDegree := providerPricing.ComputeHighDegree(ps.Task, resourceSolu, ps.ProviderList)
valueSum := profit/maxprofit + highDegree
//将每个确定任务分配策略的最高的策略得分存储到里面
if valueSum > maxStrategy.ValueSum {
strategy.Profit = profit
strategy.HighDegree = highDegree
}
if valueSum > maxStrategy.ValueSum {
maxStrategy.ValueSum = valueSum
maxStrategy.Tasksolution = strategy.Tasksolution
newResourceSolu := [][]int{}
newResourceSolu = append(newResourceSolu, resourceSolu)
maxStrategy.Resourcesolution = newResourceSolu
maxStrategy.Profit = profit
maxStrategy.HighDegree = highDegree
}
}
}
if len(ps.ProviderList) == 0 {
return nil, errors.New("empty providers")
}
ps.Task.MaxscoreStrategy = maxStrategy // 记录该任务的最终分配策略
return ps.Task, nil
}
//type strategyService interface {
// computeMaxScore() (*providerPricing.Task, error)
//}
func (ps *pricingStrategy) ScheduleWithFullCollaboration() (*providerPricing.Task, error) {
task, err := ps.computeMaxScore()
if err != nil {
return nil, err
}
//计算任务i的resourcePerTask属性
for i, _ := range ps.ProviderList {
tasksolu := task.MaxscoreStrategy.Tasksolution[i] // 第j个提供商分到的任务数
resourcesolu := task.MaxscoreStrategy.Resourcesolution[0][i] // 第j个提供商分到的资源数
// 在第j个云提供商处声明一个长度为资源数的链表
resourcePerTaskPerProviders := make([]int, resourcesolu)
if tasksolu > 0 {
for tasksolu > 0 {
for j := 0; j < resourcesolu; j++ {
resourcePerTaskPerProviders[j] += 1
tasksolu -= 1
}
}
} else if tasksolu == 0 {
resourcePerTaskPerProviders = []int{0}
}
task.ResourcePerTask = append(task.ResourcePerTask, resourcePerTaskPerProviders)
}
return task, nil
}