數據挖掘—BP神經網絡(Java實現)

在這里插入圖片描述


public class Test {public static void main(String args[]) throws Exception {ArrayList<ArrayList<Double>> alllist = new ArrayList<ArrayList<Double>>(); // 存放所有數據ArrayList<String> outlist = new ArrayList<String>(); // 存放分類的字符串int in_num = 0, out_num = 0; // 輸入輸出數據的個數DataUtil dataUtil = new DataUtil(); // 初始化數據dataUtil.NormalizeData("src/bp/train.txt");dataUtil.SetTypeNum(3); // 設置輸出類型的數量dataUtil.ReadFile("src/bp/train.txt", ",", 0);in_num = dataUtil.GetInNum(); // 獲得輸入數據的個數out_num = dataUtil.GetOutNum(); // 獲得輸出數據的個數(個數代表類型個數)alllist = dataUtil.GetList(); // 獲得初始化后的數據outlist = dataUtil.GetOutList();System.out.print("分類的類型:");for(int i =0 ;i<outlist.size();i++)System.out.print(outlist.get(i)+"  ");System.out.println();System.out.println("訓練集的數量:"+alllist.size());BPNN bpnn = new BPNN();// 訓練System.out.println("Train Start!");System.out.println(".............");bpnn.Train(in_num, out_num, alllist);System.out.println("Train End!");// 測試DataUtil testUtil = new DataUtil();testUtil.NormalizeData("src/bp/test.txt");testUtil.SetTypeNum(3); // 設置輸出類型的數量testUtil.ReadFile("src/bp/test.txt", ",", 1);ArrayList<ArrayList<Double>> testList = new ArrayList<ArrayList<Double>>();ArrayList<ArrayList<Double>> resultList = new ArrayList<ArrayList<Double>>();ArrayList<String> normallist = new ArrayList<String>(); // 存放測試集標準的輸出字符串ArrayList<String> resultlist = new ArrayList<String>(); // 存放測試集計算后的輸出字符串double right = 0; // 分類正確的數量int type_num = 0; // 類型的數量double all_num = 0; //測試集的數量type_num = outlist.size();testList = testUtil.GetList(); // 獲取測試數據normallist = testUtil.GetCheckList();int errorcount=0; // 分類錯誤的數量resultList = bpnn.ForeCast(testList); // 測試all_num=resultList.size();for (int i = 0; i < resultList.size(); i++) {String checkString = "unknow";for (int j = 0; j < type_num; j++) {if(resultList.get(i).get(j)==1.0){checkString = outlist.get(j);resultlist.add(checkString);}/*else{resultlist.add(checkString);}*/}/*if(checkString.equals("unknow"))errorcount++;*/if(checkString.equals(normallist.get(i)))right++;}System.out.println("測試集的數量:"+ (new Double(all_num)).intValue());System.out.println("分類正確的數量:"+(new Double(right)).intValue());System.out.println("算法的分類正確率為:"+right/all_num);System.out.println("分類結果存儲在:E:\\BP_data\\result.txt");}
}
package bp;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;class DataUtil {private ArrayList<ArrayList<Double>> alllist = new ArrayList<ArrayList<Double>>(); // 存放所有數據private ArrayList<String> outlist = new ArrayList<String>(); // 存放輸出數據,索引對應每個everylist的輸出private ArrayList<String> checklist = new ArrayList<String>();  //存放測試集的真實輸出字符串private int in_num = 0;private int out_num = 0; // 輸入輸出數據的個數private int type_num = 0; // 輸出的類型數量private double[][] nom_data; //歸一化輸入數據中的最大值和最小值private int in_data_num = 0; //提前獲得輸入數據的個數// 獲取輸出類型的個數public int GetTypeNum() {return type_num;}// 設置輸出類型的個數public void SetTypeNum(int type_num) {this.type_num = type_num;}// 獲取輸入數據的個數public int GetInNum() {return in_num;}// 獲取輸出數據的個數public int GetOutNum() {return out_num;}// 獲取所有數據的數組public ArrayList<ArrayList<Double>> GetList() {return alllist;}// 獲取輸出為字符串形式的數據public ArrayList<String> GetOutList() {return outlist;}// 獲取輸出為字符串形式的數據public ArrayList<String> GetCheckList() {return checklist;}//返回歸一化數據所需最大最小值public double[][] GetMaxMin(){return nom_data;}// 讀取文件初始化數據public void ReadFile(String filepath, String sep, int flag)throws Exception {ArrayList<Double> everylist = new ArrayList<Double>(); // 存放每一組輸入輸出數據int readflag = flag; // flag=0,train;flag=1,testString encoding = "GBK";File file = new File(filepath);if (file.isFile() && file.exists()) { // 判斷文件是否存在InputStreamReader read = new InputStreamReader(new FileInputStream(file), encoding);// 考慮到編碼格式BufferedReader bufferedReader = new BufferedReader(read);String lineTxt = null;while ((lineTxt = bufferedReader.readLine()) != null) {int in_number = 0;String splits[] = lineTxt.split(sep); // 按','截取字符串if (readflag == 0) {for (int i = 0; i < splits.length; i++)try {everylist.add(Normalize(Double.valueOf(splits[i]),nom_data[i][0],nom_data[i][1]));in_number++;} catch (Exception e) {if (!outlist.contains(splits[i]))outlist.add(splits[i]); // 存放字符串形式的輸出數據for (int k = 0; k < type_num; k++) {everylist.add(0.0);}everylist.set(in_number + outlist.indexOf(splits[i]),1.0);}} else if (readflag == 1) {for (int i = 0; i < splits.length; i++)try {everylist.add(Normalize(Double.valueOf(splits[i]),nom_data[i][0],nom_data[i][1]));in_number++;} catch (Exception e) {checklist.add(splits[i]); // 存放字符串形式的輸出數據}}alllist.add(everylist); // 存放所有數據in_num = in_number;out_num = type_num;everylist = new ArrayList<Double>();everylist.clear();}bufferedReader.close();}}//向文件寫入分類結果public void WriteFile(String filepath, ArrayList<ArrayList<Double>> list, int in_number,  ArrayList<String> resultlist) throws IOException{File file = new File(filepath);FileWriter fw = null;BufferedWriter writer = null;try {fw = new FileWriter(file);writer = new BufferedWriter(fw);System.out.println(resultlist.size());for(int i=0;i<resultlist.size()-1;i++){for(int j=0;j<in_number;j++)writer.write(list.get(i).get(j)+",");writer.write(resultlist.get(i));writer.newLine();}writer.flush();} catch (IOException e) {e.printStackTrace();}finally{writer.close();fw.close();}}//學習樣本歸一化,找到輸入樣本數據的最大值和最小值public void NormalizeData(String filepath) throws IOException{//提前獲得輸入數據的個數GetBeforIn(filepath);int flag=1;nom_data = new double[in_data_num][2];String encoding = "GBK";File file = new File(filepath);if (file.isFile() && file.exists()) { // 判斷文件是否存在InputStreamReader read = new InputStreamReader(new FileInputStream(file), encoding);// 考慮到編碼格式BufferedReader bufferedReader = new BufferedReader(read);String lineTxt = null;while ((lineTxt = bufferedReader.readLine()) != null) {String splits[] = lineTxt.split(","); // 按','截取字符串for (int i = 0; i < splits.length-1; i++){if(flag==1){nom_data[i][0]=Double.valueOf(splits[i]);nom_data[i][1]=Double.valueOf(splits[i]);}else{if(Double.valueOf(splits[i])>nom_data[i][0])nom_data[i][0]=Double.valueOf(splits[i]);if(Double.valueOf(splits[i])<nom_data[i][1])nom_data[i][1]=Double.valueOf(splits[i]);}}flag=0;}bufferedReader.close();}}//歸一化前獲得輸入數據的個數public void GetBeforIn(String filepath) throws IOException{String encoding = "GBK";File file = new File(filepath);if (file.isFile() && file.exists()) { // 判斷文件是否存在InputStreamReader read = new InputStreamReader(new FileInputStream(file), encoding);// 考慮到編碼格式//提前獲得輸入數據的個數BufferedReader beforeReader = new BufferedReader(read);String beforetext = beforeReader.readLine();String splits[] = beforetext.split(",");in_data_num = splits.length-1;beforeReader.close();}}//歸一化公式public double Normalize(double x, double max, double min){double y = 0.1+0.8*(x-min)/(max-min);return y;}
}
class BPNN {// private static int LAYER = 3; // 三層神經網絡private static int NodeNum = 10; // 每層的最多節點數private static final int ADJUST = 5; // 隱層節點數調節常數private static final int MaxTrain = 2000; // 最大訓練次數private static final double ACCU = 0.015; // 每次迭代允許的誤差private double ETA_W = 0.5; // 權值學習效率0.5private double ETA_T = 0.5; // 閾值學習效率private double accu;// 附加動量項//private static final double ETA_A = 0.3; // 動量常數0.1//private double[][] in_hd_last; // 上一次的權值調整量//private double[][] hd_out_last;private int in_num; // 輸入層節點數private int hd_num; // 隱層節點數private int out_num; // 輸入出節點數private ArrayList<ArrayList<Double>> list = new ArrayList<>(); // 輸入輸出數據private double[][] in_hd_weight; // BP網絡in-hidden突觸權值private double[][] hd_out_weight; // BP網絡hidden_out突觸權值private double[] in_hd_th; // BP網絡in-hidden閾值private double[] hd_out_th; // BP網絡hidden-out閾值private double[][] out; // 每個神經元的值經S型函數轉化后的輸出值,輸入層就為原值private double[][] delta; // delta學習規則中的值// 獲得網絡三層中神經元最多的數量public int GetMaxNum() {return Math.max(Math.max(in_num, hd_num), out_num);}// 設置權值學習率public void SetEtaW() {ETA_W = 0.5;}// 設置閾值學習率public void SetEtaT() {ETA_T = 0.5;}// BPNN訓練public void Train(int in_number, int out_number,ArrayList<ArrayList<Double>> arraylist) throws IOException {list = arraylist;in_num = in_number;out_num = out_number;GetNums(in_num, out_num); // 獲取輸入層、隱層、輸出層的節點數// SetEtaW(); // 設置學習率// SetEtaT();InitNetWork(); // 初始化網絡的權值和閾值int datanum = list.size(); // 訓練數據的組數int createsize = GetMaxNum(); // 比較創建存儲每一層輸出數據的數組out = new double[3][createsize];for (int iter = 0; iter < MaxTrain; iter++) {for (int cnd = 0; cnd < datanum; cnd++) {// 第一層輸入節點賦值for (int i = 0; i < in_num; i++) {out[0][i] = list.get(cnd).get(i); // 為輸入層節點賦值,其輸入與輸出相同}Forward(); // 前向傳播Backward(cnd); // 誤差反向傳播}System.out.println("This is the " + (iter + 1)+ " th trainning NetWork !");accu = GetAccu();System.out.println("All Samples Accuracy is " + accu);if (accu < ACCU)break;}}// 獲取輸入層、隱層、輸出層的節點數,in_number、out_number分別為輸入層節點數和輸出層節點數public void GetNums(int in_number, int out_number) {in_num = in_number;out_num = out_number;hd_num = (int) Math.sqrt(in_num + out_num) + ADJUST;if (hd_num > NodeNum)hd_num = NodeNum; // 隱層節點數不能大于最大節點數}// 初始化網絡的權值和閾值public void InitNetWork() {// 初始化上一次權值量,范圍為-0.5-0.5之間//in_hd_last = new double[in_num][hd_num];//hd_out_last = new double[hd_num][out_num];in_hd_weight = new double[in_num][hd_num];for (int i = 0; i < in_num; i++)for (int j = 0; j < hd_num; j++) {int flag = 1; // 符號標志位(-1或者1)if ((new Random().nextInt(2)) == 1)flag = 1;elseflag = -1;in_hd_weight[i][j] = (new Random().nextDouble() / 2) * flag; // 初始化in-hidden的權值//in_hd_last[i][j] = 0;}hd_out_weight = new double[hd_num][out_num];for (int i = 0; i < hd_num; i++)for (int j = 0; j < out_num; j++) {int flag = 1; // 符號標志位(-1或者1)if ((new Random().nextInt(2)) == 1)flag = 1;elseflag = -1;hd_out_weight[i][j] = (new Random().nextDouble() / 2) * flag; // 初始化hidden-out的權值//hd_out_last[i][j] = 0;}// 閾值均初始化為0in_hd_th = new double[hd_num];for (int k = 0; k < hd_num; k++)in_hd_th[k] = 0;hd_out_th = new double[out_num];for (int k = 0; k < out_num; k++)hd_out_th[k] = 0;}// 計算單個樣本的誤差public double GetError(int cnd) {double ans = 0;for (int i = 0; i < out_num; i++)ans += 0.5 * (out[2][i] - list.get(cnd).get(in_num + i))* (out[2][i] - list.get(cnd).get(in_num + i));return ans;}// 計算所有樣本的平均精度public double GetAccu() {double ans = 0;int num = list.size();for (int i = 0; i < num; i++) {int m = in_num;for (int j = 0; j < m; j++)out[0][j] = list.get(i).get(j);Forward();int n = out_num;for (int k = 0; k < n; k++)ans += 0.5 * (list.get(i).get(in_num + k) - out[2][k])* (list.get(i).get(in_num + k) - out[2][k]);}return ans / num;}// 前向傳播public void Forward() {// 計算隱層節點的輸出值for (int j = 0; j < hd_num; j++) {double v = 0;for (int i = 0; i < in_num; i++)v += in_hd_weight[i][j] * out[0][i];v += in_hd_th[j];out[1][j] = Sigmoid(v);}// 計算輸出層節點的輸出值for (int j = 0; j < out_num; j++) {double v = 0;for (int i = 0; i < hd_num; i++)v += hd_out_weight[i][j] * out[1][i];v += hd_out_th[j];out[2][j] = Sigmoid(v);}}// 誤差反向傳播public void Backward(int cnd) {CalcDelta(cnd); // 計算權值調整量UpdateNetWork(); // 更新BP神經網絡的權值和閾值}// 計算delta調整量public void CalcDelta(int cnd) {int createsize = GetMaxNum(); // 比較創建數組delta = new double[3][createsize];// 計算輸出層的delta值for (int i = 0; i < out_num; i++) {delta[2][i] = (list.get(cnd).get(in_num + i) - out[2][i])* SigmoidDerivative(out[2][i]);}// 計算隱層的delta值for (int i = 0; i < hd_num; i++) {double t = 0;for (int j = 0; j < out_num; j++)t += hd_out_weight[i][j] * delta[2][j];delta[1][i] = t * SigmoidDerivative(out[1][i]);}}// 更新BP神經網絡的權值和閾值public void UpdateNetWork() {// 隱含層和輸出層之間權值和閥值調整for (int i = 0; i < hd_num; i++) {for (int j = 0; j < out_num; j++) {hd_out_weight[i][j] += ETA_W * delta[2][j] * out[1][i]; // 未加權值動量項/* 動量項* hd_out_weight[i][j] += (ETA_A * hd_out_last[i][j] + ETA_W* delta[2][j] * out[1][i]); hd_out_last[i][j] = ETA_A ** hd_out_last[i][j] + ETA_W delta[2][j] * out[1][i];*/}}for (int i = 0; i < out_num; i++)hd_out_th[i] += ETA_T * delta[2][i];// 輸入層和隱含層之間權值和閥值調整for (int i = 0; i < in_num; i++) {for (int j = 0; j < hd_num; j++) {in_hd_weight[i][j] += ETA_W * delta[1][j] * out[0][i]; // 未加權值動量項/* 動量項* in_hd_weight[i][j] += (ETA_A * in_hd_last[i][j] + ETA_W* delta[1][j] * out[0][i]); in_hd_last[i][j] = ETA_A ** in_hd_last[i][j] + ETA_W delta[1][j] * out[0][i];*/}}for (int i = 0; i < hd_num; i++)in_hd_th[i] += ETA_T * delta[1][i];}// 符號函數signpublic int Sign(double x) {if (x > 0)return 1;else if (x < 0)return -1;elsereturn 0;}// 返回最大值public double Maximum(double x, double y) {if (x >= y)return x;elsereturn y;}// 返回最小值public double Minimum(double x, double y) {if (x <= y)return x;elsereturn y;}// log-sigmoid函數public double Sigmoid(double x) {return (double) (1 / (1 + Math.exp(-x)));}// log-sigmoid函數的倒數public double SigmoidDerivative(double y) {return (double) (y * (1 - y));}// tan-sigmoid函數public double TSigmoid(double x) {return (double) ((1 - Math.exp(-x)) / (1 + Math.exp(-x)));}// tan-sigmoid函數的倒數public double TSigmoidDerivative(double y) {return (double) (1 - (y * y));}// 分類預測函數public ArrayList<ArrayList<Double>> ForeCast(ArrayList<ArrayList<Double>> arraylist) {ArrayList<ArrayList<Double>> alloutlist = new ArrayList<>();ArrayList<Double> outlist = new ArrayList<Double>();int datanum = arraylist.size();for (int cnd = 0; cnd < datanum; cnd++) {for (int i = 0; i < in_num; i++)out[0][i] = arraylist.get(cnd).get(i); // 為輸入節點賦值Forward();for (int i = 0; i < out_num; i++) {if (out[2][i] > 0 && out[2][i] < 0.5)out[2][i] = 0;else if (out[2][i] > 0.5 && out[2][i] < 1) {out[2][i] = 1;}outlist.add(out[2][i]);}alloutlist.add(outlist);outlist = new ArrayList<Double>();outlist.clear();}return alloutlist;}}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/392105.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/392105.shtml
英文地址,請注明出處:http://en.pswp.cn/news/392105.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

c語言掌握常用函數,c語言一些常用函數.pdf

c語言一些常用函數C 語言程序設計(常用函數說明)C 語言是 1972 年由美國的 Dennis Ritchie 設計發明的,并首次在 UNIX 操作系統的 DEC PDP-11 計算機上使用。它由早期的編程語言 BCPL(Basic Combind ProgrammingLanguage)發展演變而來。在 1970 年,AT&T 貝爾實驗室的 Ken T…

高階函數 - 函數節流

/*** 函數節流 - 限制函數被頻繁調用* param {Function} fn [需要執行的函數]* param {[type]} interval [限制多長的時間再重復執行fn]*/var throttle function(fn, interval) {var __self fn,timer,firstTime true;return function() {var args arguments,__me…

[CareerCup] 8.7 Chat Server 聊天服務器

8.7 Explain how you would design a chat server. In particular, provide details about the various backend components, classes, and methods. What would be the hardest problems to solve? 這個簡易的聊天服務器功能十分的有限&#xff0c;畢竟只是針對面試題的&…

react hooks使用_如何開始使用React Hooks:受控表格

react hooks使用by Kevin Okeh由Kevin Okeh 如何開始使用React Hooks&#xff1a;受控表格 (How to Get Started With React Hooks: Controlled Forms) React Hooks are a shiny new proposal that will allow you to write 90% cleaner React. According to Dan Abramov, Hoo…

特征工程tf-idf_特征工程-保留和刪除的內容

特征工程tf-idfThe next step after exploring the patterns in data is feature engineering. Any operation performed on the features/columns which could help us in making a prediction from the data could be termed as Feature Engineering. This would include the…

c語言定義數組a10 指定各元素,C語言填空題.doc

C語言填空題.doc二、填空題1、C 語言只有 32 個關鍵字和 9 種控制語句。2、每個源程序有且只有一個 main 函數&#xff0c;系統總是從該函數開始執行 C 語言程序。 3、C 語言程序的注釋可以出現在程序中的任何地方&#xff0c;它總是以 * 符號作為開始標記&#xff0c;以 */ 符…

貓狗隊列

功能要求&#xff1a; 用戶可以調用push方法將cat類或dog類的實例放入隊列中;用戶可以調用pollAll方法&#xff0c;將隊列中所有的實例按照進隊列的先后順序依次彈出;用戶可以調用pollDog方法&#xff0c;將隊列中dog類的實例按照進隊列的先后順序依次彈出;用戶可以調用pollCat…

如何使用HTML5,JavaScript和Bootstrap構建自定義文件上傳器

by Prashant Yadav通過Prashant Yadav 如何使用HTML5&#xff0c;JavaScript和Bootstrap構建自定義文件上傳器 (How to build a custom file uploader with HTML5, JavaScript, & Bootstrap) In this short article, we’ll learn how to create custom file uploader wit…

monkey測試===通過monkey測試檢查app內存泄漏和cpu占用

最近一直在研究monkey測試。網上資料很多&#xff0c;但都是一個抄一個的。原創的很少 我把檢查app內存泄漏的情況梳理一下&#xff1a; 參考資料&#xff1a; Monkey測試策略&#xff1a;https://testerhome.com/topics/597 Android Monkey測試詳細介紹&#xff1a;http://www…

數據挖掘—主成分分析法降維和最小最大規范化

算法步驟:1)將原始數據按列組成n行m列矩陣X2)特征中心化。即每一維的數據都減去該維的均值&#xff0c;使每一維的均值都為03)求出協方差矩陣4)求出協方差矩陣的特征值及對應的特征向量5)將特征向量按對應的特征值大小從上往下按行排列成矩陣&#xff0c;取前k行組成矩陣p6)YPX…

用戶使用說明c語言,(C語言使用指南.docx

(C語言使用指南Turbo C(V2.0)使用指南(本文的許多命令或方法同樣適用于TC3) 在開始看本文以前&#xff0c;我先說明一下C語言的安裝和使用中最應該注意的地方&#xff1a;許多網友在下載Turbo C 2.0和Turbo C 3.0后&#xff0c;向我問得最多的是在使用過程中碰到如下問題&…

三維空間兩直線/線段最短距離、線段計算算法 【轉】

https://segmentfault.com/a/1190000006111226d(ls,lt)|sj?tj||s0?t0(be?cd)u? ?(ae?bd)v? ac?bd(ls,lt)|sj?tj||s0?t0(be?cd)u? ?(ae?bd)v? ac?b2|具體實現代碼如下&#xff08;C#實現&#xff09;&#xff1a; public bool IsEqual(double d1, double d2) { …

【慎思堂】之JS牛腩總結

一 JS基礎 1-定義 Javascript是一種腳本語言/描述語言&#xff0c;是一種解釋性語言。用于開發交互式web網頁&#xff0c;使得網頁和用戶之間實現了一種實時性的、動態的、交互性的關系&#xff0c;使網頁包含更多活躍的元素和更加精彩的內容。 主要用于&#xff1a;表單驗證 …

vuejs 輪播_如何在VueJS中設計和構建輪播功能

vuejs 輪播by Fabian Hinsenkamp由Fabian Hinsenkamp設計 A carousel, slideshow, or slider — however you call it this class of UI — has become one of the core elements used in modern web development. Today, it’s almost impossible to find any Website or UI …

iOS繪圓形圖-CGContextAddArc各參數說明

2019獨角獸企業重金招聘Python工程師標準>>> 1.使用 UIGraphicsGetCurrentContext() 畫圓 CGContextAddArc(<#CGContextRef _Nullable c#>, <#CGFloat x#>, <#CGFloat y#>, <#CGFloat radius#>, <#CGFloat startAngle#>, <#CGFlo…

c語言中if和goto的用法,C語言中if和goto的用法.doc

C語言中if和goto的用法C語言中&#xff0c;if是一個條件語句&#xff0c;用法??if(條件表達式) 語句如果滿足括號里面表達式&#xff0c;表示邏輯為真于是執行后面的語句&#xff0c;否則不執行(表達式為真則此表達式的值不為0&#xff0c;為假則為0&#xff0c;也就是說&…

數據挖掘—K-Means算法(Java實現)

算法描述 &#xff08;1&#xff09;任意選擇k個數據對象作為初始聚類中心 &#xff08;2&#xff09;根據簇中對象的平均值&#xff0c;將每個對象賦給最類似的簇 &#xff08;3&#xff09;更新簇的平均值&#xff0c;即計算每個對象簇中對象的平均值 &#xff08;4&#xf…

自我價值感缺失的表現_不同類型的缺失價值觀和應對方法

自我價值感缺失的表現Before handling the missing values, we must know what all possible types of it exists in the data science world. Basically there are 3 types to be found everywhere on the web, but in some of the core research papers there is one more ty…

[收藏轉載]C# GDI+ 簡單繪圖(一)

最近對GDI這個東西接觸的比較多&#xff0c;也做了些簡單的實例&#xff0c;比如繪圖板&#xff0c;仿QQ截圖等&#xff0e; 廢話不多說了&#xff0c;我們先來認識一下這個GDI&#xff0c;看看它到底長什么樣. GDI&#xff1a;Graphics Device Interface Plus也就是圖形設備接…

mybaties總結+hibernate總結

一、對原生態jdbc程序中問題總結 1.1 jdbc程序 需求&#xff1a;使用jdbc查詢mysql數據庫中用戶表的記錄 statement:向數據庫中發送一個sql語句 預編譯statement&#xff1a;好處&#xff1a;提高數據庫性能。 預編譯statement向數據庫中發送一個sql語句&#xff0c;數據庫編譯…