Java 动态规划

article/2025/9/11 17:58:20

Java中的动态规划

介绍

动态规划典型的被用于优化递归算法,因为它们倾向于以指数的方式进行扩展。动态规划主要思想是将复杂问题(带有许多递归调用)分解为更小的子问题,然后将它们保存到内存中,这样我们就不必在每次使用它们时重新计算它们。

要理解动态规划的概念,我们需要熟悉一些主题:

  1. 什么是动态规划?
  2. 贪心算法
  3. 简化的背包问题
  4. 传统的背包问题
  5. LCS-最长的共同子序列
  6. 利用动态规划的其他问题
  7. 结论

什么是动态规划?

动态规划是一种编程原理,可以通过将非常复杂的问题划分为更小的子问题来解决。这个原则与递归很类似,但是与递归有一个关键点的不同,就是每个不同的子问题只能被解决一次。

为了理解动态规划,我们首先需要理解递归关系的问题。每个单独的复杂问题可以被划分为很小的子问题,这表示我们可以在这些问题之间构造一个递归关系。
让我们来看一个我们所熟悉的例子:斐波拉契数列,斐波拉契数列的定义具有以下的递归关系:
在这里插入图片描述
注意:递归关系是递归地定义下一项是先前项的函数的序列的等式。Fibonacci序列就是一个很好的例子。

所以,如果我们想要找到斐波拉契数列序列中的第n个数,我们必须知道序列中第n个前面的两个数字。

但是,每次我们想要计算Fibonacci序列的不同元素时,我们在递归调用中都有一些重复调用,如下图所示,我们计算Fibonacci(5)
在这里插入图片描述

例如:如果我们想计算F(5),明显的我们需要计算F(3)F(4)作为计算F(5)的先决条件。然而,为了计算F(4),我们需要计算F(3)F(2),因此我们又需要计算F(2)F(1)来得到F(3),其他的求解诸如此类。

这样的话就会导致很多重复的计算,这些重复计算本质上是冗余的,并且明显的减慢了算法的效率。为了解决这种问题,我们介绍动态规划。

在这种方法中,我们对解决方案进行建模,就像我们要递归地解决它一样,但我们从头开始解决它,将解决方案记忆到我们到达顶部的子问题(步骤)。
因此,对于Fibonacci序列,我们首先求解并记忆F(1)F(2),然后使用两个记忆步骤计算F(3),依此类推。这意味着序列中每个单独元素的计算都是O(1),因为我们已经知道前两个元素。

当使用动态规划解决问题的时候,我们一般会采用下面三个步骤:

  1. 确定适用于所述问题的递归关系
  2. 初始化内存、数组、矩阵的初始值
  3. 确保当我们进行递归调用(可以访问子问题的答案)的时候它总是被提前解决。

遵循这些规则,让我们来看一下使用动态规划的算法的例子:

贪心算法

下面来以这个为例子:

Given a rod of length n and an array that contains prices of all pieces of size smaller than n. Determine the maximum value obtainable by cutting up the rod and selling the pieces.

###对于没有经验的开发者可能会采取下面这种做法:###

这个问题实际上是为动态规划量身定做的,但是因为这是我们的第一个真实例子,让我们看看通过运行这些代码运行来遇到多少问题:

public class naiveSolution {  static int getValue(int[] values, int length) {if (length <= 0)return 0;int tmpMax = -1;for (int i = 0; i < length; i++) {tmpMax = Math.max(tmpMax, values[i] + getValue(values, length - i - 1));}return tmpMax;}public static void main(String[] args) {int[] values = new int[]{3, 7, 1, 3, 9};int rodLength = values.length;System.out.println("Max rod value: " + getValue(values, rodLength));}
}

输出结果:

Max rod value: 17

虽然这段代码得到的结果是正确的,按时代码的效率和很低。因为递归调用的结果不可以被保存因此代码不得不每次都去解决相同的子问题,这里就会存在一个重叠的答案。

动态方法

利用上面相同的基本原理,但添加memoization并排除递归调用,我们得到以下实现:

public class dpSolution {  static int getValue(int[] values, int rodLength) {int[] subSolutions = new int[rodLength + 1];for (int i = 1; i <= rodLength; i++) {int tmpMax = -1;for (int j = 0; j < i; j++)tmpMax = Math.max(tmpMax, values[j] + subSolutions[i - j - 1]);subSolutions[i] = tmpMax;}return subSolutions[rodLength];}public static void main(String[] args) {int[] values = new int[]{3, 7, 1, 3, 9};int rodLength = values.length;System.out.println("Max rod value: " + getValue(values, rodLength));}
}

输出结果:

Max rod value: 17

正如我们所看到的的,输出结果是一样的,所不同的是时间和空间复杂度。

通过从头开始解决子问题,我们消除了递归调用的需要,利用已解决给定问题的所有先前子问题的事实。

性能的提升

为了给出动态方法效率更高的观点的证据,让我们尝试使用30个值来运行该算法。 一种算法需要大约5.2秒来执行,而动态解决方法需要大约0.000095秒来执行。

简化的背包问题

简化的背包问题是一个优化问题,没有一个解决方案。这个问题的问题是 - “解决方案是否存在?”:

Given a set of items, each with a weight w1, w2... determine the number of each item to put in a knapsack so that the total weight is less than or equal to a given limit K.

首先让我们把元素的所有权重存储在W数组中。接下来,假设有n个项目,我们将使用从1到n的数字枚举它们,因此第i个项目的权重为W [i]。我们将形成(n + 1)x(K + 1)维的矩阵MM [x] [y]对应于背包问题的解决方案,但仅包括起始数组的前x个项,并且最大容量为y

例如

假设我们有3个元素,权重分别是w1=2kg,w2=3kg,w3=4kg。利用上面的方法,我们可以说M [1] [2]是一个有效的解决方案。
这意味着我们正在尝试用重量阵列中的第一个项目(w1)填充容量为2kg的背包。

M [3] [5]中,我们尝试使用重量阵列的前3项(w1,w2,w3)填充容量为5kg的背包。
这不是一个有效的解决方案,因为我们过度拟合它。

矩阵初始化

当初始化矩阵的时候有两点需要注意:

Does a solution exist for the given subproblem (M[x][y].exists) AND does the given solution include the latest item added to the array (M[x][y].includes).

因此,初始化矩阵是相当容易的,M[0][k].exists总是false,如果k>0,因为我们没有把任何物品放在带有k容量的背包里。

另一方面,M[0][0].exists = true,当k=0的时候,背包应该是空的,因此我们在里面没有放任何东西,这个是一个有效的解决方案。

此外,我们可以说M[k][0].exists = true,但是对于每个k来说 M[k][0].includes = false

注意:仅仅因为对于给定的M [x] [y]存在解决方案,它并不一定意味着该特定组合是解决方案。
M [10] [0]的情况下,存在一种解决方案 - 不包括10个元素中的任何一个。
这就是M [10] [0] .exists = trueM [10] [0] .includes = false的原因。

算法原则

接下来,让我们使用以下伪代码构造M [i] [k]的递归关系:

if (M[i-1][k].exists == True):  M[i][k].exists = TrueM[i][k].includes = False
elif (k-W[i]>=0):  if(M[i-1][k-W[i]].exists == true):M[i][k].exists = TrueM[i][k].includes = True
else:  M[i][k].exists = False

因此,解决方案的要点是将子问题分为两种情况:

  1. 对于容量k,当存在第一个i-1元素的解决方案
  2. 对于容量k-W [i],当第一个i-1元素存在解决方案

第一种情况是不言自明的,我们已经有了问题的解决方案。

实现:

下面这何种实现方式,使得事情变得更加容易,我们创建了一个类Element来存储元素:

public class Element {  private boolean exists;private boolean includes;public Element(boolean exists, boolean includes) {this.exists = exists;this.includes = includes;}public Element(boolean exists) {this.exists = exists;this.includes = false;}public boolean isExists() {return exists;}public void setExists(boolean exists) {this.exists = exists;}public boolean isIncludes() {return includes;}public void setIncludes(boolean includes) {this.includes = includes;}
}

接着,我们可以深入了解主要的类:

public class Knapsack {  public static void main(String[] args) {Scanner scanner = new Scanner (System.in);System.out.println("Insert knapsack capacity:");int k = scanner.nextInt();System.out.println("Insert number of items:");int n = scanner.nextInt();System.out.println("Insert weights: ");int[] weights = new int[n + 1];for (int i = 1; i <= n; i++) {weights[i] = scanner.nextInt();}Element[][] elementMatrix = new Element[n + 1][k + 1];elementMatrix[0][0] = new Element(true);for (int i = 1; i <= k; i++) {elementMatrix[0][i] = new Element(false);}for (int i = 1; i <= n; i++) {for (int j = 0; j <= k; j++) {elementMatrix[i][j] = new Element(false);if (elementMatrix[i - 1][j].isExists()) {elementMatrix[i][j].setExists(true);elementMatrix[i][j].setIncludes(false);} else if (j >= weights[i]) {if (elementMatrix[i - 1][j - weights[i]].isExists()) {elementMatrix[i][j].setExists(true);elementMatrix[i][j].setIncludes(true);}}}}System.out.println(elementMatrix[n][k].isExists());}
}

唯一剩下的就是解决方案的重建,在上面的类中,我们知道解决方案是存在的,但是我们不知道它是什么。

为了重建,我们使用下面的代码:

List<Integer> solution = new ArrayList<>(n);if (elementMatrix[n][k].isExists()) {  int i = n;int j = k;while (j > 0 && i > 0) {if (elementMatrix[i][j].isIncludes()) {solution.add(i);j = j - weights[i];}i = i - 1;}
}System.out.println("The elements with the following indexes are in the solution:\n" + (solution.toString()));  

输出:

Insert knapsack capacity:  
12  
Insert number of items:  
5  
Insert weights:  
9 7 4 10 3  
true  
The elements with the following indexes are in the solution:  
[5, 1]

背包问题的一个简单变化是在没有价值优化的情况下填充背包,但现在每个单独项目的数量无限。

通过对现有代码进行简单调整,可以解决这种变化:

// Old code for simplified knapsack problem
else if (j >= weights[i]) {  if (elementMatrix[i - 1][j - weights[i]].isExists()) {elementMatrix[i][j].setExists(true);elementMatrix[i][j].setIncludes(true);}
}// New code, note that we're searching for a solution in the same
// row (i-th row), which means we're looking for a solution that
// already has some number of i-th elements (including 0) in it's solution
else if (j >= weights[i]) {  if (elementMatrix[i][j - weights[i]].isExists()) {elementMatrix[i][j].setExists(true);elementMatrix[i][j].setIncludes(true);}
}

传统的背包问题

利用以前的两种变体,现在让我们来看看传统的背包问题,看看它与简化版本的不同之处:

Given a set of items, each with a weight w1, w2... and a value v1, v2... determine the number of each item to include in a collection so that the total weight is less than or equal to a given limit k and the total value is as large as possible.

在简化版中,每个解决方案都同样出色。但是,现在我们有一个找到最佳解决方案的标准(也就是可能的最大值)。请记住,这次我们每个项目都有无限数量,因此项目可以在解决方案中多次出现。

在实现中,我们将使用旧的类Element,其中添加了私有字段value,用于存储给定子问题的最大可能值:

public class Element {  private boolean exists;private boolean includes;private int value;// appropriate constructors, getters and setters
}

实现非常相似,唯一的区别是现在我们必须根据结果值选择最佳解决方案:

public static void main(String[] args) {  // Same code as before with the addition of the values[] arraySystem.out.println("Insert values: ");int[] values = new int[n + 1];for (int i=1; i <= n; i++) {values[i] = scanner.nextInt();}Element[][] elementMatrix = new Element[n + 1][k + 1];// A matrix that indicates how many newest objects are used// in the optimal solution.// Example: contains[5][10] indicates how many objects with// the weight of W[5] are contained in the optimal solution// for a knapsack of capacity K=10int[][] contains = new int[n + 1][k + 1];elementMatrix[0][0] = new Element(0);for (int i = 1; i <= n; i++) {elementMatrix[i][0] = new Element(0);contains[i][0] = 0;}for (int i = 1; i <= k; i++) {elementMatrix[0][i] = new Element(0);contains[0][i] = 0;}for (int i = 1; i <= n; i++) {for (int j = 0; j <= k; j++) {elementMatrix[i][j] = new Element(elementMatrix[i - 1][j].getValue());contains[i][j] = 0;elementMatrix[i][j].setIncludes(false);elementMatrix[i][j].setValue(M[i - 1][j].getValue());if (j >= weights[i]) {if ((elementMatrix[i][j - weights[i]].getValue() > 0 || j == weights[i])) {if (elementMatrix[i][j - weights[i]].getValue() + values[i] > M[i][j].getValue()) {elementMatrix[i][j].setIncludes(true);elementMatrix[i][j].setValue(M[i][j - weights[i]].getValue() + values[i]);contains[i][j] = contains[i][j - weights[i]] + 1;}}}System.out.print(elementMatrix[i][j].getValue() + "/" + contains[i][j] + "  ");}System.out.println();}System.out.println("Value: " + elementMatrix[n][k].getValue());
}

输出:

Insert knapsack capacity:  
12  
Insert number of items:  
5  
Insert weights:  
9 7 4 10 3  
Insert values:  
1 2 3 4 5  
0/0  0/0  0/0  0/0  0/0  0/0  0/0  0/0  0/0  1/1  0/0  0/0  0/0  
0/0  0/0  0/0  0/0  0/0  0/0  0/0  2/1  0/0  1/0  0/0  0/0  0/0  
0/0  0/0  0/0  0/0  3/1  0/0  0/0  2/0  6/2  1/0  0/0  5/1  9/3  
0/0  0/0  0/0  0/0  3/0  0/0  0/0  2/0  6/0  1/0  4/1  5/0  9/0  
0/0  0/0  0/0  5/1  3/0  0/0  10/2  8/1  6/0  15/3  13/2  11/1  20/4  
Value: 20  

Levenshtein Distance

另一个使用动态规划的非常好的例子是Edit DistanceLevenshtein Distance

Levenshtein Distance就是两个字符串A,B,我们需要使用原子操作将A转换为B

  1. 字符串删除
  2. 字符串插入
  3. 字符替换(从技术上讲,它不止一个操作,但为了简单起见,我们称之为原子操作)

这个问题是通过有条理地解决起始字符串的子串的问题来处理的,逐渐增加子字符串的大小,直到它们等于起始字符串。

我们用于此问题的递归关系如下:
在这里插入图片描述
如果a == bc(a,b)为0,如果a = = bc(a,b)为1。

实现:

public class editDistance {  public static void main(String[] args) {String s1, s2;Scanner scanner = new Scanner(System.in);System.out.println("Insert first string:");s1 = scanner.next();System.out.println("Insert second string:");s2 = scanner.next();int n, m;n = s1.length();m = s2.length();// Matrix of substring edit distances// example: distance[a][b] is the edit distance// of the first a letters of s1 and b letters of s2int[][] distance = new int[n + 1][m + 1];// Matrix initialization:// If we want to turn any string into an empty string// the fastest way no doubt is to just delete// every letter individually.// The same principle applies if we have to turn an empty string// into a non empty string, we just add appropriate letters// until the strings are equal.for (int i = 0; i <= n; i++) {distance[i][0] = i;}for (int j = 0; j <= n; j++) {distance[0][j] = j;}// Variables for storing potential values of current edit distanceint e1, e2, e3, min;for (int i = 1; i <= n; i++) {for (int j = 1; j <= m; j++) {e1 = distance[i - 1][j] + 1;e2 = distance[i][j - 1] + 1;if (s1.charAt(i - 1) == s2.charAt(j - 1)) {e3 = distance[i - 1][j - 1];} else {e3 = distance[i - 1][j - 1] + 1;}min = Math.min(e1, e2);min = Math.min(min, e3);distance[i][j] = min;}}System.out.println("Edit distance of s1 and s2 is: " + distance[n][m]);}
}

输出:

Insert first string:  
man  
Insert second string:  
machine  
Edit distance of s1 and s2 is: 3  

最长共同子序列(LCS)

这个问题描述如下:

Given two sequences, find the length of the longest subsequence present in both of them. A subsequence is a sequence that appears in the same relative order, but not necessarily contiguous.

给定两个序列,找到两个序列中存在的最长子序列的长度。子序列是以相同的相对顺序出现的序列,但不一定是连续的.

阐明:

如果我们有两个字符串s1="MICE"s2="MINCE",最长的共同子序列是MI或者CE。但是,最长的公共子序列将是“MICE”,因为结果子序列的元素不必是连续的顺序。

递归关系与一般逻辑:
在这里插入图片描述
我们可以看到,Levenshtein distanceLCS之间只有微小的差别,特别是移动成本。

LCS中,我们没有字符插入和字符删除的成本,这意味着我们只计算字符替换(对角线移动)的成本,如果两个当前字符串字符a [i]b [j] 是相同的,则成本为1。

LCS的最终成本是2个字符串的最长子序列的长度,这正是我们所需要的。

Using this logic, we can boil down a lot of string comparison algorithms to simple recurrence relations which utilize the base formula of the Levenshtein distance

使用这个逻辑,我们可以将许多字符串比较算法归结为简单的递归关系,它使用Levenshtein distance的基本公式。

实现:

public class LCS {  public static void main(String[] args) {String s1 = new String("Hillfinger");String s2 = new String("Hilfiger");int n = s1.length();int m = s2.length();int[][] solutionMatrix = new int[n+1][m+1];for (int i = 0; i < n; i++) {solutionMatrix[i][0] = 0;}for (int i = 0; i < m; i++) {solutionMatrix[0][i] = 0;}for (int i = 1; i <= n; i++) {for (int j = 1; j <= m; j++) {int max1, max2, max3;max1 = solutionMatrix[i - 1][j];max2 = solutionMatrix[i][j - 1];if (s1.charAt(i - 1) == s2.charAt(j - 1)) {max3 = solutionMatrix[i - 1][j - 1] + 1;} else {max3 = solutionMatrix[i - 1][j - 1];}int tmp = Math.max(max1, max2);solutionMatrix[i][j] = Math.max(tmp, max3);}}System.out.println("Length of longest continuous subsequence: " + solutionMatrix[n][m]);}
}

输出:

Length of longest continuous subsequence: 8  

利用动态规划的其他问题:

利用动态规划可以解决很多问题,下面列举了一些:

  1. 分区问题:给定一组整数,找出它是否可以分成两个具有相等和的子集
  2. 子集和问题:给你一个正整数的数组及元素还有一个合计值,是否在数组中存在一个子集的的元素之和等于合计值。
  3. 硬币变化问题:鉴于给定面额的硬币无限供应,找到获得所需变化的不同方式的总数
  4. k变量线性方程的所有可能的解:给定k个变量的线性方程,计算它的可能解的总数
  5. 找到醉汉不会从悬崖上掉下来的概率:给定一个线性空间代表距离悬崖的距离,让你知道酒鬼从悬崖起始的距离,以及他向悬崖p前进并远离悬崖1-p的倾向,计算出他的生存概率

##结论:##
动态编程是一种工具,可以节省大量的计算时间,以换取更大的空间复杂性,这在很大程度上取决于您正在处理的系统类型,如果CPU时间很宝贵,您选择耗费内存的解决方案,另一方面,如果您的内存有限,则选择更耗时的解决方案

原文:https://stackabuse.com/dynamic-programming-in-java/

作者: Vladimir Batoćanin

译者:lee

在这里插入图片描述


http://chatgpt.dhexx.cn/article/6o2QOgpy.shtml

相关文章

PDF如何转换成jpg图片

PDF文件转换成jpg&#xff0c;有些人一看到问题可能有点懵逼&#xff0c;其实就是PDF转换成图片了&#xff0c;只要转换器中的PDF转图片功能中图片格式支持jpg格式&#xff0c;就可以直接转换成jpg图片了&#xff0c;比如奥凯丰 PDF转换大师&#xff0c;支持PDF转jpg、PDF转png…

数据结构和算法Java实现(韩顺平)

目录 稀疏数组 队列 数组模拟队列思路 数组模拟环形队列 链表 单链表的翻转 单链表的逆序输出&#xff08;栈&#xff09; 双向链表 Jasephu 问题 栈 数组模拟 栈实现计算器 中缀表达式 计算器 逆波兰表达式 &#xff08;后缀表达式&#xff09; 中缀转后缀实现计算…

pdf文件转图片(java实现)

项目中pdf文件太大&#xff0c;在手机端打开缓慢。需要将pdf文件转换成图片。加载比较快&#xff0c;增加用户体验。话不多说&#xff0c;直接上干货。 一、在pom引入依赖的jar <!-- https://mvnrepository.com/artifact/org.apache.pdfbox/fontbox --><dependency&g…

袋鼠云与中航金网达成战略合作并成立信创大数据联合实验室

当前&#xff0c;加快推进“新基建”已成为新形势下国家稳定经济发展的重要方针&#xff0c;而作为“新基建底座”的信创产业&#xff0c;有望成为未来中国十年科技发展的核心领域。纵观信创产业近五年发展&#xff0c;产品和技术已从“基本可用”向“好用易用”大跨步迈进&…

基于java实现PDF转图片图片合成PDF

平常在工作中&#xff0c;经常需要用到pdf转换成图片或者图片转换成pdf的功能。能将pdf转换成图片的工具比较多&#xff0c;比如wps就支持转换为图片&#xff0c;不过高清的转换需要开通会员才行&#xff0c;比较麻烦。免费的转换不光清晰度有问题&#xff0c;还存在水印等&…

《Java语言程序设计(第三版 沈泽刚)》编程练习2

编程练习 2 2.1 编写程序&#xff0c;从键盘上输入一个double类型的华氏温度&#xff0c;然后将其转换为摄氏温度输出。转换公式为&#xff1a; 摄氏度 &#xff08; 5 / 9 &#xff09;&#xff08;华氏度 − 32 &#xff09; 摄氏度&#xff08;5/9&#xff09;&#xff08…

PDF怎么转换成jpg图片保存?简单几步就能解决。

在我们的日常工作和生活中&#xff0c;我们经常会和别人在线传输各种文件。但是在传输Word文档、Excel表格、PPT等格式的文件时&#xff0c;文件内容排版和布局容易出现变化。因此&#xff0c;人们在传输文件时一般都将文件转换为PDF&#xff0c;但PDF文件在手机上观看并不方便…

pdf如何转换成jpg图片?

pdf如何转换成jpg图片&#xff1f;PDF&#xff08;Portable Document Format&#xff09;是一种常见的文件格式&#xff0c;由Adobe Systems创建。与其他文档格式相比&#xff0c;它具有固定页面布局和跨平台兼容性等优点&#xff0c;因此广泛应用于电子书、论文、技术手册、合…

PDF怎么转换成jpg图片

PDF怎么转换成jpg图片&#xff1f;在日常工作中&#xff0c;PDF文件是一种非常常用的格式类型。文件存储安全性高&#xff0c;可以保护用户文件的内容&#xff0c;文件的转换也很方便。支持多种文件类型&#xff0c;可自由切换。有的朋友还是比较习惯查阅图片格式的内容&#x…

动态规划(Java)

文章目录 前言一、背包问题二、字符串转化问题三、纸牌问题四、最少贴纸数总结 前言 动态规划的目的就是避免重复计算&#xff0c;在暴力递归的过程中若在计算过程中产生了重复计算那么就可以进行动态规划的优化。以空间换时间&#xff0c;可以根据暴力递归的过程写出动态规划…

袋鼠云与中航金网达成战略合作,成立信创大数据联合实验室

当前&#xff0c;加快推进“新基建”已成为新形势下国家稳定经济发展的重要方针&#xff0c;而作为“新基建底座”的信创产业&#xff0c;有望成为未来中国十年科技发展的核心领域。纵观信创产业近五年发展&#xff0c;产品和技术已从“基本可用”向“好用易用”大跨步迈进&…

北京市委书记蔡奇调研 PingCAP 立足自主研发和开源战略,助推产业数字化转型

2021 年 3 月&#xff0c;开源正式被列入国家十四五规划发展纲要&#xff0c;可以预期&#xff0c;开源将成为中国未来发展基础软硬件技术的关键路径。**3 月 23 日上午&#xff0c;北京市委书记蔡奇一行参观考察 PingCAP&#xff08;平凯星辰&#xff09;&#xff0c;专题调研…

如何把pdf转成图片?

怎么把pdf转成图片&#xff1f;作为上班族&#xff0c;能熟练的使用各种办公软件是职场必备技能&#xff0c;特别是在处理各种类型的文件时候&#xff0c;如果能熟练的将文件格式进行相互转换&#xff0c;那不仅能提升自己的工作效率&#xff0c;也会方便跟自己对接工作的人。就…

袋鼠云与沃趣科技达成战略合作,共同驱动企业数字化升级

12月3日,袋鼠云与沃趣科技正式达成战略合作,并于袋鼠云总部举行签约仪式。沃趣科技创始人&CEO 陈栋、联合创始人&CTO 李建辉、合伙人&总裁 郭华、技术中心负责人 魏兴华,袋鼠云创始人&董事长 陈吉平、联合创始人&CEO 徐进挺、联合创始人&易知微CEO 宁海…

袋鼠云陈吉平:深耕国产自研数字化技术与服务,持续为客户创造价值

在经济面临下行压力、疫情反复等不确定因素之下&#xff0c;推动数字化转型就成为了许多企业的“救命稻草”。然而&#xff0c;较高的数字化转型门槛、不成系统的数据服务&#xff0c;以及缺乏规范的行业标准等都成了企业数字化转型路上的“绊脚石”。 ​ 2015年&#xff0c;…

陈吉平-阿里巴巴离职DBA在35岁总结的职业生涯

导读&#xff1a;去年很多朋友私下或新浪微博上在总结自己的职业生涯与职业规划&#xff0c;也感觉到很纠结与彷徨&#xff0c;尤其技术人的职业生涯&#xff0c;随年龄增加&#xff0c;一些优势逐渐丧失。4月 13 日数据库技术大会的主办方举行的晚宴上&#xff0c;也让本人支持…

从产品到平台和生态,数据中台「竞争」升级

据可靠信源&#xff0c;中国首家数据中台公司袋鼠云已于去年年底完成C轮融资&#xff0c;由中信证券领投&#xff0c;东方富海、杭州凯泰资本跟投。 这意味着自去年以来颇受争议的数据中台赛道已经有公司率先突破C轮魔咒、迈上新台阶。 创投圈存在一个“C轮死”的魔咒&#xff…

B12专访 | 袋鼠云拖雷:未来十年是数据中台的黄金年代

B座12楼(以下简称“B12”&#xff09;&#xff0c;关注创业和投资的互联网媒体&#xff0c;精准覆盖创投圈数十万粉丝&#xff0c;让创新得到赞赏。 最近&#xff0c;B12找到拖雷&#xff0c;聊了聊大众对数据中台的认知误区、袋鼠云的数据中台“51”方法论以及袋鼠云的生态等&…

陈吉平的Oracle职业生涯:兴趣与思考 成败之所系

陈吉平的Oracle职业生涯&#xff1a;兴趣与思考 成败之所系 出处信息 编者按&#xff1a;这是陈吉平以前在ITPUB论坛上写下的职业生涯总结&#xff0c;随着时间推移&#xff0c;他早已经从技术岗位转向了管理&#xff0c;现在带领团队承担着淘宝无线的开发工作(现在淘宝拆分了&…