Project-OptimizationCounter

概述

  近段时间在学习Qt,所以利用这个小项目来熟悉下。OptimizationCounter由于寻找多项式的最小值点,将使用无约束优化方法有三种,目前仅实现了梯度下降方法,另外两种之后完成。
  项目源码地址:SuperYanyann/OptimizationCounter

软件简介

开发环境

  ubuntu 17.0
  Qt(Community)

软件界面

  主界面如下:
          主界面
  About标签的触发在”edit”菜单下:
                     主界面

使用方法

  在多项式前填写好系数,选择优化方法,包括梯度下降,牛顿方法,共轭方法。如果选择的是梯度下降方法,则需要填写两个参数:”epoch”为迭代的次数,最大值为“9999”,;”step”为迭代的步长,最小值为“0.00001”.之后点击”OK”,则在“Output”显示得到的最小值点。

测试

  设置一组系数,然后设置优化方法为梯度下降法,迭代次数为500,迭代步长为0.01,测试结果如下:
          主界面

实现简介

槽函数

  信号与槽是Qt开发的核心之一,这个项目使用了两次connect函数:第一次为”OK”按键按下的计算触发,第二次为“About”标签的菜单项触发:

1
2
connect(ui->certain,&QPushButton::clicked,this,&MainWindow::computeOptimization);
connect(ui->actionabout,&QAction::triggered,this,&MainWindow::displayAbout);

梯度下降

  计算过程中首先解决的问题是QString和double/int格式的转换问题,用到了QString类的toInt()和toDouble()方法,以及转变为QString的静态方法:QString::number()。
  由于优化对象为多项式,其导数格式已经确定,所以只要将导函数写出即可,具体代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// use to compute the min
void MainWindow::computeOptimization()
{
QString str_x5 = ui->lineEdit_X5->text();
int int_X5 = str_x5.toInt();
QString str_x4 = ui->lineEdit_X4->text();
int int_X4 = str_x4.toInt();
QString str_x3 = ui->lineEdit_X3->text();
int int_X3 = str_x3.toInt();
QString str_x2 = ui->lineEdit_X2->text();
int int_X2 = str_x2.toInt();
QString str_x1 = ui->lineEdit_X1->text();
int int_X1 = str_x1.toInt();
QString str_x0 = ui->lineEdit_X0 ->text();
int int_X0 = str_x0.toInt();

QString epochs = ui->epoch->text();
int int_epoch = epochs.toInt();
QString steps = ui->step->text();
double dou_step = steps.toDouble();

double x0 = 0;
double y0 = 0;
double dx0 = 0;

for (int i=1;i<=int_epoch;i++)
{
dx0 = int_X5*5*pow(x0,4.0) + int_X4*4*pow(x0,3.0) +int_X3*3*pow(x0,2.0) +int_X2*2*pow(x0,1.0) +int_X1;
x0 = x0 - dou_step * dx0;
}

double result_x = x0;
double result_y = int_X5*pow(x0,5.0) + int_X4*pow(x0,4.0) +int_X3*pow(x0,3.0) +int_X2*pow(x0,2.0) +int_X1*x0+int_X0;

ui->output_x->setText(QString::number(result_x));
ui->output_y->setText(QString::number(result_y));
}

值获取与显示

  关于GUI上输入值的获取与显示,调用了lineEdit对象的text()和setText()方法即可,代码如上。

遇到的问题

  在本项目的过程中遇到的一个问题是,由于需要两个界面,因此需要两个ui类,在第一次添加的时候,选择继承的MainWindows类,编译的时候无法编译通过,之后尝试继承Widget类,并把about的头文件包含到主界面的头文件下,在主界面类中新建about界面的方法,编译通过。

1
2
3
private:
Ui::MainWindow *ui;
aboutWindow aboutWin;

  新建ui文件的方法如下图:
photo1
photo2

小结

  虽然项目比较简单,但是感觉对于Qt的开发方式熟悉了许多。
  PS:推荐一套我觉得不错的教学视频:b站Qt教程