24小时热门版块排行榜    

查看: 3847  |  回复: 19
【奖励】 本帖被评价11次,作者cttsyauchina增加金币 8
当前只显示满足指定条件的回帖,点击这里查看本话题的所有回帖

cttsyauchina

木虫 (小有名气)


[资源] 【PSO】粒子群算法,大家接触多少? Particle Swarm Optimization for everyone

Threshold Regressive Model,简称TR,是 Kennedy 和 Eberhart 受鸟群觅食行为的启发,于 1995 年在美国提出来的,是一种随机全局优化算法。PSO具有收敛速度快,设置参数少,简单容易实现且功能强大等特点,自提出后短短几年的时间便获得很大的发展,在有关进化计算、神经网络以及人工智能诸多领域获得了广泛的应用。但由于计算过于复杂,PSO在国内应用或多或少受到限制。
      前一段刚把这块编出来, 论文也发表,在这儿我也把源代码贴出来,供大家分享!

粒子算法界面图
CODE:
Imports System.Math
Public Class Form1
  Dim Datas() As Single
  Dim Rnd As New System.Random
  Dim Vmin, Vmax As Double
  Dim StepNumber As Integer
  Dim ParticleNumber As Integer
  Dim ThresholdNumber As Integer
  Dim isOnePosition As Boolean
  Dim answers As New List(Of FnAndPos)
  Private Structure FnAndPos
    Dim F As Double
    Dim pos As Thresholds
    Public Function Clone() As FnAndPos
      Dim copy As New FnAndPos
      copy.F = F
      copy.pos = Me.pos.clone
      Return copy
    End Function
  End Structure
  Private Sub init()
    readDatas()
    ParticleNumber = Integer.Parse(TextBox2.Text.Trim)
    StepNumber = Integer.Parse(TextBox3.Text.Trim)
    ThresholdNumber = Integer.Parse(TextBox4.Text.Trim)
    isOnePosition = CheckBox1.Checked
    Vmax = Datas.Length * Rnd.Next(200, 1000) / 2000
    Vmin = -Vmax
  End Sub
  Sub readDatas()
    Dim dataList As New List(Of Single)
    For Each line As String In TextBox1.Lines
      Dim Temp As Single = 0
      If Single.TryParse(line.Trim, Temp) Then
        dataList.Add(Temp)
      End If
    Next
    Datas = dataList.ToArray
  End Sub

  Private Sub VAdjusting(ByRef nextV() As Thresholds)
    Dim i, j As Integer
    For i = 0 To nextV.Length - 1
      For j = 0 To nextV(i).Count - 1
        If nextV(i)(j) < Vmin Then nextV(i)(j) = Vmin
        If nextV(i)(j) > Vmax Then nextV(i)(j) = Vmax
      Next
    Next

  End Sub
  Private Sub XAdjusting(ByRef nextX() As Thresholds)
    Dim i, j As Integer
    For i = 0 To nextX.Length - 1
      For j = 0 To nextX(i).Count - 1
        If nextX(i)(j) <= 0 Then nextX(i)(j) = 1
        If nextX(i)(j) > Datas.Length - 1 Then nextX(i)(j) = Datas.Length - 1
      Next
    Next
  End Sub
  Private Function getNextV(ByVal currentV() As Thresholds, ByVal currentPBests() As FnAndPos, ByVal currentGBest As FnAndPos, ByVal currentX() As Thresholds) As Thresholds()
    Dim result(currentV.Length - 1) As Thresholds
    Dim i As Integer = 0
    Dim c1 As Double = 2, c2 As Double = 2 '加速度都取2
    Dim r1 As Double = Rnd.NextDouble
    Dim r2 As Double = Rnd.NextDouble
    For i = 0 To currentV.Length - 1
      result(i) = currentV(i) + c1 * r1 * (currentPBests(i).pos - currentX(i)) + c2 * r2 * (currentGBest.pos - currentX(i))
    Next
    VAdjusting(result)
    Return result
  End Function
  Private Function getNextX(ByVal currentX() As Thresholds, ByVal NextV() As Thresholds) As Thresholds()
    Dim result(currentX.Length - 1) As Thresholds
    For i As Integer = 0 To currentX.Length - 1
      result(i) = currentX(i) + NextV(i)
    Next
    XAdjusting(result)
    Return result
  End Function
  Private Function getFnandPos(ByVal currentX() As Thresholds) As FnAndPos()
    Dim average As Single = 0
    Dim V2 As Double = 0, S2(currentX.Count - 1) As Double, B2(currentX.Count - 1) As Double
    Dim result(currentX.Count - 1) As FnAndPos
    Dim t, i As Integer 't是指粒子数;i是指门限阈值个数
    For Each item As Single In Datas
      average += item
    Next
    average /= Datas.Length
    For Each item As Single In Datas
      V2 += (item - average) ^ 2
    Next
    For t = 0 To currentX.Count - 1
      With currentX(t)
        S2(t) += squareSum(0, .Item(0) - 1)
        For i = 0 To .Count - 2       '当阈值大于2时,运行此项。
          S2(t) += squareSum(.Item(i), .Item(i + 1) - 1)
        Next
        S2(t) += squareSum(.Item(.Count - 1), Datas.Length - 1)


        B2(t) = V2 - S2(t)
        result(t).F = B2(t) * (Datas.Length - .Count - 1) / (S2(t) * (.Count)) '注意公式查看
        result(t).pos = currentX(t)
      End With
    Next
    Return result
  End Function
  Private Function squareSum(ByVal startId As Integer, ByVal endId As Integer) As Double
    Dim average As Double = 0, sum As Double = 0
    If startId <= endId Then
      For i As Integer = startId To endId
        average += Datas(i)
      Next
      average /= Abs(endId - startId) + 1
      For i As Integer = startId To endId
        sum += (Datas(i) - average) ^ 2
      Next
    Else
      For i As Integer = startId To endId Step -1
        average += Datas(i)
      Next
      average /= Abs(endId - startId) + 1
      For i As Integer = startId To endId Step -1
        sum += (Datas(i) - average) ^ 2
      Next
    End If
    Return sum
  End Function
  Private Function pBest(ByVal oldPns() As FnAndPos, ByVal Xns() As FnAndPos) As FnAndPos()
    Dim i As Integer
    Dim result(oldPns.Length - 1) As FnAndPos
    For i = 0 To oldPns.Length - 1
      If Xns(i).F > oldPns(i).F Then
        result(i).F = Xns(i).F
        result(i).pos = Xns(i).pos
      Else
        result(i).F = oldPns(i).F
        result(i).pos = oldPns(i).pos
      End If
    Next
    Return result
  End Function
  Private Function gBest(ByVal gPbests() As FnAndPos) As FnAndPos
    Dim i As Integer, mmax As Double = Double.MinValue
    Dim result As FnAndPos = Nothing
    For i = 0 To gPbests.Length - 1
      If mmax < gPbests(i).F Then
        mmax = gPbests(i).F
        result.F = mmax
        result.pos = gPbests(i).pos
      End If
    Next
    Return result
  End Function

  Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
    Dim TBoxString As New System.Text.StringBuilder
    Dim answer As Boolean = False
    If TextBox1.Text = "" Then
      TextBox1.Text = "没有输入数据,请数据数据"
      TextBox1.SelectAll()
      TextBox1.Focus()
      Exit Sub
    End If
    For Each line As String In TextBox1.Lines
      Dim Temp As Single = 0
      If Single.TryParse(line.Trim, Temp) Then
        If TBoxString.Length <> 0 Then
          TBoxString.Append(vbCrLf & line.Trim)
        Else
          TBoxString.Append(line.Trim)
        End If
      Else
        If Not answer Then
          If MessageBox.Show("存在无效数据或空行,是否剔除?", "数据无效", MessageBoxButtons.YesNo, MessageBoxIcon.Question) = Windows.Forms.DialogResult.Yes Then
            answer = True
            Continue For
          Else
            Exit Sub
          End If
        End If
      End If
    Next
    TextBox1.Text = TBoxString.ToString
    TextBox1.Text.Trim()
    MessageBox.Show("检测成功!")
  End Sub

  Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    init()
    Dim currentX(ParticleNumber - 1), nextX(ParticleNumber - 1) As Thresholds
    Dim currentV(ParticleNumber - 1), nextV(ParticleNumber - 1) As Thresholds
    Dim currentPbest(ParticleNumber - 1), nextPbest(ParticleNumber - 1) As FnAndPos
    Dim currentGbest, nextGbest As FnAndPos
    Dim i, j As Integer
    answers.Clear()
    TextBox5.Clear()
    If isOnePosition Then
      Dim X0 As New Thresholds
      For j = 0 To ThresholdNumber - 1
        X0.Add(Rnd.Next(0, Datas.Length - 2) + 1) ' 设置每个粒子初始位置为(1,Datas.length-1)之间
      Next

      For i = 0 To ParticleNumber - 1
        currentV(i) = New Thresholds
        currentX(i) = New Thresholds
        For j = 0 To ThresholdNumber - 1
          currentV(i).Add((Rnd.NextDouble - 0.5) * Vmax) '速度
          currentX(i).Add(X0(j))
        Next
      Next
    Else
      For i = 0 To ParticleNumber - 1
        currentV(i) = New Thresholds
        currentX(i) = New Thresholds
        For j = 0 To ThresholdNumber - 1
          currentV(i).Add((Rnd.NextDouble - 0.5) * Vmax) '速度
          currentX(i).Add(Rnd.Next(0, Datas.Length - 2) + 1)
        Next
      Next
    End If
    currentPbest = getFnandPos(currentX)
    currentGbest = gBest(currentPbest)
    answers.Add(currentGbest)

    For i = 0 To StepNumber - 1
      nextV = getNextV(currentV, currentPbest, currentGbest, currentX)
      nextX = getNextX(currentX, nextV)
      nextPbest = pBest(currentPbest, getFnandPos(nextX))
      nextGbest = gBest(nextPbest)
      answers.Add(nextGbest)
      currentV = nextV.Clone
      currentX = nextX.Clone
      currentPbest = nextPbest.Clone
      currentGbest = nextGbest.Clone
    Next
    i = 0
    For Each item As FnAndPos In answers
      TextBox5.AppendText(String.Format("Step{0}({1}) F={2}{3}", i.ToString.PadRight(6), String.Join(",", item.pos.ToArray), item.F.ToString("F3"), vbCrLf))
      i += 1
    Next
  End Sub

  Private Sub TextBox1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles TextBox1.KeyDown
    If e.Control And e.KeyCode = Keys.A Then
      TextBox1.SelectAll()
    End If
  End Sub

  Structure Fpos
    Dim i As Integer
    Dim j As Integer
    Dim F As Double
  End Structure
  Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
    readDatas()
    Dim i, j As Integer
    Dim s2 As Double = 0
    Dim B2 As Double = 0
    Dim F As Double = 0
    Dim average As Double = 0
    Dim V2 As Double = 0
    Dim DataLength As Integer = Datas.Length
    Dim mMax As Double = Double.MinValue
    Dim mFpos As Fpos
    Dim dataList As New List(Of Fpos)
    For Each item As Single In Datas
      average += item
    Next
    average /= Datas.Length
    For Each item As Single In Datas
      V2 += (item - average) ^ 2
    Next


    For i = 0 To DataLength - 3
      For j = i + 1 To DataLength - 2
        s2 = squareSum(0, i) + squareSum(i + 1, j) + squareSum(j + 1, DataLength - 1)
        B2 = V2 - s2
        F = B2 * (Datas.Length - 2 - 1) / (s2 * 2)
        If F > mMax Then
          mMax = F
          mFpos.i = i
          mFpos.j = j
          mFpos.F = F
          dataList.Add(mFpos)
        End If
      Next
    Next
    'i = 37
    'j = 40
    's2 = squareSum(0, i) + squareSum(i, j) + squareSum(j, DataLength - 1)
    'B2 = V2 - s2
    'F = B2 * (Datas.Length - 2 - 1) / (s2 * 2)
    'MsgBox(F)
    For Each item As Fpos In dataList
      TextBox5.AppendText(String.Format("({0},{1}) F={2}" & vbCrLf, item.i, item.j, item.F.ToString("F4")))
    Next
  End Sub
  Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
  End Sub
End Class
‘%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
’构建Thresholds向量类
‘%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Public Class Thresholds
  Inherits List(Of Integer)
  Public Function clone() As Thresholds
    Dim a As New Thresholds   '复制问题
    a.InsertRange(0, Me)
    Return a
  End Function
  'Public Function Sort() As Thresholds
  '  Return MyBase.Sort
  'End Function
  Public Shared Operator +(ByVal A As Thresholds, ByVal B As Thresholds) As Thresholds
    Dim c As New Thresholds
    For i As Integer = 0 To A.Count - 1
      c.Add(A(i) + B(i))
    Next
    Return c
  End Operator
  Public Shared Operator -(ByVal A As Thresholds, ByVal B As Thresholds) As Thresholds
    Dim c As New Thresholds
    For i As Integer = 0 To A.Count - 1
      c.Add(A(i) - B(i))
    Next
    Return c
  End Operator
  Public Shared Operator *(ByVal A As Single, ByVal B As Thresholds) As Thresholds
    Dim c As New Thresholds
    For i As Integer = 0 To B.Count - 1
      c.Add(A * B(i))
    Next
    Return c
  End Operator
  Public Shared Operator *(ByVal A As Thresholds, ByVal B As Single) As Thresholds
    Dim c As New Thresholds
    For i As Integer = 0 To A.Count - 1
      c.Add(A(i) * B)
    Next
    Return c
  End Operator
End Class

[ Last edited by cttsyauchina on 2011-12-17 at 15:43 ]
回复此楼

» 收录本帖的淘帖专辑推荐

数学与算法等 杂货铺子 source 科研宝库

» 猜你喜欢

» 本主题相关价值贴推荐,对您同样有帮助:

» 抢金币啦!回帖就可以得到:

查看全部散金贴

已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

cttsyauchina

木虫 (小有名气)


cttsyauchina: 回帖置顶 2011-12-18 14:24:03
cttsyauchina: 取消置顶 2011-12-18 14:26:14
引用回帖:
2楼: Originally posted by yalefield at 2011-12-17 17:33:31:
写个C/C++语言版的发上回来吧。

C 交互性太差,而且没有.net方便
3楼2011-12-17 18:20:14
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖
查看全部 20 个回答

cttsyauchina(金币+1):谢谢参与
ben_ladeng: 专家考核+1 2011-12-17 17:53:52
写个C/C++语言版的发上回来吧。
2楼2011-12-17 17:33:31
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

nwwolfchj

金虫 (正式写手)


★★★★★ 五星级,优秀推荐


dubo: 金币+1, 欢迎讨论 2012-04-04 22:27:46
这个算法作高维度非线性优化可行不?实现方便不?
4楼2011-12-18 14:19:00
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖

cttsyauchina

木虫 (小有名气)



dubo: 金币+1, 欢迎讨论 2012-04-04 22:27:37
引用回帖:
4楼: Originally posted by nwwolfchj at 2011-12-18 14:19:00:
这个算法作高维度非线性优化可行不?实现方便不?

可行啊,如图门限个数就是你所说的维数。
5楼2011-12-18 14:26:01
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖
☆ 无星级 ★ 一星级 ★★★ 三星级 ★★★★★ 五星级
普通表情 高级回复 (可上传附件)
信息提示
请填处理意见