2026-02-17 22:53:45 +08:00
|
|
|
|
package model
|
2025-12-21 17:18:33 +00:00
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|