机房差不多就这样结束了,组合查询是我们学习机房系统时遇到的新的问题,但是一直没有总结,,,这两天一直在用两种方法解决组合查询,到今天为止,终于两种方法都突破了。很巧的是,这两种方法对于上周日米老师讲的局部最优法和全局最优法的就是一种完美呈现。
话不多说,看代码:
局部最优
Private Sub cmdInquiry_Click()
Dim txtSQL As String
Dim MsgText As String
Dim Mrc As ADODB.Recordset
'第一次条件查询
If Trim(ComboField1.Text) = "" Or Trim(ComboOpsign1.Text) = "" Or Trim(txtInquiryContent1.Text) = "" Then
MsgBox "请输入完整的查询条件!", vbInformation, "提示"
Exit Sub
End If
'连接worklog表,查询第一行的条件
txtSQL = "select * from worklog_Info where "
txtSQL = txtSQL & Fieldname(ComboField1.Text) & ComboOpsign1.Text & "'" & Trim(txtInquiryContent1.Text) & "'"
'第二次条件查询(第一次组合查询)
If Trim(comboCombineRelation1.Text <> "") Then
If Trim(ComboField2.Text) = "" Or Trim(ComboOpsign2.Text) = "" Or Trim(txtInquiryContent2.Text) = "" Then
MsgBox "您选择了第一个组合关系,请输入第二行条件再执行查询!", vbInformation, "提示"
Exit Sub
End If
'查询第一行和第二行的条件
txtSQL = txtSQL & Fieldname(comboCombineRelation1.Text) & " " & Fieldname(ComboField2.Text) & ComboOpsign2.Text & "'" & Trim(txtInquiryContent2.Text) & "'"
End If
'第三次查询(第二次组合查询)
If Trim(comboCombineRelation2.Text) <> "" Then
If Trim(ComboField3.Text) = "" Or Trim(ComboOpsign3.Text) = "" Or Trim(txtInquiryContent3.Text) = "" Then
MsgBox "您选择了第二个组合关系,请输入第三行条件再执行查询!", vbInformation, "提示"
Exit Sub
End If
'查询三行的条件
txtSQL = txtSQL & Fieldname(comboCombineRelation2.Text) & " " & Fieldname(ComboField3.Text) & ComboOpsign3.Text & "'" & Trim(txtInquiryContent3.Text) & "'"
End If
Set Mrc = ExecuteSQL(txtSQL, MsgText)
With MSHFlexGrid1 '显示查询内容
.Rows = 1
.CellAlignment = 4
.TextMatrix(0, 0) = "序列号"
.TextMatrix(0, 1) = "教师"
.TextMatrix(0, 2) = "级别"
.TextMatrix(0, 3) = "注册日期"
.TextMatrix(0, 4) = "注册时间"
.TextMatrix(0, 5) = "注销日期"
.TextMatrix(0, 6) = "注销时间"
.TextMatrix(0, 7) = "机器名"
.TextMatrix(0, 8) = "状态"
If Mrc.EOF Then
MsgBox "没有您要查找的操作员工作记录!", vbOKOnly + vbExclamation, "提示"
ComboField1.SetFocus
Exit Sub
Else '存在上机记录,填充表格
Do While Not Mrc.EOF
.Rows = .Rows + 1
.CellAlignment = 4
.TextMatrix(.Rows - 1, 0) = Mrc!serial
.TextMatrix(.Rows - 1, 1) = Mrc!userID
.TextMatrix(.Rows - 1, 2) = Mrc!Level
.TextMatrix(.Rows - 1, 3) = Mrc!LoginDate
.TextMatrix(.Rows - 1, 4) = Mrc!LoginTime
.TextMatrix(.Rows - 1, 5) = Mrc!LogoutDate & ""
.TextMatrix(.Rows - 1, 6) = Mrc!logoutTime & ""
.TextMatrix(.Rows - 1, 7) = Mrc!computer
.TextMatrix(.Rows - 1, 8) = Mrc!Status
Mrc.MoveNext
Loop
Mrc.Close
End If
End With
End Sub
顾名思义,局部最优可以保证每一步都是最优的,但是最终结果却不一定是最优的,尽管如此,当问题规模很大时,局部最优往往是一种简便可行的方法。另外对于代码程序,用局部最优的方法,可以省去很多麻烦,少写很多代码。
全局最优
Private Sub cmdInquiry_Click()全局最优,可以满足结果是最优的。
Dim txtSQL As String
Dim MsgText As String
txtSQL = "select * from worklog_Info where "
'第一次查询,判断第一行是否为空
If Trim(ComboField1.Text) = "" Or Trim(ComboOpsign1.Text) = "" Or Trim(txtInquiryContent1.Text) = "" Then
MsgBox "请输入完整的查询条件!", vbOKOnly + vbExclamation, "警告"
Exit Sub
End If
'全部判断,判断是否选择第一个组合关系
If Trim(comboCombineRelation1.Text) <> "" Then
If Trim(ComboField2.Text) = "" Or Trim(ComboOpsign2.Text) = "" Or Trim(txtInquiryContent2.Text) = "" Then
'MsgBox "您选择了第一个组合关系,请输入完整的第二行查询条件", vbOKOnly + vbExclamation, "警告"
Exit Sub
Else
'判断是否选择第二个组合关系
If Trim(comboCombineRelation2.Text) <> "" Then
If Trim(ComboField3.Text) = "" Or Trim(ComboOpsign3.Text) = "" Or Trim(txtInquiryContent3.Text) = "" Then
MsgBox "您选择了第二个组合关系,请输入第三行的查询条件!", vbOKOnly + vbExclamation, "警告"
Exit Sub
Else
'查询三行条件
txtSQL = txtSQL & Fieldname(ComboField1.Text) & ComboOpsign1.Text & "'" & Trim(txtInquiryContent1.Text) & "'"
txtSQL = txtSQL & Fieldname(comboCombineRelation1.Text) & " " & Fieldname(ComboField2.Text) & ComboOpsign2.Text & "'" & Trim(txtInquiryContent2.Text) & "'"
'txtSQL = txtSQL & ")" '"A or B and C"and比or先运算,加上()后就是(A or B)and C
txtSQL = txtSQL & Fieldname(comboCombineRelation2.Text) & " " & Fieldname(ComboField3.Text) & ComboOpsign3.Text & "'" & Trim(txtInquiryContent3.Text) & "'"
Set Mrc = ExecuteSQL(txtSQL, MsgText)
Call viewdate
End If
Else
'查询前两行条件
txtSQL = txtSQL & Fieldname(ComboField1.Text) & ComboOpsign1.Text & "'" & Trim(txtInquiryContent1.Text) & "'"
txtSQL = txtSQL & Fieldname(comboCombineRelation1.Text) & " " & Fieldname(ComboField2.Text) & ComboOpsign2.Text & "'" & Trim(txtInquiryContent2.Text) & "'"
'txtSQL = txtSQL & FiledName(comboRelation1.Text) & " " & FiledName(comboFiledName2.Text) & comboOperate2.Text & "'" & Trim(txtContent2.Text) & "'"
Set Mrc = ExecuteSQL(txtSQL, MsgText)
Call viewdate
End If
End If
Else
'查询第一行条件
txtSQL = txtSQL & Fieldname(ComboField1.Text) & ComboOpsign1.Text & "'" & Trim(txtInquiryContent1.Text) & "'"
'txtSQL = txtSQL & Fieldname(ComboField1.Text) & ComboOpsign1.Text & "'" & Trim(txtInquiryContent1.Text) & "'"
Set Mrc = ExecuteSQL(txtSQL, MsgText)
Call viewdate
End If
End Sub
Public Sub viewdate()
With MSHFlexGrid1
.Rows = 1
.CellAlignment = 4
.TextMatrix(0, 0) = "序列号"
.TextMatrix(0, 1) = "教师"
.TextMatrix(0, 2) = "级别"
.TextMatrix(0, 3) = "注册日期"
.TextMatrix(0, 4) = "注册时间"
.TextMatrix(0, 5) = "注销日期"
.TextMatrix(0, 6) = "注销时间"
.TextMatrix(0, 7) = "机器名"
.TextMatrix(0, 8) = "状态"
If Mrc.EOF Then
MsgBox "没有您要查询的学生基本信息!", vbOKOnly + vbExclamation, "提示"
ComboField1.SetFocus
End If
Do While Not Mrc.EOF
.Rows = .Rows + 1
.CellAlignment = 4
.TextMatrix(.Rows - 1, 0) = Mrc!serial
.TextMatrix(.Rows - 1, 1) = Mrc!userID
.TextMatrix(.Rows - 1, 2) = Mrc!Level
.TextMatrix(.Rows - 1, 3) = Mrc!LoginDate
.TextMatrix(.Rows - 1, 4) = Mrc!LoginTime
.TextMatrix(.Rows - 1, 5) = Mrc!LogoutDate & ""
.TextMatrix(.Rows - 1, 6) = Mrc!logoutTime & ""
.TextMatrix(.Rows - 1, 7) = Mrc!computer
.TextMatrix(.Rows - 1, 8) = Mrc!Status
Mrc.MoveNext
Loop
End With
End Sub
当问题规模很大时,想要找到全局最优必然是要浪费很大的精力,但是此时,局部最优不失为一种很好的方法。
另外,全局最优法逻辑性很强,需要考虑到每一个细节,由此也会带来一个问题,就是代码必然会比局部最优多。
拓展-分治法
上周日米老师还提到了分治法的思想
分治法可以通俗的解释为:把一片领土分解,分解为若干块小部分,然后一块块地占领征服,被分解的可以是不同的政治派别或是其他什么,然后让他们彼此异化。
分治法的精髓:
分--将问题分解为规模更小的子问题;
治--将这些规模更小的子问题逐个击破;
合--将已解决的子问题合并,最终得出"母"问题的解;
由此可以看出,分治法和局部最优解的思想是相同的,都是通过将整体分解成部分,然后各个击破,求出各部分的解,而整体的解就是各部分解的合并。
在计算机科学中,分治法是一种很重要的算法。这个技巧是很多高效算法的基础,如排序算法(快速排序,归并排序),傅立叶变换(快速傅立叶变换)……
在生活中,我们有时候会很迷茫,不能肯定自己将来能做什么,以及成为什么样的人,并将以什么方式去为之奋斗,但我们能做到的是珍惜时间,把握当下,走好人生中的每一步。因此,局部最优解也许可以成为我们生活中的最佳选择。