算法

最佳调度(回溯法)

走远了吗. 提交于 2020-01-30 04:39:07
最佳调度问题 【问题描述】 假设有n个任务由k个可并行工作的机器完成。完成任务i需要的时间为ti。试设计一个算法找出完成这n个任务的最佳调度,使得完成全部任务的时间最早。 【编程任务】 对任意给定的整数n和k,以及完成任务i需要的时间为ti,i=1~n。编程计算完成这n个任务的最佳调度。 【输入样例】 7 3 2 14 4 16 6 5 3 【输出样例】 17 首先列个七乘三的二维数组了解算法思路: 我们知道回溯法其实是穷举法加剪枝函数 我们的函数用到递归,层层返回。 解空间树为一颗n叉树,每搜索到叶子节点就更新一次最大值,是用一次搜索结束后三个机器中花费时间最长的机器的所用时间作为此次分配的所用时间。 上图:红色为第一次分配;黄背景色为第二次;加粗字体为第三次;下划线为第四次。从上到下递归,然后层层返回。 算法设计: 从n个作业中找出有最小完成时间和的作业调度,所以批处理作业调度问题的解空间是一棵排列树。按照回溯法搜索排列树的算法框架,设开始时t=[1,2, … , n]是所给的n个作业的完成时间,则相应的排列树由t[1:n]的所有排列构成。 数组len[]用于存储一组空间解,comp()函数用于计算一个完整调度的完成时间,search()函数用来做搜索,best记录相应的当前最佳作业调度完成时间。 当dep>n时,算法搜索至叶子结点,得到一个新的作业调度方案

离散粒子群优化应用到时间窗车辆调度问题(matlab+附github链接)

老子叫甜甜 提交于 2020-01-30 02:12:59
项目简介: 最近需要实现一篇论文的算法,讲的是将PSO(粒子群算法)应用到TSPTW问题(时间窗车辆调度问题)上,查询了一些资料,以往的资料大多是蚁群算法的应用,所以就试着自己一步步完成这个算法。 参考论文: [1]A Novel Set-Based Particle Swarm Optimization Method for Discrete Optimization Problems [2]Gong Y J, Zhang J, Liu O, et al. Optimizing the Vehicle Routing Problem With Time Windows: A Discrete Particle Swarm Optimization Approach[J]. IEEE Transactions on Systems Man & Cybernetics Part C, 2012, 42(2):254-267. 论文建议先阅读[1], 再阅读[2]会比较好理解,这个算法比较巧妙的地方在于我们将每一个可能的路线规划图作为一个粒子(注意是将整个规划图作为一个粒子而不是规划图中的节点,我们让粒子进行运动并且不断修改它的运动方向,其实就是调整规划图中连接节点各条边的指向,使得粒子位置被不断进行更新,新的粒子对应着各条边被调整后的整幅规划图)

HDOJ1686 / POJ 3461 Oulipo #KMP算法#

点点圈 提交于 2020-01-30 01:31:16
Oulipo Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 59573 Accepted: 23116 Description The French author Georges Perec (1936–1982) once wrote a book, La disparition, without the letter 'e'. He was a member of the Oulipo group. A quote from the book: Tout avait Pair normal, mais tout s’affirmait faux. Tout avait Fair normal, d’abord, puis surgissait l’inhumain, l’affolant. Il aurait voulu savoir où s’articulait l’association qui l’unissait au roman : stir son tapis, assaillant à tout instant son imagination, l’intuition d’un tabou, la vision d’un mal obscur, d’un quoi vacant, d’un

粒子群算法简介及应用

五迷三道 提交于 2020-01-30 00:05:28
简介 定义 粒子群优化算法(Particle Swarm optimization,PSO)又翻译为粒子群算法、微粒群算法、或微粒群优化算法。是通过模拟鸟群觅食行为而发展起来的一种基于群体协作的随机搜索算法。通常认为它是群集智能 (Swarm intelligence, SI) 的一种。它可以被纳入多主体优化系统(Multiagent Optimization System, MAOS). 模拟捕食 SO模拟鸟群的捕食行为。一群鸟在随机搜索食物,在这个区域里只有一块食物。所有的鸟都不知道食物在那里。但是他们知道当前的位置离食物还有多远。那么找到食物的最优策略是什么呢。最简单有效的就是搜寻离食物最近的鸟的周围区域。 抽象成粒子 PSO中,每个优化问题的解都是搜索空间中的一只鸟。我们称之为“粒子”。所有的粒子都有一个由被优化的函数决定的适应值(fitnessvalue),每个粒子还有一个速度决定他们飞翔的方向和距离。然后粒子们就追随当前的最优粒子在解空间中搜索。 更新 PSO初始化为一群随机粒子(随机解),然后通过迭代找到最优解,在每一次叠代中,粒子通过跟踪两个“极值”来更新自己。第一个就是粒子本身所找到的最优解,这个解叫做个体极值pBest,另一个极值是整个种群找到的最优解,这个极值是全局极值gBest。另外也可以不用整个种群而只是用其中一部分最优粒子的邻居

排序算法

筅森魡賤 提交于 2020-01-29 23:13:51
第一种:选择排序 第二种:冒泡排序、改进冒泡排序 第三种:插入排序 第四种:快速排序 第五种:归并排序 #include<iostream> #include<cstring> using namespace std; const int MAXN=1000; int a[MAXN]; int n; //选择排序 void xuanze(){ int k; for(int i=0;i<n;i++){ k=i; for(int j=i+1;j<n;j++) if(a[j]<a[k]) k=j; //注意是a[j]<a[[k] if(k!=i) { swap(a[i],a[k]); } } cout<<"选择排序如下: "; for(int i=0;i<n;i++) cout<<a[i]<<" "; cout<<endl; } //冒泡排序 void maopao(){ for(int i=n-1;i>=1;i--){ for(int j=0;j<i;j++){ if(a[j]>a[j+1]) swap(a[j],a[j+1]); } } cout<<"冒泡排序如下: "; for(int i=0;i<n;i++) cout<<a[i]<<" "; cout<<endl; } //改进冒泡排序 void impmaopao(){ bool ok; for(int i=n-1;i>=1

Hash签名 (数字摘要算法)

ぐ巨炮叔叔 提交于 2020-01-29 21:11:55
一、什么是Hash签名? Hash签名是最主要的数字签名方法,也称之为数字摘要法(Digital Digest)或数字指纹法(Digital Finger Print)。数字摘要就是采用单项Hash函数将需要加密的明文“摘要”成一串固定长度(128位)的密文这一串密文又称为数字指纹,它有固定的长度,而且不同的明文摘要成密文,其结果总是不同的,而同样的明文其摘要必定一致。 二、数字签名和验证的文件传输过程如下: (1) 被发送文件用MD5编码加密产生128bit的数字摘要。 (2) 发送方用自己的私用 密钥 对摘要再加密,这就形成了数字签名。 (3) 将原文和加密的摘要同时传给对方。 (4) 对方用发送方的公共密钥对摘要解密,同时对收到的文件用MD5编码加密产生又一摘要。 (5) 将解密后的摘要和收到的文件在接收方重新加密产生的摘要相互对比。如两者一致,则说明传送过程中信息没有被破坏或篡改过。否则不然。 三、常见Hash算法 : MD2 MD4 MD5 HAVAL SHA 来源: https://www.cnblogs.com/naray/p/4191543.html

算法笔记——搜索初步

给你一囗甜甜゛ 提交于 2020-01-29 21:03:36
把这几天学的搜索做一个初步总结。 一、 深度优先搜索(DFS):从起点出发,走过的点要做标记,发现有没走过的点,就随意挑一个往前走,走不动了就回退。不能走已经走过的点(需要判重)。 举几个栗子: 1.判断从V出发是否能走到终点: bool Dfs(V) { if( V 为终点) return true; if( V 为旧点) return false; 将V标记为旧点; 对和V相邻的每个节点U { if( Dfs(U) == true) return true; } return false; } 判断从v出发是否能走到终点时,返回值有意义。 因为有回溯的过程,所以会把k出发能走到的点都走一遍。 2.判断从v出发是否能走到终点,如果能,要记录路径。 bool Dfs(V) { if( V为终点) { path[depth] = V; return true; } if( V 为旧点) return false; 将V标记为旧点; path[depth]=V; ++depth; 对和V相邻的每个节点U { if( Dfs(U) == true) return true; } --depth; return false; } --depth的过程就是回溯的过程。 3.在图中寻找最优(步数最少路径) void Dfs(V) { if( V为终点) { path[depth] = V;

JAVA经典算法(四十)

余生长醉 提交于 2020-01-29 20:39:06
题目:海滩上有一堆桃子,五只猴子来分。第一只猴子把这堆桃子凭据分为五份,多了一个,这只猴子把多的一个扔入海中,拿走了一份。第二只猴子把剩下的桃子又平均分成五份,又多了一个,它同样把多的一个扔入海中,拿走了一份,第三、第四、第五只猴子都是这样做的,问海滩上原来最少有多少个桃子? package cn.ls.lanqiao; public class Test40 { public static void main(String[] args) { for (int i = 1;; i++) { int sum = i; if ((sum - 1) % 5 == 0) { sum = (sum - 1) / 5 * 4; if ((sum - 1) % 5 == 0) { sum = (sum - 1) / 5 * 4; if ((sum - 1) % 5 == 0) { sum = (sum - 1) / 5 * 4; if ((sum - 1) % 5 == 0) { sum = (sum - 1) / 5 * 4; if ((sum - 1) % 5 == 0) { System.out.println(i); break; } } } } } } } } 来源: CSDN 作者: ls~wifi 链接: https://blog.csdn.net/ls_wifi/article

Java 实现四位数的吸血鬼算法

偶尔善良 提交于 2020-01-29 18:19:08
public class Main { public static void main(String[] args) { int[] startDigit = new int[4]; int[] productDigit = new int[4]; // 可以判断: 两个数只有两位数字,num1和num2代表这两个数 for (int num1 = 10; num1 <= 99; num1++) { for (int num2 = num1; num2 <= 99; num2++) { // 得到num1和num2两个数的乘积 int product = num1 * num2; // 将num1和num2的个位十位进行分离,存储到startDigit[]数组中 startDigit[0] = num1 / 10; startDigit[1] = num1 % 10; startDigit[2] = num2 / 10; startDigit[3] = num2 % 10; // 将得到的乘积四位数进行分割得到四个数组,并存放到productDigit[]数组中 productDigit[0] = product / 1000; productDigit[1] = product % 1000 / 100; productDigit[2] = product % 1000 %

算法训练——学做菜

烂漫一生 提交于 2020-01-29 16:30:56
//学做菜 #include<stdio.h> int main(){ int a,b,c,d,num = 0; scanf("%d\n%d\n%d\n%d",&a,&b,&c,&d); while(1){ if(a>=2 && b>=1 && d >=2){ //可以做菜品1 num++; a-=2; b-=1; d-=2; } else{ break; } } printf("%d\n",num); num = 0; while(1){ if(a>=1&&b>=1&&c>=1&&d>=1){ //可以做菜品2 num++; a-=1; b-=1; c-=1; d-=1; } else{ break; } } printf("%d\n",num); num = 0; while(1){ if(c>=2&&d>=1){ //可以做菜谱3 num++; c-=2; d-=1; } else{ break; } } printf("%d\n",num); num = 0; while(1){ if(b>=3){ //可以做菜谱4 num++; b-=3; } else break; } printf("%d\n",num); num = 0; while(1){ if(a>=1&&d>=1){ //可以做菜谱5 num++; a-=1; d-=1; } else break; }