⑴ 如何得到当日(仅指当日)获利盘10%的价格不是Cost(10)这个用法!
HIGH 最高价
返回该周期最高价。
用法: HIGH
H 最高价
返回该周期最高价。
用法: H
LOW 最低价
返回该周期最低价。
用法: LOW
L 最低价
返回该周期最低价。
用法: L
CLOSE 收盘价
返回该周期收盘价。
用法: CLOSE
C 收盘价
返回该周期收盘价。
用法: C
VOL 成交量
返回该周期成交量。
用法: VOL
V 成交量
返回该周期成交量。
用法: V
OPEN 开盘价
返回该周期开盘价。
用法: OPEN
O: 开盘价
返回该周期开盘价。
用法: O
ADVANCE 上涨家数
返回该周期上涨家数。
用法: ADVANCE (本函数仅对大盘有效)
DECLINE 下跌家数
返回该周期下跌家数。
用法: DECLINE (本函数仅对大盘有效)
AMOUNT 成交额
返回该周期成交额。
用法: AMOUNT
ASKPRICE 委卖价
返回委卖1--委卖3价格。
用法: ASKPRICE(N) N取1—3。
(本函数仅个股在分笔成交分析周期有效)
ASKVOL 委卖量
返回委卖1--委卖3量。
用法: ASKVOL(N) N取1—3。
(本函数仅个股在分笔成交分析周期有效)
BIDPRICE 委买价
返回委买1--委买3价格。
用法: BIDPRICE(N) N取1—3。
(本函数仅个股在分笔成交分析周期有效)
BIDVOL 委买量
返回委买1--委买3量。
用法: BIDVOL(N) N取1—3。
(本函数仅个股在分笔成交分析周期有效)
BUYVOL 主动性买盘
返回主动性买单量。
用法: BUYVOL 当本笔成交为主动性买盘时,其数值等于成交量,否则为0。
(本函数仅个股在分笔成交分析周期有效)
SELLVOL 主动性卖盘
返回主动性卖单量。
用法: SELLVOL 当本笔成交为主动性卖盘时,其数值等于成交量,否则为0。
(本函数仅个股在分笔成交分析周期有效)
ISBUYORDER 主动性买单
返回该成交是否为主动性买单。
用法: ISBUYORDER 当本笔成交为主动性买盘时,返回1,否则为0。
(本函数仅个股在分笔成交分析周期有效)
ISSELLORDER 主动性卖单
返回该成交是否为主动性卖单。
用法: ISSELLORDER 当本笔成交为主动性卖盘时,返回1,否则为0。
(本函数仅个股在分笔成交分析周期有效)
ATE 日期
取得该周期从1900以来的年月日。
用法: DATE 例如函数返回1000101,表示2000年1月1日。
TIME 时间
取得该周期的时分秒。
用法: TIME 函数返回有效值范围为(000000-235959)。
YEAR 年份
取得该周期的年份。
用法:YEAR
MONTH 月份
取得该周期的月份。
用法:MONTH 函数返回有效值范围为(1-12)。
WEEK 星期
取得该周期的星期数。
用法: WEEK 函数返回有效值范围为(0-6),0表示星期天。
DAY 日期
取得该周期的日期。
用法: DAY 函数返回有效值范围为(1-31)。
HOUR 小时
取得该周期的小时数。
用法: HOUR 函数返回有效值范围为(0-23),对于日线及更长的分析周期值为0。
MINUTE 分钟
取得该周期的分钟数。
用法: MINUTE 函数返回有效值范围为(0-59),对于日线及更长的分析周期值为0。
FROMOPEN 分钟
求当前时刻距开盘有多长时间。
用法: FROMOPEN 返回当前时刻距开盘有多长时间,单位为分钟。
例如: FROMOPEN 当前时刻为早上十点,则返回31。
DRAWNULL 无效数
返回无效数。
用法: DRAWNULL
例如: IF(CLOSE>REF(CLOSE,1),CLOSE,DRAWNULL) 表示下跌时分析图上不画线。
BACKSET 向前赋值
将当前位置到若干周期前的数据设为1。
用法: BACKSET(X,N) 若X非0,则将当前位置到N周期前的数值设为1。
例如: BACKSET(CLOSE>OPEN,2) 若收阳则将该周期及前一周期数值设为1,否则为0。
BARSCOUNT 有效数据周期数
求总的周期数。
用法: BARSCOUNT(X) 第一个有效数据到当前的天数。
例如: BARSCOUNT(CLOSE) 对于日线数据取得上市以来总交易日数,对于分笔成交取得当日成交笔数,对于1分钟线取得当日交易分钟数。
CURRBARSCOUNT 到最后交易日的周期数
求到最后交易日的周期数.
用法:
CURRBARSCOUNT 求到最后交易日的周期数
TOTALBARSCOUNT 总的周期数
求总的周期数.
用法:
TOTALBARSCOUNT 求总的周期数
BARSLAST 上一次条件成立位置
上一次条件成立到当前的周期数。
用法: BARSLAST(X) 上一次X不为0到现在的天数。
例如: BARSLAST(CLOSE/REF(CLOSE,1)>=1.1) 表示上一个涨停板到当前的周期数。
BARSSINCE 第一个条件成立位置
第一个条件成立到当前的周期数。
用法: BARSSINCE(X) 第一次X不为0到现在的天数。
例如: BARSSINCE(HIGH>10) 表示股价超过10元时到当前的周期数。
COUNT 统计
统计满足条件的周期数。
用法: COUNT(X,N) 统计N周期中满足X条件的周期数,若N=0则从第一个有效值开始。
例如: COUNT(CLOSE>OPEN,20) 表示统计20周期内收阳的周期数。
HHV 最高值
求最高值。
用法: HHV(X,N) 求N周期内X最高值,N=0则从第一个有效值开始。
例如: HHV(HIGH,30) 表示求30日最高价。
HHVBARS 上一高点位置
求上一高点到当前的周期数。
用法: HHVBARS(X,N) 求N周期内X最高值到当前周期数,N=0表示从第一个有效值开始统计。
例如: HHVBARS(HIGH,0) 求得历史新高到到当前的周期数。
LLV 最低值
求最低值。
用法: LLV(X,N) 求N周期内X最低值,N=0则从第一个有效值开始。
例如: LLV(LOW,0) 表示求历史最低价。
LLVBARS 上一低点位置
求上一低点到当前的周期数。
用法: LLVBARS(X,N) 求N周期内X最低值到当前周期数,N=0表示从第一个有效值开始统计。
例如: LLVBARS(HIGH,20) 求得20日最低点到当前的周期数。
REVERSE 求相反数
求相反数。
用法: REVERSE(X) 返回-X。
例如: REVERSE(CLOSE) 返回-CLOSE。
REF 向前引用
引用若干周期前的数据。
用法: REF(X,A) 引用A周期前的X值。
例如: REF(CLOSE,1) 表示上一周期的收盘价,在日线上就是昨收。
REFDATE 指定引用
引用指定日期的数据。
用法: REFDATE(X,A) 引用A日期的X值。
例如: REF(CLOSE,20011208) 表示2001年12月08日的收盘价。
SUM 总和
求总和。
用法: SUM(X,N) 统计N周期中X的总和,N=0则从第一个有效值开始。
例如: SUM(VOL,0) 表示统计从上市第一天以来的成交量总和。
FILTER 过滤
过滤连续出现的信号。
用法: FILTER(X,N) X满足条件后,删除其后N周期内的数据置为0。
例如: FILTER(CLOSE>OPEN,5) 查找阳线,5天内再次出现的阳线不被记录在内。
SUMBARS 累加到指定值的周期数
向前累加到指定值到现在的周期数。
用法: SUMBARS(X,A) 将X向前累加直到大于等于A,返回这个区间的周期数。
例如: SUMBARS(VOL,CAPITAL) 求完全换手到现在的周期数。
SMA 移动平均
返回移动平均。
用法: SMA(X,N,M) X的M日移动平均,M为权重,如Y=(X*M+Y'*(N-M))/N
MA 简单移动平均
返回简单移动平均。
用法: MA(X,M) X的M日简单移动平均。
DMA 动态移动平均
求动态移动平均。
用法: DMA(X,A) 求X的动态移动平均。
算法: 若Y=DMA(X,A)则 Y=A*X+(1-A)*Y',其中Y'表示上一周期Y值,A必须小于1。
例如: DMA(CLOSE,VOL/CAPITAL) 表示求以换手率作平滑因子的平均价。
EMA(或EXPMA) 指数移动平均
返回指数移动平均。
用法: EMA(X,M) X的M日指数移动平均。
MEMA 平滑移动平均
返回平滑移动平均
用法: MEMA(X,M) X的M日平滑移动平均。
MEMA(X,N)与MA的差别在于起始值为一平滑值,而不是初始值
EXPMEMA 指数平滑移动平均
返回指数平滑移动平均。
用法: EXPMEMA(X,M) X的M日指数平滑移动平均。
EXPMEMA同EMA(即EXPMA)的差别在于他的起始值为一平滑值
RANGE 介于某个范围之间
用法: RANGE(A,B,C) A在B和C。
例如: RANGE(A,B,C)表示A大于B同时小于C时返回1,否则返回0。
CONST 取值设为常数
用法: CONST(A) 取A最后的值为常量.
例如: CONST(INDEXC)表示取大盘现价。
CROSS 上穿
两条线交叉。
用法: CROSS(A,B) 表示当A从下方向上穿过B时返回1,否则返回0。
例如: CROSS(MA(CLOSE,5),MA(CLOSE,10)) 表示5日均线与10日均线交金叉。
LONGCROSS 维持一定周期后上穿
两条线维持一定周期后交叉。
用法: LONGCROSS(A,B,N) 表示A在N周期内都小于B,本周期从下方向上穿过B时返回1,否则返回0。
UPNDAY 连涨
返回是否连涨周期数。
用法: UPNDAY(CLOSE,M) 表示连涨M个周期。
DOWNNDAY 连跌
返回是否连跌周期。
用法: DOWNNDAY(CLOSE,M) 表示连跌M个周期。
NDAY 连大
返回是否持续存在X>Y。
用法: NDAY(CLOSE,OPEN,3) 表示连续3日收阳线。
EXIST 存在
是否存在。
用法: EXIST(CLOSE>OPEN,10) 表示前10日内存在着阳线。
EVERY 一直存在
一直存在。
用法: EVERY(CLOSE>OPEN,10) 表示前10日内一直阳线。
LAST 持续存在
用法: LAST(X,A,B) A>B,表示从前A日到前B日一直满足X条件。若A为0,表示从第一天开始,B为0,表示到最后日止。
例如: LAST(CLOSE>OPEN,10,5) 表示从前10日到前5日内一直阳线。
NOT 取反
求逻辑非。
用法: NOT(X) 返回非X,即当X=0时返回1,否则返回0。
例如: NOT(ISUP) 表示平盘或收阴。
IF 逻辑判断
根据条件求不同的值。
用法: IF(X,A,B) 若X不为0则返回A,否则返回B。
例如: IF(CLOSE>OPEN,HIGH,LOW)表示该周期收阳则返回最高值,否则返回最低值。
IFF 逻辑判断
根据条件求不同的值。
用法: IFF(X,A,B) 若X不为0则返回A,否则返回B。
例如: IFF(CLOSE>OPEN,HIGH,LOW) 表示该周期收阳则返回最高值,否则返回最低值。
IFN 逻辑判断
根据条件求不同的值。
用法: IFN(X,A,B) 若X不为0则返回B,否则返回A。
例如: IFN(CLOSE>OPEN,HIGH,LOW) 表示该周期收阴则返回最高值,否则返回最低值。
MAX 较大值
求最大值。
用法: MAX(A,B) 返回A和B中的较大值。
例如: MAX(CLOSE-OPEN,0) 表示若收盘价大于开盘价返回它们的差值,否则返回0。
MIN 较小值
求最小值。
用法: MIN(A,B) 返回A和B中的较小值。
例如: MIN(CLOSE,OPEN) 返回开盘价和收盘价中的较小值。
ACOS 反余弦
反余弦值。
用法: ACOS(X) 返回X的反余弦值。
ASIN 反正弦
反正弦值。
用法: ASIN(X) 返回X的反正弦值。
ATAN 反正切
反正切值。
用法: ATAN(X) 返回X的反正切值。
COS 余弦
余弦值。
用法: COS(X) 返回X的余弦值。
SIN 正弦
正弦值。
用法: SIN(X) 返回X的正弦值。
TAN 正切
正切值。
用法: TAN(X) 返回X的正切值。
EXP 指数
指数。
用法: EXP(X) e的X次幂。
例如: EXP(CLOSE) 返回e的CLOSE次幂。
LN 自然对数
求自然对数。
用法: LN(X) 以e为底的对数。
例如: LN(CLOSE) 求收盘价的对数。
LOG 对数
求10为底的对数。
用法: LOG(X) 取得X的对数。
例如: LOG(100) 等于2。
SQRT 开方
开平方。
用法: SQRT(X) 求X的平方根。
例如: SQRT(CLOSE) 收盘价的平方根。
ABS 绝对值
求绝对值。
用法: ABS(X) 返回X的绝对值。
例如: ABS(-34) 返回34。
POW 乘幂
乘幂。
用法: POW(A,B) 返回A的B次幂。
例如: POW(CLOSE,3) 求得收盘价的3次方。
CEILING 向上舍入
向上舍入。
用法: CEILING(A) 返回沿A数值增大方向最接近的整数。
例如: CEILING(12.3) 求得13,CEILING(-3.5)求得-3。
FLOOR 向下舍入
向下舍入。
用法: FLOOR(A) 返回沿A数值减小方向最接近的整数。
例如: FLOOR(12.3) 求得12,FLOOR(-3.5)求得-4。
INTPART 取整
用法: INTPART(A) 返回沿A绝对值减小方向最接近的整数。
例如: INTPART(12.3) 求得12,INTPART(-3.5)求得-3。
BETWEEN: 介于
介于。
用法: BETWEEN(A,B,C) 表示A处于B和C之间时返回1,否则返回0。
例如: BETWEEN(CLOSE,MA(CLOSE,10),MA(CLOSE,5))表示收盘价介于5日均线和10日均线之间。
AVEDEV 平均绝对方差
AVEDEV(X,N) 返回平均绝对方差。
DEVSQ 数据偏差平方和
DEVSQ(X,N) 返回数据偏差平方和。
FORCAST 线性回归预测值
FORCAST(X,N) 返回线性回归预测值。
SLOPE 线性回归斜率
SLOPE(X,N) 返回线性回归斜率。
STD 估算标准差
STD(X,N) 返回估算标准差。
STDP 总体标准差
STDP(X,N) 返回总体标准差。
VAR 估算样本方差
VAR(X,N) 返回估算样本方差。
VARP 总体样本方差
VARP(X,N) 返回总体样本方差 。
BLOCKSETNUM 板块股票个数
用法: BLOCKSETNUM(板块名称) 返回该板块股票个数。
HORCALC 多股统计
用法: HORCALC(板块名称,数据项,计算方式,权重)
数据项:100-HIGH,101-OPEN,102-LOW,103-CLOSE,104-VOL,105-涨幅
计算方式: 0-累加,1-排名次
权重: 0-总股本,1-流通股本,2-等同权重,3-流通市值
COST 成本分布
成本分布情况。
用法: COST(10),表示10%获利盘的价格是多少,即有10%的持仓量在该价格以下,其余90%在该价格以上,为套牢盘。
该函数仅对日线分析周期有效。
PEAK 波峰值
前M个ZIG转向波峰值。
用法: PEAK(K,N,M) 表示之字转向ZIG(K,N)的前M个波峰的数值,M必须大于等于1。
例如: PEAK(1,5,1) 表示%5最高价ZIG转向的上一个波峰的数值。
PEAKBARS 波峰位置
前M个ZIG转向波峰到当前距离。
用法: PEAKBARS(K,N,M) 表示之字转向ZIG(K,N)的前M个波峰到当前的周期数,M必须大于等于1。
例如: PEAKBARS (0,5,1) 表示%5开盘价ZIG转向的上一个波峰到当前的周期数。
SAR 抛物转向
抛物转向。
用法: SAR(N,S,M),N为计算周期,S为步长,M为极值。
例如: SAR(10,2,20) 表示计算10日抛物转向,步长为2%,极限值为20%。
SARTURN 抛物转向点
抛物转向点。
用法: SARTURN(N,S,M) N为计算周期,S为步长,M为极值,若发生向上转向则返回1,若发生向下转向则返回-1,否则为0。
其用法与SAR函数相同。
TROUGH 波谷值
前M个ZIG转向波谷值。
用法: TROUGH(K,N,M) 表示之字转向ZIG(K,N)的前M个波谷的数值,M必须大于等于1。
例如: TROUGH(2,5,2) 表示%5最低价ZIG转向的前2个波谷的数值。
TROUGHBARS 波谷位置
前M个ZIG转向波谷到当前距离。
用法: TROUGHBARS(K,N,M) 表示之字转向ZIG(K,N)的前M个波谷到当前的周期数,M必须大于等于1。
例如: TROUGH(2,5,2) 表示%5最低价ZIG转向的前2个波谷到当前的周期数。
WINNER 获利盘比例
获利盘比例。
用法: WINNER(CLOSE) 表示以当前收市价卖出的获利盘比例。
例如: 返回0.1表示10%获利盘,WINNER(10.5)表示10.5元价格的获利盘比例。
该函数仅对日线分析周期有效。
LWINNER 近期获利盘比例
近期获利盘比例。
用法: LWINNER(5,CLOSE) 表示最近5天的那部分成本以当前收市价卖出的获利盘比例。例如返回0.1表示10%获利盘。
PWINNER 远期获利盘比例
远期获利盘比例。
用法: PWINNER(5,CLOSE) 表示5天前的那部分成本以当前收市价卖出的获利盘比例。例如返回0.1表示10%获利盘。
COSTEX 区间成本
区间成本。
用法: COSTEX(CLOSE,REF(CLOSE)),表示近两日收盘价格间筹码的成本,例如返回10表示区间成本为20元。
该函数仅对日线分析周期有效。
PPART 远期成本分布比例
远期成本分布比例。
用法: PPART(10),表示10前的成本占总成本的比例,0.2表示20%。
ZIG 之字转向
之字转向。
用法: ZIG(K,N) 当价格变化量超过N%时转向,K表示0:开盘价,1:最高价,2:最低价,3:收盘价,其余:数组信息
例如: ZIG(3,5) 表示收盘价的5%的ZIG转向。
INDEXA 返回大盘成交额
INDEXADV 返回上涨家数
INDEXDEC 返回下跌家数
INDEXC 返回大盘收盘价
INDEXH 返回大盘最高价
INDEXL 返回大盘最低价
INDEXO 返回大盘开盘价
INDEXV 返回大盘成交量
PLOYLINE 折线段
在图形上绘制折线段。
用法: PLOYLINE(COND,PRICE),当COND条件满足时,以PRICE位置为顶点画折线连接。
例如: PLOYLINE(HIGH>=HHV(HIGH,20),HIGH)表示在创20天新高点之间画折线。
DRAWLINE 绘制直线段
在图形上绘制直线段。
用法: DRAWLINE(COND1,PRICE1,COND2,PRICE2,EXPAND)
当COND1条件满足时,在PRICE1位置画直线起点,当COND2条件满足时,在PRICE2位置画直线终点,EXPAND为延长类型。
例如: DRAWLINE(HIGH>=HHV(HIGH,20),HIGH,LOW<=LLV(LOW,20),LOW,1) 表示在创20天新高与创20天新低之间画直线并且向右延长。
DRAWKLINE 绘制K线
用法: DRAWKLINE(HIGH,OPEN,LOW,CLOSE) 以HIGH为最高价,OPEN为开盘价,LOW为最低,CLOSE收盘画K线。
STICKLINE 绘制柱线
在图形上绘制柱线。
用法: STICKLINE(COND,PRICE1,PRICE2,WIDTH,EMPTY),当COND条件满足时,在PRICE1和PRICE2位置之间画柱状线,宽度为WIDTH(10为标准间距),EMPTH不为0则画空心柱。
例如: STICKLINE(CLOSE>OPEN,CLOSE,OPEN,0.8,1)表示画K线中阳线的空心柱体部分。
DRAWICON 绘制图标
在图形上绘制小图标。
用法: DRAWICON(COND,PRICE,TYPE),当COND条件满足时,在PRICE位置画TYPE号图标。
例如: DRAWICON(CLOSE>OPEN,LOW,1) 表示当收阳时在最低价位置画1号图标。图标一共有九个,图形如附图。序号,最下面的是“1”号,最上面的是“9”号。
DRAWTEXT 显示文字
在图形上显示文字。
用法: DRAWTEXT(COND,PRICE,TEXT),当COND条件满足时,在PRICE位置书写文字TEXT。
例如: DRAWTEXT(CLOSE/OPEN>1.08,LOW,'大阳线')表示当日涨幅大于8%时在最低价位置显示'大阳线'字样。
FINANCE(1) 总股本(万股)
FINANCE(2) 国家股(万股)
FINANCE(3) 发起人法人股(万股)
FINANCE(4) 法人股(万股)
FINANCE(5) B股(万股)
FINANCE(6) H股(万股)
FINANCE(7) 流通股本(万股)
CAPITAL 流通股本(手)
FINANCE(8) 职工股(万股)
FINANCE(10) 总资产
FINANCE(11) 流动资产
FINANCE(12) 固定资产
FINANCE(13) 无形资产
FINANCE(14) 长期投资
FINANCE(15) 流动负债
FINANCE(16) 长期负债
FINANCE(17) 资本公积金
FINANCE(18) 每股公积金
FINANCE(19) 股东权益
FINANCE(20) 主营收入
FINANCE(21) 主营利益
FINANCE(22) 其它利益
FINANCE(23) 营业利益
FINANCE(24) 投资收益
FINANCE(25) 补贴收入
FINANCE(26) 营业外收支
FINANCE(27) 上年损益调整
FINANCE(28) 利益总额
FINANCE(29) 税后利益
FINANCE(30) 净利益
FINANCE(31) 未分配利益
FINANCE(32) 每股未分配利润
FINANCE(33) 每股收益
FINANCE(34) 每股净资产
FINANCE(35) 调整每股净资产
FINANCE(36) 股东权益比
FINANCE(40) 流通市值
FINANCE(41) 总市值
FINANCE(42) 上市日期
DYNAINFO(3) 前收盘价
DYNAINFO(4) 今开
DYNAINFO(5) 最高
DYNAINFO(6) 最低
DYNAINFO(7) 现价
DYNAINFO(8) 总手
DYNAINFO(9) 现手
DYNAINFO(10) 总成交金额
DYNAINFO(11) 均价
DYNAINFO(12) 日升跌
DYNAINFO(13) 振幅度
DYNAINFO(14) 涨幅度
DYNAINFO(15) 委托比
DYNAINFO(16) 委量差
DYNAINFO(17) 量比
DYNAINFO(20) 最新叫买价
DYNAINFO(21) 最新叫卖价
DYNAINFO(22) 内盘
DYNAINFO(23) 外盘
DYNAINFO(25) 买一量
DYNAINFO(26) 买二量
DYNAINFO(27) 买三量
DYNAINFO(28) 买一价
DYNAINFO(29) 买二价
DYNAINFO(30) 买三价
DYNAINFO(31) 卖一量
DYNAINFO(32) 卖二量
DYNAINFO(33) 卖三量
DYNAINFO(34) 卖一价
DYNAINFO(35) 卖二价
DYNAINFO(36) 卖三价
DYNAINFO(37) 换手率
DYNAINFO(39) 市盈率
DYNAINFO(40) 成交方向
DYNAINFO(50) 采样点数
DYNAINFO(51) 内外比
DYNAINFO(52) 多空平衡
DYNAINFO(53) 多头获利
DYNAINFO(54) 空头回补
DYNAINFO(55) 多头止损
DYNAINFO(56) 空头止损
DYNAINFO(57) 笔升跌
COLOR 自定义色
格式为COLOR+“RRGGBB”:RR、GG、BB表示红蓝色、绿色和蓝色的分量,每种颜色的取值范围是00-FF,采用了16进制。
例如:MA5:MA(CLOSE,5),COLOR00FFFF 表示纯红色与纯绿色的混合色:COLOR808000表示淡蓝色和淡绿色的混合色。
COLORBLACK 画黑色
COLORBLUE 画蓝色
COLORGREEN 画绿色
COLORCYAN 画青色
COLORRED 画红色
COLORMAGENTA 画洋红色
COLORBROWN 画棕色
COLORLIGRAY 画淡灰色
COLORGRAY 画深灰色
COLORLIBLUE 画淡蓝色
COLORLIGREEN 画淡绿色
COLORLICYAN 画淡青色
COLORLIRED 画淡红色
COLORLIMAGENTA 画淡洋红色
COLORYELLOW 画黄色
COLORWHITE 画白色
LINETHICK 线型粗细
格式:“LINETHICK+(1-9)” 参数的取值范围在1—9之间,“LINETHICK1”表示最细的线,而“LINETHICK9”表示最粗的线。
STICK 画柱状线
COLORSTICK 画彩色柱状线
VOLSTICK 画彩色柱状线
成交量柱状线,当股价上涨时显示红色空心柱,则显示绿色实心柱
LINESTICK 同时画出柱状线和指标线
CROSSDOT 画小叉线
CIRCLEDOT 画小圆圈线
POINTDOT 画小圆点线
⑵ void push(SqStack &S,int e)有什么错误
函数类型应为int型,因为之后存在函数调用,有返回值return ok(0);
即:
int push(Sqstack &s,int e){
*s.top++=e;
return ok;
}
⑶ C++,ios::ate和ios::app
用ios::ate的话,输出结果是这样的:1236而不是你说的456。
根据定义,ate的用法是:输入的第一个字节被放在文件最后,而剩下输入的字符将覆盖之前输入的字符,也就是光标仍然在原来文件的末尾,也就是3的后面。4和5都被6覆盖掉了。
希望采纳
⑷ ate,bake,excel怎么分列
选中该列,数据,分列,勾选分隔符号,下一步,勾选逗号,或者其它,空格中输入
,
完成。
⑸ 如何看sci论文crosscheck / ithenticate查重报告
1)、报告中的内容会有各种颜色标示,标示了颜色的说明是检测到重复的,不同的颜色只是用于区分重复源不同;
2)、颜色上方的数字是序号,跟报告后面的重复来源对应,方便同学们查阅,序号越小说明与此重复源的相同内容越多;
3)、SIMILARITY INDEX是指检测的总重复率,杂志社一般是看这个指标(也有部分杂志对单重复源有要求,具体请咨询对应期刊),总重复率是由下面的Crossref、Internet、Publications等数据库的重复通过程序算法权加得到;
以上答案来源于ithenticate中文官网,更多的信息可到官网上查看了
⑹ 网络安全 简述RSA算法的原理和特点
1978年就出现了这种算法,它是第一个既能用于数据加密也能用于数字签名的算法。
它易于理解和操作,也很流行。算法的名字以发明者的名字命名:Ron Rivest, Adi
Shamir 和Leonard Adleman。但RSA的安全性一直未能得到理论上的证明。
RSA的安全性依赖于大数分解。公钥和私钥都是两个大素数( 大于 100
个十进制位)的函数。据猜测,从一个密钥和密文推断出明文的难度等同于分解两个
大素数的积。
密钥对的产生。选择两个大素数,p 和q 。计算:
n = p * q
然后随机选择加密密钥e,要求 e 和 ( p - 1 ) * ( q - 1 ) 互质。最后,利用
Euclid 算法计算解密密钥d, 满足
e * d = 1 ( mod ( p - 1 ) * ( q - 1 ) )
其中n和d也要互质。数e和
n是公钥,d是私钥。两个素数p和q不再需要,应该丢弃,不要让任何人知道。
加密信息 m(二进制表示)时,首先把m分成等长数据块 m1 ,m2,..., mi ,块长s
,其中 2^s <= n, s 尽可能的大。对应的密文是:
ci = mi^e ( mod n ) ( a )
解密时作如下计算:
mi = ci^d ( mod n ) ( b )
RSA 可用于数字签名,方案是用 ( a ) 式签名, ( b )
式验证。具体操作时考虑到安全性和 m信息量较大等因素,一般是先作 HASH 运算。
RSA 的安全性。
RSA的安全性依赖于大数分解,但是否等同于大数分解一直未能得到理论上的证明,因
为没有证明破解
RSA就一定需要作大数分解。假设存在一种无须分解大数的算法,那它肯定可以修改成
为大数分解算法。目前, RSA
的一些变种算法已被证明等价于大数分解。不管怎样,分解n是最显然的攻击方法。现
在,人们已能分解140多个十进制位的大素数。因此,模数n
必须选大一些,因具体适用情况而定。
RSA的速度。
由于进行的都是大数计算,使得RSA最快的情况也比DES慢上100倍,无论是软件还是硬
件实现。速度一直是RSA的缺陷。一般来说只用于少量数据加密。
RSA的选择密文攻击。
RSA在选择密文攻击面前很脆弱。一般攻击者是将某一信息作一下伪装(
Blind),让拥有私钥的实体签署。然后,经过计算就可得到它所想要的信息。实际上
,攻击利用的都是同一个弱点,即存在这样一个事实:乘幂保留了输入的乘法结构:
( XM )^d = X^d *M^d mod n
前面已经提到,这个固有的问题来自于公钥密码系统的最有用的特征--每个人都能使
用公钥。但从算法上无法解决这一问题,主要措施有两条:一条是采用好的公钥协议
,保证工作过程中实体不对其他实体任意产生的信息解密,不对自己一无所知的信息
签名;另一条是决不对陌生人送来的随机文档签名,签名时首先使用One-Way Hash
Function
对文档作HASH处理,或同时使用不同的签名算法。在中提到了几种不同类型的攻击方
法。
RSA的公共模数攻击。
若系统中共有一个模数,只是不同的人拥有不同的e和d,系统将是危险的。最普遍的
情况是同一信息用不同的公钥加密,这些公钥共模而且互质,那末该信息无需私钥就
可得到恢复。设P为信息明文,两个加密密钥为e1和e2,公共模数是n,则:
C1 = P^e1 mod n
C2 = P^e2 mod n
密码分析者知道n、e1、e2、C1和C2,就能得到P。
因为e1和e2互质,故用Euclidean算法能找到r和s,满足:
r * e1 + s * e2 = 1
假设r为负数,需再用Euclidean算法计算C1^(-1),则
( C1^(-1) )^(-r) * C2^s = P mod n
另外,还有其它几种利用公共模数攻击的方法。总之,如果知道给定模数的一对e和d
,一是有利于攻击者分解模数,一是有利于攻击者计算出其它成对的e’和d’,而无
需分解模数。解决办法只有一个,那就是不要共享模数n。
RSA的小指数攻击。 有一种提高
RSA速度的建议是使公钥e取较小的值,这样会使加密变得易于实现,速度有所提高。
但这样作是不安全的,对付办法就是e和d都取较大的值。
RSA算法是第一个能同时用于加密和数字签名的算法,也易于理解和操作。RSA是被研
究得最广泛的公钥算法,从提出到现在已近二十年,经历了各种攻击的考验,逐渐为
人们接受,普遍认为是目前最优秀的公钥方案之一。RSA
的安全性依赖于大数的因子分解,但并没有从理论上证明破译RSA的难度与大数分解难
度等价。即RSA的重大缺陷是无法从理论上把握它的保密性能如何,而且密码学界多数
人士倾向于因子分解不是NPC问题。
RSA的缺点主要有:A)产生密钥很麻烦,受到素数产生技术的限制,因而难以做到一次
一密。B)分组长度太大,为保证安全性,n 至少也要 600 bits
以上,使运算代价很高,尤其是速度较慢,较对称密码算法慢几个数量级;且随着大
数分解技术的发展,这个长度还在增加,不利于数据格式的标准化。目前,SET(
Secure Electronic Transaction
)协议中要求CA采用2048比特长的密钥,其他实体使用1024比特的密钥。
DSS/DSA算法
Digital Signature Algorithm
(DSA)是Schnorr和ElGamal签名算法的变种,被美国NIST作为DSS(Digital Signature
Standard)。算法中应用了下述参数:
p:L bits长的素数。L是64的倍数,范围是512到1024;
q:p - 1的160bits的素因子;
g:g = h^((p-1)/q) mod p,h满足h < p - 1, h^((p-1)/q) mod p > 1;
x:x < q,x为私钥 ;
y:y = g^x mod p ,( p, q, g, y )为公钥;
H( x ):One-Way Hash函数。DSS中选用SHA( Secure Hash Algorithm )。
p, q,
g可由一组用户共享,但在实际应用中,使用公共模数可能会带来一定的威胁。签名及
验证协议如下:
1. P产生随机数k,k < q;
2. P计算 r = ( g^k mod p ) mod q
s = ( k^(-1) (H(m) + xr)) mod q
签名结果是( m, r, s )。
3. 验证时计算 w = s^(-1)mod q
u1 = ( H( m ) * w ) mod q
u2 = ( r * w ) mod q
v = (( g^u1 * y^u2 ) mod p ) mod q
若v = r,则认为签名有效。
DSA是基于整数有限域离散对数难题的,其安全性与RSA相比差不多。DSA的一个重要特
点是两个素数公开,这样,当使用别人的p和q时,即使不知道私钥,你也能确认它们
是否是随机产生的,还是作了手脚。RSA算法却作不到。
本文来自CSDN博客,
⑺ 自动测试设备(ATE)
自动化测试设备,用AG3070成本太贵,可以定做非标自动化测试设备,由电脑,数据采集卡,控制卡,电源等仪器,治具....等组成。
深圳市中誉达自动化测试设备有限公司(英文名ZYATE):是一家专业从事PCBA、手机、电视、音响、冰箱、洗衣机、空调、电源等电子产品的自动化功能测试方案设计的现代化高科技企业,公司主要产品有:FCT fixture、ICT fixture、MCU fixture、自动化测试设备、自动化测试系统、功能测试夹具等,均是各大电子产品厂商常用的提高产品质量和工作效率的自动化测试系统。
我公司采用的开发工具主要有:NI Labview、Teststand、labwindows CVI、Vision Builder、Vision Assistant、VB、VC++等,测试产品类别极其广阔,有洗衣机自动化测试设备/系统、电烤箱自动化测试设备/系统、冰箱自动化测试设备/系统、变压器自动化测试设备/系统、电感自动化测试设备/系统、贴片电阻自动测试分选设备/系统、电子书自动化测试设备/系统、LCD/LED字符自动读取测试设备/系统、液晶电视机的自动化测试设备/系统、空调自动化测试设备/系统、节能灯自动化测试设备/系统、医疗器械自动化测试设备、老化自动化测试设备、闪光灯自动化测试设备/系统、FPC自动化测试设备/软板自动化测试设备、手机自动化测试设备、微针测试设备、边界扫描测试设备.....等所有电子产品相关的PCBA自动化测试设备/测试系统。
公司拥有一支高素质的管理、研发、生产、服务专业团队,为适应现代化企业的高速发展,公司一直秉承“以客户需求为标准”的宗旨,“以人为本”的经营理念,不断更新技术,开拓创新,努力发展成为国内外具备相当规模及知名度的自动化测试设备的提供者。
⑻ 锾ATE数据到MySQL数据库为什么存入的时
如果mysql的数据类型是date的话 用date('Y-m-d')获取时间
如果是datetime类型,用date('Y-m-d H:i:s')获取时间
个人建议,用int存储,这样占用的的资源小,查询的速度也会快,用time()方法获取时间戳,在调用的时候根据你想要的形式,将时间戳转换成你要的时间,如果只显示年月日的话,用date('Y-m-d',$date),如果需要显示精确时间,用date('Y-m-d H:i:s')就可以了
⑼ 求八数码问题算法,并说明下该算法优缺点,要算法,不是源代码(可以没有)。
八数码问题
一.八数码问题
八数码问题也称为九宫问题。在3×3的棋盘,摆有八个棋子,每个棋子上标有1至8的某一数字,不同棋子上标的数字不相同。棋盘上还有一个空格,与空格相邻的棋子可以移到空格中。要求解决的问题是:给出一个初始状态和一个目标状态,找出一种从初始转变成目标状态的移动棋子步数最少的移动步骤。所谓问题的一个状态就是棋子在棋盘上的一种摆法。棋子移动后,状态就会发生改变。解八数码问题实际上就是找出从初始状态到达目标状态所经过的一系列中间过渡状态。
八数码问题一般使用搜索法来解。搜索法有广度优先搜索法、深度优先搜索法、A*算法等。这里通过用不同方法解八数码问题来比较一下不同搜索法的效果。
二.搜索算法基类
1.八数码问题的状态表示
八数码问题的一个状态就是八个数字在棋盘上的一种放法。每个棋子用它上面所标的数字表示,并用0表示空格,这样就可以将棋盘上棋子的一个状态存储在一个一维数组p[9]中,存储的顺序是从左上角开始,自左至右,从上到下。也可以用一个二维数组来存放。
2.结点
搜索算法中,问题的状态用结点描述。结点中除了描述状态的数组p[9]外,还有一个父结点指针last,它记录了当前结点的父结点编号,如果一个结点v是从结点u经状态变化而产生的,则结点u就是结点v的父结点,结点v的last记录的就是结点u的编号。在到达目标结点后,通过last 可以找出搜索的路径。
3.类的结构
在C++中用类来表示结点,类将结点有关的数据操作封装在一起。
不同的搜索算法具有一定共性,也有各自的个性,因此这里将不同搜索算法的共有的数据和功能封装在一个基类中,再通过继承方式实现不同的搜索算法。
4.结点扩展规则
搜索就是按照一定规则扩展已知结点,直到找到目标结点或所有结点都不能扩展为止。
八数码问题的结点扩展应当遵守棋子的移动规则。按照棋子移动的规则,每一次可以将一个与空格相邻棋子移动到空格中,实际上可以看作是空格作相反移动。空格移动的方向可以是右、下、左、上,当然不能移出边界。棋子的位置,也就是保存状态的数组元素的下标。空格移动后,它的位置发生变化,在不移出界时,空格向右、下、左和上移动后,新位置是原位置分别加上1、3、-1、-3,如果将空格向右、下、左和上移动分别用0、1、2、3表示,并将-3、3、-1、1放在静态数组d[4]中,空格位置用spac表示,那么空格向方向i移动后,它的位置变为spac+d[i]。空格移动所产生的状态变化,反映出来则是将数组p[]中,0的新位置处的数与0交换位置。
5.八数码问题的基类
八数码问题的基类及其成员函数的实现如下:
#define Num 9
class TEight
{
public:
TEight(){}
TEight(char *fname); //用文件数据构造节点
virtual void Search()=0; //搜索
protected:
int p[Num];
int last,spac;
static int q[Num],d[],total;
void Printf();
bool operator==(const TEight &T);
bool Extend(int i);
};
int TEight::q[Num];//储存目标节点
int TEight::d[]={1,3,-1,-3};//方向
int TEight::total=0;//步数
TEight::TEight(char *fname)
{
ifstream fin;
fin.open(fname,ios::in);
if(!fin)
{
cout<<"不能打开数据文件!"<<endl;
return;
}
int i;
for(i=0;i<Num;)//得到源节点
fin>>p[i++];
fin>>spac;
for(i=0;i<Num;)//得到目标节点
fin>>q[i++];
fin.close();
last=-1;
total=0;
}
void TEight::Printf()//把路径打印到结果文件
{
ofstream fout;
fout.open("eight_result.txt",ios::ate|ios::app);
fout<<total++<<"t";
for(int i=0;i<Num;)
fout<<" "<<p[i++];
fout<<endl;
fout.close();
}
bool TEight::operator==(const TEight &T)//判断两个状态是否相同
{
for(int i=0;i<Num;)
if(T.p[i]!=p[i++])
return 0;
return 1;
}
bool TEight::Extend(int i)//扩展
{
if(i==0 && spac%3==2 || i==1 && spac>5
|| i==2 && spac%3==0 || i==3 && spac<3)
return 0;
int temp=spac;
spac+=d[i];
p[temp]=p[spac];
p[spac]=0;
return 1;
}
数据文件的结构:
一共三行,第一行是用空格隔开的九个数字0~8,这是初始状态。第二行是一个数字,空格(数字0)的位置,第三行也是用空格隔开的九个数字0~8,这是目标状态。
三.线性表
搜索法在搜索过程中,需要使用一个队列存储搜索的中间结点,为了在找到目标结点后,能够找到从初始结点到目标结点的路径,需要保留所有搜索过的结点。另一方面,不同问题甚至同一问题的不同搜索方法中,需要存储的结点数量相差很大,所以这里采用链式线性表作为存储结构,同时,为适应不同问题,线性表设计成类模板形式。
template<class Type> class TList; //线性表前视定义
template<class Type> class TNode //线性表结点类模板
{
friend class TList<Type>;
public:
TNode(){}
TNode(const Type& dat);
private:
TNode<Type>* Next;
Type Data;
};
template<class Type> class TList
{
public:
TList(){Last=First=0;Length=0;} //构造函数
int Getlen()const{return Length;} //成员函数,返回线性表长度
int Append(const Type& T); //成员函数,从表尾加入结点
int Insert(const Type& T,int k); //成员函数,插入结点
Type GetData(int i); //成员函数,返回结点数据成员
void SetData(const Type& T,int k); //成员函数,设置结点数据成员
private:
TNode<Type> *First,*Last; //数据成员,线性表首、尾指针
int Length; //数据成员,线性表长度
};
template<class Type> int TList<Type>::Append(const Type& T)
{
Insert(T,Length);
return 1;
}
template<class Type> int TList<Type>::Insert(const Type& T,int k)
{
TNode<Type> *p=new TNode<Type>;
p->Data=T;
if(First)
{
if(k<=0)
{
p->Next=First;
First=p;
}
if(k>Length-1)
{
Last->Next=p;
Last=Last->Next;
Last->Next=0;
}
if(k>0 && k<Length)
{
k--;
TNode<Type> *q=First;
while(k-->0)
q=q->Next;
p->Next=q->Next;
q->Next=p;
}
}
else
{
First=Last=p;
First->Next=Last->Next=0;
}
Length++;
return 1;
}
template<class Type> Type TList<Type>::GetData(int k)
{
TNode<Type> *p=First;
while(k-->0)
p=p->Next;
return p->Data;
}
template<class Type> void TList<Type>::SetData(const Type& T,int k)
{
TNode<Type> *p=First;
while(k-->0)
p=p->Next;
p->Data=T;
}
线性表单独以头文件形式存放。
四.广度优先搜索法
在搜索法中,广度优先搜索法是寻找最短路经的首选。
1.广度优先搜索算法的基本步骤
1)建立一个队列,将初始结点入队,并设置队列头和尾指针
2)取出队列头(头指针所指)的结点进行扩展,从它扩展出子结点,并将这些结点按扩展的顺序加入队列。
3)如果扩展出的新结点与队列中的结点重复,则抛弃新结点,跳至第六步。
4)如果扩展出的新结点与队列中的结点不重复,则记录其父结点,并将它加入队列,更新队列尾指针。
5)如果扩展出的结点是目标结点,则输出路径,程序结束。否则继续下一步。
6)如果队列头的结点还可以扩展,直接返回第二步。否则将队列头指针指向下一结点,再返回第二步。
2.搜索路径的输出
搜索到目标结点后,需要输出搜索的路径。每个结点有一个数据域last,它记录了结点的父结点,因此输出搜索路径时,就是从目标结点Q出发,根据last找到它的父结点,再根据这个结点的last找到它的父结点,....,最后找到初始结点。搜索的路径就是从初始结点循相反方向到达目标结点的路径。
3.广度优先搜索法TBFS类的结构
广度优先搜索法TBFS类是作为TEight类的一个子类。其类的结构和成员函数的实现如下:
class TBFS:public TEight
{
public:
TBFS(){}
TBFS(char *fname):TEight(fname){}
virtual void Search();
private:
void Printl(TList<TBFS> &L);
int Repeat(TList<TBFS> &L);
int Find();
};
void TBFS::Printl(TList<TBFS> &L)
{
TBFS T=*this;
if(T.last==-1)
return;
else
{
T=L.GetData(T.last);
T.Printl(L);
T.Printf();
}
}
int TBFS::Repeat(TList<TBFS> &L)
{
int n=L.Getlen();
int i;
for(i=0;i<n;i++)
if(L.GetData(i)==*this)
break;
return i;
}
int TBFS::Find()
{
for(int i=0;i<Num;)
if(p[i]!=q[i++])
return 0;
return 1;
}
void TBFS::Search()
{
TBFS T=*this;
TList<TBFS> L;
L.Append(T);
int head=0,tail=0;
while(head<=tail)
{
for(int i=0;i<4;i++)
{
T=L.GetData(head);
if(T.Extend(i) && T.Repeat(L)>tail)
{
T.last=head;
L.Append(T);
tail++;
}
if(T.Find())
{
T.Printl(L);
T.Printf();
return;
}
}
head++;
}
}
4.广度优先搜索法的缺点
广度优先搜索法在有解的情形总能保证搜索到最短路经,也就是移动最少步数的路径。但广度优先搜索法的最大问题在于搜索的结点数量太多,因为在广度优先搜索法中,每一个可能扩展出的结点都是搜索的对象。随着结点在搜索树上的深度增大,搜索的结点数会很快增长,并以指数形式扩张,从而所需的存储空间和搜索花费的时间也会成倍增长。
五、A*算法
1.启发式搜索
广度优先搜索和双向广度优先搜索都属于盲目搜索,这在状态空间不大的情况下是很合适的算法,可是当状态空间十分庞大时,它们的效率实在太低,往往都是在搜索了大量无关的状态结点后才碰到解答,甚至更本不能碰到解答。
搜索是一种试探性的查寻过程,为了减少搜索的盲目性引,增加试探的准确性,就要采用启发式搜索了。所谓启发式搜索就是在搜索中要对每一个搜索的位置进行评估,从中选择最好、可能容易到达目标的位置,再从这个位置向前进行搜索,这样就可以在搜索中省略大量无关的结点,提高了效率。
2.A*算法
A*算法是一种常用的启发式搜索算法。
在A*算法中,一个结点位置的好坏用估价函数来对它进行评估。A*算法的估价函数可表示为:
f'(n) = g'(n) + h'(n)
这里,f'(n)是估价函数,g'(n)是起点到终点的最短路径值(也称为最小耗费或最小代价),h'(n)是n到目标的最短路经的启发值。由于这个f'(n)其实是无法预先知道的,所以实际上使用的是下面的估价函数:
f(n) = g(n) + h(n)
其中g(n)是从初始结点到节点n的实际代价,h(n)是从结点n到目标结点的最佳路径的估计代价。在这里主要是h(n)体现了搜索的启发信息,因为g(n)是已知的。用f(n)作为f'(n)的近似,也就是用g(n)代替g'(n),h(n)代替h'(n)。这样必须满足两个条件:(1)g(n)>=g'(n)(大多数情况下都是满足的,可以不用考虑),且f必须保持单调递增。(2)h必须小于等于实际的从当前节点到达目标节点的最小耗费h(n)<=h'(n)。第二点特别的重要。可以证明应用这样的估价函数是可以找到最短路径的。
3.A*算法的步骤
A*算法基本上与广度优先算法相同,但是在扩展出一个结点后,要计算它的估价函数,并根据估价函数对待扩展的结点排序,从而保证每次扩展的结点都是估价函数最小的结点。
A*算法的步骤如下:
1)建立一个队列,计算初始结点的估价函数f,并将初始结点入队,设置队列头和尾指针。
2)取出队列头(队列头指针所指)的结点,如果该结点是目标结点,则输出路径,程序结束。否则对结点进行扩展。
3)检查扩展出的新结点是否与队列中的结点重复,若与不能再扩展的结点重复(位于队列头指针之前),则将它抛弃;若新结点与待扩展的结点重复(位于队列头指针之后),则比较两个结点的估价函数中g的大小,保留较小g值的结点。跳至第五步。
4)如果扩展出的新结点与队列中的结点不重复,则按照它的估价函数f大小将它插入队列中的头结点后待扩展结点的适当位置,使它们按从小到大的顺序排列,最后更新队列尾指针。
5)如果队列头的结点还可以扩展,直接返回第二步。否则将队列头指针指向下一结点,再返回第二步。
4.八数码问题的A*算法的估价函数
估价函数中,主要是计算h,对于不同的问题,h有不同的含义。那么在八数码问题中,h的含意是各什么?八数码问题的一个状态实际上是数字0~8的一个排列,用一个数组p[9]来存储它,数组中每个元素的下标,就是该数在排列中的位置。例如,在一个状态中,p[3]=7,则数字7的位置是3。如果目标状态数字3的位置是8,那么数字7对目标状态的偏移距离就是3,因为它要移动3步才可以回到目标状态的位置。
八数码问题中,每个数字可以有9个不同的位置,因此,在任意状态中的每个数字和目标状态中同一数字的相对距离就有9*9种,可以先将这些相对距离算出来,用一个矩阵存储,这样只要知道两个状态中同一个数字的位置,就可查出它们的相对距离,也就是该数字的偏移距离:
0 1 2 3 4 5 6 7 8
0 0 1 2 1 2 3 2 3 4
1 1 0 1 2 1 2 3 2 3
2 2 1 0 3 2 1 4 3 2
3 1 2 3 0 1 2 1 2 3
4 2 1 2 1 0 1 2 1 2
5 3 2 1 2 1 0 3 2 1
6 2 3 4 1 2 3 0 1 2
7 3 2 3 2 1 2 1 0 1
8 4 3 2 3 2 1 2 1 0
例如在一个状态中,数字8的位置是3,在另一状态中位置是7,那么从矩阵的3行7列可找到2,它就是8在两个状态中的偏移距离。
估价函数中的h就是全体数字偏移距离之和。显然,要计算两个不同状态中同一数字的偏移距离,需要知道该数字在每个状态中的位置,这就要对数组p[9]进行扫描。由于状态发生变化,个数字的位置也要变化,所以每次计算h都沿线扫描数组,以确定每个数字在数组中的位置。为了简化计算,这里用一个数组存储状态中各个数字的位置,并让它在状态改变时随着变化,这样就不必在每次计算h时,再去扫描状态数组。
例如,某个状态中,数字5的位置是8,如果用数组r[9]存储位置,那么就有r[5]=8。
现在用数组r[9]存储当前状态的数字位置,而用s[9]存储目标状态的数字位置,那么当前状态数字i对目标状态的偏移距离就是矩阵中r[i]行s[i]列对应的值。
5.A*算法的类结构
A*算法的类声明如下:
class TAstar:public TEight
{
public:
TAstar(){} //构造函数
TAstar(char *fname); //带参数构造函数
virtual void Search(); //A*搜索法
private:
int f,g,h; //估价函数
int r[Num]; //存储状态中各个数字位置的辅助数组
static int s[Num]; //存储目标状态中各个数字位置的辅助数组
static int e[]; //存储各个数字相对距离的辅助数组
void Printl(TList<TAstar> L); //成员函数,输出搜索路径
int Expend(int i); //成员函数,A*算法的状态扩展函数
int Calcuf(); //成员函数,计算估价函数
void Sort(TList<TAstar>& L,int k); //成员函数,将新扩展结点按f从小到大顺序插入待扩展结点队列
int Repeat(TList<TAstar> &L); //成员函数,检查结点是否重复
};
int TAstar::s[Num],TAstar::e[Num*Num];
TAstar::TAstar(char *fname):TEight(fname)
{
for(int i=0;i<Num;)
{
r[p[i]]=i; //存储初始状态个个数字的位置
s[q[i]]=i++; //存储目标状态个个数字的位置
}
ifstream fin;
fin.open("eight_dis.txt",ios::in); //打开数据文件
if(!fin)
{
cout<<"不能打开数据文件!"<<endl;
return;
}
for(int i=0;i<Num*Num;i++) //读入各个数字相对距离值
fin>>e[i];
fin.close();
f=g=h=0; //估价函数初始值
}
void TAstar::Printl(TList<TAstar> L)
{
TAstar T=*this;
if(T.last==-1) return;
else
{
T=L.GetData(T.last);
T.Printl(L);
T.Printf();
}
}
int TAstar::Expend(int i)
{
if(Extend(i)) //结点可扩展
{
int temp=r[p[r[0]]]; //改变状态后数字位置变化,存储改变后的位置
r[p[r[0]]]=r[0];
r[0]=temp;
return 1;
}
return 0;
}
int TAstar::Calcuf()
{
h=0;
for(int i=0;i<Num;i++) //计算估价函数的 h
h+=e[Num*r[i]+s[i]];
return ++g+h;
}
void TAstar::Sort(TList<TAstar>& L,int k)
{
int n=L.Getlen();
int i;
for(i=k+1;i<n;i++)
{
TAstar T=L.GetData(i);
if(this->f<=T.f)
break;
}
L.Insert(*this,i);
}
int TAstar::Repeat(TList<TAstar> &L)
{
int n=L.Getlen();
int i;
for(i=0;i<n;i++)
if(L.GetData(i)==*this)
break;
return i;
}
void TAstar::Search()
{
TAstar T=*this; //初始结点
T.f=T.Calcuf(); //初始结点的估价函数
TList<TAstar> L; //建立队列
L.Append(T); //初始结点入队
int head=0,tail=0; //队列头和尾指针
while(head<=tail) //队列不空则循环
{
for(int i=0;i<4;i++) //空格可能移动方向
{
T=L.GetData(head); //去队列头结点
if(T.h==0) //是目标结点
{
T.Printl(L);//输出搜索路径
T.Printf(); //输出目标状态
return; //结束
}
if(T.Expend(i)) //若结点可扩展
{
int k=T.Repeat(L); //返回与已扩展结点重复的序号
if(k<head) //如果是不能扩展的结点
continue; //丢弃
T.last=head; //不是不能扩展的结点,记录父结点
T.f=T.Calcuf(); //计算f
if(k<=tail) //新结点与可扩展结点重复
{
TAstar Temp=L.GetData(k);
if(Temp.g>T.g) //比较两结点g值
L.SetData(T,k); //保留g值小的
continue;
}
T.Sort(L,head) ; //新结点插入可扩展结点队列
tail++; //队列尾指针后移
}
}
head++; //一个结点不能再扩展,队列头指针指向下一结点
}
}
六、测试程序
A*算法的测试:
int main()
{
TAstar aStar("eight.txt");
aStar.Search();
system("pauze");
return 0;
}
eight.txt文件中的数据(初始态和目标态):
一共三行,第一行是用空格隔开的九个数字0~8,这是初始状态。第二行是一个数字,空格(数字0)的位置,第三行也是用空格隔开的九个数字0~8,这是目标状态。
8 3 5 1 2 7 4 6 0
8
1 2 3 4 5 6 7 8 0
eight_dis.txt中的数据(估计函数使用)
0 1 2 1 2 3 2 3 4
1 0 1 2 1 2 3 2 3
2 1 0 3 2 1 4 3 2
1 2 3 0 1 2 1 2 3
2 1 2 1 0 1 2 1 2
3 2 1 2 1 0 3 2 1
2 3 4 1 2 3 0 1 2
3 2 3 2 1 2 1 0 1
4 3 2 3 2 1 2 1 0
eight_Result.txt中的结果(运行后得到的结果)
七、算法运行结果
1.BFS算法只能适用于到达目标结点步数较少的情况,如果步数超过15步,运行时间太长,实际上不再起作用。
2.对于随机生成的同一个可解状态,BFS算法最慢,DBFS算法较慢,A*算法较快。但在15步以内,DBFS算法与A*算法相差时间不大,超过15步后,随步数增加,A*算法的优势就逐渐明显,A*算法要比DBFS算法快5倍以上,并随步数增大而增大。到25步以上,DBFS同样因运行时间过长而失去价值。
3.一般来说,解答的移动步数每增加1,程序运行时间就要增加5倍以上。由于八数码问题本身的特点,需要检查的节点随步数增大呈指数形式增加,即使用A*算法,也难解决移动步数更多的问题。
八、问题可解性
八数码问题的一个状态实际上是0~9的一个排列,对于任意给定的初始状态和目标,不一定有解,也就是说从初始状态不一定能到达目标状态。因为排列有奇排列和偶排列两类,从奇排列不能转化成偶排列或相反。
如果一个数字0~8的随机排列871526340,用F(X)表示数字X前面比它小的数的个数,全部数字的F(X)之和为Y=∑(F(X)),如果Y为奇数则称原数字的排列是奇排列,如果Y为偶数则称原数字的排列是偶排列。
例如871526340这个排列的
Y=0+0+0+1+1+3+2+3+0=10
10是偶数,所以他偶排列。871625340
Y=0+0+0+1+1+2+2+3+0=9
9是奇数,所以他奇排列。
因此,可以在运行程序前检查初始状态和目标状态的窘是否相同,相同则问题可解,应当能搜索到路径。否则无解。
PS:整理自网络
⑽ 象棋对弈软件是如何编制出来的
呵呵,开始我也觉得没有破绽,后来发现了软件也会出昏招。原来原理很简单,只是把基本的开局定式以及常见的对弈拆解局面转换成数据库函数,当出现数据库招数,便调出同类型的宏功能。说到底,只是电脑软件做到了更多的对弈棋局收集,把相关的招数进行了数码汇编。比如:仙人指路开局,软件就会自动把存储在数据库中的符合这一定式类型的所有函数自动调出,选择基本应招(根据用户选手游戏难度不同,软件也会选择相应招数致胜比率和复杂程度)。所以按一般局面和软件玩,就等于和一个熟读兵法的谋士作战,很难赢。你会有看不透,想不到的时候,软件按步就班,数据库就是它的眼睛和脑袋。但是编制软件的并不是一流大师,他们手头上有的都是找得到的棋局,但是棋盘千变万化,有很多招式不可能存在软件中,所以软件也会碰到出昏招的时候。我们可以做一个小实验,两台电脑玩相同的象棋游戏,如果以A电脑进行先手,B电脑进行后手,以B电脑的招式来和A电脑下。百分之九十九的机率是和棋。如果我们用自己的方式操作B电脑和A电脑进行至中局(有一方有多子优势),然后再让两台电脑自己下,肯定有一台电脑是输的。你就会发现输的电脑下的棋局很一般,因为它还是在以应对的形式开展,试问没有优势的情况下,那台数据库一样的电脑软件会出现奇招嘛?也就是说软件也是会输的。我记得国际象棋那个深蓝也输给过卡斯帕罗夫,然后那个更深的蓝赢了卡斯帕罗夫。还是赢在数据采集啊。