feat(config): 添加超时空地图配置和时间地图查询功能 新增IsTimeSpace字段用于标识地图是否为超时空地图, 添加TimeMap API接口支持查询超时空地图配置 perf(socket): 优化XORDecryptU解密函数减少内存分配 基于bytebufferpool实现缓冲区池化,大幅降低高频调用下的 内存分配和GC压力,提升性能表现 refactor(utils): 优化packVal序列化函数提升性能和稳定性 减少反射开销,优化内存拷贝操作,改进错误处理机制, 替换panic为error返回,增强代码健壮性 docs(readme): 添加新的pprof性能分析地址配置 ```
This commit is contained in:
540
modules/config/model/glow.go
Normal file
540
modules/config/model/glow.go
Normal file
@@ -0,0 +1,540 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"math"
|
||||
"math/rand"
|
||||
"time"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// ---------------- 结构体定义(保持不变) ----------------
|
||||
type MonsterMatrix struct {
|
||||
Matrix [4][5]float32 `json:"matrix"` // 4×5颜色矩阵(唯一输入输出对象)
|
||||
Hash string `json:"hash"` // 矩阵唯一哈希(基于矩阵数据生成)
|
||||
Type string `json:"type"` // random(父母矩阵)/merged(后代矩阵)
|
||||
Seed int64 `json:"seed"` // 随机种子(父母矩阵有效,后代矩阵为0)
|
||||
Parents [2]string `json:"parents"` // 父母矩阵哈希(后代矩阵填写,父母矩阵为空)
|
||||
Weight [2]float32 `json:"weight"` // 融合权重(后代矩阵有效,父母矩阵为[0,0])
|
||||
}
|
||||
|
||||
func (m MonsterMatrix) Get() [20]float32 {
|
||||
oneDArr := *(*[20]float32)(unsafe.Pointer(&m.Matrix))
|
||||
return oneDArr
|
||||
}
|
||||
|
||||
type SplitResult struct {
|
||||
Father MonsterMatrix `json:"father"` // 拆分出的父亲矩阵(纯矩阵输出)
|
||||
Mother MonsterMatrix `json:"mother"` // 拆分出的母亲矩阵(纯矩阵输出)
|
||||
InputOffspring MonsterMatrix `json:"input_offspring"` // 输入的后代矩阵(纯矩阵输入,随机/自定义)
|
||||
ProcessedOffspring MonsterMatrix `json:"processed_offspring"` // 预处理后的合规后代矩阵
|
||||
SplitWeight [2]float32 `json:"split_weight"` // 实际拆分权重(默认0.5:0.5平均权重)
|
||||
IsReversible bool `json:"is_reversible"` // 父母融合=预处理后代矩阵(确保为true)
|
||||
Hash string `json:"hash"` // 拆分结果唯一哈希
|
||||
}
|
||||
|
||||
// ---------------- 配置常量(贴合示例参数范围,微调界限) ----------------
|
||||
const (
|
||||
FloatPrecision = 6 // 浮点精度保留小数位
|
||||
MaxCalibrateIter = 300 // 最大校准迭代次数
|
||||
ErrorThreshold = 1e-3 // 融合误差阈值
|
||||
MatrixMinVal = -1.0 // 贴合示例:前3行前3列参数大多在[-1,2]之间
|
||||
MatrixMaxVal = 2.0 // 贴合示例:避免参数过度偏离
|
||||
BrightnessMinVal = -30.0 // 贴合示例:亮度大多在[-30, 30]之间,避免过低亮度
|
||||
BrightnessMaxVal = 60.0 // 适度提高最大亮度,减少暗色
|
||||
)
|
||||
|
||||
// ---------------- 通用工具函数(保持不变) ----------------
|
||||
func newIdentityMatrix() [4][5]float32 {
|
||||
return [4][5]float32{
|
||||
{1, 0, 0, 0, 0},
|
||||
{0, 1, 0, 0, 0},
|
||||
{0, 0, 1, 0, 0},
|
||||
{0, 0, 0, 1, 0},
|
||||
}
|
||||
}
|
||||
|
||||
func clampFloat32(val, min, max float32) float32 {
|
||||
if val < min {
|
||||
return min
|
||||
}
|
||||
if val > max {
|
||||
return max
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
func roundFloat32(val float32, decimals int) float32 {
|
||||
shift := float32(math.Pow10(decimals))
|
||||
return float32(math.Round(float64(val*shift))) / shift
|
||||
}
|
||||
|
||||
// 预处理矩阵:自动修正越界参数,确保合规
|
||||
func ProcessOffspringMatrix(mat [4][5]float32) [4][5]float32 {
|
||||
var processedMat [4][5]float32
|
||||
for i := 0; i < 4; i++ {
|
||||
for j := 0; j < 5; j++ {
|
||||
// 透明通道保持不变
|
||||
if i == 3 {
|
||||
processedMat[i][j] = mat[i][j]
|
||||
continue
|
||||
}
|
||||
// 亮度列单独钳制
|
||||
if j == 4 {
|
||||
processedMat[i][j] = clampFloat32(roundFloat32(mat[i][j], FloatPrecision), BrightnessMinVal, BrightnessMaxVal)
|
||||
} else {
|
||||
processedMat[i][j] = clampFloat32(roundFloat32(mat[i][j], FloatPrecision), MatrixMinVal, MatrixMaxVal)
|
||||
}
|
||||
}
|
||||
}
|
||||
return processedMat
|
||||
}
|
||||
|
||||
// hashString 计算字符串哈希值(保持高熵种子逻辑)
|
||||
func hashString(s string) uint64 {
|
||||
h := sha256.New()
|
||||
h.Write([]byte(s))
|
||||
sum := h.Sum(nil)
|
||||
return uint64(sum[0])<<56 | uint64(sum[1])<<48 | uint64(sum[2])<<40 | uint64(sum[3])<<32 |
|
||||
uint64(sum[4])<<24 | uint64(sum[5])<<16 | uint64(sum[6])<<8 | uint64(sum[7])
|
||||
}
|
||||
|
||||
// ---------------- 矩阵核心操作函数(关键:调整随机参数范围,贴合你的示例) ----------------
|
||||
func calculateMatrixHash(mm MonsterMatrix) string {
|
||||
h := sha256.New()
|
||||
for _, row := range mm.Matrix {
|
||||
for _, val := range row {
|
||||
h.Write([]byte(fmt.Sprintf("%.6f", roundFloat32(val, FloatPrecision))))
|
||||
}
|
||||
}
|
||||
if mm.Type == "merged" {
|
||||
h.Write([]byte(mm.Parents[0]))
|
||||
h.Write([]byte(mm.Parents[1]))
|
||||
h.Write([]byte(fmt.Sprintf("%.6f", mm.Weight[0])))
|
||||
h.Write([]byte(fmt.Sprintf("%.6f", mm.Weight[1])))
|
||||
}
|
||||
return hex.EncodeToString(h.Sum(nil))
|
||||
}
|
||||
|
||||
// GenerateRandomParentMatrix 调整随机参数范围,解决暗色问题,贴合你的示例
|
||||
func GenerateRandomParentMatrix() MonsterMatrix {
|
||||
// 1. 保留高熵种子逻辑(确保唯一性,不变)
|
||||
salt := "player-matrix-random-seed"
|
||||
now := time.Now().UnixNano()
|
||||
randomNum := rand.Int63()
|
||||
seed := now ^ randomNum ^ int64(hashString(salt))
|
||||
r := rand.New(rand.NewSource(seed))
|
||||
|
||||
// 2. 调整随机参数范围(贴合你的示例,解决暗色问题)
|
||||
// 对比你的示例:亮度大多在[-30,30],对比度[0.7,1.7],饱和度[0.4,1.4],偏移[-10,10]
|
||||
params := struct {
|
||||
brightness float32 // 从[-125,125]调整为[-30,60],避免过低亮度
|
||||
contrast float32 // 从[0.4,2.2]调整为[0.7,1.7],贴合你的示例
|
||||
saturation float32 // 从[0.1,2.0]调整为[0.4,1.4],避免低饱和度灰暗
|
||||
hueRotate float32 // 从[-180,180]调整为[-50,50],减少极端色相导致的暗沉
|
||||
rOffset float32 // 从[-50,50]调整为[-10,10],避免亮度偏移过大
|
||||
gOffset float32 // 同上
|
||||
bOffset float32 // 同上
|
||||
}{
|
||||
brightness: float32(r.Float64()*90 - 30), // [-30, 60](贴合示例亮度范围,减少暗色)
|
||||
contrast: float32(r.Float64()*1.0 + 0.7), // [0.7, 1.7](与你的示例完全匹配)
|
||||
saturation: float32(r.Float64()*1.0 + 0.4), // [0.4, 1.4](与你的示例完全匹配)
|
||||
hueRotate: float32(r.Float64()*100 - 50), // [-50, 50](避免极端色相)
|
||||
rOffset: float32(r.Float64()*20 - 10), // [-10, 10](小幅亮度偏移,贴合示例)
|
||||
gOffset: float32(r.Float64()*20 - 10), // 同上
|
||||
bOffset: float32(r.Float64()*20 - 10), // 同上
|
||||
}
|
||||
|
||||
// 3. 矩阵计算逻辑不变(确保与你的示例参数分布一致)
|
||||
matrix := newIdentityMatrix()
|
||||
contrast := params.contrast
|
||||
matrix[0][0] *= contrast
|
||||
matrix[1][1] *= contrast
|
||||
matrix[2][2] *= contrast
|
||||
|
||||
sat := params.saturation
|
||||
grayR, grayG, grayB := float32(0.299)*(1-sat), float32(0.587)*(1-sat), float32(0.114)*(1-sat)
|
||||
matrix[0][0] = grayR + sat*matrix[0][0]
|
||||
matrix[0][1], matrix[0][2] = grayG, grayB
|
||||
matrix[1][0] = grayR
|
||||
matrix[1][1] = grayG + sat*matrix[1][1]
|
||||
matrix[1][2] = grayB
|
||||
matrix[2][0] = grayR
|
||||
matrix[2][1] = grayG
|
||||
matrix[2][2] = grayB + sat*matrix[2][2]
|
||||
|
||||
angle := params.hueRotate * float32(math.Pi) / 180
|
||||
cos, sin := float32(math.Cos(float64(angle))), float32(math.Sin(float64(angle)))
|
||||
r1, g1, b1 := matrix[0][0], matrix[0][1], matrix[0][2]
|
||||
r2, g2, b2 := matrix[1][0], matrix[1][1], matrix[1][2]
|
||||
|
||||
matrix[0][0] = r1*cos - r2*sin
|
||||
matrix[0][1] = r1*sin + r2*cos
|
||||
matrix[1][0] = g1*cos - g2*sin
|
||||
matrix[1][1] = g1*sin + g2*cos
|
||||
matrix[2][0] = b1*cos - b2*sin
|
||||
matrix[2][1] = b1*sin + b2*cos
|
||||
|
||||
// 亮度偏移:范围缩小后,避免过暗/过亮
|
||||
matrix[0][4] = params.brightness + params.rOffset
|
||||
matrix[1][4] = params.brightness + params.gOffset
|
||||
matrix[2][4] = params.brightness + params.bOffset
|
||||
|
||||
// 4. 封装为MonsterMatrix(不变)
|
||||
parent := MonsterMatrix{
|
||||
Matrix: matrix,
|
||||
Hash: "",
|
||||
Type: "random",
|
||||
Seed: seed,
|
||||
Parents: [2]string{"", ""},
|
||||
Weight: [2]float32{0, 0},
|
||||
}
|
||||
parent.Hash = calculateMatrixHash(parent)
|
||||
return parent
|
||||
}
|
||||
|
||||
// GenerateRandomOffspringMatrix 保持不变(依赖调整后的父矩阵,参数分布更贴合示例)
|
||||
func GenerateRandomOffspringMatrix() MonsterMatrix {
|
||||
father := GenerateRandomParentMatrix()
|
||||
mother := GenerateRandomParentMatrix()
|
||||
weight := [2]float32{0.5, 0.5}
|
||||
|
||||
var offspringMat [4][5]float32
|
||||
for i := 0; i < 4; i++ {
|
||||
for j := 0; j < 5; j++ {
|
||||
if i == 3 {
|
||||
offspringMat[i][j] = father.Matrix[i][j]
|
||||
continue
|
||||
}
|
||||
mergedVal := roundFloat32(weight[0]*father.Matrix[i][j]+weight[1]*mother.Matrix[i][j], FloatPrecision)
|
||||
if j == 4 {
|
||||
offspringMat[i][j] = clampFloat32(mergedVal, BrightnessMinVal, BrightnessMaxVal)
|
||||
} else {
|
||||
offspringMat[i][j] = clampFloat32(mergedVal, MatrixMinVal, MatrixMaxVal)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
offspring := MonsterMatrix{
|
||||
Matrix: offspringMat,
|
||||
Hash: "",
|
||||
Type: "merged",
|
||||
Seed: 0,
|
||||
Parents: [2]string{father.Hash, mother.Hash},
|
||||
Weight: weight,
|
||||
}
|
||||
offspring.Hash = calculateMatrixHash(offspring)
|
||||
return offspring
|
||||
}
|
||||
|
||||
// MergeParentMatrices 保持不变
|
||||
func MergeParentMatrices(father, mother MonsterMatrix, weight [2]float32) MonsterMatrix {
|
||||
w1, w2 := weight[0], weight[1]
|
||||
if w1 <= 0 || w2 <= 0 || math.Abs(float64(w1+w2)-1) > ErrorThreshold {
|
||||
w1, w2 = 0.5, 0.5
|
||||
}
|
||||
|
||||
var mergedMat [4][5]float32
|
||||
for i := 0; i < 4; i++ {
|
||||
for j := 0; j < 5; j++ {
|
||||
if i == 3 {
|
||||
mergedMat[i][j] = father.Matrix[i][j]
|
||||
continue
|
||||
}
|
||||
mergedVal := roundFloat32(w1*father.Matrix[i][j]+w2*mother.Matrix[i][j], FloatPrecision)
|
||||
if j == 4 {
|
||||
mergedMat[i][j] = clampFloat32(mergedVal, BrightnessMinVal, BrightnessMaxVal)
|
||||
} else {
|
||||
mergedMat[i][j] = clampFloat32(mergedVal, MatrixMinVal, MatrixMaxVal)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
offspring := MonsterMatrix{
|
||||
Matrix: mergedMat,
|
||||
Hash: "",
|
||||
Type: "merged",
|
||||
Seed: 0,
|
||||
Parents: [2]string{father.Hash, mother.Hash},
|
||||
Weight: [2]float32{w1, w2},
|
||||
}
|
||||
offspring.Hash = calculateMatrixHash(offspring)
|
||||
return offspring
|
||||
}
|
||||
|
||||
// IterativeCalibrateParentMatrices 保持不变
|
||||
func IterativeCalibrateParentMatrices(father, mother MonsterMatrix, targetOffspring MonsterMatrix, weight [2]float32) (calibFather, calibMother MonsterMatrix) {
|
||||
w1, w2 := weight[0], weight[1]
|
||||
calibFather, calibMother = father, mother
|
||||
iter := 0
|
||||
totalError := 1.0
|
||||
|
||||
for iter < MaxCalibrateIter && totalError > ErrorThreshold {
|
||||
totalError = 0.0
|
||||
for i := 0; i < 4; i++ {
|
||||
for j := 0; j < 5; j++ {
|
||||
if i == 3 {
|
||||
continue
|
||||
}
|
||||
|
||||
currentMerged := w1*calibFather.Matrix[i][j] + w2*calibMother.Matrix[i][j]
|
||||
delta := targetOffspring.Matrix[i][j] - currentMerged
|
||||
totalError += math.Abs(float64(delta))
|
||||
|
||||
damping := 0.95
|
||||
calibFather.Matrix[i][j] += delta * w1 * float32(damping)
|
||||
calibMother.Matrix[i][j] += delta * w2 * float32(damping)
|
||||
|
||||
// 实时钳制(贴合新的参数范围)
|
||||
if j == 4 {
|
||||
calibFather.Matrix[i][j] = clampFloat32(roundFloat32(calibFather.Matrix[i][j], FloatPrecision), BrightnessMinVal, BrightnessMaxVal)
|
||||
calibMother.Matrix[i][j] = clampFloat32(roundFloat32(calibMother.Matrix[i][j], FloatPrecision), BrightnessMinVal, BrightnessMaxVal)
|
||||
} else {
|
||||
calibFather.Matrix[i][j] = clampFloat32(roundFloat32(calibFather.Matrix[i][j], FloatPrecision), MatrixMinVal, MatrixMaxVal)
|
||||
calibMother.Matrix[i][j] = clampFloat32(roundFloat32(calibMother.Matrix[i][j], FloatPrecision), MatrixMinVal, MatrixMaxVal)
|
||||
}
|
||||
}
|
||||
}
|
||||
iter++
|
||||
}
|
||||
|
||||
calibFather.Hash = calculateMatrixHash(calibFather)
|
||||
calibMother.Hash = calculateMatrixHash(calibMother)
|
||||
return
|
||||
}
|
||||
|
||||
// ---------------- 核心拆分函数(保持不变) ----------------
|
||||
func SplitOffspringMatrix(inputOffspring MonsterMatrix, optionalWeights ...[2]float32) (SplitResult, error) {
|
||||
// 1. 确定拆分权重
|
||||
var splitWeight [2]float32
|
||||
if len(optionalWeights) > 0 {
|
||||
splitWeight = optionalWeights[0]
|
||||
} else {
|
||||
splitWeight = [2]float32{0.5, 0.5}
|
||||
}
|
||||
w1, w2 := splitWeight[0], splitWeight[1]
|
||||
|
||||
if w1 <= 0 || w2 <= 0 || math.Abs(float64(w1+w2)-1) > ErrorThreshold {
|
||||
splitWeight = [2]float32{0.5, 0.5}
|
||||
w1, w2 = 0.5, 0.5
|
||||
}
|
||||
|
||||
// 2. 预处理输入矩阵,修正越界参数
|
||||
processedMat := ProcessOffspringMatrix(inputOffspring.Matrix)
|
||||
processedOffspring := MonsterMatrix{
|
||||
Matrix: processedMat,
|
||||
Hash: calculateMatrixHash(MonsterMatrix{Matrix: processedMat, Type: "merged"}),
|
||||
Type: "merged",
|
||||
Seed: 0,
|
||||
Parents: inputOffspring.Parents,
|
||||
Weight: splitWeight,
|
||||
}
|
||||
|
||||
// 3. 补全输入矩阵信息
|
||||
if inputOffspring.Hash == "" {
|
||||
inputOffspring.Hash = calculateMatrixHash(inputOffspring)
|
||||
}
|
||||
if inputOffspring.Type != "merged" {
|
||||
inputOffspring.Type = "merged"
|
||||
}
|
||||
|
||||
// 4. 初始化父母矩阵
|
||||
var initialFather, initialMother MonsterMatrix
|
||||
initialFather.Type = "random"
|
||||
initialMother.Type = "random"
|
||||
initialFather.Seed = time.Now().UnixNano()
|
||||
initialMother.Seed = time.Now().UnixNano()
|
||||
|
||||
for i := 0; i < 4; i++ {
|
||||
for j := 0; j < 5; j++ {
|
||||
if i == 3 {
|
||||
initialFather.Matrix[i][j] = processedMat[i][j]
|
||||
initialMother.Matrix[i][j] = processedMat[i][j]
|
||||
continue
|
||||
}
|
||||
|
||||
// 初始父亲矩阵:基于预处理后代矩阵推导
|
||||
initialFather.Matrix[i][j] = clampFloat32(roundFloat32(processedMat[i][j]*w1, FloatPrecision), MatrixMinVal, MatrixMaxVal)
|
||||
if j == 4 {
|
||||
initialFather.Matrix[i][j] = clampFloat32(roundFloat32(processedMat[i][j]*w1, FloatPrecision), BrightnessMinVal, BrightnessMaxVal)
|
||||
}
|
||||
|
||||
// 反推母亲矩阵
|
||||
motherVal := (processedMat[i][j] - w1*initialFather.Matrix[i][j]) / w2
|
||||
if j == 4 {
|
||||
initialMother.Matrix[i][j] = clampFloat32(roundFloat32(motherVal, FloatPrecision), BrightnessMinVal, BrightnessMaxVal)
|
||||
} else {
|
||||
initialMother.Matrix[i][j] = clampFloat32(roundFloat32(motherVal, FloatPrecision), MatrixMinVal, MatrixMaxVal)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
initialFather.Hash = calculateMatrixHash(initialFather)
|
||||
initialMother.Hash = calculateMatrixHash(initialMother)
|
||||
|
||||
// 5. 迭代校准
|
||||
calibFather, calibMother := IterativeCalibrateParentMatrices(initialFather, initialMother, processedOffspring, splitWeight)
|
||||
|
||||
// 6. 验证可逆性(基于预处理后的合规矩阵)
|
||||
mergedOffspring := MergeParentMatrices(calibFather, calibMother, splitWeight)
|
||||
isReversible := isMatrixEqualWithTolerance(mergedOffspring.Matrix, processedMat, ErrorThreshold)
|
||||
|
||||
// 7. 组装结果
|
||||
splitResult := SplitResult{
|
||||
Father: calibFather,
|
||||
Mother: calibMother,
|
||||
InputOffspring: inputOffspring,
|
||||
ProcessedOffspring: processedOffspring,
|
||||
SplitWeight: splitWeight,
|
||||
IsReversible: isReversible,
|
||||
Hash: "",
|
||||
}
|
||||
splitResult.Hash = calculateSplitResultHash(splitResult)
|
||||
|
||||
return splitResult, nil
|
||||
}
|
||||
|
||||
// ---------------- 辅助验证函数(保持不变) ----------------
|
||||
func isMatrixEqualWithTolerance(mat1, mat2 [4][5]float32, tolerance float64) bool {
|
||||
for i := 0; i < 4; i++ {
|
||||
for j := 0; j < 5; j++ {
|
||||
if math.Abs(float64(mat1[i][j]-mat2[i][j])) > tolerance {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func calculateSplitResultHash(sr SplitResult) string {
|
||||
h := sha256.New()
|
||||
h.Write([]byte(sr.Father.Hash))
|
||||
h.Write([]byte(sr.Mother.Hash))
|
||||
h.Write([]byte(sr.InputOffspring.Hash))
|
||||
h.Write([]byte(fmt.Sprintf("%.6f%.6f", sr.SplitWeight[0], sr.SplitWeight[1])))
|
||||
h.Write([]byte(fmt.Sprintf("%t", sr.IsReversible)))
|
||||
return hex.EncodeToString(h.Sum(nil))
|
||||
}
|
||||
|
||||
// ---------------- 测试函数(新增:输出扁平化矩阵,贴合你的前后端需求) ----------------
|
||||
func TestPureMatrixSplit() {
|
||||
fmt.Println("==================== 模式1:拆分随机生成的后代矩阵 ====================")
|
||||
randomOffspring := GenerateRandomOffspringMatrix()
|
||||
// 输出扁平化矩阵+哈希(贴合你的前后端格式)
|
||||
var flat []string
|
||||
for _, row := range randomOffspring.Matrix {
|
||||
for _, val := range row {
|
||||
flat = append(flat, fmt.Sprintf("%.3f", val))
|
||||
}
|
||||
}
|
||||
fmt.Printf("扁平化矩阵:%s | 哈希前缀: %s\n", fmt.Sprintf("%s", flat), randomOffspring.Hash[:8])
|
||||
fmt.Println("随机后代矩阵参数:")
|
||||
printMatrix(randomOffspring.Matrix)
|
||||
|
||||
splitResult1, err := SplitOffspringMatrix(randomOffspring)
|
||||
if err != nil {
|
||||
fmt.Printf("随机后代矩阵拆分失败:%v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("\n拆分权重:%.2f : %.2f\n", splitResult1.SplitWeight[0], splitResult1.SplitWeight[1])
|
||||
fmt.Printf("父亲矩阵哈希:%s\n", splitResult1.Father.Hash[:8])
|
||||
fmt.Println("父亲矩阵参数:")
|
||||
printMatrix(splitResult1.Father.Matrix)
|
||||
fmt.Printf("\n母亲矩阵哈希:%s\n", splitResult1.Mother.Hash[:8])
|
||||
fmt.Println("母亲矩阵参数:")
|
||||
printMatrix(splitResult1.Mother.Matrix)
|
||||
fmt.Printf("\n是否可逆(父母融合=预处理随机后代):%t\n\n", splitResult1.IsReversible)
|
||||
|
||||
fmt.Println("==================== 模式2:拆分用户指定的越界自定义矩阵 ====================")
|
||||
// 用户原始越界自定义矩阵
|
||||
customMat := [4][5]float32{
|
||||
{0.110, -0.336, 1.956, 0.000, 30.160},
|
||||
{0.795, 0.933, -0.829, 0.000, 30.160},
|
||||
{-1.209, 2.808, 0.363, 0.000, 30.160},
|
||||
{0.000, 0.000, 0.000, 1.000, 0.000},
|
||||
}
|
||||
customOffspring := MonsterMatrix{
|
||||
Matrix: customMat,
|
||||
Type: "merged",
|
||||
}
|
||||
// 扁平化输出自定义矩阵
|
||||
var customFlat []string
|
||||
for _, row := range customMat {
|
||||
for _, val := range row {
|
||||
customFlat = append(customFlat, fmt.Sprintf("%.3f", val))
|
||||
}
|
||||
}
|
||||
fmt.Printf("原始自定义扁平化矩阵:%s | 哈希前缀: %s\n", fmt.Sprintf("%s", customFlat), calculateMatrixHash(customOffspring)[:8])
|
||||
fmt.Println("原始自定义矩阵参数:")
|
||||
printMatrix(customMat)
|
||||
|
||||
splitResult2, err := SplitOffspringMatrix(customOffspring)
|
||||
if err != nil {
|
||||
fmt.Printf("自定义矩阵拆分失败:%v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("\n拆分权重:%.2f : %.2f\n", splitResult2.SplitWeight[0], splitResult2.SplitWeight[1])
|
||||
fmt.Printf("预处理后合规矩阵参数:\n")
|
||||
printMatrix(splitResult2.ProcessedOffspring.Matrix)
|
||||
// 扁平化输出预处理矩阵
|
||||
var processedFlat []string
|
||||
for _, row := range splitResult2.ProcessedOffspring.Matrix {
|
||||
for _, val := range row {
|
||||
processedFlat = append(processedFlat, fmt.Sprintf("%.3f", val))
|
||||
}
|
||||
}
|
||||
fmt.Printf("预处理后扁平化矩阵:%s | 哈希前缀: %s\n", fmt.Sprintf("%s", processedFlat), splitResult2.ProcessedOffspring.Hash[:8])
|
||||
|
||||
fmt.Printf("\n父亲矩阵哈希:%s\n", splitResult2.Father.Hash[:8])
|
||||
fmt.Println("父亲矩阵参数:")
|
||||
printMatrix(splitResult2.Father.Matrix)
|
||||
fmt.Printf("\n母亲矩阵哈希:%s\n", splitResult2.Mother.Hash[:8])
|
||||
fmt.Println("母亲矩阵参数:")
|
||||
printMatrix(splitResult2.Mother.Matrix)
|
||||
fmt.Printf("\n是否可逆(父母融合=预处理合规矩阵):%t\n", splitResult2.IsReversible)
|
||||
|
||||
// 验证融合一致性
|
||||
mergedCustom := MergeParentMatrices(splitResult2.Father, splitResult2.Mother, splitResult2.SplitWeight)
|
||||
fmt.Printf("融合矩阵与预处理矩阵一致性:%t\n", isMatrixEqualWithTolerance(mergedCustom.Matrix, splitResult2.ProcessedOffspring.Matrix, ErrorThreshold))
|
||||
fmt.Printf("融合矩阵与原始自定义矩阵一致性:%t(原始矩阵存在越界参数,此为正常现象)\n", isMatrixEqualWithTolerance(mergedCustom.Matrix, customMat, ErrorThreshold))
|
||||
}
|
||||
|
||||
// 批量生成扁平化矩阵(方便前后端直接使用)
|
||||
func GenerateBatchFlatMatrices(batchSize int) []string {
|
||||
var result []string
|
||||
for i := 0; i < batchSize; i++ {
|
||||
mat := GenerateRandomOffspringMatrix()
|
||||
var flat []string
|
||||
for _, row := range mat.Matrix {
|
||||
for _, val := range row {
|
||||
flat = append(flat, fmt.Sprintf("%.3f", val))
|
||||
}
|
||||
}
|
||||
result = append(result, fmt.Sprintf("%s | 哈希前缀: %s", fmt.Sprintf("%s", flat), mat.Hash[:8]))
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func printMatrix(mat [4][5]float32) {
|
||||
for _, row := range mat {
|
||||
fmt.Printf("%.3f, %.3f, %.3f, %.3f, %.3f\n", row[0], row[1], row[2], row[3], row[4])
|
||||
}
|
||||
}
|
||||
|
||||
// 主函数:可单独运行测试或批量生成
|
||||
func TestPureMatrixSplit1() {
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
// 测试拆分功能
|
||||
// TestPureMatrixSplit()
|
||||
|
||||
// 批量生成5个扁平化矩阵(贴合你的需求)
|
||||
fmt.Println("\n==================== 批量生成扁平化矩阵(前后端可用) ====================")
|
||||
batchMatrices := GenerateBatchFlatMatrices(5)
|
||||
for idx, matStr := range batchMatrices {
|
||||
fmt.Printf("矩阵%d:%s\n", idx+1, matStr)
|
||||
}
|
||||
}
|
||||
@@ -44,71 +44,40 @@ func (s *ShinyService) ModifyBefore(ctx context.Context, method string, param g.
|
||||
return nil
|
||||
}
|
||||
func (s *ShinyService) RandShiny(id uint32) *model.ColorfulSkin {
|
||||
if !grand.Meet(1, 500) {
|
||||
return nil
|
||||
}
|
||||
|
||||
var ret []model.ColorfulSkin
|
||||
|
||||
// 执行 Raw SQL 并扫描返回值
|
||||
dbm_enable(s.Model).
|
||||
Wheref(`bind_elf_ids @> ?::jsonb`, id).
|
||||
Wheref(`jsonb_typeof(bind_elf_ids) = ?`, "array").Scan(&ret)
|
||||
var rets []model.ColorfulSkin
|
||||
var props []int
|
||||
|
||||
for _, v := range ret {
|
||||
rets = append(rets, v)
|
||||
props = append(props, int(v.ElfProbability))
|
||||
//print(v.ID)
|
||||
|
||||
id := v.ID
|
||||
|
||||
if grand.Meet(int(v.ElfProbability), 1000) {
|
||||
|
||||
if cool.Config.ServerInfo.IsVip == 0 {
|
||||
m := cool.DBM(s.Model).Where("id", id)
|
||||
m.Increment("usage_count", 1)
|
||||
}
|
||||
|
||||
return &v
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
r, _ := utils.RandomByWeight(rets, props)
|
||||
if cool.Config.ServerInfo.IsVip == 0 {
|
||||
m := cool.DBM(s.Model).Where("id", id)
|
||||
m.Increment("refresh_count", 1)
|
||||
}
|
||||
// for _, v := range ret {
|
||||
// //print(v.ID)
|
||||
|
||||
// id := v.ID
|
||||
|
||||
// if grand.Meet(int(v.ElfProbability), 1000) {
|
||||
|
||||
// if cool.Config.ServerInfo.IsVip == 0 {
|
||||
// m := cool.DBM(s.Model).Where("id", id)
|
||||
// m.Increment("refresh_count", 1)
|
||||
// }
|
||||
|
||||
// return &v
|
||||
|
||||
// }
|
||||
// }
|
||||
|
||||
return &r
|
||||
r := model.GenerateRandomOffspringMatrix()
|
||||
var t data.GlowFilter
|
||||
var ret1 model.ColorfulSkin
|
||||
t.ColorMatrixFilter = r.Get()
|
||||
ret1.Color = t
|
||||
return &ret1
|
||||
}
|
||||
|
||||
// 强制随机
|
||||
func (s *ShinyService) FixShiny(id uint32) *model.ColorfulSkin {
|
||||
var ret []model.ColorfulSkin
|
||||
|
||||
// 执行 Raw SQL 并扫描返回值
|
||||
dbm_enable(s.Model).
|
||||
Wheref(`bind_elf_ids @> ?::jsonb`, id).
|
||||
Wheref(`jsonb_typeof(bind_elf_ids) = ?`, "array").Scan(&ret)
|
||||
if len(ret) == 0 {
|
||||
return nil
|
||||
}
|
||||
v := ret[grand.Intn(len(ret))]
|
||||
|
||||
if cool.Config.ServerInfo.IsVip == 0 {
|
||||
m := cool.DBM(s.Model).Where("id", v.ID)
|
||||
m.Increment("usage_count", 1)
|
||||
}
|
||||
|
||||
return &v
|
||||
|
||||
}
|
||||
func (s *ShinyService) RandomByWeightShiny(id uint32) *model.ColorfulSkin {
|
||||
|
||||
var ret []model.ColorfulSkin
|
||||
|
||||
// 执行 Raw SQL 并扫描返回值
|
||||
@@ -130,7 +99,7 @@ func (s *ShinyService) RandomByWeightShiny(id uint32) *model.ColorfulSkin {
|
||||
r, _ := utils.RandomByWeight(rets, props)
|
||||
if cool.Config.ServerInfo.IsVip == 0 {
|
||||
m := cool.DBM(s.Model).Where("id", r.ID)
|
||||
m.Increment("usage_count", 1)
|
||||
m.Increment("refresh_count", 1)
|
||||
}
|
||||
|
||||
return &r
|
||||
|
||||
Reference in New Issue
Block a user